Merge branch 'release/Wagtail-anpassungen' into develop
# Conflicts: # server/core/settings.py # server/users/migrations/0032_alter_license_isbn.py
This commit is contained in:
commit
c432825aa8
|
|
@ -47,3 +47,4 @@ server/media/
|
|||
# test reports
|
||||
client/cypress/test-reports/
|
||||
server/test-reports/
|
||||
.direnv
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<div class="cms-document-block">
|
||||
<document-icon class="cms-document-block__icon" />
|
||||
<a
|
||||
:href="value.url"
|
||||
class="cms-document-block__link"
|
||||
target="_blank"
|
||||
>{{ value.display_text }}</a>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const DocumentIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/DocumentIcon');
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: Object,
|
||||
},
|
||||
|
||||
components: {
|
||||
DocumentIcon,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "~styles/helpers";
|
||||
|
||||
.cms-document-block {
|
||||
display: grid;
|
||||
grid-template-columns: 50px 1fr 50px;
|
||||
align-items: center;
|
||||
margin-bottom: $large-spacing;
|
||||
|
||||
&__icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
&__link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -31,6 +31,7 @@ const ImageUrlBlock = () => import(/* webpackChunkName: "content-components" */'
|
|||
const VideoBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/VideoBlock');
|
||||
const LinkBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/LinkBlock');
|
||||
const DocumentBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/DocumentBlock');
|
||||
const CmsDocumentBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/CmsDocumentBlock');
|
||||
const InfogramBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/InfogramBlock');
|
||||
const ThinglinkBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/ThinglinkBlock');
|
||||
const GeniallyBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/GeniallyBlock');
|
||||
|
|
@ -88,6 +89,7 @@ export default {
|
|||
'content_list': ContentListBlock,
|
||||
'module_room_slug': ModuleRoomSlug,
|
||||
'thinglink_block': ThinglinkBlock,
|
||||
'cms_document_block': CmsDocumentBlock,
|
||||
Survey,
|
||||
Solution,
|
||||
Instruction,
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "~styles/helpers";
|
||||
|
||||
.image-block {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
border-radius: 13px;
|
||||
margin-bottom: 30px;
|
||||
margin-bottom: $large-spacing;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -24,3 +24,24 @@ To see the backup schedule
|
|||
|
||||
To download a backup use
|
||||
`heroku pg:backups:download --app <appname>`
|
||||
|
||||
|
||||
### Load a backup locally
|
||||
|
||||
Be careful since you download user data as well. Therefore use preprod app by
|
||||
default, it is anonymized.
|
||||
|
||||
####Download backup
|
||||
|
||||
`heroku pg:backups:download --app <appname>`
|
||||
|
||||
|
||||
####Load dump file into your db
|
||||
|
||||
To download a backup
|
||||
`pg_restore --verbose --clean --no-acl --no-owner -h localhost -U skillbox -d skillbox latest.dump`
|
||||
|
||||
Add
|
||||
|
||||
python manage.py migrate
|
||||
python manage.py dummy_users
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ from graphene.types import Scalar
|
|||
from graphene_django.converter import convert_django_field
|
||||
from graphql_relay import to_global_id
|
||||
from wagtail.core.fields import StreamField
|
||||
from wagtail.documents.models import Document
|
||||
from wagtail.images.models import Image
|
||||
|
||||
from assignments.models import Assignment
|
||||
from basicknowledge.models import BasicKnowledge
|
||||
from books.models import CustomDocument
|
||||
from surveys.models import Survey
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -85,6 +87,23 @@ def augment_fields(raw_data):
|
|||
item_data = data['value']
|
||||
data['value'] = augment_fields(item_data)
|
||||
|
||||
if _type == 'cms_document_block':
|
||||
try:
|
||||
_value = data['value']
|
||||
document = CustomDocument.objects.get(id=_value)
|
||||
value = {
|
||||
'value': _value,
|
||||
'id': document.id,
|
||||
'file_name': document.filename,
|
||||
'file_extension': document.file_extension,
|
||||
'url': document.url,
|
||||
'title': document.title,
|
||||
'display_text': document.display_text
|
||||
}
|
||||
data['value'] = value
|
||||
except CustomDocument.DoesNotExist:
|
||||
logger.error('CustomDocument {} does not exist'.format(_value))
|
||||
|
||||
return raw_data
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ class Assignment(index.Indexed, TimeStampedModel):
|
|||
taskbase_id = models.CharField(max_length=255, null=True, blank=True)
|
||||
|
||||
search_fields = [
|
||||
index.SearchField('title', partial_match=True)
|
||||
index.SearchField('title', partial_match=True),
|
||||
index.SearchField('assignment', partial_match=True),
|
||||
]
|
||||
|
||||
panels = [
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ from .models import Assignment
|
|||
class AssignmentAdmin(ModelAdmin):
|
||||
model = Assignment
|
||||
menu_label = 'Assignments'
|
||||
list_display = ('title', 'module', 'pk',)
|
||||
list_display = ('title', 'module', 'assignment')
|
||||
search_fields = ('title', 'assignment')
|
||||
menu_icon = 'form'
|
||||
|
||||
|
||||
modeladmin_register(AssignmentAdmin)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 3.2.13 on 2022-07-28 08:48
|
||||
|
||||
from django.db import migrations
|
||||
import wagtail.core.blocks
|
||||
import wagtail.core.fields
|
||||
import wagtail.documents.blocks
|
||||
import wagtail.images.blocks
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('basicknowledge', '0017_auto_20220630_0743'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='basicknowledge',
|
||||
name='contents',
|
||||
field=wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['bold', 'ul', 'brand', 'secondary']))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('section_title', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('infogram_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock()), ('title', wagtail.core.blocks.TextBlock())])), ('genially_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('thinglink_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('cms_document_block', wagtail.documents.blocks.DocumentChooserBlock())], blank=True, null=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -2,6 +2,7 @@ from django.db import models
|
|||
from django.utils.text import slugify
|
||||
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel
|
||||
from wagtail.core.fields import RichTextField, StreamField
|
||||
from wagtail.documents.blocks import DocumentChooserBlock
|
||||
from wagtail.images.blocks import ImageChooserBlock
|
||||
|
||||
from books.blocks import DocumentBlock, GeniallyBlock, InfogramBlock, InstrumentTextBlock, LinkBlock, SectionTitleBlock, \
|
||||
|
|
@ -35,6 +36,7 @@ class InstrumentType(models.Model):
|
|||
return self.type
|
||||
|
||||
|
||||
|
||||
class BasicKnowledge(StrictHierarchyPage):
|
||||
parent_page_types = ['books.book']
|
||||
|
||||
|
|
@ -51,6 +53,7 @@ class BasicKnowledge(StrictHierarchyPage):
|
|||
('genially_block', GeniallyBlock()),
|
||||
('thinglink_block', ThinglinkBlock()),
|
||||
('subtitle', SubtitleBlock()),
|
||||
('cms_document_block', DocumentChooserBlock()),
|
||||
], null=True, blank=True)
|
||||
|
||||
new_type = models.ForeignKey(InstrumentType, null=True, on_delete=models.PROTECT, related_name='instruments')
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ from .models import BasicKnowledge
|
|||
class InstrumentAdmin(ModelAdmin):
|
||||
model = BasicKnowledge
|
||||
menu_label = 'Instruments'
|
||||
list_display = ('title', 'new_type')
|
||||
list_display = ('title', 'new_type', 'status_string')
|
||||
search_fields = ('title', 'new_type__name')
|
||||
|
||||
|
||||
modeladmin_register(InstrumentAdmin)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Iterativ GmbH
|
||||
# http://www.iterativ.ch/
|
||||
#
|
||||
# Copyright (c) 2015 Iterativ GmbH. All rights reserved.
|
||||
#
|
||||
# Created on 2022-08-02
|
||||
# @author: lorenz.padberg@iterativ.ch
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
from django.core.management import BaseCommand
|
||||
|
||||
from books.migrate_document_model import migrate_documents_to_custom_document_model
|
||||
from books.models import Module
|
||||
from surveys.models import Survey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
self.stdout.write("Migrating Wagtail documents to Custommyskillbox documents")
|
||||
migrate_documents_to_custom_document_model()
|
||||
self.stdout.write("Finish migration")
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
from .models.custom_document import CustomDocument
|
||||
|
||||
|
||||
def migrate_documents_to_custom_document_model(dryrun=False):
|
||||
try:
|
||||
from wagtail.documents.models import Document
|
||||
all_documents = Document.objects.all()
|
||||
except Exception as e:
|
||||
# new databases do not have the table for the standart wagtail documents there fore the migration is not
|
||||
# necessary. Mainly
|
||||
return
|
||||
print(f"Found {all_documents.count()} Documents")
|
||||
|
||||
for document in all_documents:
|
||||
tags = document.title.replace(':', '').split(' ')
|
||||
|
||||
if dryrun:
|
||||
print('')
|
||||
print(document.title)
|
||||
print(tags)
|
||||
print(document.created_at)
|
||||
print(document.url)
|
||||
print(document.file)
|
||||
print(document.uploaded_by_user)
|
||||
|
||||
else:
|
||||
print('')
|
||||
new_document, created = CustomDocument.objects.get_or_create(title=document.title)
|
||||
new_document.display_text = document.title
|
||||
new_document.created_at = document.created_at
|
||||
new_document.uploaded_by_user = document.uploaded_by_user
|
||||
new_document.file = document.file
|
||||
new_document.collection = document.collection
|
||||
new_document.file_hash = document.file_hash
|
||||
new_document.file_size = document.file_size
|
||||
|
||||
new_document.save()
|
||||
if created:
|
||||
print(f'Created New Document {new_document}')
|
||||
else:
|
||||
print(f'Udated document {document}')
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
# Generated by Django 3.2.13 on 2022-07-28 08:48
|
||||
|
||||
import assignments.models
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import surveys.models
|
||||
import taggit.managers
|
||||
import wagtail.core.blocks
|
||||
import wagtail.core.fields
|
||||
import wagtail.core.models.collections
|
||||
import wagtail.documents.blocks
|
||||
import wagtail.images.blocks
|
||||
import wagtail.search.index
|
||||
import wagtail.snippets.blocks
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('taggit', '0004_alter_taggeditem_content_type_alter_taggeditem_tag'),
|
||||
('wagtailcore', '0066_collection_management_permissions'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('books', '0034_alter_contentblock_contents'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='contentblock',
|
||||
name='contents',
|
||||
field=wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul', 'bold']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(page_type=['basicknowledge.BasicKnowledge'], required=True))])), ('assignment', wagtail.core.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.core.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('solution', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul', 'bold']))], icon='tick')), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('infogram_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock()), ('title', wagtail.core.blocks.TextBlock())])), ('genially_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('thinglink_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('instruction', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('text', wagtail.core.blocks.TextBlock(required=False))])), ('module_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())])), ('cms_document_block', wagtail.documents.blocks.DocumentChooserBlock()), ('content_list_item', wagtail.core.blocks.StreamBlock([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul', 'bold']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(page_type=['basicknowledge.BasicKnowledge'], required=True))])), ('assignment', wagtail.core.blocks.StructBlock([('assignment_id', wagtail.snippets.blocks.SnippetChooserBlock(assignments.models.Assignment))])), ('survey', wagtail.core.blocks.StructBlock([('survey_id', wagtail.snippets.blocks.SnippetChooserBlock(surveys.models.Survey))])), ('image_block', wagtail.images.blocks.ImageChooserBlock()), ('image_url_block', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('solution', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul', 'bold']))], icon='tick')), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('infogram_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock()), ('title', wagtail.core.blocks.TextBlock())])), ('genially_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('thinglink_block', wagtail.core.blocks.StructBlock([('id', wagtail.core.blocks.TextBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('instruction', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock()), ('text', wagtail.core.blocks.TextBlock(required=False))])), ('module_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())])), ('cms_document_block', wagtail.documents.blocks.DocumentChooserBlock())]))], blank=True, null=True),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomDocument',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=255, verbose_name='title')),
|
||||
('file', models.FileField(upload_to='documents', verbose_name='file')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')),
|
||||
('file_size', models.PositiveIntegerField(editable=False, null=True)),
|
||||
('file_hash', models.CharField(blank=True, editable=False, max_length=40)),
|
||||
('display_text', models.CharField(default='', max_length=1024)),
|
||||
('collection', models.ForeignKey(default=wagtail.core.models.collections.get_root_collection_id, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.collection', verbose_name='collection')),
|
||||
('tags', taggit.managers.TaggableManager(blank=True, help_text=None, through='taggit.TaggedItem', to='taggit.Tag', verbose_name='tags')),
|
||||
('uploaded_by_user', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='uploaded by user')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'document',
|
||||
'verbose_name_plural': 'documents',
|
||||
'abstract': False,
|
||||
},
|
||||
bases=(wagtail.search.index.Indexed, models.Model),
|
||||
),
|
||||
]
|
||||
|
|
@ -4,3 +4,4 @@ from .topic import *
|
|||
from .chapter import *
|
||||
from .contentblock import *
|
||||
from .snapshot import *
|
||||
from .custom_document import *
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from django.db import models
|
|||
from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList, StreamFieldPanel
|
||||
from wagtail.core.blocks import StreamBlock
|
||||
from wagtail.core.fields import StreamField
|
||||
from wagtail.documents.blocks import DocumentChooserBlock
|
||||
from wagtail.images.blocks import ImageChooserBlock
|
||||
|
||||
from core.wagtail_utils import get_default_settings
|
||||
|
|
@ -63,7 +64,8 @@ class ContentBlock(StrictHierarchyPage):
|
|||
('thinglink_block', ThinglinkBlock()),
|
||||
('subtitle', SubtitleBlock()),
|
||||
('instruction', InstructionBlock()),
|
||||
('module_room_slug', ModuleRoomSlugBlock())
|
||||
('module_room_slug', ModuleRoomSlugBlock()),
|
||||
('cms_document_block', DocumentChooserBlock())
|
||||
]
|
||||
|
||||
content_list_item = StreamBlock(content_blocks)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
from django.db import models
|
||||
|
||||
from wagtail.documents.models import Document, AbstractDocument
|
||||
|
||||
|
||||
class CustomDocument(AbstractDocument):
|
||||
# Custom field example:
|
||||
display_text = models.CharField(
|
||||
max_length=1024, default='')
|
||||
|
||||
admin_form_fields = Document.admin_form_fields + (
|
||||
'display_text',
|
||||
)
|
||||
|
|
@ -1,6 +1,3 @@
|
|||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList
|
||||
|
|
@ -52,7 +49,9 @@ class Module(StrictHierarchyPage):
|
|||
parent_page_types = ['books.Topic']
|
||||
subpage_types = ['books.Chapter']
|
||||
|
||||
#todo: isn't this a duplicate definition?
|
||||
|
||||
|
||||
# todo: isn't this a duplicate definition?
|
||||
def get_child_ids(self):
|
||||
return self.get_children().values_list('id', flat=True)
|
||||
|
||||
|
|
@ -93,6 +92,8 @@ class Module(StrictHierarchyPage):
|
|||
for objective_group in objective_groups:
|
||||
objective_group.sync_visibility(school_class_template, school_class_to_sync)
|
||||
|
||||
def get_admin_display_title(self):
|
||||
return f"{self.meta_title} - {self.title}"
|
||||
|
||||
|
||||
class RecentModule(models.Model):
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ class Topic(StrictHierarchyPage):
|
|||
FieldPanel('description'),
|
||||
]
|
||||
|
||||
|
||||
edit_handler = TabbedInterface([
|
||||
ObjectList(content_panels, heading='Content'),
|
||||
get_default_settings()
|
||||
|
|
@ -40,3 +39,7 @@ class Topic(StrictHierarchyPage):
|
|||
|
||||
parent_page_types = ['books.Book']
|
||||
subpage_types = ['books.Module']
|
||||
|
||||
def get_admin_display_title(self):
|
||||
return f"" \
|
||||
f"{self.get_verbose_name()}- {self.title}"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class InputTypes(graphene.Enum):
|
|||
video_block = 'video_block'
|
||||
document_block = 'document_block'
|
||||
content_list_item = 'content_list_item'
|
||||
subtitle= 'subtitle'
|
||||
subtitle = 'subtitle'
|
||||
|
||||
|
||||
class ContentElementValueInput(InputObjectType):
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ ALLOWED_BLOCKS = (
|
|||
'assignment',
|
||||
'document_block',
|
||||
'content_list_item',
|
||||
'subtitle'
|
||||
'subtitle',
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
from django.test import TestCase
|
||||
from wagtail.documents.models import Document
|
||||
|
||||
from books.migrate_document_model import migrate_documents_to_custom_document_model
|
||||
from books.models.custom_document import CustomDocument
|
||||
|
||||
TITLE = 'T9 M2 A2: Quellencheck'
|
||||
|
||||
|
||||
class NewContentBlockMutationTest(TestCase):
|
||||
def setUp(self):
|
||||
old_document, created = Document.objects.get_or_create(title=TITLE, file='whatever_is_green.pdf')
|
||||
migrate_documents_to_custom_document_model()
|
||||
|
||||
def test_migrate_creates_new_document(self):
|
||||
self.assertEqual(Document.objects.all().count(), 1)
|
||||
self.assertEqual(Document.objects.filter(title=TITLE).count(), 1)
|
||||
self.assertEqual(CustomDocument.objects.filter(title=TITLE).count(), 1)
|
||||
|
||||
def test_migrate_display_title_migration(self):
|
||||
new_document = CustomDocument.objects.get(title=TITLE)
|
||||
self.assertEqual(new_document.display_text, TITLE)
|
||||
|
||||
def test_migration_is_indempodent(self):
|
||||
migrate_documents_to_custom_document_model()
|
||||
migrate_documents_to_custom_document_model()
|
||||
self.assertEqual(Document.objects.all().count(), 1)
|
||||
self.assertEqual(Document.objects.filter(title=TITLE).count(), 1)
|
||||
self.assertEqual(CustomDocument.objects.filter(title=TITLE).count(), 1)
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
from django.core.management import BaseCommand
|
||||
|
||||
from core.factories import UserFactory
|
||||
from users.services import create_users, create_student
|
||||
from .data.user_data import user_data
|
||||
|
||||
from users.models import User
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
UserFactory(
|
||||
username='test',
|
||||
is_staff=True,
|
||||
is_superuser=True,
|
||||
first_name='Nicol',
|
||||
last_name='Bolas',
|
||||
onboarding_visited=True
|
||||
)
|
||||
|
||||
create_users(user_data)
|
||||
|
||||
# create student without class
|
||||
create_student(
|
||||
username='hansli',
|
||||
first_name='Hansli',
|
||||
last_name='Alleini'
|
||||
)
|
||||
|
||||
users = User.objects.all()
|
||||
|
||||
for usr in users:
|
||||
print(usr.email)
|
||||
usr.set_password('test')
|
||||
usr.save()
|
||||
|
||||
|
||||
|
|
@ -367,6 +367,8 @@ WAGTAILSEARCH_BACKENDS = {
|
|||
'BACKEND': 'wagtail.search.backends.database',
|
||||
}
|
||||
}
|
||||
WAGTAILDOCS_DOCUMENT_MODEL = 'books.CustomDocument'
|
||||
|
||||
|
||||
GRAPHQL_QUERIES_DIR = os.path.join(BASE_DIR, '..', 'client', 'src', 'graphql', 'gql', 'queries')
|
||||
GRAPHQL_MUTATIONS_DIR = os.path.join(GRAPHQL_QUERIES_DIR, '../mutations')
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
{# This template is overwritten to create a custom cms ui for the model "chapter" to improve navigation experience.#}
|
||||
{# See MS-538#}
|
||||
|
||||
{% load i18n %}
|
||||
{% load l10n %}
|
||||
{% load wagtailadmin_tags %}
|
||||
<table class="listing {% if full_width %}full-width{% endif %} {% block table_classname %}{% endblock %}">
|
||||
{% if show_ordering_column or show_bulk_actions %}
|
||||
<col width="10px"/>
|
||||
{% endif %}
|
||||
<col/>
|
||||
{% if show_parent %}
|
||||
<col/>
|
||||
{% endif %}
|
||||
<col width="12%"/>
|
||||
<col width="12%"/>
|
||||
<col width="12%"/>
|
||||
<col width="10%"/>
|
||||
<thead>
|
||||
{% block pre_parent_page_headers %}
|
||||
{% endblock %}
|
||||
|
||||
{% if parent_page %}
|
||||
{% page_permissions parent_page as parent_page_perms %}
|
||||
<tr class="index {% if not parent_page.live %} unpublished{% endif %}
|
||||
{% block parent_page_row_classname %}{% endblock %}">
|
||||
<td class="title"{% if show_ordering_column or show_bulk_actions %} colspan="2"{% endif %}>
|
||||
{% block parent_page_title %}
|
||||
{% endblock %}
|
||||
</td>
|
||||
<td class="updated" valign="bottom">{% if parent_page.latest_revision_created_at %}
|
||||
<div class="human-readable-date"
|
||||
title="{{ parent_page.latest_revision_created_at|date:"DATETIME_FORMAT" }}">
|
||||
{% blocktrans with time_period=parent_page.latest_revision_created_at|timesince %}{{ time_period }}
|
||||
ago{% endblocktrans %}</div>{% endif %}</td>
|
||||
<td class="type" valign="bottom">
|
||||
{% if not parent_page.is_root %}
|
||||
{{ parent_page.content_type.model_class.get_verbose_name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="status" valign="bottom">
|
||||
{% if not parent_page.is_root %}
|
||||
{% include "wagtailadmin/shared/page_status_tag.html" with page=parent_page %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
{% block post_parent_page_headers %}
|
||||
{% endblock %}
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if pages %}
|
||||
{% trans "Select page" as checkbox_aria_label %}
|
||||
{% for page in pages %}
|
||||
{% page_permissions page as page_perms %}
|
||||
<tr {% if ordering == "ord" %}id="page_{{ page.id|unlocalize }}"
|
||||
data-page-title="{{ page.get_admin_display_title }}"{% endif %}
|
||||
class="{% if not page.live %}unpublished{% endif %} {% block page_row_classname %}{% endblock %}">
|
||||
{% if show_ordering_column %}
|
||||
<td class="ord">{% if orderable and ordering == "ord" %}
|
||||
<div class="handle icon icon-grip text-replace">{% trans 'Drag' %}</div>{% endif %}</td>
|
||||
{% elif show_bulk_actions %}
|
||||
{% include "wagtailadmin/bulk_actions/listing_checkbox_cell.html" with obj_type="page" obj=page aria_labelledby_prefix="page_" aria_labelledby=page.pk|unlocalize aria_labelledby_suffix="_title" %}
|
||||
{% endif %}
|
||||
<td id="page_{{ page.pk|unlocalize }}_title" class="title" valign="top" data-listing-page-title>
|
||||
|
||||
{% block page_title %}
|
||||
{% endblock %}
|
||||
{% if page.content_type.model == 'chapter' %}
|
||||
<div style="margin-top:10px; padding-left: 30px">
|
||||
<ul>
|
||||
{% for c in page.get_children %}
|
||||
{% if not c.specific.user_created and not c.specific.contentblocksnapshot %}
|
||||
<li>
|
||||
{% if page_perms.can_edit %}
|
||||
<a href="{% url 'wagtailadmin_pages:edit' c.id %}"
|
||||
title="{% trans 'Edit this page' %}"> {{ c.get_admin_display_title }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ c.get_admin_display_title }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if show_parent %}
|
||||
<td class="parent" valign="top">
|
||||
{% block page_parent_page_title %}
|
||||
{% with page.get_parent as parent %}
|
||||
{% if parent %}
|
||||
<a href="{% url 'wagtailadmin_explore' parent.id %}">{{ parent.specific_deferred.get_admin_display_title }}</a>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="updated" valign="top">{% if page.latest_revision_created_at %}
|
||||
<div class="human-readable-date"
|
||||
title="{{ page.latest_revision_created_at|date:"DATETIME_FORMAT" }}">
|
||||
{% blocktrans with time_period=page.latest_revision_created_at|timesince %}{{ time_period }}
|
||||
ago{% endblocktrans %}</div>{% endif %}</td>
|
||||
<td class="type" valign="top">{{ page.content_type.model_class.get_verbose_name }}</td>
|
||||
<td class="status" valign="top">
|
||||
{% include "wagtailadmin/shared/page_status_tag.html" with page=page %}
|
||||
</td>
|
||||
|
||||
|
||||
{% block page_navigation %}
|
||||
{% endblock %}
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% block no_results %}{% endblock %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
@ -6,10 +6,12 @@ from django.urls import re_path
|
|||
from django.views.generic import RedirectView
|
||||
from wagtail.admin import urls as wagtailadmin_urls
|
||||
from wagtail.core import urls as wagtail_urls
|
||||
from wagtail.documents import urls as wagtaildocs_urls
|
||||
|
||||
from wagtailautocomplete.urls.admin import urlpatterns as autocomplete_admin_urls
|
||||
|
||||
from core import views
|
||||
|
||||
from core.views import override_wagtailadmin_explore_default_ordering
|
||||
|
||||
urlpatterns = [
|
||||
# django admin
|
||||
|
|
@ -18,7 +20,9 @@ urlpatterns = [
|
|||
|
||||
# wagtail
|
||||
url(r'^admin/autocomplete/', include(autocomplete_admin_urls)),
|
||||
re_path(r'^cms/pages/(\d+)/$', override_wagtailadmin_explore_default_ordering),
|
||||
url(r'^cms/', include(wagtailadmin_urls)),
|
||||
url(r'^documents/', include(wagtaildocs_urls)),
|
||||
|
||||
# graphql backend
|
||||
url(r'^api/', include('api.urls', namespace="api")),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import requests
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.http.response import HttpResponse
|
||||
from django.http.response import HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||
from django.views.generic import TemplateView
|
||||
from graphene_django.views import GraphQLView
|
||||
from wagtail.admin.views.pages.listing import index as wagtailadmin_explore
|
||||
|
||||
|
||||
class PrivateGraphQLView(LoginRequiredMixin, GraphQLView):
|
||||
|
|
@ -24,3 +24,14 @@ def home(request):
|
|||
print('Can not connect to dev server at http://localhost:8080:', e)
|
||||
|
||||
return render(request, 'index.html', {})
|
||||
|
||||
|
||||
def override_wagtailadmin_explore_default_ordering(request, parent_page_id):
|
||||
"""
|
||||
Wrap Wagtail's explore view to change the default ordering
|
||||
"""
|
||||
if request.method == 'GET' and 'ordering' not in request.GET:
|
||||
# Display reordering handles by default for children of all Page types.
|
||||
return HttpResponseRedirect(request.path_info + '?ordering=ord')
|
||||
|
||||
return wagtailadmin_explore(request, parent_page_id=parent_page_id)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,26 @@
|
|||
# Generated by Django 3.2.13 on 2022-07-28 08:48
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import wagtail.core.blocks
|
||||
import wagtail.core.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rooms', '0011_alter_roomentry_contents'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='comment',
|
||||
name='room_entry',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='rooms.roomentry'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='roomentry',
|
||||
name='contents',
|
||||
field=wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul', 'bold']))])), ('image_url_block', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('link_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock()), ('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('subtitle', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.TextBlock())])), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())]))], blank=True, null=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -2,15 +2,21 @@ from django.contrib.auth import get_user_model
|
|||
from django.db import models
|
||||
from django.db.models import JSONField
|
||||
from wagtail.snippets.models import register_snippet
|
||||
from wagtail.search import index
|
||||
|
||||
|
||||
@register_snippet
|
||||
class Survey(models.Model):
|
||||
class Survey(models.Model, index.Indexed):
|
||||
title = models.CharField(max_length=255)
|
||||
module = models.ForeignKey('books.Module', related_name='surveys', on_delete=models.CASCADE, null=True,
|
||||
blank=True)
|
||||
data = JSONField()
|
||||
|
||||
search_fields = [
|
||||
index.SearchField('title', partial_match=True),
|
||||
index.SearchField('module__meta_title', partial_match=True),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
||||
from .models import Survey
|
||||
|
||||
|
||||
class SurveyAdmin(ModelAdmin):
|
||||
model = Survey
|
||||
menu_label = 'Surveys'
|
||||
list_display = ('title', 'module')
|
||||
search_fields = ('title', 'module__meta_title')
|
||||
menu_icon = 'help'
|
||||
|
||||
|
||||
modeladmin_register(SurveyAdmin)
|
||||
|
||||
Loading…
Reference in New Issue