diff --git a/server/book/models/contentblock.py b/server/book/models/contentblock.py index 38f77998..33bc4d23 100644 --- a/server/book/models/contentblock.py +++ b/server/book/models/contentblock.py @@ -16,6 +16,18 @@ class ContentBlock(StrictHierarchyPage): verbose_name = 'Inhaltsblock' verbose_name_plural = 'Inhaltsblöcke' + PLAIN = 'plain' + YELLOW = 'yellow' + GREEN = 'green' + BLUE = 'blue' + + TYPE_CHOICES = ( + (PLAIN, 'Normal'), + (YELLOW, 'Gelb'), + (GREEN, 'Grün'), + (BLUE, 'Blau'), + ) + contents = StreamField([ ('text_block', TextBlock(icon='doc-full')), ('basic_knowledge', BasicKnowledgeBlock(icon='placeholder')), @@ -27,12 +39,8 @@ class ContentBlock(StrictHierarchyPage): type = models.CharField( max_length=100, - choices=( - ('plain', 'Normal'), - ('yellow', 'Gelb'), - ('green', 'Grün'), - ('blue', 'Blau'), - ) + choices=TYPE_CHOICES, + default=PLAIN ) content_panels = [ diff --git a/server/book/schema/inputs.py b/server/book/schema/inputs.py new file mode 100644 index 00000000..332ecd94 --- /dev/null +++ b/server/book/schema/inputs.py @@ -0,0 +1,29 @@ +from graphene import InputObjectType +import graphene + + +class InputTypes(graphene.Enum): + text_block = 'text_block' + basic_knowledge = 'basic_knowledge' + student_entry = 'student_entry' + image_block = 'image_block' + link_block = 'link_block' + task = 'task' + + +class ContentElementInput(InputObjectType): + # we'll handle this with a single input, even tho it would be nice to have a type for every different possibility + # see discussion at https://github.com/graphql/graphql-js/issues/207 + type = InputTypes(required=True) + text = graphene.String(description='To be used for link_block, text_block types') + url = graphene.String(description='To be used for link, basic_knowledge, image_block types') + description = graphene.String(description='To be used for basic_knowledge type') + title = graphene.String(description='To be used for image_block type') + task_text = graphene.String(description='To be used for task type') + + +class ContentBlockInput(InputObjectType): + title = graphene.String(required=True) + type = graphene.String() + after = graphene.ID() + contents = graphene.List(ContentElementInput) diff --git a/server/book/schema/mutations.py b/server/book/schema/mutations.py index 8d03cfa2..2e01e84a 100644 --- a/server/book/schema/mutations.py +++ b/server/book/schema/mutations.py @@ -1,12 +1,17 @@ +import json + import graphene +from graphene import relay from django.core.exceptions import ValidationError +from wagtail.core.fields import StreamField from api.utils import get_object, get_errors -from book.models import ContentBlock +from book.models import ContentBlock, Chapter +from book.schema.inputs import ContentBlockInput from book.schema.queries import ContentBlockNode -class MutateContentBlock(graphene.relay.ClientIDMutation): +class MutateContentBlock(relay.ClientIDMutation): class Input: id = graphene.ID() type = graphene.String() @@ -58,5 +63,37 @@ class MutateContentBlock(graphene.relay.ClientIDMutation): return cls(content_block=None, errors=errors) +class AddContentBlock(relay.ClientIDMutation): + class Input: + content_block = graphene.Argument(ContentBlockInput) + + new_content_block = graphene.Field(ContentBlockNode) + + @classmethod + def mutate_and_get_payload(cls, root, info, **args): + content_block_data = args.get('content_block') + title = content_block_data.get('title') + new_content_block = ContentBlock(title=title) + parent = Chapter.objects.get(pk=18).specific # atm just "1.1 Lehrbeginn" / todo: dynamic, refactor in above class + parent.add_child(instance=new_content_block) + revision = new_content_block.save_revision() + revision.publish() + new_content_block.save() + + contents = content_block_data.get('contents') + for content in contents: + # todo: add all the content blocks + # todo: refactor this mess + if content['type'] == 'text_block': + new_content_block.contents = json.dumps([ + {'type': 'text_block', 'value': { + 'text': '

{}

'.format(content['text']) + }} + ]) + new_content_block.save() + return cls(new_content_block=new_content_block) + + class BookMutations(object): mutate_content_block = MutateContentBlock.Field() + add_content_block = AddContentBlock.Field()