Display snapshot module detail
This commit is contained in:
parent
ca549e93e5
commit
70e7dc39a9
|
|
@ -55,154 +55,160 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import ContentBlock from '@/components/ContentBlock';
|
||||
import AddContentButton from '@/components/AddContentButton';
|
||||
import BookmarkActions from '@/components/notes/BookmarkActions';
|
||||
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
||||
import ContentBlock from '@/components/ContentBlock';
|
||||
import AddContentButton from '@/components/AddContentButton';
|
||||
import BookmarkActions from '@/components/notes/BookmarkActions';
|
||||
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
||||
|
||||
import {mapState} from 'vuex';
|
||||
import {hidden} from '@/helpers/visibility';
|
||||
import {CONTENT_TYPE, CHAPTER_DESCRIPTION_TYPE, CHAPTER_TITLE_TYPE} from '@/consts/types';
|
||||
import {mapState} from 'vuex';
|
||||
import {hidden} from '@/helpers/visibility';
|
||||
import {CHAPTER_DESCRIPTION_TYPE, CHAPTER_TITLE_TYPE, CONTENT_TYPE} from '@/consts/types';
|
||||
|
||||
import UPDATE_CHAPTER_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateChapterBookmark.gql';
|
||||
import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql';
|
||||
import UPDATE_CHAPTER_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateChapterBookmark.gql';
|
||||
import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql';
|
||||
|
||||
import me from '@/mixins/me';
|
||||
import me from '@/mixins/me';
|
||||
|
||||
export default {
|
||||
props: ['chapter', 'index'],
|
||||
export default {
|
||||
props: ['chapter', 'index'],
|
||||
|
||||
mixins: [me],
|
||||
mixins: [me],
|
||||
|
||||
components: {
|
||||
BookmarkActions,
|
||||
VisibilityAction,
|
||||
ContentBlock,
|
||||
AddContentButton
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['editModule']),
|
||||
filteredContentBlocks() {
|
||||
if (!(this.chapter && this.chapter.contentBlocks)) {
|
||||
return [];
|
||||
}
|
||||
if (this.editModule) {
|
||||
return this.chapter.contentBlocks;
|
||||
}
|
||||
return this.chapter.contentBlocks.filter(contentBlock => !hidden({
|
||||
block: contentBlock,
|
||||
schoolClass: this.schoolClass,
|
||||
type: CONTENT_TYPE
|
||||
}));
|
||||
components: {
|
||||
BookmarkActions,
|
||||
VisibilityAction,
|
||||
ContentBlock,
|
||||
AddContentButton,
|
||||
},
|
||||
note() {
|
||||
if (this.chapter && this.chapter.bookmark) {
|
||||
return this.chapter.bookmark.note;
|
||||
}
|
||||
},
|
||||
titleGreyedOut() {
|
||||
return this.textHidden(CHAPTER_TITLE_TYPE) && this.editModule;
|
||||
},
|
||||
// never hidden when editing the module
|
||||
titleHidden() {
|
||||
return this.textHidden(CHAPTER_TITLE_TYPE) && !this.editModule;
|
||||
},
|
||||
descriptionGreyedOut() {
|
||||
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && this.editModule;
|
||||
},
|
||||
// never hidden when editing the module
|
||||
descriptionHidden() {
|
||||
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && !this.editModule;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
bookmark(bookmarked) {
|
||||
const id = this.chapter.id;
|
||||
this.$apollo.mutate({
|
||||
mutation: UPDATE_CHAPTER_BOOKMARK_MUTATION,
|
||||
variables: {
|
||||
input: {
|
||||
chapter: id,
|
||||
bookmarked
|
||||
}
|
||||
},
|
||||
update: (store, response) => {
|
||||
const query = CHAPTER_QUERY;
|
||||
const variables = {id};
|
||||
const data = store.readQuery({
|
||||
query,
|
||||
variables
|
||||
});
|
||||
|
||||
const chapter = data.chapter;
|
||||
|
||||
if (bookmarked) {
|
||||
chapter.bookmark = {
|
||||
__typename: 'ChapterBookmarkNode',
|
||||
note: null
|
||||
};
|
||||
} else {
|
||||
chapter.bookmark = null;
|
||||
}
|
||||
|
||||
data.chapter = chapter;
|
||||
|
||||
store.writeQuery({
|
||||
data,
|
||||
query,
|
||||
variables
|
||||
});
|
||||
},
|
||||
optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
updateChapterBookmark: {
|
||||
__typename: 'UpdateChapterBookmarkPayload',
|
||||
success: true
|
||||
}
|
||||
computed: {
|
||||
...mapState(['editModule']),
|
||||
filteredContentBlocks() {
|
||||
if (!(this.chapter && this.chapter.contentBlocks)) {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
if (this.editModule) {
|
||||
return this.chapter.contentBlocks;
|
||||
}
|
||||
return this.chapter.contentBlocks.filter(contentBlock => !hidden({
|
||||
block: contentBlock,
|
||||
schoolClass: this.schoolClass,
|
||||
type: CONTENT_TYPE,
|
||||
}));
|
||||
},
|
||||
note() {
|
||||
if (this.chapter && this.chapter.bookmark) {
|
||||
return this.chapter.bookmark.note;
|
||||
}
|
||||
},
|
||||
titleGreyedOut() {
|
||||
return this.textHidden(CHAPTER_TITLE_TYPE) && this.editModule;
|
||||
},
|
||||
// never hidden when editing the module
|
||||
titleHidden() {
|
||||
if (this.chapter.titleHidden === true) {
|
||||
return true;
|
||||
}
|
||||
return this.textHidden(CHAPTER_TITLE_TYPE) && !this.editModule;
|
||||
},
|
||||
descriptionGreyedOut() {
|
||||
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && this.editModule;
|
||||
},
|
||||
// never hidden when editing the module
|
||||
descriptionHidden() {
|
||||
if (this.chapter.descriptionHidden === true) {
|
||||
return true;
|
||||
}
|
||||
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && !this.editModule;
|
||||
},
|
||||
},
|
||||
addNote(id) {
|
||||
this.$store.dispatch('addNote', {
|
||||
content: id,
|
||||
parent: this.chapter.id
|
||||
});
|
||||
},
|
||||
editNote() {
|
||||
this.$store.dispatch('editNote', this.chapter.bookmark.note);
|
||||
},
|
||||
textHidden(type) {
|
||||
return hidden({
|
||||
block: this.chapter,
|
||||
schoolClass: this.schoolClass,
|
||||
type
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
methods: {
|
||||
bookmark(bookmarked) {
|
||||
const id = this.chapter.id;
|
||||
this.$apollo.mutate({
|
||||
mutation: UPDATE_CHAPTER_BOOKMARK_MUTATION,
|
||||
variables: {
|
||||
input: {
|
||||
chapter: id,
|
||||
bookmarked,
|
||||
},
|
||||
},
|
||||
update: (store, response) => {
|
||||
const query = CHAPTER_QUERY;
|
||||
const variables = {id};
|
||||
const data = store.readQuery({
|
||||
query,
|
||||
variables,
|
||||
});
|
||||
|
||||
const chapter = data.chapter;
|
||||
|
||||
if (bookmarked) {
|
||||
chapter.bookmark = {
|
||||
__typename: 'ChapterBookmarkNode',
|
||||
note: null,
|
||||
};
|
||||
} else {
|
||||
chapter.bookmark = null;
|
||||
}
|
||||
|
||||
data.chapter = chapter;
|
||||
|
||||
store.writeQuery({
|
||||
data,
|
||||
query,
|
||||
variables,
|
||||
});
|
||||
},
|
||||
optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
updateChapterBookmark: {
|
||||
__typename: 'UpdateChapterBookmarkPayload',
|
||||
success: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
addNote(id) {
|
||||
this.$store.dispatch('addNote', {
|
||||
content: id,
|
||||
parent: this.chapter.id,
|
||||
});
|
||||
},
|
||||
editNote() {
|
||||
this.$store.dispatch('editNote', this.chapter.bookmark.note);
|
||||
},
|
||||
textHidden(type) {
|
||||
return hidden({
|
||||
block: this.chapter,
|
||||
schoolClass: this.schoolClass,
|
||||
type,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/styles/_mixins.scss";
|
||||
@import "@/styles/_mixins.scss";
|
||||
|
||||
.chapter {
|
||||
position: relative;
|
||||
|
||||
&__bookmark-actions {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
&__intro {
|
||||
.chapter {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__description {
|
||||
@include lead-paragraph;
|
||||
&__bookmark-actions {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
margin-bottom: $large-spacing;
|
||||
&__intro {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__description {
|
||||
@include lead-paragraph;
|
||||
|
||||
margin-bottom: $large-spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -70,10 +70,14 @@ export const hidden = ({
|
|||
visibleFor,
|
||||
hiddenFor,
|
||||
titleHiddenFor,
|
||||
descriptionHiddenFor
|
||||
descriptionHiddenFor,
|
||||
hidden
|
||||
},
|
||||
schoolClass
|
||||
}) => {
|
||||
if (hidden === true) {
|
||||
return true;
|
||||
}
|
||||
switch (type) {
|
||||
case CONTENT_TYPE:
|
||||
case OBJECTIVE_TYPE:
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
Hello
|
||||
{{ id }}
|
||||
<module :module="snapshot" />
|
||||
</div>
|
||||
<module :module="snapshot"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -20,7 +16,7 @@
|
|||
},
|
||||
|
||||
components: {
|
||||
Module
|
||||
Module,
|
||||
},
|
||||
|
||||
apollo: {
|
||||
|
|
@ -28,9 +24,9 @@
|
|||
query: SNAPSHOT_DETAIL_QUERY,
|
||||
variables() {
|
||||
return {
|
||||
id: this.id
|
||||
id: this.id,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,3 +8,7 @@ class ContentBlockInterface(relay.Node):
|
|||
title = graphene.String()
|
||||
contents = GenericStreamFieldType()
|
||||
type = graphene.String()
|
||||
|
||||
@staticmethod
|
||||
def resolve_type(parent, info, **kwargs):
|
||||
return parent.type
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from graphene import relay
|
|||
|
||||
class ModuleInterface(relay.Node):
|
||||
pk = graphene.Int()
|
||||
hero_image = graphene.String()
|
||||
hero_image = graphene.String(required=True)
|
||||
topic = graphene.Field('books.schema.nodes.TopicNode')
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
import graphene
|
||||
from graphene import relay, ObjectType
|
||||
from graphene_django import DjangoObjectType
|
||||
|
||||
from books.models import ContentBlock
|
||||
from books.schema.interfaces.contentblock import ContentBlockInterface
|
||||
from books.utils import are_solutions_enabled_for
|
||||
from core.logger import get_logger
|
||||
from notes.models import ContentBlockBookmark
|
||||
from notes.schema import ContentBlockBookmarkNode
|
||||
from rooms.models import ModuleRoomSlug
|
||||
|
||||
from core.logger import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
|
|
@ -39,6 +37,8 @@ def is_solution_and_hidden_for_user(type, user, module):
|
|||
class ContentBlockNode(DjangoObjectType):
|
||||
mine = graphene.Boolean()
|
||||
bookmarks = graphene.List(ContentBlockBookmarkNode)
|
||||
hidden_for = graphene.List('users.schema.SchoolClassNode')
|
||||
visible_for = graphene.List('users.schema.SchoolClassNode')
|
||||
|
||||
class Meta:
|
||||
model = ContentBlock
|
||||
|
|
@ -54,10 +54,6 @@ class ContentBlockNode(DjangoObjectType):
|
|||
def resolve_mine(parent, info, **kwargs):
|
||||
return parent.owner is not None and parent.owner.pk == info.context.user.pk
|
||||
|
||||
@staticmethod
|
||||
def resolve_type(parent, info, **kwargs):
|
||||
return parent.type
|
||||
|
||||
def resolve_contents(self, info, **kwargs):
|
||||
updated_stream_data = []
|
||||
for content in self.contents.stream_data:
|
||||
|
|
@ -82,6 +78,11 @@ class ContentBlockNode(DjangoObjectType):
|
|||
content_block=self
|
||||
)
|
||||
|
||||
def resolve_hidden_for(parent, info, **kwargs):
|
||||
return parent.hidden_for.all()
|
||||
|
||||
def resolve_visible_for(parent, info, **kwargs):
|
||||
return parent.visible_for.all()
|
||||
|
||||
|
||||
def process_module_room_slug_block(content):
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ class ModuleNode(DjangoObjectType):
|
|||
'slug': ['exact', 'icontains', 'in'],
|
||||
'title': ['exact', 'icontains', 'in'],
|
||||
}
|
||||
interfaces = (ModuleInterface, )
|
||||
|
||||
interfaces = (ModuleInterface,)
|
||||
|
||||
chapters = DjangoFilterConnectionField(ChapterNode)
|
||||
solutions_enabled = graphene.Boolean()
|
||||
|
|
@ -36,7 +35,6 @@ class ModuleNode(DjangoObjectType):
|
|||
my_chapter_bookmarks = DjangoFilterConnectionField(ChapterBookmarkNode)
|
||||
snapshots = graphene.List('books.schema.nodes.SnapshotNode')
|
||||
|
||||
|
||||
def resolve_chapters(self, info, **kwargs):
|
||||
return Chapter.get_by_parent(self)
|
||||
|
||||
|
|
@ -88,6 +86,7 @@ class ModuleNode(DjangoObjectType):
|
|||
def resolve_snapshots(parent, info, **kwargs):
|
||||
return parent.snapshots.all()
|
||||
|
||||
|
||||
class RecentModuleNode(DjangoObjectType):
|
||||
class Meta:
|
||||
model = RecentModule
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class SnapshotContentBlock:
|
|||
self.id = content_block.id
|
||||
self.pk = content_block.pk
|
||||
self.title = content_block.title
|
||||
self.contents = content_block.title
|
||||
self.contents = content_block.contents
|
||||
self.type = content_block.type
|
||||
self.hidden = snapshot.hidden_content_blocks.filter(id=content_block.id).exists()
|
||||
|
||||
|
|
@ -61,21 +61,18 @@ class SnapshotChapterNode(ObjectType):
|
|||
title_hidden = graphene.Boolean()
|
||||
|
||||
|
||||
|
||||
|
||||
class SnapshotNode(DjangoObjectType):
|
||||
title = graphene.String()
|
||||
# chapters = graphene.Field(SnapshotChapterNode)
|
||||
snapshot_chapters = DjangoFilterConnectionField(ChapterInSnapshotNode)
|
||||
chapters = graphene.List(SnapshotChapterNode)
|
||||
meta_title = graphene.String()
|
||||
hero_image = graphene.String()
|
||||
|
||||
class Meta:
|
||||
model = Snapshot
|
||||
interfaces = (relay.Node,)
|
||||
|
||||
@staticmethod
|
||||
def resolve_snapshot_chapters(parent, info, **kwargs):
|
||||
# return Chapter.objects.filter(chapter_snapshots__snapshot=self)
|
||||
return parent.chapters.through.objects.all()
|
||||
|
||||
@staticmethod
|
||||
def resolve_chapters(parent, info, **kwargs):
|
||||
return [
|
||||
|
|
@ -85,9 +82,19 @@ class SnapshotNode(DjangoObjectType):
|
|||
title_hidden=chapter_snapshot.title_hidden,
|
||||
description_hidden=chapter_snapshot.description_hidden
|
||||
)
|
||||
for chapter_snapshot in parent.chapters.through.objects.all()
|
||||
for chapter_snapshot in parent.chapters.through.objects.filter(snapshot=parent)
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def resolve_title(parent, info, **kwargs):
|
||||
return parent.__str__()
|
||||
|
||||
@staticmethod
|
||||
def resolve_meta_title(parent, info, **kwargs):
|
||||
return parent.module.meta_title
|
||||
|
||||
@staticmethod
|
||||
def resolve_hero_image(parent, info, **kwargs):
|
||||
if parent.module.hero_image:
|
||||
return parent.module.hero_image.file.url
|
||||
return ''
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ type ChapterNode implements ChapterInterface {
|
|||
descriptionHiddenFor(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection!
|
||||
id: ID!
|
||||
bookmark: ChapterBookmarkNode
|
||||
contentBlocks(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ContentBlockNodeConnection
|
||||
contentBlocks: [ContentBlockNode]
|
||||
}
|
||||
|
||||
type ChapterNodeConnection {
|
||||
|
|
@ -309,8 +309,8 @@ interface ContentBlockInterface {
|
|||
type ContentBlockNode implements ContentBlockInterface {
|
||||
title: String
|
||||
slug: String!
|
||||
hiddenFor(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection!
|
||||
visibleFor(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection!
|
||||
hiddenFor: [SchoolClassNode]
|
||||
visibleFor: [SchoolClassNode]
|
||||
userCreated: Boolean!
|
||||
contents: GenericStreamFieldType
|
||||
type: String
|
||||
|
|
@ -659,7 +659,7 @@ type ModuleEdge {
|
|||
interface ModuleInterface {
|
||||
id: ID!
|
||||
pk: Int
|
||||
heroImage: String
|
||||
heroImage: String!
|
||||
topic: TopicNode
|
||||
}
|
||||
|
||||
|
|
@ -667,7 +667,7 @@ type ModuleNode implements ModuleInterface {
|
|||
title: String!
|
||||
slug: String!
|
||||
metaTitle: String!
|
||||
heroImage: String
|
||||
heroImage: String!
|
||||
teaser: String!
|
||||
intro: String!
|
||||
assignments(offset: Int, before: String, after: String, first: Int, last: Int): AssignmentNodeConnection!
|
||||
|
|
@ -929,7 +929,8 @@ type SnapshotNode implements Node {
|
|||
creator: UserNode
|
||||
chapterSnapshots(offset: Int, before: String, after: String, first: Int, last: Int, id: ID): ChapterInSnapshotNodeConnection!
|
||||
title: String
|
||||
snapshotChapters(offset: Int, before: String, after: String, first: Int, last: Int, id: ID): ChapterInSnapshotNodeConnection
|
||||
metaTitle: String
|
||||
heroImage: String
|
||||
}
|
||||
|
||||
input SpellCheckInput {
|
||||
|
|
|
|||
Loading…
Reference in New Issue