Enable scrolling to the content blocks in a module
This commit is contained in:
parent
65a09fb9c7
commit
9fb8e13c1c
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="chapter">
|
||||
<div class="chapter" :data-scrollto="chapter.id">
|
||||
<h3 :id="'chapter-' + index">{{chapter.title}}</h3>
|
||||
|
||||
<bookmark-actions
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<template>
|
||||
<div class="content-component" :class="{'content-component--bookmarked': bookmarked}">
|
||||
<div class="content-component"
|
||||
:class="{'content-component--bookmarked': bookmarked}"
|
||||
:data-scrollto="component.id">
|
||||
<bookmark-actions
|
||||
v-if="showBookmarkActions"
|
||||
@add-note="addNote(component.id)"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="survey-block">
|
||||
<div class="survey-block" :data-scrollto="value.id">
|
||||
<router-link class="button button--primary"
|
||||
:to="{name: 'survey', params: {id:value.id}}">Übung anzeigen
|
||||
</router-link>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="assignment" :data-scrollto="assignment.id">
|
||||
<div class="assignment" :data-scrollto="value.id">
|
||||
<p class="assignment__assignment-text">
|
||||
{{assignment.assignment}}
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<div class="module-activity__entry module-activity-entry"
|
||||
v-for="submission in module.mySubmissions"
|
||||
:key="submission.id"
|
||||
@click="goToAssignment(submission.assignment.id)">
|
||||
@click="goTo(submission.assignment.id)">
|
||||
<h3 class="module-activity-entry__title">Aufgabe & Ergebnis</h3>
|
||||
<p class="module-activity-entry__text">
|
||||
{{submission.text}}
|
||||
|
|
@ -14,7 +14,8 @@
|
|||
</div>
|
||||
<div class="module-activity__entry module-activity-entry"
|
||||
v-for="answer in module.myAnswers"
|
||||
:key="answer.id">
|
||||
:key="answer.id"
|
||||
@click="goTo(answer.survey.id)">
|
||||
<h3 class="module-activity-entry__title">Übung</h3>
|
||||
<p class="module-activity-entry__text">
|
||||
{{answer.survey.title}}
|
||||
|
|
@ -23,12 +24,14 @@
|
|||
</div>
|
||||
<div class="module-activity__entry"
|
||||
v-for="bookmark in module.myContentBookmarks"
|
||||
:key="bookmark.id">
|
||||
:key="bookmark.id"
|
||||
@click="goTo(bookmark.uuid)">
|
||||
<content-bookmark :bookmark="bookmark"></content-bookmark>
|
||||
</div>
|
||||
<div class="module-activity__entry"
|
||||
v-for="bookmark in module.myChapterBookmarks"
|
||||
:key="bookmark.id">
|
||||
:key="bookmark.id"
|
||||
@click="goTo(bookmark.chapter.id)">
|
||||
<h3 class="module-activity-entry__title">Lesezeichen</h3>
|
||||
<p class="module-activity-entry__text">
|
||||
{{bookmark.chapter.description}}
|
||||
|
|
@ -51,6 +54,8 @@
|
|||
import {mapActions} from 'vuex'
|
||||
import ContentBookmark from '@/components/profile/ContentBookmark';
|
||||
|
||||
import SCROLL_TO_MUTATION from '@/graphql/gql/local/mutations/scrollTo.gql';
|
||||
|
||||
export default {
|
||||
props: ['module'],
|
||||
components: {
|
||||
|
|
@ -74,9 +79,14 @@
|
|||
},
|
||||
methods: {
|
||||
...mapActions(['scrollToAssignmentId']),
|
||||
goToAssignment(id) {
|
||||
goTo(scrollTo) {
|
||||
const url = `/module/${this.module.slug}/`;
|
||||
this.scrollToAssignmentId(id);
|
||||
this.$apollo.mutate({
|
||||
mutation: SCROLL_TO_MUTATION,
|
||||
variables: {
|
||||
scrollTo
|
||||
}
|
||||
});
|
||||
this.$router.push(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
mutation($scrollTo: String!) {
|
||||
scrollTo(scrollTo: $scrollTo) @client
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
query ScrollPosition {
|
||||
scrollPosition @client {
|
||||
scrollTo
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters, mapActions } from 'vuex'
|
||||
import {mapGetters, mapActions} from 'vuex'
|
||||
import ASSIGNMENTS_QUERY from '@/graphql/gql/assignmentsQuery.gql';
|
||||
import {moduleQuery} from '@/graphql/queries';
|
||||
import MODULE_DETAILS_QUERY from '@/graphql/gql/moduleDetailsQuery.gql';
|
||||
|
||||
import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
|
||||
import SCROLL_TO_MUTATION from '@/graphql/gql/local/mutations/scrollTo.gql';
|
||||
|
||||
import Module from '@/components/modules/Module.vue';
|
||||
|
||||
|
|
@ -16,23 +19,65 @@
|
|||
|
||||
methods: {
|
||||
...mapActions(['scrollToAssignmentReady', 'scrollingToAssignment']),
|
||||
scrollTo() {
|
||||
if (this.scrollPosition && this.scrollPosition.scrollTo) {
|
||||
let options = {
|
||||
container: 'body',
|
||||
easing: 'ease',
|
||||
offset: -60,
|
||||
onStart: (element) => {
|
||||
},
|
||||
onDone: (element) => {
|
||||
},
|
||||
onCancel: function () {
|
||||
// scrolling has been interrupted
|
||||
},
|
||||
x: false,
|
||||
y: true
|
||||
};
|
||||
setTimeout(() => {
|
||||
this.$scrollTo(`[data-scrollto="${this.scrollPosition.scrollTo}"]`, 1000, options);
|
||||
this.$apollo.mutate({
|
||||
mutation: SCROLL_TO_MUTATION,
|
||||
variables: {
|
||||
scrollTo: ''
|
||||
}
|
||||
})
|
||||
}, 250); // unfortunately this timeout is needed as it is hard to tell when everything is rendered
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters({
|
||||
scrollToAssignmentId: 'scrollToAssignmentId',
|
||||
isScrollingToAssignment: 'scrollingToAssignment',
|
||||
editModule: 'editModule'
|
||||
}),
|
||||
editModule: 'editModule'
|
||||
}),
|
||||
},
|
||||
|
||||
apollo: {
|
||||
module: moduleQuery,
|
||||
module() {
|
||||
return {
|
||||
query: MODULE_DETAILS_QUERY,
|
||||
variables: {
|
||||
slug: this.$route.params.slug
|
||||
},
|
||||
update(data) {
|
||||
return this.$getRidOfEdges(data).module || {};
|
||||
},
|
||||
result() {
|
||||
// scroll only after the module has been loaded completely
|
||||
this.scrollTo();
|
||||
}
|
||||
}
|
||||
},
|
||||
assignments() {
|
||||
return {
|
||||
query: ASSIGNMENTS_QUERY
|
||||
}
|
||||
}
|
||||
},
|
||||
scrollPosition: {
|
||||
query: SCROLL_POSITION
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
@ -41,34 +86,5 @@
|
|||
assignments: []
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$store.subscribe((mutation, state) => {
|
||||
if (mutation.type === 'setScrollToAssignmentReady' && mutation.payload && !this.isScrollingToAssignment) {
|
||||
this.scrollingToAssignment(true);
|
||||
let options = {
|
||||
container: 'body',
|
||||
easing: 'ease',
|
||||
offset: -60,
|
||||
onStart: (element) => {
|
||||
},
|
||||
onDone: (element) => {
|
||||
this.scrollToAssignmentReady(false);
|
||||
this.scrollingToAssignment(false);
|
||||
},
|
||||
onCancel: function() {
|
||||
// scrolling has been interrupted
|
||||
},
|
||||
x: false,
|
||||
y: true
|
||||
};
|
||||
setTimeout(() => {
|
||||
this.$scrollTo(`[data-scrollto="${this.scrollToAssignmentId}"]`, 1000, options);
|
||||
}, 250) // unfortunately this timeout is needed as it is hard to tell when everything is rendered
|
||||
}
|
||||
})
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.scrollToAssignmentReady(false);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -225,34 +225,35 @@ class BookNode(DjangoObjectType):
|
|||
return Topic.get_by_parent(self)
|
||||
|
||||
|
||||
class FilteredChapterNode(DjangoObjectType):
|
||||
content_blocks = DjangoFilterConnectionField(ContentBlockNode)
|
||||
|
||||
class Meta:
|
||||
model = Chapter
|
||||
only_fields = [
|
||||
'slug', 'title', 'description',
|
||||
]
|
||||
filter_fields = [
|
||||
'slug', 'title',
|
||||
]
|
||||
interfaces = (relay.Node,)
|
||||
|
||||
def resolve_content_blocks(self, *args, **kwargs):
|
||||
return ContentBlock.get_by_parent(self)
|
||||
# todo: do we need this?
|
||||
# class FilteredChapterNode(DjangoObjectType):
|
||||
# content_blocks = DjangoFilterConnectionField(ContentBlockNode)
|
||||
#
|
||||
# class Meta:
|
||||
# model = Chapter
|
||||
# only_fields = [
|
||||
# 'slug', 'title', 'description',
|
||||
# ]
|
||||
# filter_fields = [
|
||||
# 'slug', 'title',
|
||||
# ]
|
||||
# interfaces = (relay.Node,)
|
||||
#
|
||||
# def resolve_content_blocks(self, *args, **kwargs):
|
||||
# return ContentBlock.get_by_parent(self)
|
||||
|
||||
|
||||
class BookQuery(object):
|
||||
book = relay.Node.Field(BookNode)
|
||||
topic = graphene.Field(TopicNode, slug=graphene.String())
|
||||
module = graphene.Field(ModuleNode, slug=graphene.String(), id=graphene.ID())
|
||||
chapter = relay.Node.Field(FilteredChapterNode)
|
||||
chapter = relay.Node.Field(ChapterNode)
|
||||
content_block = relay.Node.Field(ContentBlockNode)
|
||||
|
||||
books = DjangoFilterConnectionField(BookNode)
|
||||
topics = DjangoFilterConnectionField(TopicNode)
|
||||
modules = DjangoFilterConnectionField(ModuleNode)
|
||||
chapters = DjangoFilterConnectionField(FilteredChapterNode)
|
||||
chapters = DjangoFilterConnectionField(ChapterNode)
|
||||
|
||||
def resolve_books(self, *args, **kwargs):
|
||||
return Book.objects.filter(**kwargs).live()
|
||||
|
|
|
|||
Loading…
Reference in New Issue