Add all activity types to page in client

This commit is contained in:
Ramon Wenger 2024-02-27 16:23:50 +01:00
parent b8ceac59cb
commit c6e6491ef9
11 changed files with 310 additions and 129 deletions

View File

@ -56,3 +56,5 @@ export interface ActionOptions {
down?: boolean; down?: boolean;
extended?: boolean; extended?: boolean;
} }
export type ActivityProperty = 'myHighlights' | 'myBookmarks' | 'mySubmissions' | 'myAnswers';

View File

@ -14,7 +14,7 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/
*/ */
const documents = { const documents = {
"\n fragment ChapterHighlightsFragment on ChapterNode {\n id\n __typename\n highlights {\n ...HighlightParts\n }\n }\n": types.ChapterHighlightsFragmentFragmentDoc, "\n fragment ChapterHighlightsFragment on ChapterNode {\n id\n __typename\n highlights {\n ...HighlightParts\n }\n }\n": types.ChapterHighlightsFragmentFragmentDoc,
"\n fragment HighlightParts on HighlightNode {\n id\n contentIndex\n paragraphIndex\n selectionLength\n contentUuid\n startPosition\n color\n note {\n text\n }\n text\n page {\n # only one of them should be necessary, but the client somehow doesn't like just the Node inline fragment\n __typename\n ... on ContentBlockNode {\n id\n }\n ... on InstrumentNode {\n id\n slug\n }\n ... on ModuleNode {\n id\n slug\n }\n ... on ChapterNode {\n id\n slug\n }\n }\n }\n": types.HighlightPartsFragmentDoc, "\n fragment HighlightParts on HighlightNode {\n id\n contentIndex\n paragraphIndex\n selectionLength\n contentUuid\n startPosition\n color\n note {\n text\n }\n text\n page {\n # only one of them should be necessary, but the client somehow doesn't like just the Node inline fragment\n __typename\n ... on ContentBlockNode {\n id\n path\n }\n ... on InstrumentNode {\n id\n slug\n }\n ... on ModuleNode {\n id\n slug\n path\n }\n ... on ChapterNode {\n id\n path\n slug\n }\n }\n }\n": types.HighlightPartsFragmentDoc,
"\n fragment ContentBlockHighlightsFragment on ContentBlockNode {\n id\n __typename\n highlights {\n ...HighlightParts\n }\n }\n": types.ContentBlockHighlightsFragmentFragmentDoc, "\n fragment ContentBlockHighlightsFragment on ContentBlockNode {\n id\n __typename\n highlights {\n ...HighlightParts\n }\n }\n": types.ContentBlockHighlightsFragmentFragmentDoc,
"\n query LanguageQuery {\n me {\n language @client\n }\n }\n ": types.LanguageQueryDocument, "\n query LanguageQuery {\n me {\n language @client\n }\n }\n ": types.LanguageQueryDocument,
"\n mutation SetLanguage($language: String!) {\n setLanguage(language: $language) @client {\n language\n }\n }\n ": types.SetLanguageDocument, "\n mutation SetLanguage($language: String!) {\n setLanguage(language: $language) @client {\n language\n }\n }\n ": types.SetLanguageDocument,
@ -36,7 +36,7 @@ const documents = {
"\n fragment ContentBlockHighlightsWithIdOnlyFragment on ContentBlockNode {\n highlights {\n id\n }\n }\n ": types.ContentBlockHighlightsWithIdOnlyFragmentFragmentDoc, "\n fragment ContentBlockHighlightsWithIdOnlyFragment on ContentBlockNode {\n highlights {\n id\n }\n }\n ": types.ContentBlockHighlightsWithIdOnlyFragmentFragmentDoc,
"\n mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {\n updateInstrumentBookmark(input: $input) {\n success\n }\n }\n ": types.UpdateInstrumentBookmarkDocument, "\n mutation UpdateInstrumentBookmark($input: UpdateInstrumentBookmarkInput!) {\n updateInstrumentBookmark(input: $input) {\n success\n }\n }\n ": types.UpdateInstrumentBookmarkDocument,
"\n mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {\n updateContentBookmark(input: $input) {\n success\n }\n }\n ": types.UpdateContentBookmarkDocument, "\n mutation UpdateContentBookmark($input: UpdateContentBookmarkInput!) {\n updateContentBookmark(input: $input) {\n success\n }\n }\n ": types.UpdateContentBookmarkDocument,
"\n query MyActivitiesQuery {\n myActivities {\n topics {\n id\n title\n modules {\n id\n slug\n title\n myHighlights {\n ...HighlightParts\n }\n myBookmarks {\n ... on ContentBlockBookmarkNode {\n id\n uuid\n contentBlock {\n id\n }\n note {\n id\n text\n }\n }\n __typename\n }\n mySubmissions {\n id\n text\n assignment {\n id\n title\n }\n }\n myAnswers {\n id\n survey {\n id\n title\n }\n }\n }\n }\n }\n }\n ": types.MyActivitiesQueryDocument, "\n query MyActivitiesQuery {\n myActivities {\n topics {\n id\n title\n modules {\n id\n slug\n title\n metaTitle\n myHighlights {\n ...HighlightParts\n }\n myBookmarks {\n ... on ChapterBookmarkNode {\n chapter {\n path\n }\n path\n note {\n id\n text\n }\n }\n ... on ContentBlockBookmarkNode {\n id\n uuid\n path\n contentBlock {\n id\n path\n }\n note {\n id\n text\n }\n }\n ... on ModuleBookmarkNode {\n path\n note {\n id\n text\n }\n }\n }\n mySubmissions {\n id\n text\n assignment {\n id\n title\n path\n module {\n slug\n }\n }\n }\n myAnswers {\n id\n survey {\n path\n id\n title\n }\n }\n }\n }\n }\n }\n ": types.MyActivitiesQueryDocument,
"\n query ChapterQuery($id: ID!) {\n chapter(id: $id) {\n path\n }\n }\n ": types.ChapterQueryDocument, "\n query ChapterQuery($id: ID!) {\n chapter(id: $id) {\n path\n }\n }\n ": types.ChapterQueryDocument,
"\n query ContentBlockQuery($id: ID!) {\n contentBlock(id: $id) {\n path\n }\n }\n ": types.ContentBlockQueryDocument, "\n query ContentBlockQuery($id: ID!) {\n contentBlock(id: $id) {\n path\n }\n }\n ": types.ContentBlockQueryDocument,
"\n fragment InstrumentParts on InstrumentNode {\n id\n title\n intro\n slug\n language\n bookmarks {\n uuid\n note {\n id\n text\n }\n }\n type {\n id\n name\n category {\n id\n name\n foreground\n background\n }\n type\n }\n contents\n highlights {\n ...HighlightParts\n }\n }\n": types.InstrumentPartsFragmentDoc, "\n fragment InstrumentParts on InstrumentNode {\n id\n title\n intro\n slug\n language\n bookmarks {\n uuid\n note {\n id\n text\n }\n }\n type {\n id\n name\n category {\n id\n name\n foreground\n background\n }\n type\n }\n contents\n highlights {\n ...HighlightParts\n }\n }\n": types.InstrumentPartsFragmentDoc,
@ -68,7 +68,7 @@ export function graphql(source: "\n fragment ChapterHighlightsFragment on Chapt
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n fragment HighlightParts on HighlightNode {\n id\n contentIndex\n paragraphIndex\n selectionLength\n contentUuid\n startPosition\n color\n note {\n text\n }\n text\n page {\n # only one of them should be necessary, but the client somehow doesn't like just the Node inline fragment\n __typename\n ... on ContentBlockNode {\n id\n }\n ... on InstrumentNode {\n id\n slug\n }\n ... on ModuleNode {\n id\n slug\n }\n ... on ChapterNode {\n id\n slug\n }\n }\n }\n"): (typeof documents)["\n fragment HighlightParts on HighlightNode {\n id\n contentIndex\n paragraphIndex\n selectionLength\n contentUuid\n startPosition\n color\n note {\n text\n }\n text\n page {\n # only one of them should be necessary, but the client somehow doesn't like just the Node inline fragment\n __typename\n ... on ContentBlockNode {\n id\n }\n ... on InstrumentNode {\n id\n slug\n }\n ... on ModuleNode {\n id\n slug\n }\n ... on ChapterNode {\n id\n slug\n }\n }\n }\n"]; export function graphql(source: "\n fragment HighlightParts on HighlightNode {\n id\n contentIndex\n paragraphIndex\n selectionLength\n contentUuid\n startPosition\n color\n note {\n text\n }\n text\n page {\n # only one of them should be necessary, but the client somehow doesn't like just the Node inline fragment\n __typename\n ... on ContentBlockNode {\n id\n path\n }\n ... on InstrumentNode {\n id\n slug\n }\n ... on ModuleNode {\n id\n slug\n path\n }\n ... on ChapterNode {\n id\n path\n slug\n }\n }\n }\n"): (typeof documents)["\n fragment HighlightParts on HighlightNode {\n id\n contentIndex\n paragraphIndex\n selectionLength\n contentUuid\n startPosition\n color\n note {\n text\n }\n text\n page {\n # only one of them should be necessary, but the client somehow doesn't like just the Node inline fragment\n __typename\n ... on ContentBlockNode {\n id\n path\n }\n ... on InstrumentNode {\n id\n slug\n }\n ... on ModuleNode {\n id\n slug\n path\n }\n ... on ChapterNode {\n id\n path\n slug\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
@ -156,7 +156,7 @@ export function graphql(source: "\n mutation UpdateContentBookmark($input
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql(source: "\n query MyActivitiesQuery {\n myActivities {\n topics {\n id\n title\n modules {\n id\n slug\n title\n myHighlights {\n ...HighlightParts\n }\n myBookmarks {\n ... on ContentBlockBookmarkNode {\n id\n uuid\n contentBlock {\n id\n }\n note {\n id\n text\n }\n }\n __typename\n }\n mySubmissions {\n id\n text\n assignment {\n id\n title\n }\n }\n myAnswers {\n id\n survey {\n id\n title\n }\n }\n }\n }\n }\n }\n "): (typeof documents)["\n query MyActivitiesQuery {\n myActivities {\n topics {\n id\n title\n modules {\n id\n slug\n title\n myHighlights {\n ...HighlightParts\n }\n myBookmarks {\n ... on ContentBlockBookmarkNode {\n id\n uuid\n contentBlock {\n id\n }\n note {\n id\n text\n }\n }\n __typename\n }\n mySubmissions {\n id\n text\n assignment {\n id\n title\n }\n }\n myAnswers {\n id\n survey {\n id\n title\n }\n }\n }\n }\n }\n }\n "]; export function graphql(source: "\n query MyActivitiesQuery {\n myActivities {\n topics {\n id\n title\n modules {\n id\n slug\n title\n metaTitle\n myHighlights {\n ...HighlightParts\n }\n myBookmarks {\n ... on ChapterBookmarkNode {\n chapter {\n path\n }\n path\n note {\n id\n text\n }\n }\n ... on ContentBlockBookmarkNode {\n id\n uuid\n path\n contentBlock {\n id\n path\n }\n note {\n id\n text\n }\n }\n ... on ModuleBookmarkNode {\n path\n note {\n id\n text\n }\n }\n }\n mySubmissions {\n id\n text\n assignment {\n id\n title\n path\n module {\n slug\n }\n }\n }\n myAnswers {\n id\n survey {\n path\n id\n title\n }\n }\n }\n }\n }\n }\n "): (typeof documents)["\n query MyActivitiesQuery {\n myActivities {\n topics {\n id\n title\n modules {\n id\n slug\n title\n metaTitle\n myHighlights {\n ...HighlightParts\n }\n myBookmarks {\n ... on ChapterBookmarkNode {\n chapter {\n path\n }\n path\n note {\n id\n text\n }\n }\n ... on ContentBlockBookmarkNode {\n id\n uuid\n path\n contentBlock {\n id\n path\n }\n note {\n id\n text\n }\n }\n ... on ModuleBookmarkNode {\n path\n note {\n id\n text\n }\n }\n }\n mySubmissions {\n id\n text\n assignment {\n id\n title\n path\n module {\n slug\n }\n }\n }\n myAnswers {\n id\n survey {\n path\n id\n title\n }\n }\n }\n }\n }\n }\n "];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */

File diff suppressed because one or more lines are too long

View File

@ -274,6 +274,7 @@ graphql(`
__typename __typename
... on ContentBlockNode { ... on ContentBlockNode {
id id
path
} }
... on InstrumentNode { ... on InstrumentNode {
id id
@ -282,9 +283,11 @@ graphql(`
... on ModuleNode { ... on ModuleNode {
id id
slug slug
path
} }
... on ChapterNode { ... on ChapterNode {
id id
path
slug slug
} }
} }

View File

@ -3,6 +3,7 @@
<div <div
:data-scrollto="value.id" :data-scrollto="value.id"
class="assignment" class="assignment"
ref="assignmentDiv"
> >
<p <p
class="assignment__main-text" class="assignment__main-text"
@ -55,7 +56,36 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
export interface Props {
value: any;
}
const route = useRoute();
const assignmentDiv = ref<HTMLElement | null>(null);
const props = defineProps<Props>();
onMounted(() => {
if (assignmentDiv.value !== null) {
if (route.hash === `#${props.value.id}`) {
setTimeout(() => {
const rect = assignmentDiv.value.getBoundingClientRect();
window.scrollTo({
top: rect.y,
behavior: 'smooth',
});
}, PAGE_LOAD_TIMEOUT);
}
}
});
</script>
<script lang="ts">
import { mapActions, mapGetters } from 'vuex'; import { mapActions, mapGetters } from 'vuex';
import ASSIGNMENT_QUERY from '@/graphql/gql/queries/assignmentQuery.gql'; import ASSIGNMENT_QUERY from '@/graphql/gql/queries/assignmentQuery.gql';
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql'; import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';
@ -67,14 +97,13 @@ import cloneDeep from 'lodash/cloneDeep';
import { sanitize } from '@/helpers/text'; import { sanitize } from '@/helpers/text';
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
import { matomoTrackEvent } from '@/helpers/matomo-client'; import { matomoTrackEvent } from '@/helpers/matomo-client';
import { PAGE_LOAD_TIMEOUT } from '@/consts/navigation.consts';
const SubmissionForm = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SubmissionForm.vue')); const SubmissionForm = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SubmissionForm.vue'));
const Solution = defineAsyncComponent(() => import('@/components/content-blocks/Solution.vue')); const Solution = defineAsyncComponent(() => import('@/components/content-blocks/Solution.vue'));
const SpellCheck = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SpellCheck.vue')); const SpellCheck = defineAsyncComponent(() => import('@/components/content-blocks/assignment/SpellCheck.vue'));
export default { export default {
props: ['value'],
components: { components: {
Solution, Solution,
SubmissionForm, SubmissionForm,

View File

@ -1,17 +1,30 @@
<template> <template>
<div class="activity-entry"> <div
v-bind="$attrs"
class="activity-entry"
>
<div class="activity-entry__content"> <div class="activity-entry__content">
<slot /> <slot />
</div> </div>
<a class="activity-entry__link"> <router-link
:to="to"
class="activity-entry__link"
>
<chevron-right class="activity-entry__icon" /> <chevron-right class="activity-entry__icon" />
</a> </router-link>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import ChevronRight from '@/components/icons/ChevronRight.vue'; import ChevronRight from '@/components/icons/ChevronRight.vue';
import { RouterLink } from 'vue-router';
// todo: define a better type
interface Props {
to: any;
}
defineProps<Props>();
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -20,7 +33,7 @@ import ChevronRight from '@/components/icons/ChevronRight.vue';
.activity-entry { .activity-entry {
padding: $small-spacing 0; padding: $small-spacing 0;
border-bottom: 1px solid $color-silver; border-top: 1px solid $color-silver;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@ -0,0 +1,59 @@
<template>
<div>
<div
v-for="topic in topics"
:key="topic.id"
>
<template v-for="module in topic.modules">
<div
class="activity__module"
v-if="module[property]?.length"
:key="module.id"
>
<h4>Thema: {{ topic.title }} - {{ module.metaTitle }}: {{ module.title }}</h4>
<div
v-for="item in module[property]"
:key="item.id"
>
<activity-entry :to="`/${path(item)}`">
<slot :item="item"></slot>
</activity-entry>
</div>
</div>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import { ActivityProperty } from '@/@types';
import ActivityEntry from '@/components/profile/ActivityEntry.vue';
import { AnswerNode, BookmarkNode, HighlightNode, StudentSubmissionNode, TopicNode } from '@/__generated__/graphql';
export interface Props {
topics: TopicNode[];
property: ActivityProperty;
}
const props = defineProps<Props>();
const isHighlight = (value: any): value is HighlightNode => {
return props.property === 'myHighlights';
};
const isAssignment = (value: any): value is StudentSubmissionNode => {
return props.property === 'mySubmissions';
};
const isSurvey = (value: any): value is AnswerNode => {
return props.property === 'myAnswers';
};
const path = (item) => {
if (isHighlight(item)) {
return item.page.path;
} else if (isAssignment(item)) {
return item.assignment.path;
} else if (isSurvey(item)) {
return item.survey.path;
} else {
return (item as BookmarkNode).path;
}
};
</script>

View File

@ -17,6 +17,7 @@ fragment HighlightLegacyParts on HighlightNode {
} }
... on ContentBlockNode { ... on ContentBlockNode {
id id
path
} }
... on InstrumentNode { ... on InstrumentNode {
slug slug
@ -24,6 +25,7 @@ fragment HighlightLegacyParts on HighlightNode {
} }
... on ChapterNode { ... on ChapterNode {
slug slug
path
id id
} }
... on ModuleNode { ... on ModuleNode {

View File

@ -33,104 +33,143 @@
</div> </div>
<div class="activity__activities"> <div class="activity__activities">
<h2>Activities go here</h2> <h2>Activities go here</h2>
<div v-if="selectedCategory === HIGHLIGHTS"> <activity-list
<h3>HIGHLIGHTS</h3> :topics="highlightTopics"
<div property="myHighlights"
v-for="topic in highlightTopics" v-if="selectedCategory === HIGHLIGHTS"
:key="topic?.id" v-slot="{ item }"
>
<mark
class="highlight"
:class="[`highlight--${item?.color}`]"
>{{ item?.text }}</mark
> >
<h4>{{ topic?.title }}</h4> <div v-if="item.note">Notiz: {{ item.note.text }}</div>
<template v-for="module in topic?.modules"> </activity-list>
<div <activity-list
class="activity__module" :topics="bookmarkTopics"
v-if="module?.myHighlights?.length" property="myBookmarks"
:key="module?.id" v-if="selectedCategory === BOOKMARKS"
> v-slot="{ item }"
<div >
v-for="highlight in module.myHighlights" <div>Lesezeichen: {{ item.id }}</div>
:key="highlight?.id" <div v-if="item.note">Notiz: {{ item.note.text }}</div>
> </activity-list>
<activity-entry> <activity-list
<mark :topics="submissionsTopics"
class="highlight" property="mySubmissions"
:class="[`highlight--${highlight?.color}`]" v-if="selectedCategory === ASSIGNMENTS"
>{{ highlight?.text }}</mark v-slot="{ item }"
> >
</activity-entry> Submission: {{ item.text }}
</div> </activity-list>
</div> <activity-list
</template> :topics="answersTopics"
</div> property="myAnswers"
</div> v-if="selectedCategory === SURVEYS"
<h3 v-if="selectedCategory === BOOKMARKS">BOOKMARKS</h3> v-slot="{ item }"
<div v-if="selectedCategory === BOOKMARKS"> >
<div Übung: {{ item.survey.title }}
v-for="topic in bookmarkTopics" </activity-list>
:key="topic?.id" <!-- <div -->
> <!-- v-for="topic in highlightTopics" -->
<h4>{{ topic?.title }}</h4> <!-- :key="topic?.id" -->
<template v-for="module in topic?.modules"> <!-- > -->
<div <!-- <h4>{{ topic?.title }}</h4> -->
class="activity__module" <!-- <template v-for="module in topic?.modules"> -->
v-if="module?.myBookmarks?.length" <!-- <div -->
:key="module?.id" <!-- class="activity__module" -->
> <!-- v-if="module?.myHighlights?.length" -->
<div <!-- :key="module?.id" -->
v-for="bookmark in module?.myBookmarks" <!-- > -->
:key="bookmark?.id" <!-- <div -->
> <!-- v-for="highlight in module.myHighlights" -->
<activity-entry> Lesezeichen: {{ bookmark.id }} </activity-entry> <!-- :key="highlight.id" -->
</div> <!-- > -->
</div> <!-- <activity-entry :to="`/${highlight.page.path}`"> -->
</template> <!-- <mark -->
</div> <!-- class="highlight" -->
</div> <!-- :class="[`highlight--${highlight?.color}`]" -->
<div v-if="selectedCategory === ASSIGNMENTS"> <!-- >{{ highlight?.text }}</mark -->
<h3>ASSIGNMENTS</h3> <!-- > -->
<div <!-- </activity-entry> -->
v-for="topic in submissionsTopics" <!-- </div> -->
:key="topic?.id" <!-- </div> -->
> <!-- </template> -->
<h4>{{ topic?.title }}</h4> <!-- </div> -->
<template v-for="module in topic?.modules"> <!-- <div v-if="selectedCategory === BOOKMARKS"> -->
<div <!-- <div -->
class="activity__module" <!-- v-for="topic in bookmarkTopics" -->
v-if="module?.mySubmissions?.length" <!-- :key="topic?.id" -->
:key="module.id" <!-- > -->
> <!-- <h4>{{ topic?.title }}</h4> -->
<div <!-- <template v-for="module in topic?.modules"> -->
v-for="submission in module?.mySubmissions" <!-- <div -->
:key="submission?.id" <!-- class="activity__module" -->
> <!-- v-if="module?.myBookmarks?.length" -->
<activity-entry>Submission {{ submission?.text }}</activity-entry> <!-- :key="module?.id" -->
</div> <!-- > -->
</div> <!-- <div -->
</template> <!-- v-for="bookmark in module?.myBookmarks" -->
</div> <!-- :key="bookmark?.id" -->
</div> <!-- > -->
<div v-if="selectedCategory === SURVEYS"> <!-- <pre>{{ bookmark }}</pre> -->
<h3>SURVEYS</h3> <!-- <activity-entry :to="`/${bookmark.path}`"> > Lesezeichen: {{ bookmark.id }} </activity-entry> -->
<div <!-- </div> -->
v-for="topic in answersTopics" <!-- </div> -->
:key="topic?.id" <!-- </template> -->
> <!-- </div> -->
<h4>{{ topic?.title }}</h4> <!-- </div> -->
<template v-for="module in topic?.modules"> <!-- <div v-if="selectedCategory === ASSIGNMENTS"> -->
<div <!-- <h3>ASSIGNMENTS</h3> -->
v-if="module?.myAnswers?.length" <!-- <div -->
:key="module.id" <!-- v-for="topic in submissionsTopics" -->
> <!-- :key="topic?.id" -->
<div <!-- > -->
class="activity__module" <!-- <h4>{{ topic?.title }}</h4> -->
v-for="answer in module?.myAnswers" <!-- <template v-for="module in topic?.modules"> -->
:key="answer?.id" <!-- <div -->
> <!-- class="activity__module" -->
<activity-entry>Übung: {{ answer?.survey.title }}</activity-entry> <!-- v-if="module?.mySubmissions?.length" -->
</div> <!-- :key="module.id" -->
</div> <!-- > -->
</template> <!-- <div -->
</div> <!-- v-for="submission in module?.mySubmissions" -->
</div> <!-- :key="submission?.id" -->
<!-- > -->
<!-- <pre>{{ submission }}</pre> -->
<!-- <activity-entry :to="`/module/${submission.assignment.module.slug}#${submission.assignment.id}`"> -->
<!-- Submission {{ submission?.text }}</activity-entry -->
<!-- > -->
<!-- </div> -->
<!-- </div> -->
<!-- </template> -->
<!-- </div> -->
<!-- </div> -->
<!-- <div v-if="selectedCategory === SURVEYS"> -->
<!-- <h3>SURVEYS</h3> -->
<!-- <div -->
<!-- v-for="topic in answersTopics" -->
<!-- :key="topic?.id" -->
<!-- > -->
<!-- <h4>{{ topic?.title }}</h4> -->
<!-- <template v-for="module in topic?.modules"> -->
<!-- <div -->
<!-- v-if="module?.myAnswers?.length" -->
<!-- :key="module.id" -->
<!-- > -->
<!-- <div -->
<!-- class="activity__module" -->
<!-- v-for="answer in module?.myAnswers" -->
<!-- :key="answer.id" -->
<!-- > -->
<!-- <pre>{{ answer }}</pre> -->
<!-- <activity-entry :to="{ name: 'profile' }"> Übung: {{ answer?.survey.title }}</activity-entry> -->
<!-- </div> -->
<!-- </div> -->
<!-- </template> -->
<!-- </div> -->
<!-- </div> -->
</div> </div>
</div> </div>
</template> </template>
@ -140,6 +179,7 @@ import { graphql } from '@/__generated__';
import { useQuery } from '@vue/apollo-composable'; import { useQuery } from '@vue/apollo-composable';
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import ActivityEntry from '@/components/profile/ActivityEntry.vue'; import ActivityEntry from '@/components/profile/ActivityEntry.vue';
import ActivityList from '@/components/profile/ActivityList.vue';
import { TopicNode } from '@/__generated__/graphql'; import { TopicNode } from '@/__generated__/graphql';
const HIGHLIGHTS = 'highlights'; const HIGHLIGHTS = 'highlights';
@ -160,22 +200,41 @@ const { result } = useQuery(
id id
slug slug
title title
metaTitle
myHighlights { myHighlights {
...HighlightParts ...HighlightParts
} }
myBookmarks { myBookmarks {
... on ChapterBookmarkNode {
chapter {
path
}
path
note {
id
text
}
}
... on ContentBlockBookmarkNode { ... on ContentBlockBookmarkNode {
id id
uuid uuid
path
contentBlock { contentBlock {
id id
path
} }
note { note {
id id
text text
} }
} }
__typename ... on ModuleBookmarkNode {
path
note {
id
text
}
}
} }
mySubmissions { mySubmissions {
id id
@ -183,11 +242,16 @@ const { result } = useQuery(
assignment { assignment {
id id
title title
path
module {
slug
}
} }
} }
myAnswers { myAnswers {
id id
survey { survey {
path
id id
title title
} }
@ -198,7 +262,7 @@ const { result } = useQuery(
} }
`) `)
); );
const topics = computed(() => result.value?.myActivities.topics || []); const topics = computed(() => result.value?.myActivities?.topics || []);
const highlightTopics = computed(() => { const highlightTopics = computed(() => {
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myHighlights?.length)); return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myHighlights?.length));
}); });
@ -236,7 +300,7 @@ const answersTopics = computed(() => {
} }
&__module { &__module {
border-top: 1px solid var(--color-silver); border-bottom: 1px solid var(--color-silver);
} }
&__entry { &__entry {

View File

@ -163,9 +163,11 @@ export default {
slug: slug, slug: slug,
}); });
const fragmentName = 'ModuleParts';
const module = store.readFragment({ const module = store.readFragment({
fragment, fragment,
id, id,
fragmentName,
}); });
let bookmark; let bookmark;
@ -187,6 +189,7 @@ export default {
store.writeFragment({ store.writeFragment({
data, data,
fragment, fragment,
fragmentName,
id, id,
}); });
}, },

View File

@ -20,7 +20,7 @@ const moduleVisibility = () => import('@/pages/module/moduleVisibility.vue');
const settingsPage = () => import('@/pages/module/moduleSettings.vue'); const settingsPage = () => import('@/pages/module/moduleSettings.vue');
const snapshots = () => import('@/pages/snapshot/snapshots.vue'); const snapshots = () => import('@/pages/snapshot/snapshots.vue');
const snapshot = () => import('@/pages/snapshot/snapshot.vue'); const snapshot = () => import('@/pages/snapshot/snapshot.vue');
const contentBlockLocator = () => import(/* webpackChunkName: "modules" */ '@/pages/contentBlockLocator.vue'); const contentBlockLocator = () => import('@/pages/contentBlockLocator.vue');
const contentBlockFormMeta = { const contentBlockFormMeta = {
// layout: LAYOUT_SIMPLE, // layout: LAYOUT_SIMPLE,