Refactor chapter component
This commit is contained in:
parent
a629f6a5e6
commit
04d06b3332
|
|
@ -2,6 +2,11 @@ export type numberOrUndefined = number | undefined;
|
|||
|
||||
type types = 'task' | 'normal' | 'base_communication' | 'base_society' | 'base_interdisciplinary';
|
||||
|
||||
export interface Page {
|
||||
id: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface InstrumentCategory {
|
||||
id: string;
|
||||
name: string;
|
||||
|
|
@ -10,10 +15,17 @@ export interface InstrumentCategory {
|
|||
types: any[];
|
||||
}
|
||||
|
||||
export interface ContentBlock {
|
||||
title: string;
|
||||
export interface Hideable {
|
||||
userCreated: boolean;
|
||||
hiddenFor: any[];
|
||||
visibleFor: any[];
|
||||
titleHiddenFor: any[];
|
||||
descriptionHiddenFor: any[];
|
||||
hidden: boolean;
|
||||
}
|
||||
|
||||
export interface ContentBlock extends Hideable, Page {
|
||||
contents: any[];
|
||||
id: string;
|
||||
isAssignment: boolean;
|
||||
type: types;
|
||||
notes: any[];
|
||||
|
|
@ -21,13 +33,15 @@ export interface ContentBlock {
|
|||
indent?: boolean;
|
||||
instrumentCategory: InstrumentCategory;
|
||||
mine: boolean;
|
||||
userCreated: boolean;
|
||||
hiddenFor: any[];
|
||||
visibleFor: any[];
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
data-cy="chapter-bookmark-actions"
|
||||
@add-note="addNote"
|
||||
@edit-note="editNote"
|
||||
@bookmark="bookmark(!chapter.bookmark)"
|
||||
@bookmark="bookmark()"
|
||||
/>
|
||||
<div
|
||||
:class="{ 'hideable-element--greyed-out': descriptionGreyedOut }"
|
||||
|
|
@ -65,164 +65,154 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentBlock from '@/components/ContentBlock';
|
||||
import AddContentButton from '@/components/AddContentButton';
|
||||
import BookmarkActions from '@/components/notes/BookmarkActions';
|
||||
import VisibilityAction from '@/components/visibility/VisibilityAction';
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import ContentBlock from '@/components/ContentBlock.vue';
|
||||
import AddContentButton from '@/components/AddContentButton.vue';
|
||||
import BookmarkActions from '@/components/notes/BookmarkActions.vue';
|
||||
import VisibilityAction from '@/components/visibility/VisibilityAction.vue';
|
||||
import CopyLink from '@/components/CopyLink.vue';
|
||||
|
||||
import type { Chapter } from '@/@types';
|
||||
import { hidden } from '@/helpers/visibility';
|
||||
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 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 {
|
||||
props: {
|
||||
chapter: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
const { schoolClass } = getMe();
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
index: 0,
|
||||
editMode: false,
|
||||
});
|
||||
|
||||
const filteredContentBlocks = computed(() => {
|
||||
if (!(props.chapter && props.chapter.contentBlocks)) {
|
||||
return [];
|
||||
}
|
||||
if (props.editMode) {
|
||||
return props.chapter.contentBlocks;
|
||||
}
|
||||
return props.chapter.contentBlocks.filter(
|
||||
(contentBlock) =>
|
||||
!hidden({
|
||||
block: contentBlock,
|
||||
schoolClass: schoolClass,
|
||||
type: CONTENT_TYPE,
|
||||
})
|
||||
);
|
||||
});
|
||||
const note = computed(() => {
|
||||
if (props.chapter && props.chapter.bookmark) {
|
||||
return props.chapter.bookmark.note;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const titleGreyedOut = computed(() => {
|
||||
return textHidden(CHAPTER_TITLE_TYPE) && props.editMode;
|
||||
});
|
||||
const titleHidden = computed(() => {
|
||||
// never hidden when editing the module
|
||||
if (props.chapter.titleHidden === true) {
|
||||
return true;
|
||||
}
|
||||
return textHidden(CHAPTER_TITLE_TYPE) && !props.editMode;
|
||||
});
|
||||
const descriptionGreyedOut = computed(() => {
|
||||
return textHidden(CHAPTER_DESCRIPTION_TYPE) && props.editMode;
|
||||
});
|
||||
const descriptionHidden = computed(() => {
|
||||
// never hidden when editing the module
|
||||
if (props.chapter.descriptionHidden === true) {
|
||||
return true;
|
||||
}
|
||||
return textHidden(CHAPTER_DESCRIPTION_TYPE) && !props.editMode;
|
||||
});
|
||||
|
||||
const { mutate: bookmark } = useMutation(UPDATE_CHAPTER_BOOKMARK_MUTATION, () => {
|
||||
const bookmarked = !props.chapter.bookmark;
|
||||
const id = props.chapter.id;
|
||||
return {
|
||||
variables: {
|
||||
input: {
|
||||
chapter: id,
|
||||
bookmarked,
|
||||
},
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
editMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
update: (store: any) => {
|
||||
const query = CHAPTER_QUERY;
|
||||
const variables = { id };
|
||||
const { chapter } = store.readQuery({
|
||||
query,
|
||||
variables,
|
||||
});
|
||||
|
||||
mixins: [me],
|
||||
let bookmark;
|
||||
|
||||
components: {
|
||||
BookmarkActions,
|
||||
VisibilityAction,
|
||||
ContentBlock,
|
||||
AddContentButton,
|
||||
CopyLink,
|
||||
},
|
||||
|
||||
computed: {
|
||||
filteredContentBlocks() {
|
||||
if (!(this.chapter && this.chapter.contentBlocks)) {
|
||||
return [];
|
||||
if (bookmarked) {
|
||||
bookmark = {
|
||||
__typename: 'ChapterBookmarkNode',
|
||||
note: null,
|
||||
};
|
||||
} else {
|
||||
bookmark = null;
|
||||
}
|
||||
if (this.editMode) {
|
||||
return this.chapter.contentBlocks;
|
||||
}
|
||||
return this.chapter.contentBlocks.filter(
|
||||
(contentBlock) =>
|
||||
!hidden({
|
||||
block: contentBlock,
|
||||
schoolClass: this.schoolClass,
|
||||
type: CONTENT_TYPE,
|
||||
})
|
||||
);
|
||||
},
|
||||
note() {
|
||||
if (this.chapter && this.chapter.bookmark) {
|
||||
return this.chapter.bookmark.note;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
titleGreyedOut() {
|
||||
return this.textHidden(CHAPTER_TITLE_TYPE) && this.editMode;
|
||||
},
|
||||
// never hidden when editing the module
|
||||
titleHidden() {
|
||||
if (this.chapter.titleHidden === true) {
|
||||
return true;
|
||||
}
|
||||
return this.textHidden(CHAPTER_TITLE_TYPE) && !this.editMode;
|
||||
},
|
||||
descriptionGreyedOut() {
|
||||
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && this.editMode;
|
||||
},
|
||||
// never hidden when editing the module
|
||||
descriptionHidden() {
|
||||
if (this.chapter.descriptionHidden === true) {
|
||||
return true;
|
||||
}
|
||||
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && !this.editMode;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
bookmark(bookmarked) {
|
||||
const id = this.chapter.id;
|
||||
this.$apollo.mutate({
|
||||
mutation: UPDATE_CHAPTER_BOOKMARK_MUTATION,
|
||||
variables: {
|
||||
input: {
|
||||
chapter: id,
|
||||
bookmarked,
|
||||
},
|
||||
const data = {
|
||||
chapter: {
|
||||
...chapter,
|
||||
bookmark,
|
||||
},
|
||||
update: (store) => {
|
||||
const query = CHAPTER_QUERY;
|
||||
const variables = { id };
|
||||
const { chapter } = store.readQuery({
|
||||
query,
|
||||
variables,
|
||||
});
|
||||
};
|
||||
|
||||
let bookmark;
|
||||
|
||||
if (bookmarked) {
|
||||
bookmark = {
|
||||
__typename: 'ChapterBookmarkNode',
|
||||
note: null,
|
||||
};
|
||||
} else {
|
||||
bookmark = null;
|
||||
}
|
||||
|
||||
const data = {
|
||||
chapter: {
|
||||
...chapter,
|
||||
bookmark,
|
||||
},
|
||||
};
|
||||
|
||||
store.writeQuery({
|
||||
data,
|
||||
query,
|
||||
variables,
|
||||
});
|
||||
},
|
||||
optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
updateChapterBookmark: {
|
||||
__typename: 'UpdateChapterBookmarkPayload',
|
||||
success: true,
|
||||
},
|
||||
},
|
||||
store.writeQuery({
|
||||
data,
|
||||
query,
|
||||
variables,
|
||||
});
|
||||
},
|
||||
addNote(id) {
|
||||
this.$store.dispatch('addNote', {
|
||||
content: id,
|
||||
parent: this.chapter.id,
|
||||
});
|
||||
|
||||
optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
updateChapterBookmark: {
|
||||
__typename: 'UpdateChapterBookmarkPayload',
|
||||
success: true,
|
||||
},
|
||||
},
|
||||
editNote() {
|
||||
this.$store.dispatch('editNote', this.chapter.bookmark.note);
|
||||
},
|
||||
textHidden(type) {
|
||||
return hidden({
|
||||
block: this.chapter,
|
||||
schoolClass: this.schoolClass,
|
||||
type,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const addNote = (id: string) => {
|
||||
store.dispatch('addNote', {
|
||||
content: id,
|
||||
parent: props.chapter.id,
|
||||
});
|
||||
};
|
||||
const editNote = () => {
|
||||
store.dispatch('editNote', props.chapter.bookmark.note);
|
||||
};
|
||||
const textHidden = (type: string) => {
|
||||
return hidden({
|
||||
block: props.chapter,
|
||||
schoolClass: schoolClass,
|
||||
type,
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<script></script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~styles/helpers';
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ import type { Modal } from '@/plugins/modal.types';
|
|||
export interface Props {
|
||||
contentBlock: ContentBlock;
|
||||
parent?: any;
|
||||
editMode: boolean;
|
||||
editMode?: boolean;
|
||||
}
|
||||
|
||||
const ContentComponent = defineAsyncComponent(
|
||||
|
|
|
|||
|
|
@ -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_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;
|
||||
switch (type) {
|
||||
case CONTENT_TYPE:
|
||||
|
|
@ -61,32 +61,43 @@ 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,
|
||||
block: { userCreated, visibleFor, hiddenFor, titleHiddenFor, descriptionHiddenFor, hidden },
|
||||
schoolClass,
|
||||
}) => {
|
||||
if (hidden === true) {
|
||||
return true;
|
||||
}
|
||||
switch (type) {
|
||||
case CONTENT_TYPE:
|
||||
case OBJECTIVE_TYPE:
|
||||
// is this content block / objective group user created?
|
||||
return userCreated
|
||||
? // if so, is visibility not explicitly set for this school class?
|
||||
if (hidden === true) {
|
||||
return true;
|
||||
}
|
||||
switch (type) {
|
||||
case CONTENT_TYPE:
|
||||
case OBJECTIVE_TYPE:
|
||||
// is this content block / objective group user created?
|
||||
return userCreated
|
||||
? // if so, is visibility not explicitly set for this school class?
|
||||
!containsClass(visibleFor, schoolClass)
|
||||
: // otherwise, is it explicitly hidden for this school class?
|
||||
: // otherwise, is it explicitly hidden for this school class?
|
||||
containsClass(hiddenFor, schoolClass);
|
||||
case OBJECTIVE_GROUP_TYPE:
|
||||
return containsClass(hiddenFor, schoolClass);
|
||||
case CHAPTER_TITLE_TYPE:
|
||||
return containsClass(titleHiddenFor, schoolClass);
|
||||
case CHAPTER_DESCRIPTION_TYPE:
|
||||
return containsClass(descriptionHiddenFor, schoolClass);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
case OBJECTIVE_GROUP_TYPE:
|
||||
return containsClass(hiddenFor, schoolClass);
|
||||
case CHAPTER_TITLE_TYPE:
|
||||
return containsClass(titleHiddenFor, schoolClass);
|
||||
case CHAPTER_DESCRIPTION_TYPE:
|
||||
return containsClass(descriptionHiddenFor, schoolClass);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Loading…
Reference in New Issue