Add first raw implementation for adtl. bookmark types
This commit is contained in:
parent
f7213b44e7
commit
7c534cbe5c
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,12 @@ fragment ChapterParts on ChapterNode {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
|
bookmark {
|
||||||
|
note {
|
||||||
|
id
|
||||||
|
text
|
||||||
|
}
|
||||||
|
}
|
||||||
contentBlocks {
|
contentBlocks {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,10 @@ fragment ModuleParts on ModuleNode {
|
||||||
slug
|
slug
|
||||||
heroImage
|
heroImage
|
||||||
solutionsEnabled
|
solutionsEnabled
|
||||||
|
bookmark {
|
||||||
|
note {
|
||||||
|
id
|
||||||
|
text
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
mutation UpdateChapterBookmark($input: UpdateChapterBookmarkInput!) {
|
||||||
|
updateChapterBookmark(input: $input) {
|
||||||
|
success
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue