262 lines
7.1 KiB
Vue
262 lines
7.1 KiB
Vue
<template>
|
|
<div class="activity">
|
|
<h1 class="activity__heading">Meine Aktivitäten</h1>
|
|
<loading-message v-if="loading">Aktivitäten werden geladen</loading-message>
|
|
<template v-else>
|
|
<div class="activity__categories">
|
|
<a
|
|
class="activity__category default-link"
|
|
data-cy="activity-category"
|
|
:class="{ 'activity__category--active': selectedCategory === HIGHLIGHTS }"
|
|
@click="selectedCategory = HIGHLIGHTS"
|
|
>Markierungen</a
|
|
>
|
|
<a
|
|
class="activity__category default-link"
|
|
data-cy="activity-category"
|
|
:class="{ 'activity__category--active': selectedCategory === BOOKMARKS }"
|
|
@click="selectedCategory = BOOKMARKS"
|
|
>Lesezeichen</a
|
|
>
|
|
<a
|
|
class="activity__category default-link"
|
|
data-cy="activity-category"
|
|
:class="{ 'activity__category--active': selectedCategory === ASSIGNMENTS }"
|
|
@click="selectedCategory = ASSIGNMENTS"
|
|
>Ergebnisse</a
|
|
>
|
|
<a
|
|
class="activity__category default-link"
|
|
data-cy="activity-category"
|
|
:class="{ 'activity__category--active': selectedCategory === SURVEYS }"
|
|
@click="selectedCategory = SURVEYS"
|
|
>Übungen</a
|
|
>
|
|
</div>
|
|
<div class="activity__activities">
|
|
<instrument-activity-list
|
|
property="highlights"
|
|
:instruments="instruments"
|
|
v-if="selectedCategory === HIGHLIGHTS"
|
|
v-slot="{ item }"
|
|
>
|
|
<mark
|
|
class="highlight"
|
|
:class="[`highlight--${item?.color}`]"
|
|
>{{ item?.text }}</mark
|
|
>
|
|
<div v-if="item.note">Notiz: {{ item.note.text }}</div>
|
|
</instrument-activity-list>
|
|
<activity-list
|
|
:topics="highlightTopics"
|
|
property="myHighlights"
|
|
v-if="selectedCategory === HIGHLIGHTS"
|
|
v-slot="{ item }"
|
|
>
|
|
<mark
|
|
class="highlight"
|
|
:class="[`highlight--${item?.color}`]"
|
|
>{{ item?.text }}</mark
|
|
>
|
|
<div v-if="item.note">Notiz: {{ item.note.text }}</div>
|
|
</activity-list>
|
|
<instrument-activity-list
|
|
property="bookmarks"
|
|
:instruments="instruments"
|
|
v-if="selectedCategory === BOOKMARKS"
|
|
v-slot="{ item }"
|
|
>
|
|
<activity-bookmark :item="item" />
|
|
</instrument-activity-list>
|
|
<activity-list
|
|
:topics="bookmarkTopics"
|
|
property="myBookmarks"
|
|
v-if="selectedCategory === BOOKMARKS"
|
|
v-slot="{ item }"
|
|
>
|
|
<activity-bookmark :item="item" />
|
|
</activity-list>
|
|
<activity-list
|
|
:topics="submissionsTopics"
|
|
property="mySubmissions"
|
|
v-if="selectedCategory === ASSIGNMENTS"
|
|
v-slot="{ item }"
|
|
>
|
|
Submission: {{ item.text }}
|
|
</activity-list>
|
|
<activity-list
|
|
:topics="answersTopics"
|
|
property="myAnswers"
|
|
v-if="selectedCategory === SURVEYS"
|
|
v-slot="{ item }"
|
|
>
|
|
Übung: {{ item.survey.title }}
|
|
</activity-list>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { graphql } from '@/__generated__';
|
|
import { useQuery } from '@vue/apollo-composable';
|
|
import { ref, computed } from 'vue';
|
|
import ActivityList from '@/components/profile/ActivityList.vue';
|
|
import InstrumentActivityList from '@/components/profile/InstrumentActivityList.vue';
|
|
import LoadingMessage from '@/components/ui/LoadingMessage.vue';
|
|
import ActivityBookmark from '@/components/ActivityBookmark.vue';
|
|
import { TopicNode } from '@/__generated__/graphql';
|
|
|
|
const HIGHLIGHTS = 'highlights';
|
|
const BOOKMARKS = 'bookmarks';
|
|
const ASSIGNMENTS = 'assignments';
|
|
const SURVEYS = 'surveys';
|
|
|
|
const selectedCategory = ref(HIGHLIGHTS);
|
|
|
|
// todo: use fragments to simplify cache updates
|
|
const { result, loading } = useQuery(
|
|
graphql(`
|
|
query MyActivitiesQuery {
|
|
myActivities {
|
|
instruments {
|
|
id
|
|
slug
|
|
title
|
|
path
|
|
highlights {
|
|
...HighlightParts
|
|
}
|
|
bookmarks {
|
|
... on InstrumentBookmarkNode {
|
|
path
|
|
content
|
|
}
|
|
}
|
|
}
|
|
topics {
|
|
id
|
|
title
|
|
modules {
|
|
id
|
|
slug
|
|
title
|
|
metaTitle
|
|
myHighlights {
|
|
...HighlightParts
|
|
}
|
|
myBookmarks {
|
|
... on ChapterBookmarkNode {
|
|
chapter {
|
|
path
|
|
}
|
|
path
|
|
content
|
|
note {
|
|
id
|
|
text
|
|
}
|
|
}
|
|
... on ContentBlockBookmarkNode {
|
|
id
|
|
uuid
|
|
path
|
|
content
|
|
contentBlock {
|
|
id
|
|
path
|
|
}
|
|
note {
|
|
id
|
|
text
|
|
}
|
|
}
|
|
... on ModuleBookmarkNode {
|
|
path
|
|
content
|
|
note {
|
|
id
|
|
text
|
|
}
|
|
}
|
|
}
|
|
mySubmissions {
|
|
id
|
|
text
|
|
assignment {
|
|
id
|
|
title
|
|
path
|
|
module {
|
|
slug
|
|
}
|
|
}
|
|
}
|
|
myAnswers {
|
|
id
|
|
survey {
|
|
path
|
|
id
|
|
title
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`)
|
|
);
|
|
const topics = computed(() => result.value?.myActivities?.topics || []);
|
|
const instruments = computed(() => result.value?.myActivities?.instruments || []);
|
|
const highlightTopics = computed(() => {
|
|
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myHighlights?.length));
|
|
});
|
|
const bookmarkTopics = computed(() => {
|
|
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myBookmarks?.length));
|
|
});
|
|
const submissionsTopics = computed(() => {
|
|
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.mySubmissions?.length));
|
|
});
|
|
const answersTopics = computed(() => {
|
|
return topics.value.filter((topic: TopicNode) => topic.modules?.some((module) => module?.myAnswers?.length));
|
|
});
|
|
</script>
|
|
|
|
<style lang="postcss">
|
|
.activity {
|
|
&__activities {
|
|
padding-top: var(--section-spacing);
|
|
}
|
|
|
|
&__heading {
|
|
margin-bottom: var(--section-spacing);
|
|
}
|
|
|
|
&__categories {
|
|
display: flex;
|
|
flex-direction: row;
|
|
border-bottom: 1px solid var(--color-silver);
|
|
padding-bottom: var(--medium-spacing);
|
|
}
|
|
|
|
&__category {
|
|
color: inherit;
|
|
flex-grow: 1;
|
|
|
|
&--active {
|
|
color: var(--color-brand);
|
|
}
|
|
}
|
|
|
|
&__module {
|
|
border-bottom: 1px solid var(--color-silver);
|
|
margin-bottom: var(--section-spacing);
|
|
}
|
|
|
|
&__entry {
|
|
padding: var(--medium-spacing) 0;
|
|
border-top: 1px solid var(--color-silver);
|
|
}
|
|
}
|
|
</style>
|