diff --git a/client/src/components/content-blocks/BasicKnowledgeWidget.vue b/client/src/components/content-blocks/BasicKnowledgeWidget.vue index 7c77c695..108cf72e 100644 --- a/client/src/components/content-blocks/BasicKnowledgeWidget.vue +++ b/client/src/components/content-blocks/BasicKnowledgeWidget.vue @@ -1,7 +1,9 @@ diff --git a/client/src/graphql/gql/basicKnowledgeQuery.gql b/client/src/graphql/gql/basicKnowledgeQuery.gql new file mode 100644 index 00000000..cce9849e --- /dev/null +++ b/client/src/graphql/gql/basicKnowledgeQuery.gql @@ -0,0 +1,9 @@ +query BasicKnowledgeQuery($slug: String!){ + basicKnowledge(slug: $slug) { + id + title + slug + type + contents + } +} diff --git a/client/src/pages/basicknowledge.vue b/client/src/pages/basicknowledge.vue index 99fa5a46..80ebc31b 100644 --- a/client/src/pages/basicknowledge.vue +++ b/client/src/pages/basicknowledge.vue @@ -1,94 +1,38 @@ + + diff --git a/client/src/pages/module-base.vue b/client/src/pages/module-base.vue index 0b02eed6..6e2444f8 100644 --- a/client/src/pages/module-base.vue +++ b/client/src/pages/module-base.vue @@ -22,7 +22,8 @@ display: grid; } justify-items: center; - grid-template-columns: 400px 1fr 400px; + + grid-template-columns: 400px minmax(max-content, 1fr) minmax(auto, 400px); /* * For IE10+ diff --git a/client/src/router/index.js b/client/src/router/index.js index 0c04c4cb..7e577927 100644 --- a/client/src/router/index.js +++ b/client/src/router/index.js @@ -43,7 +43,7 @@ const routes = [ {path: '/edit-room/:id', name: 'edit-room', component: editRoom, props: true}, {path: '/room/:slug', name: 'room', component: room, props: true}, {path: '/article/:slug', name: 'article', component: article, meta: {layout: 'simple'}}, - {path: '/basic-knowledge', name: 'basic-knowledge', component: basicknowledge, meta: {layout: 'simple'}}, + {path: '/basic-knowledge/:slug', name: 'basic-knowledge', component: basicknowledge, meta: {layout: 'simple'}}, {path: '/submission/:id', name: 'submission', component: submission, meta: {layout: 'simple'}}, { path: '/book', diff --git a/server/api/graphene_wagtail.py b/server/api/graphene_wagtail.py index 26a82c6f..4002fb65 100644 --- a/server/api/graphene_wagtail.py +++ b/server/api/graphene_wagtail.py @@ -8,6 +8,7 @@ from wagtail.core.fields import StreamField from wagtail.images.models import Image from assignments.models import Assignment +from basicknowledge.models import BasicKnowledge class GenericStreamFieldType(Scalar): @@ -35,20 +36,27 @@ class GenericStreamFieldType(Scalar): 'id': to_global_id('AssignmentNode', assignment.pk) } d['value'] = value + if _type == 'basic_knowledge': + _value = d['value'] + basic_knowledge = BasicKnowledge.objects.get(pk=_value['basic_knowledge']) + _value.update({ + 'slug': basic_knowledge.slug + }) + d['value'] = _value - # value = dict(d['value']) - # if 'document' in value: - # value['document'] = Document.objects.get(id=value['document']).file.url - # if 'image' in value: - # value['image'] = Image.objects.get(id=value['image']).file.url + # value = dict(d['value']) + # if 'document' in value: + # value['document'] = Document.objects.get(id=value['document']).file.url + # if 'image' in value: + # value['image'] = Image.objects.get(id=value['image']).file.url - # else: - # _type = d[0] - # value = dict(d[1]) - # if 'document' in value: - # value['document'] = value['document'].file.url - # if 'image' in value: - # value['image'] = value['image'].file.url + # else: + # _type = d[0] + # value = dict(d[1]) + # if 'document' in value: + # value['document'] = value['document'].file.url + # if 'image' in value: + # value['image'] = value['image'].file.url return stream_data diff --git a/server/api/schema.py b/server/api/schema.py index 3a6287eb..97ba521f 100644 --- a/server/api/schema.py +++ b/server/api/schema.py @@ -7,6 +7,7 @@ from graphene_django.debug import DjangoDebug from api import graphene_wagtail # Keep this import exactly here, it's necessary for StreamField conversion from assignments.schema.mutations import AssignmentMutations from assignments.schema.queries import AssignmentsQuery, StudentSubmissionQuery +from basicknowledge.queries import BasicKnowledgeQuery from books.schema.mutations.main import BookMutations from books.schema.queries import BookQuery from core.schema.mutations.main import CoreMutations @@ -18,7 +19,7 @@ from users.schema import UsersQuery class Query(UsersQuery, RoomsQuery, ObjectivesQuery, BookQuery, AssignmentsQuery, StudentSubmissionQuery, - graphene.ObjectType): + BasicKnowledgeQuery, graphene.ObjectType): node = relay.Node.Field() if settings.DEBUG: diff --git a/server/basicknowledge/__init__.py b/server/basicknowledge/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/basicknowledge/migrations/0001_initial.py b/server/basicknowledge/migrations/0001_initial.py new file mode 100644 index 00000000..74da6d78 --- /dev/null +++ b/server/basicknowledge/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 2.0.6 on 2018-10-25 08:59 + +from django.db import migrations, models +import django.db.models.deletion +import wagtail.core.blocks +import wagtail.core.fields +import wagtail.images.blocks + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('wagtailcore', '0040_page_draft_title'), + ] + + operations = [ + migrations.CreateModel( + name='BasicKnowledge', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')), + ('contents', wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())])), ('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())]))], blank=True, null=True)), + ('type', models.CharField(choices=[('language_communication', 'Sprache & Kommunikation'), ('society', 'Gesellschaft')], max_length=100)), + ], + options={ + 'abstract': False, + }, + bases=('wagtailcore.page',), + ), + ] diff --git a/server/basicknowledge/migrations/__init__.py b/server/basicknowledge/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/server/basicknowledge/models.py b/server/basicknowledge/models.py new file mode 100644 index 00000000..c7003227 --- /dev/null +++ b/server/basicknowledge/models.py @@ -0,0 +1,38 @@ +from django.db import models +from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel +from wagtail.core.fields import StreamField +from wagtail.images.blocks import ImageChooserBlock + +from books.blocks import TextBlock, LinkBlock, VideoBlock, DocumentBlock +from core.wagtail_utils import StrictHierarchyPage + + +class BasicKnowledge(StrictHierarchyPage): + parent_page_types = ['books.book'] + + contents = StreamField([ + ('text_block', TextBlock()), + ('image_block', ImageChooserBlock()), + ('link_block', LinkBlock()), + ('video_block', VideoBlock()), + ('document_block', DocumentBlock()), + ], null=True, blank=True) + + LANGUAGE_COMMUNICATION = 'language_communication' + SOCIETY = 'society' + + TYPE_CHOICES = ( + (LANGUAGE_COMMUNICATION, 'Sprache & Kommunikation'), + (SOCIETY, 'Gesellschaft'), + ) + + type = models.CharField( + max_length=100, + choices=TYPE_CHOICES + ) + + content_panels = [ + FieldPanel('title', classname="full title"), + FieldPanel('type'), + StreamFieldPanel('contents') + ] diff --git a/server/basicknowledge/queries.py b/server/basicknowledge/queries.py new file mode 100644 index 00000000..aadb4eca --- /dev/null +++ b/server/basicknowledge/queries.py @@ -0,0 +1,32 @@ +import graphene +from graphene import relay +from graphene_django import DjangoObjectType +from graphene_django.filter import DjangoFilterConnectionField + +from api.utils import get_object +from .models import BasicKnowledge + + +class BasicKnowledgeNode(DjangoObjectType): + class Meta: + model = BasicKnowledge + filter_fields = ['slug'] + interfaces = (relay.Node,) + only_fields = [ + 'slug', 'title', 'type', 'contents', + ] + + +class BasicKnowledgeQuery(object): + basic_knowledge = graphene.Field(BasicKnowledgeNode, slug=graphene.String(), id=graphene.ID()) + basic_knowledge_pages = DjangoFilterConnectionField(BasicKnowledgeNode) + + def resolve_basic_knowledge(self, info, **kwargs): + slug = kwargs.get('slug') + room_id = kwargs.get('id') + + if room_id is not None: + return get_object(BasicKnowledge, room_id) + if slug is not None: + return BasicKnowledge.objects.get(slug=slug) + return None diff --git a/server/basicknowledge/wagtail_hooks.py b/server/basicknowledge/wagtail_hooks.py new file mode 100644 index 00000000..864a3404 --- /dev/null +++ b/server/basicknowledge/wagtail_hooks.py @@ -0,0 +1,11 @@ +from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register +from .models import BasicKnowledge + + +class BasicKnowledgeAdmin(ModelAdmin): + model = BasicKnowledge + menu_label = 'Basiswissen' + list_display = ('title',) + + +modeladmin_register(BasicKnowledgeAdmin) diff --git a/server/books/blocks.py b/server/books/blocks.py index 689a7c56..71c8583a 100644 --- a/server/books/blocks.py +++ b/server/books/blocks.py @@ -26,7 +26,7 @@ class BasicKnowledgeBlock(blocks.StructBlock): icon = 'placeholder' description = blocks.RichTextBlock() - url = blocks.URLBlock() + basic_knowledge = blocks.PageChooserBlock(required=True, target_model='basicknowledge.BasicKnowledge') # 'image_url' diff --git a/server/books/migrations/0005_auto_20181025_1155.py b/server/books/migrations/0005_auto_20181025_1155.py new file mode 100644 index 00000000..df4b8931 --- /dev/null +++ b/server/books/migrations/0005_auto_20181025_1155.py @@ -0,0 +1,21 @@ +# Generated by Django 2.0.6 on 2018-10-25 11:55 + +from django.db import migrations +import wagtail.core.blocks +import wagtail.core.fields +import wagtail.images.blocks + + +class Migration(migrations.Migration): + + dependencies = [ + ('books', '0004_remove_module_order'), + ] + + operations = [ + migrations.AlterField( + model_name='contentblock', + name='contents', + field=wagtail.core.fields.StreamField([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock()), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(required=True, target_model=['basicknowledge.BasicKnowledge']))])), ('assignment', wagtail.core.blocks.StructBlock([('assignment_id', wagtail.core.blocks.IntegerBlock())])), ('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())])), ('task', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock())], icon='tick')), ('video_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())])), ('document_block', wagtail.core.blocks.StructBlock([('url', wagtail.core.blocks.URLBlock())]))], blank=True, null=True), + ), + ] diff --git a/server/books/models/book.py b/server/books/models/book.py index 383de484..bf88bc17 100644 --- a/server/books/models/book.py +++ b/server/books/models/book.py @@ -27,4 +27,4 @@ class Book(StrictHierarchyPage): template = 'generic_page.html' - subpage_types = ['books.Topic'] + subpage_types = ['books.Topic', 'basicknowledge.BasicKnowledge'] diff --git a/server/core/settings.py b/server/core/settings.py index a69414c6..fba4f128 100644 --- a/server/core/settings.py +++ b/server/core/settings.py @@ -50,9 +50,11 @@ INSTALLED_APPS = [ 'objectives', 'rooms', 'assignments', + 'basicknowledge', 'wagtail.contrib.forms', 'wagtail.contrib.redirects', + 'wagtail.contrib.modeladmin', 'wagtail.embeds', 'wagtail.sites', 'wagtail.users',