From 01ab01a9e9de4d017a6663be0adc0ddfaeb61c0c Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Wed, 8 Jan 2020 14:56:07 +0100 Subject: [PATCH 01/12] Add instruments to local cache --- client/src/graphql/client.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/graphql/client.js b/client/src/graphql/client.js index 7280a0e7..664216d5 100644 --- a/client/src/graphql/client.js +++ b/client/src/graphql/client.js @@ -53,6 +53,7 @@ export default function (uri) { // todo: remove, the new client seems to cache this correctly by itself // module: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ModuleNode', id: args.id}), projectEntry: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ProjectEntryNode', id: args.id}), + instrument: (_, args, {getCacheKey}) => getCacheKey({__typename: 'InstrumentNode', id: args.id}), } } }); From 8765de960332734a457d704b1a2a3b6f788b2c4b Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Wed, 8 Jan 2020 14:58:07 +0100 Subject: [PATCH 02/12] Add instrument query by id --- .../src/graphql/gql/fragments/instrumentParts.gql | 14 ++++++++++++++ client/src/graphql/gql/instrumentQuery.gql | 7 ++----- client/src/graphql/gql/instrumentQueryById.gql | 6 ++++++ server/basicknowledge/queries.py | 6 +++--- 4 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 client/src/graphql/gql/fragments/instrumentParts.gql create mode 100644 client/src/graphql/gql/instrumentQueryById.gql diff --git a/client/src/graphql/gql/fragments/instrumentParts.gql b/client/src/graphql/gql/fragments/instrumentParts.gql new file mode 100644 index 00000000..73c2bb1e --- /dev/null +++ b/client/src/graphql/gql/fragments/instrumentParts.gql @@ -0,0 +1,14 @@ +fragment InstrumentParts on InstrumentNode { + id + title + slug + bookmarks { + uuid + note { + id + text + } + } + type + contents +} diff --git a/client/src/graphql/gql/instrumentQuery.gql b/client/src/graphql/gql/instrumentQuery.gql index 2f7f0e07..c89e8fcf 100644 --- a/client/src/graphql/gql/instrumentQuery.gql +++ b/client/src/graphql/gql/instrumentQuery.gql @@ -1,9 +1,6 @@ +#import "./fragments/instrumentParts.gql" query InstrumentQuery($slug: String!){ instrument(slug: $slug) { - id - title - slug - type - contents + ...InstrumentParts } } diff --git a/client/src/graphql/gql/instrumentQueryById.gql b/client/src/graphql/gql/instrumentQueryById.gql new file mode 100644 index 00000000..f0fa658e --- /dev/null +++ b/client/src/graphql/gql/instrumentQueryById.gql @@ -0,0 +1,6 @@ +#import "./fragments/instrumentParts.gql" +query InstrumentQuery($id: ID!){ + instrument(id: $id) { + ...InstrumentParts + } +} diff --git a/server/basicknowledge/queries.py b/server/basicknowledge/queries.py index 6b079d0d..14360489 100644 --- a/server/basicknowledge/queries.py +++ b/server/basicknowledge/queries.py @@ -23,10 +23,10 @@ class BasicKnowledgeQuery(object): def resolve_instrument(self, info, **kwargs): slug = kwargs.get('slug') - room_id = kwargs.get('id') + instrument_id = kwargs.get('id') - if room_id is not None: - return get_object(BasicKnowledge, room_id) + if instrument_id is not None: + return get_object(BasicKnowledge, instrument_id) if slug is not None: return BasicKnowledge.objects.get(slug=slug) return None From c8a09badada6dabc39db3c251a711d2652403e1d Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Wed, 8 Jan 2020 14:59:18 +0100 Subject: [PATCH 03/12] Add bookmarks to instruments on server side --- server/basicknowledge/queries.py | 16 ++++++++-- .../migrations/0003_instrumentbookmark.py | 30 +++++++++++++++++++ server/notes/models.py | 4 +++ server/notes/schema.py | 13 ++++++-- 4 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 server/notes/migrations/0003_instrumentbookmark.py diff --git a/server/basicknowledge/queries.py b/server/basicknowledge/queries.py index 14360489..cf4a9127 100644 --- a/server/basicknowledge/queries.py +++ b/server/basicknowledge/queries.py @@ -4,10 +4,14 @@ from graphene_django import DjangoObjectType from graphene_django.filter import DjangoFilterConnectionField from api.utils import get_object +from notes.models import InstrumentBookmark +from notes.schema import InstrumentBookmarkNode from .models import BasicKnowledge -class BasicKnowledgeNode(DjangoObjectType): +class InstrumentNode(DjangoObjectType): + bookmarks = graphene.List(InstrumentBookmarkNode) + class Meta: model = BasicKnowledge filter_fields = ['slug', 'type'] @@ -16,10 +20,16 @@ class BasicKnowledgeNode(DjangoObjectType): 'slug', 'title', 'type', 'contents', ] + def resolve_bookmarks(self, info, **kwargs): + return InstrumentBookmark.objects.filter( + user=info.context.user, + instrument=self + ) + class BasicKnowledgeQuery(object): - instrument = graphene.Field(BasicKnowledgeNode, slug=graphene.String(), id=graphene.ID()) - instruments = DjangoFilterConnectionField(BasicKnowledgeNode) + instrument = graphene.Field(InstrumentNode, slug=graphene.String(), id=graphene.ID()) + instruments = DjangoFilterConnectionField(InstrumentNode) def resolve_instrument(self, info, **kwargs): slug = kwargs.get('slug') diff --git a/server/notes/migrations/0003_instrumentbookmark.py b/server/notes/migrations/0003_instrumentbookmark.py new file mode 100644 index 00000000..9f566040 --- /dev/null +++ b/server/notes/migrations/0003_instrumentbookmark.py @@ -0,0 +1,30 @@ +# Generated by Django 2.0.6 on 2020-01-08 12:54 + +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), + ('basicknowledge', '0004_auto_20191128_1601'), + ('notes', '0002_chapterbookmark_modulebookmark'), + ] + + operations = [ + migrations.CreateModel( + name='InstrumentBookmark', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uuid', models.UUIDField(unique=True)), + ('instrument', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='basicknowledge.BasicKnowledge')), + ('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, + }, + ), + ] diff --git a/server/notes/models.py b/server/notes/models.py index 72eea13e..1d7794ed 100644 --- a/server/notes/models.py +++ b/server/notes/models.py @@ -28,3 +28,7 @@ class ModuleBookmark(Bookmark): class ChapterBookmark(Bookmark): chapter = models.ForeignKey('books.Chapter', on_delete=models.CASCADE) + +class InstrumentBookmark(Bookmark): + uuid = models.UUIDField(unique=True) + instrument = models.ForeignKey('basicknowledge.BasicKnowledge', on_delete=models.CASCADE) diff --git a/server/notes/schema.py b/server/notes/schema.py index 818d44e7..7ff958cb 100644 --- a/server/notes/schema.py +++ b/server/notes/schema.py @@ -2,7 +2,7 @@ import graphene from graphene import relay from graphene_django import DjangoObjectType -from notes.models import Note, ContentBlockBookmark, ModuleBookmark, ChapterBookmark +from notes.models import Note, ContentBlockBookmark, ModuleBookmark, ChapterBookmark, InstrumentBookmark class NoteNode(DjangoObjectType): @@ -17,7 +17,6 @@ class NoteNode(DjangoObjectType): class ContentBlockBookmarkNode(DjangoObjectType): - # note = graphene. uuid = graphene.UUID() note = graphene.Field(NoteNode) @@ -41,3 +40,13 @@ class ChapterBookmarkNode(DjangoObjectType): model = ChapterBookmark filter_fields = [] interfaces = (relay.Node,) + + +class InstrumentBookmarkNode(DjangoObjectType): + uuid = graphene.UUID() + note = graphene.Field(NoteNode) + + class Meta: + model = InstrumentBookmark + filter_fields = [] + interfaces = (relay.Node,) From 2b40f81764b763692d4db6fb18e31d6ca5a17251 Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Wed, 8 Jan 2020 15:00:40 +0100 Subject: [PATCH 04/12] Add bookmark actions to instrument, implement instrument bookmark --- .../content-blocks/ContentComponent.vue | 54 +-------- .../mutations/updateInstrumentBookmark.gql | 5 + .../update-content-bookmark-mutation.js | 113 ++++++++++++++++++ client/src/pages/instrument.vue | 39 ++---- server/notes/mutations.py | 37 +++++- 5 files changed, 167 insertions(+), 81 deletions(-) create mode 100644 client/src/graphql/gql/mutations/updateInstrumentBookmark.gql create mode 100644 client/src/helpers/update-content-bookmark-mutation.js diff --git a/client/src/components/content-blocks/ContentComponent.vue b/client/src/components/content-blocks/ContentComponent.vue index 348bd44a..e1324310 100644 --- a/client/src/components/content-blocks/ContentComponent.vue +++ b/client/src/components/content-blocks/ContentComponent.vue @@ -39,8 +39,7 @@ import Solution from '@/components/content-blocks/Solution'; import BookmarkActions from '@/components/notes/BookmarkActions'; - import UPDATE_CONTENT_BOOKMARK from '@/graphql/gql/mutations/updateContentBookmark.gql'; - import CONTENT_BLOCK_QUERY from '@/graphql/gql/contentBlockQuery.gql'; + import {constructContentComponentBookmarkMutation} from '@/helpers/update-content-bookmark-mutation'; export default { props: ['component', 'parent', 'bookmarks', 'notes', 'root'], @@ -91,56 +90,7 @@ this.$store.dispatch('editNote', this.note); }, bookmarkContent(uuid, bookmarked) { - this.$apollo.mutate({ - mutation: UPDATE_CONTENT_BOOKMARK, - variables: { - input: { - uuid, - contentBlock: this.root, - bookmarked - } - }, - update: (store, response) => { - const query = CONTENT_BLOCK_QUERY; - const variables = {id: this.root}; - const data = store.readQuery({ - query, - variables - }); - - const bookmarks = data.contentBlock.bookmarks; - - if (bookmarked) { - bookmarks.push({ - note: null, - uuid: uuid, - __typename: 'ContentBlockBookmarkNode' - }); - } else { - let index = bookmarks.findIndex(element => { - return element.uuid === uuid; - }); - if (index > -1) { - bookmarks.splice(index, 1); - } - } - - data.contentBlock.bookmarks = bookmarks; - - store.writeQuery({ - data, - query, - variables - }); - }, - optimisticResponse: { - __typename: 'Mutation', - updateContentBookmark: { - __typename: 'UpdateContentBookmarkPayload', - success: true - } - } - }); + this.$apollo.mutate(constructContentComponentBookmarkMutation(uuid, bookmarked, this.parent, this.root)); } } }; diff --git a/client/src/graphql/gql/mutations/updateInstrumentBookmark.gql b/client/src/graphql/gql/mutations/updateInstrumentBookmark.gql new file mode 100644 index 00000000..17679013 --- /dev/null +++ b/client/src/graphql/gql/mutations/updateInstrumentBookmark.gql @@ -0,0 +1,5 @@ +mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) { + updateInstrumentBookmark(input: $input) { + success + } +} diff --git a/client/src/helpers/update-content-bookmark-mutation.js b/client/src/helpers/update-content-bookmark-mutation.js new file mode 100644 index 00000000..7d364542 --- /dev/null +++ b/client/src/helpers/update-content-bookmark-mutation.js @@ -0,0 +1,113 @@ +import UPDATE_CONTENT_BOOKMARK from '@/graphql/gql/mutations/updateContentBookmark.gql'; +import UPDATE_INSTRUMENT_BOOKMARK from '@/graphql/gql/mutations/updateInstrumentBookmark.gql'; +import CONTENT_BLOCK_QUERY from '@/graphql/gql/contentBlockQuery.gql'; +import INSTRUMENT_QUERY from '@/graphql/gql/instrumentQueryById.gql'; + +export const constructContentComponentBookmarkMutation = (uuid, bookmarked, parent, root) => { + let mutation = {}; + console.log(uuid, bookmarked, parent, root); + if (parent.__typename === 'ContentBlockNode') { + mutation = { + mutation: UPDATE_CONTENT_BOOKMARK, + variables: { + input: { + uuid, + contentBlock: root, + bookmarked + } + }, + update: (store, response) => { + const query = CONTENT_BLOCK_QUERY; + const variables = {id: root}; + const data = store.readQuery({ + query, + variables + }); + + const bookmarks = data.contentBlock.bookmarks; + + if (bookmarked) { + bookmarks.push({ + note: null, + uuid, + __typename: 'ContentBlockBookmarkNode' + }); + } else { + let index = bookmarks.findIndex(element => { + return element.uuid === uuid; + }); + if (index > -1) { + bookmarks.splice(index, 1); + } + } + + data.contentBlock.bookmarks = bookmarks; + + store.writeQuery({ + data, + query, + variables + }); + }, + optimisticResponse: { + __typename: 'Mutation', + updateContentBookmark: { + __typename: 'UpdateContentBookmarkPayload', + success: true + } + } + } + } else { + mutation = { + mutation: UPDATE_INSTRUMENT_BOOKMARK, + variables: { + input: { + uuid, + instrument: root, + bookmarked + } + }, + update: (store, response) => { + const query = INSTRUMENT_QUERY; + const variables = {id: root}; + const data = store.readQuery({ + query, + variables + }); + + const bookmarks = data.instrument.bookmarks; + + if (bookmarked) { + bookmarks.push({ + note: null, + uuid, + __typename: 'InstrumentBookmarkNode' + }) + } else { + let index = bookmarks.findIndex(element => { + return element.uuid === uuid; + }); + if (index > -1) { + bookmarks.splice(index, 1); + } + } + + data.instrument.bookmarks = bookmarks; + + store.writeQuery({ + data, + query, + variables + }); + }, + optimisticResponse: { + __typename: 'Mutation', + updateInstrumentBookmark: { + __typename: 'UpdateInstrumentBookmarkPayload', + success: true + } + } + }; + } + return mutation; +}; diff --git a/client/src/pages/instrument.vue b/client/src/pages/instrument.vue index 4d05d476..1efcc857 100644 --- a/client/src/pages/instrument.vue +++ b/client/src/pages/instrument.vue @@ -2,11 +2,15 @@

{{instrument.title}}

- - + +
@@ -14,17 +18,7 @@