Add first raw implementation for adtl. bookmark types

This commit is contained in:
Ramon Wenger 2019-12-02 13:56:52 +01:00
parent f7213b44e7
commit 7c534cbe5c
11 changed files with 194 additions and 6 deletions

View File

@ -2,6 +2,8 @@
<div class="chapter"> <div class="chapter">
<h3 :id="'chapter-' + index">{{chapter.title}}</h3> <h3 :id="'chapter-' + index">{{chapter.title}}</h3>
<h1>Bookmark: {{chapter.bookmark}} <a @click="bookmark">Click</a></h1>
<p class="chapter__description"> <p class="chapter__description">
{{chapter.description}} {{chapter.description}}
</p> </p>
@ -23,6 +25,8 @@
import {isHidden} from '@/helpers/content-block'; import {isHidden} from '@/helpers/content-block';
import {meQuery} from '@/graphql/queries'; import {meQuery} from '@/graphql/queries';
import UPDATE_CHAPTER_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateChapterBookmark.gql';
export default { export default {
props: ['chapter', 'index'], props: ['chapter', 'index'],
@ -53,6 +57,21 @@
} }
}, },
methods: {
bookmark() {
console.log('bookmark');
this.$apollo.mutate({
mutation: UPDATE_CHAPTER_BOOKMARK_MUTATION,
variables: {
input: {
chapter: this.chapter.id,
bookmarked: true
}
}
});
}
},
apollo: { apollo: {
me: meQuery me: meQuery
} }

View File

@ -3,6 +3,12 @@ fragment ChapterParts on ChapterNode {
id id
title title
description description
bookmark {
note {
id
text
}
}
contentBlocks { contentBlocks {
edges { edges {
node { node {

View File

@ -7,4 +7,10 @@ fragment ModuleParts on ModuleNode {
slug slug
heroImage heroImage
solutionsEnabled solutionsEnabled
bookmark {
note {
id
text
}
}
} }

View File

@ -0,0 +1,5 @@
mutation UpdateChapterBookmark($input: UpdateChapterBookmarkInput!) {
updateChapterBookmark(input: $input) {
success
}
}

View File

@ -0,0 +1,21 @@
# Generated by Django 2.0.6 on 2019-11-28 16:01
from django.db import migrations
import wagtail.core.blocks
import wagtail.core.fields
import wagtail.images.blocks
class Migration(migrations.Migration):
dependencies = [
('basicknowledge', '0003_auto_20190912_1228'),
]
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']))])), ('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())]))], blank=True, null=True),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 2.0.6 on 2019-11-28 16:01
import assignments.models
from django.db import migrations
import surveys.models
import wagtail.core.blocks
import wagtail.core.fields
import wagtail.images.blocks
import wagtail.snippets.blocks
class Migration(migrations.Migration):
dependencies = [
('books', '0015_contentblock_bookmarks'),
]
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']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(required=True, target_model=['basicknowledge.BasicKnowledge']))])), ('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']))], 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())])), ('module_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())])), ('content_list_item', wagtail.core.blocks.StreamBlock([('text_block', wagtail.core.blocks.StructBlock([('text', wagtail.core.blocks.RichTextBlock(features=['ul']))])), ('basic_knowledge', wagtail.core.blocks.StructBlock([('description', wagtail.core.blocks.RichTextBlock(required=False)), ('basic_knowledge', wagtail.core.blocks.PageChooserBlock(required=True, target_model=['basicknowledge.BasicKnowledge']))])), ('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']))], 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())])), ('module_room_slug', wagtail.core.blocks.StructBlock([('title', wagtail.core.blocks.TextBlock())]))]))], blank=True, null=True),
),
]

View File

@ -5,8 +5,8 @@ from graphene_django.filter import DjangoFilterConnectionField
from api.utils import get_object from api.utils import get_object
from books.utils import are_solutions_enabled_for from books.utils import are_solutions_enabled_for
from notes.models import ContentBlockBookmark from notes.models import ContentBlockBookmark, ChapterBookmark, ModuleBookmark
from notes.schema import ContentBlockBookmarkNode from notes.schema import ContentBlockBookmarkNode, ChapterBookmarkNode, ModuleBookmarkNode
from rooms.models import ModuleRoomSlug from rooms.models import ModuleRoomSlug
from ..models import Book, Topic, Module, Chapter, ContentBlock from ..models import Book, Topic, Module, Chapter, ContentBlock
@ -66,6 +66,7 @@ class ContentBlockNode(DjangoObjectType):
class ChapterNode(DjangoObjectType): class ChapterNode(DjangoObjectType):
content_blocks = DjangoFilterConnectionField(ContentBlockNode) content_blocks = DjangoFilterConnectionField(ContentBlockNode)
bookmark = graphene.Field(ChapterBookmarkNode)
class Meta: class Meta:
model = Chapter model = Chapter
@ -96,6 +97,11 @@ class ChapterNode(DjangoObjectType):
return publisher_content_blocks.union(user_created_content_blocks) return publisher_content_blocks.union(user_created_content_blocks)
def resolve_bookmark(self, info, **kwags):
return ChapterBookmark.objects.filter(
user=info.context.user,
chapter=self
).first()
class ModuleNode(DjangoObjectType): class ModuleNode(DjangoObjectType):
pk = graphene.Int() pk = graphene.Int()
@ -103,6 +109,7 @@ class ModuleNode(DjangoObjectType):
topic = graphene.Field('books.schema.queries.TopicNode') topic = graphene.Field('books.schema.queries.TopicNode')
hero_image = graphene.String() hero_image = graphene.String()
solutions_enabled = graphene.Boolean() solutions_enabled = graphene.Boolean()
bookmark = graphene.Field(ModuleBookmarkNode)
class Meta: class Meta:
model = Module model = Module
@ -132,6 +139,12 @@ class ModuleNode(DjangoObjectType):
teacher = info.context.user.get_teacher() teacher = info.context.user.get_teacher()
return self.solutions_enabled_by.filter(pk=teacher.pk).exists() if teacher is not None else False return self.solutions_enabled_by.filter(pk=teacher.pk).exists() if teacher is not None else False
def resolve_bookmark(self, info, **kwags):
return ModuleBookmark.objects.filter(
user=info.context.user,
module=self
).first()
class TopicNode(DjangoObjectType): class TopicNode(DjangoObjectType):
pk = graphene.Int() pk = graphene.Int()

View File

@ -0,0 +1,41 @@
# Generated by Django 2.0.6 on 2019-11-28 16:01
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('books', '0016_auto_20191128_1601'),
('notes', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='ChapterBookmark',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('chapter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='books.Chapter')),
('note', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='notes.Note')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='ModuleBookmark',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='books.Module')),
('note', models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='notes.Note')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]

View File

@ -10,7 +10,6 @@ class Note(models.Model):
class Bookmark(models.Model): class Bookmark(models.Model):
uuid = models.UUIDField(unique=True)
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
note = models.OneToOneField(Note, null=True, on_delete=models.SET_NULL) note = models.OneToOneField(Note, null=True, on_delete=models.SET_NULL)
@ -19,4 +18,13 @@ class Bookmark(models.Model):
class ContentBlockBookmark(Bookmark): class ContentBlockBookmark(Bookmark):
uuid = models.UUIDField(unique=True)
content_block = models.ForeignKey('books.ContentBlock', on_delete=models.CASCADE) content_block = models.ForeignKey('books.ContentBlock', on_delete=models.CASCADE)
class ModuleBookmark(Bookmark):
module = models.ForeignKey('books.Module', on_delete=models.CASCADE)
class ChapterBookmark(Bookmark):
chapter = models.ForeignKey('books.Chapter', on_delete=models.CASCADE)

View File

@ -5,9 +5,9 @@ import json
from graphene import relay from graphene import relay
from api.utils import get_object from api.utils import get_object
from books.models import ContentBlock from books.models import ContentBlock, Chapter
from notes.inputs import AddNoteArgument, UpdateNoteArgument from notes.inputs import AddNoteArgument, UpdateNoteArgument
from notes.models import ContentBlockBookmark, Note from notes.models import ContentBlockBookmark, Note, ChapterBookmark
from notes.schema import NoteNode from notes.schema import NoteNode
@ -95,8 +95,39 @@ class UpdateNote(relay.ClientIDMutation):
note.save() note.save()
return cls(note=note) return cls(note=note)
class UpdateChapterBookmark(relay.ClientIDMutation):
class Input:
chapter = graphene.ID(required=True)
bookmarked = graphene.Boolean(required=True)
success = graphene.Boolean()
@classmethod
def mutate_and_get_payload(cls, root, info, **kwargs):
user = info.context.user
content_block_id = kwargs.get('chapter')
bookmarked = kwargs.get('bookmarked')
chapter = get_object(Chapter, content_block_id)
if bookmarked:
ChapterBookmark.objects.create(
chapter=chapter,
user=user
)
else:
ChapterBookmark.objects.get(
chapter=chapter,
user=user
).delete()
return cls(success=True)
class NoteMutations: class NoteMutations:
add_note = AddNote.Field() add_note = AddNote.Field()
update_note = UpdateNote.Field() update_note = UpdateNote.Field()
update_content_bookmark = UpdateContentBookmark.Field() update_content_bookmark = UpdateContentBookmark.Field()
update_chapter_bookmark = UpdateChapterBookmark.Field()

View File

@ -2,7 +2,7 @@ import graphene
from graphene import relay from graphene import relay
from graphene_django import DjangoObjectType from graphene_django import DjangoObjectType
from notes.models import Note, ContentBlockBookmark from notes.models import Note, ContentBlockBookmark, ModuleBookmark, ChapterBookmark
class NoteNode(DjangoObjectType): class NoteNode(DjangoObjectType):
@ -23,3 +23,17 @@ class ContentBlockBookmarkNode(DjangoObjectType):
class Meta: class Meta:
model = ContentBlockBookmark model = ContentBlockBookmark
class ModuleBookmarkNode(DjangoObjectType):
note = graphene.Field(NoteNode)
class Meta:
model = ModuleBookmark
class ChapterBookmarkNode(DjangoObjectType):
note = graphene.Field(NoteNode)
class Meta:
model = ChapterBookmark