Refactor chapter component

This commit is contained in:
Ramon Wenger 2023-02-13 14:10:00 +01:00
parent a629f6a5e6
commit 04d06b3332
4 changed files with 186 additions and 171 deletions

View File

@ -2,6 +2,11 @@ export type numberOrUndefined = number | undefined;
type types = 'task' | 'normal' | 'base_communication' | 'base_society' | 'base_interdisciplinary'; type types = 'task' | 'normal' | 'base_communication' | 'base_society' | 'base_interdisciplinary';
export interface Page {
id: string;
title: string;
}
export interface InstrumentCategory { export interface InstrumentCategory {
id: string; id: string;
name: string; name: string;
@ -10,10 +15,17 @@ export interface InstrumentCategory {
types: any[]; types: any[];
} }
export interface ContentBlock { export interface Hideable {
title: string; userCreated: boolean;
hiddenFor: any[];
visibleFor: any[];
titleHiddenFor: any[];
descriptionHiddenFor: any[];
hidden: boolean;
}
export interface ContentBlock extends Hideable, Page {
contents: any[]; contents: any[];
id: string;
isAssignment: boolean; isAssignment: boolean;
type: types; type: types;
notes: any[]; notes: any[];
@ -21,13 +33,15 @@ export interface ContentBlock {
indent?: boolean; indent?: boolean;
instrumentCategory: InstrumentCategory; instrumentCategory: InstrumentCategory;
mine: boolean; mine: boolean;
userCreated: boolean;
hiddenFor: any[];
visibleFor: any[];
root: string; root: string;
titleHiddenFor: any[]; }
descriptionHiddenFor: any[];
hidden: boolean; export interface Chapter extends Hideable, Page {
contentBlocks: ContentBlock[];
bookmark: any;
titleHidden: boolean;
descriptionHidden: boolean;
description: string;
} }
export interface ActionOptions { export interface ActionOptions {

View File

@ -32,7 +32,7 @@
data-cy="chapter-bookmark-actions" data-cy="chapter-bookmark-actions"
@add-note="addNote" @add-note="addNote"
@edit-note="editNote" @edit-note="editNote"
@bookmark="bookmark(!chapter.bookmark)" @bookmark="bookmark()"
/> />
<div <div
:class="{ 'hideable-element--greyed-out': descriptionGreyedOut }" :class="{ 'hideable-element--greyed-out': descriptionGreyedOut }"
@ -65,104 +65,92 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import ContentBlock from '@/components/ContentBlock'; import { computed } from 'vue';
import AddContentButton from '@/components/AddContentButton'; import ContentBlock from '@/components/ContentBlock.vue';
import BookmarkActions from '@/components/notes/BookmarkActions'; import AddContentButton from '@/components/AddContentButton.vue';
import VisibilityAction from '@/components/visibility/VisibilityAction'; import BookmarkActions from '@/components/notes/BookmarkActions.vue';
import VisibilityAction from '@/components/visibility/VisibilityAction.vue';
import CopyLink from '@/components/CopyLink.vue'; import CopyLink from '@/components/CopyLink.vue';
import type { Chapter } from '@/@types';
import { hidden } from '@/helpers/visibility'; import { hidden } from '@/helpers/visibility';
import { CHAPTER_DESCRIPTION_TYPE, CHAPTER_TITLE_TYPE, CONTENT_TYPE } from '@/consts/types'; import { CHAPTER_DESCRIPTION_TYPE, CHAPTER_TITLE_TYPE, CONTENT_TYPE } from '@/consts/types';
import { useStore } from 'vuex';
import UPDATE_CHAPTER_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateChapterBookmark.gql'; import UPDATE_CHAPTER_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateChapterBookmark.gql';
import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql'; import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql';
import { getMe } from '@/mixins/me';
import { useMutation } from '@vue/apollo-composable';
import me from '@/mixins/me'; export interface Props {
chapter: Chapter;
index: number;
editMode: boolean;
}
export default { const { schoolClass } = getMe();
props: {
chapter: {
type: Object,
default: () => ({}),
},
index: {
type: Number,
default: 0,
},
editMode: {
type: Boolean,
default: false,
},
},
mixins: [me], const store = useStore();
components: { const props = withDefaults(defineProps<Props>(), {
BookmarkActions, index: 0,
VisibilityAction, editMode: false,
ContentBlock, });
AddContentButton,
CopyLink,
},
computed: { const filteredContentBlocks = computed(() => {
filteredContentBlocks() { if (!(props.chapter && props.chapter.contentBlocks)) {
if (!(this.chapter && this.chapter.contentBlocks)) {
return []; return [];
} }
if (this.editMode) { if (props.editMode) {
return this.chapter.contentBlocks; return props.chapter.contentBlocks;
} }
return this.chapter.contentBlocks.filter( return props.chapter.contentBlocks.filter(
(contentBlock) => (contentBlock) =>
!hidden({ !hidden({
block: contentBlock, block: contentBlock,
schoolClass: this.schoolClass, schoolClass: schoolClass,
type: CONTENT_TYPE, type: CONTENT_TYPE,
}) })
); );
}, });
note() { const note = computed(() => {
if (this.chapter && this.chapter.bookmark) { if (props.chapter && props.chapter.bookmark) {
return this.chapter.bookmark.note; return props.chapter.bookmark.note;
} }
return false; return false;
}, });
titleGreyedOut() { const titleGreyedOut = computed(() => {
return this.textHidden(CHAPTER_TITLE_TYPE) && this.editMode; return textHidden(CHAPTER_TITLE_TYPE) && props.editMode;
}, });
const titleHidden = computed(() => {
// never hidden when editing the module // never hidden when editing the module
titleHidden() { if (props.chapter.titleHidden === true) {
if (this.chapter.titleHidden === true) {
return true; return true;
} }
return this.textHidden(CHAPTER_TITLE_TYPE) && !this.editMode; return textHidden(CHAPTER_TITLE_TYPE) && !props.editMode;
}, });
descriptionGreyedOut() { const descriptionGreyedOut = computed(() => {
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && this.editMode; return textHidden(CHAPTER_DESCRIPTION_TYPE) && props.editMode;
}, });
const descriptionHidden = computed(() => {
// never hidden when editing the module // never hidden when editing the module
descriptionHidden() { if (props.chapter.descriptionHidden === true) {
if (this.chapter.descriptionHidden === true) {
return true; return true;
} }
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && !this.editMode; return textHidden(CHAPTER_DESCRIPTION_TYPE) && !props.editMode;
}, });
},
methods: { const { mutate: bookmark } = useMutation(UPDATE_CHAPTER_BOOKMARK_MUTATION, () => {
bookmark(bookmarked) { const bookmarked = !props.chapter.bookmark;
const id = this.chapter.id; const id = props.chapter.id;
this.$apollo.mutate({ return {
mutation: UPDATE_CHAPTER_BOOKMARK_MUTATION,
variables: { variables: {
input: { input: {
chapter: id, chapter: id,
bookmarked, bookmarked,
}, },
}, },
update: (store) => { update: (store: any) => {
const query = CHAPTER_QUERY; const query = CHAPTER_QUERY;
const variables = { id }; const variables = { id };
const { chapter } = store.readQuery({ const { chapter } = store.readQuery({
@ -194,6 +182,7 @@ export default {
variables, variables,
}); });
}, },
optimisticResponse: { optimisticResponse: {
__typename: 'Mutation', __typename: 'Mutation',
updateChapterBookmark: { updateChapterBookmark: {
@ -201,28 +190,29 @@ export default {
success: true, success: true,
}, },
}, },
};
}); });
},
addNote(id) { const addNote = (id: string) => {
this.$store.dispatch('addNote', { store.dispatch('addNote', {
content: id, content: id,
parent: this.chapter.id, parent: props.chapter.id,
}); });
}, };
editNote() { const editNote = () => {
this.$store.dispatch('editNote', this.chapter.bookmark.note); store.dispatch('editNote', props.chapter.bookmark.note);
}, };
textHidden(type) { const textHidden = (type: string) => {
return hidden({ return hidden({
block: this.chapter, block: props.chapter,
schoolClass: this.schoolClass, schoolClass: schoolClass,
type, type,
}); });
},
},
}; };
</script> </script>
<script></script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~styles/helpers'; @import '~styles/helpers';

View File

@ -121,7 +121,7 @@ import type { Modal } from '@/plugins/modal.types';
export interface Props { export interface Props {
contentBlock: ContentBlock; contentBlock: ContentBlock;
parent?: any; parent?: any;
editMode: boolean; editMode?: boolean;
} }
const ContentComponent = defineAsyncComponent( const ContentComponent = defineAsyncComponent(

View File

@ -10,7 +10,7 @@ import UPDATE_OBJECTIVE_VISIBILITY_MUTATION from '@/graphql/gql/mutations/update
import UPDATE_OBJECTIVE_GROUP_VISIBILITY_MUTATION from '@/graphql/gql/mutations/updateObjectiveGroupVisibility.gql'; import UPDATE_OBJECTIVE_GROUP_VISIBILITY_MUTATION from '@/graphql/gql/mutations/updateObjectiveGroupVisibility.gql';
import UPDATE_CHAPTER_VISIBILITY_MUTATION from '@/graphql/gql/mutations/updateChapterVisibility.gql'; import UPDATE_CHAPTER_VISIBILITY_MUTATION from '@/graphql/gql/mutations/updateChapterVisibility.gql';
export const createVisibilityMutation = (type, id, visibility) => { export const createVisibilityMutation = (type: string, id: string, visibility: string) => {
let mutation, variables; let mutation, variables;
switch (type) { switch (type) {
case CONTENT_TYPE: case CONTENT_TYPE:
@ -61,9 +61,20 @@ export const createVisibilityMutation = (type, id, visibility) => {
}; };
}; };
const containsClass = (arr = [], schoolClass) => arr.map((entry) => entry.id).includes(schoolClass.id); const containsClass = (arr: any[] = [], schoolClass: any) => arr.map((entry) => entry.id).includes(schoolClass.id);
export const hidden = ({ export const hidden: (options: {
type: string;
block: {
userCreated: boolean;
visibleFor: any[];
hiddenFor: any[];
titleHiddenFor: any[];
descriptionHiddenFor: any[];
hidden: boolean;
};
schoolClass: any;
}) => boolean = ({
type, type,
block: { userCreated, visibleFor, hiddenFor, titleHiddenFor, descriptionHiddenFor, hidden }, block: { userCreated, visibleFor, hiddenFor, titleHiddenFor, descriptionHiddenFor, hidden },
schoolClass, schoolClass,