use activity data in frontent
This commit is contained in:
parent
fa98141f3c
commit
59d88d5143
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="{'no-scroll': showModal || showMobileNavigation}" class="app">
|
<div :class="{'no-scroll': showModal || showMobileNavigation}" class="app" id="app">
|
||||||
<component :is="showModal" v-if="showModal"></component>
|
<component :is="showModal" v-if="showModal"></component>
|
||||||
<component :is="layout"></component>
|
<component :is="layout"></component>
|
||||||
<mobile-navigation v-if="showMobileNavigation"></mobile-navigation>
|
<mobile-navigation v-if="showMobileNavigation"></mobile-navigation>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<router-link to="/me">
|
<router-link to="/me/activity">
|
||||||
<div class="user-widget" :class="{'user-widget--is-profile': isProfile}">
|
<div class="user-widget" :class="{'user-widget--is-profile': isProfile}">
|
||||||
<user-icon class="user-widget__avatar" :src="avatar"></user-icon>
|
<user-icon class="user-widget__avatar" :src="avatar"></user-icon>
|
||||||
<span class="user-widget__name">{{firstName}} {{lastName}}</span>
|
<span class="user-widget__name">{{firstName}} {{lastName}}</span>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="assignment">
|
<div class="assignment">
|
||||||
<h3 class="assignment__title">{{assignment.title}}</h3>
|
<h3 class="assignment__title" :id="assignment.id.replace(/=/g, '')">{{assignment.title}}</h3>
|
||||||
<p class="assignment__assignment-text">
|
<p class="assignment__assignment-text">
|
||||||
{{assignment.assignment}}
|
{{assignment.assignment}}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -67,6 +67,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import ASSIGNMENT_QUERY from '@/graphql/gql/assignmentQuery.gql';
|
import ASSIGNMENT_QUERY from '@/graphql/gql/assignmentQuery.gql';
|
||||||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||||
import UPDATE_ASSIGNMENT_MUTATION from '@/graphql/gql/mutations/updateAssignmentMutation.gql';
|
import UPDATE_ASSIGNMENT_MUTATION from '@/graphql/gql/mutations/updateAssignmentMutation.gql';
|
||||||
|
|
@ -92,6 +93,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapGetters(['scrollToAssignmentId']),
|
||||||
final() {
|
final() {
|
||||||
return !!this.submission && this.submission.final
|
return !!this.submission && this.submission.final
|
||||||
},
|
},
|
||||||
|
|
@ -109,6 +111,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
...mapActions(['scrollToAssignmentReady']),
|
||||||
_save: debounce(function (submission) {
|
_save: debounce(function (submission) {
|
||||||
this.saving++;
|
this.saving++;
|
||||||
this.$apollo.mutate({
|
this.$apollo.mutate({
|
||||||
|
|
@ -196,6 +199,9 @@
|
||||||
result({data}) {
|
result({data}) {
|
||||||
this.assignment = cloneDeep(data.assignment);
|
this.assignment = cloneDeep(data.assignment);
|
||||||
this.assignment.submission = Object.assign(this.initialSubmission(), this.assignment.submission);
|
this.assignment.submission = Object.assign(this.initialSubmission(), this.assignment.submission);
|
||||||
|
if (this.assignment.id === this.scrollToAssignmentId) {
|
||||||
|
this.$nextTick(() => this.scrollToAssignmentReady(true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
me: {
|
me: {
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="module-activity">
|
<div class="module-activity">
|
||||||
<h3 class="module-activity__module-name">Geld und Kauf - Modul 9</h3>
|
<h3 class="module-activity__module-name">{{moduleTitle}}</h3>
|
||||||
<h2 class="module-activity__title">Ökololololologie</h2>
|
<h2 class="module-activity__title">{{title}}</h2>
|
||||||
<div class="module-activity__tasks activity-tasks">
|
<div class="module-activity__tasks activity-tasks">
|
||||||
<h4 class="activity-tasks__title">Aufträge</h4>
|
<h4 class="activity-tasks__title">Aufträge</h4>
|
||||||
<ol class="activity-tasks__task-list task-list">
|
<ol class="activity-tasks__task-list task-list">
|
||||||
<li class="task-list__item task-item">
|
<li v-for="activity in activities" :key="activity.key" class="task-list__item task-item">
|
||||||
<h5 class="task-item__title">Auftrag x, Begründung</h5>
|
<h5 class="task-item__title">{{activity.assignmentTitle}}</h5>
|
||||||
<p class="task-item__submission">"eine Antwrotasdfasdfasdf"</p>
|
<p class="task-item__submission">{{activity.answer}}</p>
|
||||||
</li>
|
<a href="#" @click="goToAssignment(activity)"><chevron-right class="task-item__chevron"></chevron-right></a>
|
||||||
<li class="task-list__item task-item">
|
|
||||||
<h5 class="task-item__title">Auftrag x, Begründung</h5>
|
|
||||||
<p class="task-item__submission">"eine Antwrotasdfasdfasdf"</p>
|
|
||||||
</li>
|
|
||||||
<li class="task-list__item task-item">
|
|
||||||
<h5 class="task-item__title">Auftrag x, Begründung</h5>
|
|
||||||
<p class="task-item__submission">"eine Antwrotasdfasdfasdf"</p>
|
|
||||||
</li>
|
|
||||||
<li class="task-list__item task-item">
|
|
||||||
<h5 class="task-item__title">Auftrag x, Begründung</h5>
|
|
||||||
<p class="task-item__submission">"eine Antwrotasdfasdfasdf"</p>
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
<div class="module-activity__tasks activity-tasks">
|
|
||||||
<h4 class="activity-tasks__title activity-tasks__title--alternative">Basiswissen</h4>
|
|
||||||
<ol class="activity-tasks__task-list task-list">
|
|
||||||
<li class="task-list__item task-item">
|
|
||||||
<h5 class="task-item__title">Auftrag x, Begründung</h5>:
|
|
||||||
<p class="task-item__submission">"eine Antwrotasdfasdfasdf"</p>
|
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -37,7 +17,25 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
import { mapActions } from 'vuex'
|
||||||
|
import ChevronRight from '@/components/icons/ChevronRight';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
props: ['metaTitle', 'title', 'activities', 'topic', 'slug'],
|
||||||
|
components: {ChevronRight},
|
||||||
|
computed: {
|
||||||
|
moduleTitle () {
|
||||||
|
return `${this.topic.title} - ${this.metaTitle}`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(['scrollToAssignmentId']),
|
||||||
|
goToAssignment (activity) {
|
||||||
|
const url = `/module/${this.slug}/`;
|
||||||
|
this.scrollToAssignmentId(activity.assignmentId);
|
||||||
|
this.$router.push(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -70,7 +68,9 @@
|
||||||
.task-item {
|
.task-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin-left: $medium-spacing;
|
justify-content: space-between;
|
||||||
|
|
||||||
|
$line-height: 50px;
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
&::after {
|
&::after {
|
||||||
|
|
@ -79,9 +79,23 @@
|
||||||
margin-right: $medium-spacing;
|
margin-right: $medium-spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__submission {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
&__title, &__submission {
|
&__title, &__submission {
|
||||||
line-height: 50px;
|
line-height: $line-height;
|
||||||
height: 50px;
|
height: $line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__chevron {
|
||||||
|
line-height: $line-height;
|
||||||
|
height: $medium-spacing;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: relative;
|
||||||
|
top: ($line-height - $medium-spacing) / 2;
|
||||||
|
fill: $color-brand;
|
||||||
|
width: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
query {
|
||||||
|
myActivity {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
text
|
||||||
|
assignment {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
module {
|
||||||
|
title
|
||||||
|
metaTitle
|
||||||
|
slug
|
||||||
|
id
|
||||||
|
topic {
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,37 +1,59 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="activity">
|
<div class="activity">
|
||||||
<h1 class="activity__header">Meine Aktivität</h1>
|
<h1 class="activity__header">Meine Aktivität</h1>
|
||||||
<module-activity class="activity"></module-activity>
|
<div class="modules">
|
||||||
<module-activity class="activity"></module-activity>
|
<module-activity v-for="moduleId in Object.keys(modules)" v-bind="modules[moduleId]" :key="moduleId" class="activity"></module-activity>
|
||||||
<module-activity class="activity"></module-activity>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import ModuleActivity from '@/components/profile/ModuleActivity';
|
import ModuleActivity from '@/components/profile/ModuleActivity';
|
||||||
|
import MY_ACTIVITY_QUERY from '@/graphql/gql/myActivity.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ModuleActivity
|
ModuleActivity
|
||||||
},
|
},
|
||||||
|
|
||||||
// apollo: {
|
apollo: {
|
||||||
// schoolClasses: {
|
submissions: {
|
||||||
// query: MY_SCHOOL_CLASSES_QUERY,
|
query: MY_ACTIVITY_QUERY,
|
||||||
// update(data) {
|
update(data) {
|
||||||
// return this.$getRidOfEdges(data).me.schoolClasses
|
return this.$getRidOfEdges(data).myActivity;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activities: []
|
submissions: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
computed: {
|
||||||
|
modules () {
|
||||||
|
let modules = {};
|
||||||
|
|
||||||
|
this.submissions.map((submission) => {
|
||||||
|
let activity = {
|
||||||
|
assignmentId: submission.assignment.id,
|
||||||
|
assignmentTitle: submission.assignment.title,
|
||||||
|
answer: submission.text
|
||||||
|
};
|
||||||
|
|
||||||
|
const module = submission.assignment.module
|
||||||
|
if (!(module.id in modules)) {
|
||||||
|
modules[module.id] = {
|
||||||
|
...module,
|
||||||
|
activities: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modules[module.id].activities = [...modules[module.id].activities, activity];
|
||||||
|
});
|
||||||
|
return modules
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapGetters, mapActions } from 'vuex'
|
||||||
import ASSIGNMENTS_QUERY from '@/graphql/gql/assignmentsQuery.gql';
|
import ASSIGNMENTS_QUERY from '@/graphql/gql/assignmentsQuery.gql';
|
||||||
import {moduleQuery} from '@/graphql/queries';
|
import {moduleQuery} from '@/graphql/queries';
|
||||||
|
|
||||||
|
|
@ -13,18 +14,60 @@
|
||||||
Module
|
Module
|
||||||
},
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
...mapActions(['scrollToAssignmentReady']),
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['scrollToAssignmentId']),
|
||||||
|
},
|
||||||
|
|
||||||
apollo: {
|
apollo: {
|
||||||
module: moduleQuery,
|
module: moduleQuery,
|
||||||
assignments: {
|
assignments() {
|
||||||
query: ASSIGNMENTS_QUERY
|
return {
|
||||||
|
query: ASSIGNMENTS_QUERY
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
module: {},
|
module: {},
|
||||||
assignments: []
|
assignments: [],
|
||||||
|
isScrolling: false
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.$store.subscribe((mutation, state) => {
|
||||||
|
if (mutation.type === 'setScrollToAssignmentReady' && state.scrollToAssignmentReady && !this.isScrolling) {
|
||||||
|
this.isScrolling = true;
|
||||||
|
// this.$nextTick(() => {
|
||||||
|
let options = {
|
||||||
|
container: '#app',
|
||||||
|
easing: 'ease-in',
|
||||||
|
offset: -60,
|
||||||
|
force: true,
|
||||||
|
cancelable: true,
|
||||||
|
onStart: (element) => {
|
||||||
|
},
|
||||||
|
onDone: (element) => {
|
||||||
|
this.scrollToAssignmentReady(false);
|
||||||
|
this.isScrolling = false;
|
||||||
|
},
|
||||||
|
onCancel: function() {
|
||||||
|
// scrolling has been interrupted
|
||||||
|
},
|
||||||
|
x: false,
|
||||||
|
y: true
|
||||||
|
};
|
||||||
|
this.$scrollTo(`#${this.scrollToAssignmentId.replace(/=/g, '')}`, 1000, options);
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
this.scrollToAssignmentReady(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -79,15 +79,12 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/me',
|
path: '/me',
|
||||||
name: 'profile',
|
|
||||||
component: profilePage,
|
component: profilePage,
|
||||||
meta: {
|
|
||||||
isProfile: true
|
|
||||||
},
|
|
||||||
children: [
|
children: [
|
||||||
{path: 'password-change', name: 'pw-change', component: passwordChange, meta: {isProfile: true}},
|
{path: 'password-change', name: 'pw-change', component: passwordChange, meta: {isProfile: true}},
|
||||||
{path: 'myclasses', name: 'my-classes', component: myClasses, meta: {isProfile: true}},
|
{path: 'myclasses', name: 'my-classes', component: myClasses, meta: {isProfile: true}},
|
||||||
{path: 'activity', name: 'activity', component: activity, meta: {isProfile: true}},
|
{path: 'activity', name: 'activity', component: activity, meta: {isProfile: true}},
|
||||||
|
{path: '', name: 'profile-activity', component: activity, meta: {isProfile: true}},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{path: '*', component: p404}
|
{path: '*', component: p404}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,9 @@ export default new Vuex.Store({
|
||||||
id: 0,
|
id: 0,
|
||||||
type: ''
|
type: ''
|
||||||
},
|
},
|
||||||
vimeoId: null
|
vimeoId: null,
|
||||||
|
scrollToAssignmentId: '',
|
||||||
|
scrollToAssignmentReady: false
|
||||||
},
|
},
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
|
|
@ -34,7 +36,9 @@ export default new Vuex.Store({
|
||||||
},
|
},
|
||||||
showMobileNavigation: state => {
|
showMobileNavigation: state => {
|
||||||
return state.showMobileNavigation
|
return state.showMobileNavigation
|
||||||
}
|
},
|
||||||
|
scrollToAssignmentId: state => state.scrollToAssignmentId,
|
||||||
|
scrollToAssignmentReady: state => state.scrollToAssignmentReady,
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
@ -118,6 +122,12 @@ export default new Vuex.Store({
|
||||||
},
|
},
|
||||||
showMobileNavigation({commit}, payload) {
|
showMobileNavigation({commit}, payload) {
|
||||||
commit('setShowMobileNavigation', payload);
|
commit('setShowMobileNavigation', payload);
|
||||||
|
},
|
||||||
|
scrollToAssignmentId({commit}, payload) {
|
||||||
|
commit('setScrollToAssignmentId', payload);
|
||||||
|
},
|
||||||
|
scrollToAssignmentReady({commit}, payload) {
|
||||||
|
commit('setScrollToAssignmentReady', payload);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -172,6 +182,12 @@ export default new Vuex.Store({
|
||||||
},
|
},
|
||||||
setShowMobileNavigation(state, payload) {
|
setShowMobileNavigation(state, payload) {
|
||||||
state.showMobileNavigation = payload;
|
state.showMobileNavigation = payload;
|
||||||
|
},
|
||||||
|
setScrollToAssignmentId(state, payload) {
|
||||||
|
state.scrollToAssignmentId = payload;
|
||||||
|
},
|
||||||
|
setScrollToAssignmentReady(state, payload) {
|
||||||
|
state.scrollToAssignmentReady = payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ class StudentSubmissionQuery(object):
|
||||||
|
|
||||||
|
|
||||||
class MyActivityQuery(object):
|
class MyActivityQuery(object):
|
||||||
# my_activity = relay.Node.Field(StudentSubmissionNode)
|
|
||||||
my_activity = DjangoFilterConnectionField(StudentSubmissionNode)
|
my_activity = DjangoFilterConnectionField(StudentSubmissionNode)
|
||||||
|
|
||||||
def resolve_my_activity(self, info, **kwargs):
|
def resolve_my_activity(self, info, **kwargs):
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,10 @@ class MyAssignemntsText(DefaultUserTestCase):
|
||||||
myActivity {
|
myActivity {
|
||||||
edges {
|
edges {
|
||||||
node {
|
node {
|
||||||
|
id
|
||||||
text
|
text
|
||||||
assignment {
|
assignment {
|
||||||
|
id
|
||||||
title
|
title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,13 +67,14 @@ class ChapterNode(DjangoObjectType):
|
||||||
class ModuleNode(DjangoObjectType):
|
class ModuleNode(DjangoObjectType):
|
||||||
pk = graphene.Int()
|
pk = graphene.Int()
|
||||||
chapters = DjangoFilterConnectionField(ChapterNode)
|
chapters = DjangoFilterConnectionField(ChapterNode)
|
||||||
|
topic = graphene.Field('books.schema.queries.TopicNode')
|
||||||
hero_image = graphene.String()
|
hero_image = graphene.String()
|
||||||
solutions_enabled = graphene.Boolean()
|
solutions_enabled = graphene.Boolean()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Module
|
model = Module
|
||||||
only_fields = [
|
only_fields = [
|
||||||
'slug', 'title', 'meta_title', 'teaser', 'intro', 'objective_groups', 'assignments', 'hero_image'
|
'slug', 'title', 'meta_title', 'teaser', 'intro', 'objective_groups', 'assignments', 'hero_image', 'topic'
|
||||||
]
|
]
|
||||||
filter_fields = {
|
filter_fields = {
|
||||||
'slug': ['exact', 'icontains', 'in'],
|
'slug': ['exact', 'icontains', 'in'],
|
||||||
|
|
@ -91,6 +92,10 @@ class ModuleNode(DjangoObjectType):
|
||||||
def resolve_chapters(self, info, **kwargs):
|
def resolve_chapters(self, info, **kwargs):
|
||||||
return Chapter.get_by_parent(self)
|
return Chapter.get_by_parent(self)
|
||||||
|
|
||||||
|
def resolve_topic(self, info, **kwargs):
|
||||||
|
some = self.get_parent().specific
|
||||||
|
return self.get_parent().specific
|
||||||
|
|
||||||
def resolve_solutions_enabled(self, info, **kwargs):
|
def resolve_solutions_enabled(self, info, **kwargs):
|
||||||
return self.solutions_enabled_by.filter(pk=info.context.user.pk).exists()
|
return self.solutions_enabled_by.filter(pk=info.context.user.pk).exists()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue