Add content block deletion mutation
This commit is contained in:
parent
4d1e156f9f
commit
ce86e45743
|
|
@ -9,6 +9,7 @@
|
|||
<add-content-block-button :parent="chapter.id"></add-content-block-button>
|
||||
|
||||
<content-block :contentBlock="contentBlock"
|
||||
:parent="chapter.id"
|
||||
:key="contentBlock.id" v-for="contentBlock in filteredContentBlocks">
|
||||
</content-block>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div class="content-block__container">
|
||||
<div class="content-block" :class="specialClass">
|
||||
<div class="content-block__actions">
|
||||
<a @click="toggleVisibility()" v-if="canManageContent" class="content-block__visibility-button">
|
||||
<a @click="toggleVisibility()" v-if="canManageContent" class="content-block__action-button">
|
||||
<eye-icon class="content-block__action-icon"></eye-icon>
|
||||
</a>
|
||||
<visibility-popover
|
||||
|
|
@ -10,9 +10,12 @@
|
|||
:content-block="contentBlock"
|
||||
class="content-block__visibility-menu"
|
||||
></visibility-popover>
|
||||
<a @click="editContentBlock()" v-if="contentBlock.userCreated">
|
||||
<a @click="editContentBlock()" v-if="contentBlock.mine" class="content-block__action-button">
|
||||
<pen-icon class="content-block__action-icon"></pen-icon>
|
||||
</a>
|
||||
<a @click="deleteContentBlock(contentBlock.id)" v-if="contentBlock.mine" class="content-block__action-button">
|
||||
<trash-icon class="content-block__action-icon"></trash-icon>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<h4 class="content-block__title">{{contentBlock.title}} {{contentBlock.userCreated}}</h4>
|
||||
|
|
@ -45,10 +48,13 @@
|
|||
import VisibilityPopover from '@/components/VisibilityPopover';
|
||||
import EyeIcon from '@/components/icons/EyeIcon';
|
||||
import PenIcon from '@/components/icons/PenIcon';
|
||||
import TrashIcon from '@/components/icons/TrashIcon';
|
||||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||
import CHAPTER_QUERY from '@/graphql/gql/chapterQuery.gql';
|
||||
import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';
|
||||
|
||||
export default {
|
||||
props: ['contentBlock'],
|
||||
props: ['contentBlock', 'parent'],
|
||||
|
||||
components: {
|
||||
'text_block': TextBlock,
|
||||
|
|
@ -63,7 +69,8 @@
|
|||
AddContentBlockButton,
|
||||
VisibilityPopover,
|
||||
EyeIcon,
|
||||
PenIcon
|
||||
PenIcon,
|
||||
TrashIcon
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
|
@ -82,6 +89,32 @@
|
|||
editContentBlock() {
|
||||
this.$store.dispatch('editContentBlock', this.contentBlock.id);
|
||||
},
|
||||
deleteContentBlock(id) {
|
||||
const parent = this.parent;
|
||||
this.$apollo.mutate({
|
||||
mutation: DELETE_CONTENT_BLOCK_MUTATION,
|
||||
variables: {
|
||||
input: {
|
||||
id: id
|
||||
}
|
||||
},
|
||||
update(store, {data: {deleteContentBlock: {success}}}) {
|
||||
try {
|
||||
if (success) {
|
||||
const query = CHAPTER_QUERY;
|
||||
const variables = {
|
||||
id: parent
|
||||
};
|
||||
const data = store.readQuery({query, variables});
|
||||
data.chapter.contentBlocks.edges.splice(data.chapter.contentBlocks.edges.findIndex(edge => edge.node.id === id), 1);
|
||||
store.writeQuery({query, variables, data});
|
||||
}
|
||||
} catch (e) {
|
||||
// Query did not exist in the cache, and apollo throws a generic Error. Do nothing
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
apollo: {
|
||||
|
|
@ -119,7 +152,7 @@
|
|||
display: grid;
|
||||
}
|
||||
|
||||
&__visibility-button {
|
||||
&__action-button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ const cache = new InMemoryCache({
|
|||
cacheRedirects: {
|
||||
Query: {
|
||||
contentBlock: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ContentBlockNode', id: args.id}),
|
||||
chapter: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ChapterNode', id: args.id}),
|
||||
assignment: (_, args, {getCacheKey}) => getCacheKey({__typename: 'AssignmentNode', id: args.id})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
# to be read from cache only
|
||||
#import "./fragments/contentBlockParts.gql"
|
||||
query ContentBlockQuery {
|
||||
contentBlocks {
|
||||
...ContentBlockParts
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#import "./fragments/chapterParts.gql"
|
||||
query ChapterQuery($id: ID!) {
|
||||
chapter(id: $id) {
|
||||
...ChapterParts
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#import "./contentBlockParts.gql"
|
||||
fragment ChapterParts on ChapterNode {
|
||||
id
|
||||
title
|
||||
description
|
||||
contentBlocks {
|
||||
edges {
|
||||
node {
|
||||
...ContentBlockParts
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ fragment ContentBlockParts on ContentBlockNode {
|
|||
type
|
||||
contents
|
||||
userCreated
|
||||
mine
|
||||
hiddenFor {
|
||||
edges {
|
||||
node {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#import "./fragments/contentBlockParts.gql"
|
||||
#import "./fragments/chapterParts.gql"
|
||||
#import "./fragments/assignmentParts.gql"
|
||||
query ModulesQuery($slug: String!) {
|
||||
module(slug: $slug) {
|
||||
|
|
@ -34,16 +34,7 @@ query ModulesQuery($slug: String!) {
|
|||
chapters {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
title
|
||||
description
|
||||
contentBlocks {
|
||||
edges {
|
||||
node {
|
||||
...ContentBlockParts
|
||||
}
|
||||
}
|
||||
}
|
||||
...ChapterParts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
mutation DeleteContentBlock($input: DeleteContentBlockInput!) {
|
||||
deleteContentBlock(input: $input) {
|
||||
success
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
||||
#{
|
||||
# "input": {
|
||||
# "id": "Um9vbU5vZGU6MjY="
|
||||
# }
|
||||
#}
|
||||
|
|
@ -3,6 +3,7 @@ import json
|
|||
import graphene
|
||||
from django.core.exceptions import ValidationError
|
||||
from graphene import relay
|
||||
from graphql_relay import from_global_id
|
||||
|
||||
from api.utils import get_object, get_errors
|
||||
from books.models import ContentBlock, Chapter, SchoolClass
|
||||
|
|
@ -115,3 +116,23 @@ class AddContentBlock(relay.ClientIDMutation):
|
|||
errors = ['Error: {}'.format(e)]
|
||||
|
||||
return cls(new_content_block=None, errors=errors)
|
||||
|
||||
|
||||
class DeleteContentBlock(relay.ClientIDMutation):
|
||||
class Input:
|
||||
id = graphene.ID(required=True)
|
||||
|
||||
success = graphene.Boolean()
|
||||
errors = graphene.String()
|
||||
|
||||
@classmethod
|
||||
def mutate_and_get_payload(cls, root, info, **kwargs):
|
||||
id = from_global_id(kwargs.get('id'))[1]
|
||||
user = info.context.user
|
||||
|
||||
try:
|
||||
content_block = ContentBlock.objects.get(pk=id, owner=user)
|
||||
content_block.delete()
|
||||
return cls(success=True)
|
||||
except ContentBlock.DoesNotExist:
|
||||
return cls(success=False, errors='Content block not found')
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from books.schema.mutations.contentblock import MutateContentBlock, AddContentBlock
|
||||
from books.schema.mutations.contentblock import MutateContentBlock, AddContentBlock, DeleteContentBlock
|
||||
|
||||
|
||||
class BookMutations(object):
|
||||
mutate_content_block = MutateContentBlock.Field()
|
||||
add_content_block = AddContentBlock.Field()
|
||||
delete_content_block = DeleteContentBlock.Field()
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ from ..models import Book, Topic, Module, Chapter, ContentBlock
|
|||
|
||||
|
||||
class ContentBlockNode(DjangoObjectType):
|
||||
mine = graphene.Boolean()
|
||||
|
||||
class Meta:
|
||||
model = ContentBlock
|
||||
only_fields = [
|
||||
|
|
@ -17,6 +19,8 @@ class ContentBlockNode(DjangoObjectType):
|
|||
]
|
||||
interfaces = (relay.Node,)
|
||||
|
||||
def resolve_mine(self, info, **kwargs):
|
||||
return self.owner is not None and self.owner.pk == info.context.user.pk
|
||||
|
||||
class ChapterNode(DjangoObjectType):
|
||||
content_blocks = DjangoFilterConnectionField(ContentBlockNode)
|
||||
|
|
|
|||
Loading…
Reference in New Issue