Move edit mode to local GraphQL property of module node

This commit is contained in:
Ramon Wenger 2022-01-31 18:24:03 +01:00
parent e1d3897e5e
commit 51fddbdf60
11 changed files with 168 additions and 49 deletions

View File

@ -19,12 +19,13 @@
<visibility-action <visibility-action
:block="chapter" :block="chapter"
type="chapter-title" type="chapter-title"
v-if="editModule" v-if="editMode"
/> />
<bookmark-actions <bookmark-actions
:bookmarked="chapter.bookmark" :bookmarked="!!chapter.bookmark"
:note="note" :note="note"
:edit-mode="editMode"
class="chapter__bookmark-actions" class="chapter__bookmark-actions"
data-cy="chapter-bookmark-actions" data-cy="chapter-bookmark-actions"
@add-note="addNote" @add-note="addNote"
@ -40,7 +41,7 @@
:block="chapter" :block="chapter"
:chapter="true" :chapter="true"
type="chapter-description" type="chapter-description"
v-if="editModule" v-if="editMode"
/> />
<p <p
class="chapter__description" class="chapter__description"
@ -51,12 +52,13 @@
<add-content-button <add-content-button
:parent="chapter" :parent="chapter"
v-if="editModule" v-if="editMode"
/> />
<content-block <content-block
:content-block="contentBlock" :content-block="contentBlock"
:parent="chapter.id" :parent="chapter.id"
:edit-mode="editMode"
v-for="contentBlock in filteredContentBlocks" v-for="contentBlock in filteredContentBlocks"
:key="contentBlock.id" :key="contentBlock.id"
/> />
@ -69,7 +71,6 @@
import BookmarkActions from '@/components/notes/BookmarkActions'; import BookmarkActions from '@/components/notes/BookmarkActions';
import VisibilityAction from '@/components/visibility/VisibilityAction'; import VisibilityAction from '@/components/visibility/VisibilityAction';
import {mapState} from 'vuex';
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';
@ -79,7 +80,20 @@
import me from '@/mixins/me'; import me from '@/mixins/me';
export default { export default {
props: ['chapter', 'index'], props: {
chapter: {
type: Object,
default: () => ({})
},
index: {
type: Number,
default: 0
},
editMode: {
type: Boolean,
default: false
}
},
mixins: [me], mixins: [me],
@ -91,12 +105,11 @@
}, },
computed: { computed: {
...mapState(['editModule']),
filteredContentBlocks() { filteredContentBlocks() {
if (!(this.chapter && this.chapter.contentBlocks)) { if (!(this.chapter && this.chapter.contentBlocks)) {
return []; return [];
} }
if (this.editModule) { if (this.editMode) {
return this.chapter.contentBlocks; return this.chapter.contentBlocks;
} }
return this.chapter.contentBlocks.filter(contentBlock => !hidden({ return this.chapter.contentBlocks.filter(contentBlock => !hidden({
@ -112,24 +125,24 @@
return false; return false;
}, },
titleGreyedOut() { titleGreyedOut() {
return this.textHidden(CHAPTER_TITLE_TYPE) && this.editModule; return this.textHidden(CHAPTER_TITLE_TYPE) && this.editMode;
}, },
// never hidden when editing the module // never hidden when editing the module
titleHidden() { titleHidden() {
if (this.chapter.titleHidden === true) { if (this.chapter.titleHidden === true) {
return true; return true;
} }
return this.textHidden(CHAPTER_TITLE_TYPE) && !this.editModule; return this.textHidden(CHAPTER_TITLE_TYPE) && !this.editMode;
}, },
descriptionGreyedOut() { descriptionGreyedOut() {
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && this.editModule; return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && this.editMode;
}, },
// never hidden when editing the module // never hidden when editing the module
descriptionHidden() { descriptionHidden() {
if (this.chapter.descriptionHidden === true) { if (this.chapter.descriptionHidden === true) {
return true; return true;
} }
return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && !this.editModule; return this.textHidden(CHAPTER_DESCRIPTION_TYPE) && !this.editMode;
}, },
}, },

View File

@ -9,7 +9,7 @@
> >
<div <div
class="block-actions" class="block-actions"
v-if="canEditContentBlock && editModule" v-if="canEditContentBlock && editMode"
> >
<user-widget <user-widget
v-bind="me" v-bind="me"
@ -58,6 +58,7 @@
:parent="contentBlock" :parent="contentBlock"
:bookmarks="contentBlock.bookmarks" :bookmarks="contentBlock.bookmarks"
:notes="contentBlock.notes" :notes="contentBlock.notes"
:edit-mode="editMode"
v-for="component in contentBlocksWithContentLists.contents" v-for="component in contentBlocksWithContentLists.contents"
:key="component.id" :key="component.id"
/> />
@ -79,8 +80,6 @@
import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql'; import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql';
import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql'; import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';
import {mapState} from 'vuex';
import me from '@/mixins/me'; import me from '@/mixins/me';
import {hidden} from '@/helpers/visibility'; import {hidden} from '@/helpers/visibility';
import {CONTENT_TYPE} from '@/consts/types'; import {CONTENT_TYPE} from '@/consts/types';
@ -96,7 +95,20 @@
export default { export default {
name: 'ContentBlock', name: 'ContentBlock',
props: ['contentBlock', 'parent'], props: {
contentBlock: {
type: Object,
default: () => ({})
},
parent: {
type: String,
default: ''
},
editMode: {
type: Boolean,
default: true
}
},
mixins: [me], mixins: [me],
@ -110,9 +122,8 @@
}, },
computed: { computed: {
...mapState(['editModule']),
canEditModule() { canEditModule() {
return !this.contentBlock.indent && this.editModule; return !this.contentBlock.indent && this.editMode;
}, },
specialClass() { specialClass() {
return `content-block--${this.contentBlock.type.toLowerCase()}`; return `content-block--${this.contentBlock.type.toLowerCase()}`;

View File

@ -7,6 +7,7 @@
<bookmark-actions <bookmark-actions
:bookmarked="bookmarked" :bookmarked="bookmarked"
:note="note" :note="note"
:edit-mode="editMode"
v-if="showBookmarkActions" v-if="showBookmarkActions"
@add-note="addNote(component.id)" @add-note="addNote(component.id)"
@edit-note="editNote" @edit-note="editNote"
@ -21,8 +22,6 @@
</template> </template>
<script> <script>
import {mapState} from 'vuex';
import {constructContentComponentBookmarkMutation} from '@/helpers/update-content-bookmark-mutation'; import {constructContentComponentBookmarkMutation} from '@/helpers/update-content-bookmark-mutation';
const TextBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/TextBlock'); const TextBlock = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/TextBlock');
@ -46,7 +45,32 @@ const Instruction = () => import(/* webpackChunkName: "content-components" */'@/
const BookmarkActions = () => import(/* webpackChunkName: "content-components" */'@/components/notes/BookmarkActions'); const BookmarkActions = () => import(/* webpackChunkName: "content-components" */'@/components/notes/BookmarkActions');
export default { export default {
props: ['component', 'parent', 'bookmarks', 'notes', 'root'], props: {
component: {
type: Object,
default: () => ({})
},
parent: {
type: Object,
default: () => ({})
},
bookmarks: {
type: Array,
default: () => ([])
},
notes: {
type: Array,
default: () => ([])
},
root: {
type: String,
default: ''
},
editMode: {
type: Boolean,
default: false
}
},
components: { components: {
'text_block': TextBlock, 'text_block': TextBlock,
@ -72,7 +96,6 @@ export default {
}, },
computed: { computed: {
...mapState(['editModule']),
bookmarked() { bookmarked() {
return this.bookmarks && !!this.bookmarks.find(bookmark => bookmark.uuid === this.component.id); return this.bookmarks && !!this.bookmarks.find(bookmark => bookmark.uuid === this.component.id);
}, },
@ -81,7 +104,7 @@ export default {
return bookmark && bookmark.note; return bookmark && bookmark.note;
}, },
showBookmarkActions() { showBookmarkActions() {
return this.component.type !== 'content_list' && this.component.type !== 'basic_knowledge' && !this.editModule; return this.component.type !== 'content_list' && this.component.type !== 'basic_knowledge' && !this.editMode;
}, },
componentClass() { componentClass() {
let classes = ['content-component', `content-component--${this.component.type}`]; let classes = ['content-component', `content-component--${this.component.type}`];

View File

@ -24,8 +24,9 @@
<div class="module__intro-wrapper"> <div class="module__intro-wrapper">
<bookmark-actions <bookmark-actions
:bookmarked="module.bookmark" :bookmarked="!!module.bookmark"
:note="note" :note="note"
:edit-mode="module.inEditMode"
class="module__bookmark-actions" class="module__bookmark-actions"
data-cy="module-bookmark-actions" data-cy="module-bookmark-actions"
@add-note="$emit('addNote')" @add-note="$emit('addNote')"
@ -53,6 +54,7 @@
<chapter <chapter
:chapter="chapter" :chapter="chapter"
:index="index" :index="index"
:edit-mode="module.inEditMode"
v-for="(chapter, index) in module.chapters" v-for="(chapter, index) in module.chapters"
:key="chapter.id" :key="chapter.id"
/> />

View File

@ -1,7 +1,7 @@
<template> <template>
<div <div
class="bookmark-actions" class="bookmark-actions"
v-if="!editModule" v-if="!editMode"
> >
<a <a
:class="{'bookmark-actions__action--bookmarked': bookmarked}" :class="{'bookmark-actions__action--bookmarked': bookmarked}"
@ -32,22 +32,30 @@
</template> </template>
<script> <script>
import {mapState} from 'vuex';
const BookmarkIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/BookmarkIcon'); const BookmarkIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/BookmarkIcon');
const AddNoteIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/AddNoteIcon'); const AddNoteIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/AddNoteIcon');
const NoteIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/NoteIcon'); const NoteIcon = () => import(/* webpackChunkName: "icons" */'@/components/icons/NoteIcon');
export default { export default {
props: ['bookmarked', 'note'], props: {
bookmarked: {
type: Boolean,
default: false
},
note: {
type: [Object, Boolean],
default: false
},
editMode: {
type: Boolean,
default: false
}
},
components: { components: {
BookmarkIcon, BookmarkIcon,
AddNoteIcon, AddNoteIcon,
NoteIcon NoteIcon
}, },
computed: {
...mapState(['editModule'])
}
}; };
</script> </script>

View File

@ -2,16 +2,16 @@
<li <li
:class="{'hideable-element--greyed-out': hidden}" :class="{'hideable-element--greyed-out': hidden}"
class="objective hideable-element" class="objective hideable-element"
v-if="editModule || !hidden" v-if="editMode || !hidden"
> >
<visibility-action <visibility-action
:block="objective" :block="objective"
:type="type" :type="type"
v-if="editModule" v-if="editMode"
/> />
<div <div
class="block-actions" class="block-actions"
v-if="editModule && canEdit" v-if="editMode && canEdit"
> >
<user-widget <user-widget
v-bind="me" v-bind="me"
@ -39,7 +39,6 @@
import {hidden} from '@/helpers/visibility'; import {hidden} from '@/helpers/visibility';
import {OBJECTIVE_TYPE} from '@/consts/types'; import {OBJECTIVE_TYPE} from '@/consts/types';
import editModule from '@/mixins/edit-module';
import me from '@/mixins/me'; import me from '@/mixins/me';
export default { export default {
@ -47,10 +46,14 @@
objective: { objective: {
type: Object, type: Object,
default: null default: null
},
editMode: {
type: Boolean,
default: false
} }
}, },
mixins: [me, editModule], mixins: [me],
components: { components: {
MoreOptionsWidget, MoreOptionsWidget,

View File

@ -2,12 +2,12 @@
<div <div
:class="{'hideable-element--greyed-out': hidden}" :class="{'hideable-element--greyed-out': hidden}"
class="objective-group hideable-element" class="objective-group hideable-element"
v-if="editModule || !hidden" v-if="editMode || !hidden"
> >
<visibility-action <visibility-action
:block="group" :block="group"
:type="type" :type="type"
v-if="editModule" v-if="editMode"
/> />
<h4>{{ group.displayTitle }}</h4> <h4>{{ group.displayTitle }}</h4>
@ -16,13 +16,14 @@
<objective <objective
:objective="objective" :objective="objective"
class="objective-group__objective" class="objective-group__objective"
:edit-mode="group.module.inEditMode"
v-for="objective in group.objectives" v-for="objective in group.objectives"
:key="objective.id" :key="objective.id"
/> />
</ul> </ul>
<add-content-button <add-content-button
:parent="group" :parent="group"
v-if="editModule" v-if="editMode"
/> />
</div> </div>
</template> </template>
@ -33,7 +34,6 @@
import AddContentButton from '@/components/AddContentButton'; import AddContentButton from '@/components/AddContentButton';
import me from '@/mixins/me'; import me from '@/mixins/me';
import editModule from '@/mixins/edit-module';
import {OBJECTIVE_GROUP_TYPE} from '@/consts/types'; import {OBJECTIVE_GROUP_TYPE} from '@/consts/types';
import {hidden} from '@/helpers/visibility'; import {hidden} from '@/helpers/visibility';
@ -46,7 +46,7 @@
} }
}, },
mixins: [me, editModule], mixins: [me],
components: { components: {
AddContentButton, AddContentButton,
@ -61,6 +61,9 @@
}, },
computed: { computed: {
editMode() {
return this.group.module.inEditMode;
},
hidden() { hidden() {
return hidden({ return hidden({
block: this.group, block: this.group,

View File

@ -1,6 +1,6 @@
<template> <template>
<toggle <toggle
:checked="checked" :checked="module.inEditMode"
data-cy="toggle-editing" data-cy="toggle-editing"
label="Modul anpassen" label="Modul anpassen"
@input="toggle" @input="toggle"
@ -8,24 +8,68 @@
</template> </template>
<script> <script>
import {mapState, mapActions} from 'vuex';
import Toggle from '@/components/ui/Toggle'; import Toggle from '@/components/ui/Toggle';
// import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery.gql';
import {gql} from '@apollo/client/core';
const QUERY = gql`
query ModuleEditModeQuery ($slug: String) {
module(slug: $slug) {
inEditMode @client
slug
}
}
`;
export default { export default {
components: { components: {
Toggle Toggle
}, },
data: () => ({
module: {
inEditMode: false
}
}),
computed: { computed: {
...mapState({ checked() {
checked: 'editModule', return false;
}), },
slug() {
return this.$route.params.slug;
}
},
apollo: {
module() {
return {
query: QUERY,
variables: {
slug: this.slug
}
};
}
}, },
methods: { methods: {
...mapActions({ toggle(newChecked){
toggle: 'editModule', const cache = this.$apollo.provider.defaultClient.cache;
}), const id = cache.identify({
__typename: 'ModuleNode',
slug: this.slug
});
cache.modify({
id,
fields: {
inEditMode() {
return newChecked;
},
}
});
}
}, },
}; };
</script> </script>

View File

@ -23,6 +23,13 @@ const typePolicies = {
keyFields: ['slug'] keyFields: ['slug']
}, },
ModuleNode: { ModuleNode: {
fields: {
inEditMode: {
read(previous) {
return previous !== undefined ? previous : false;
}
}
},
keyFields: ['slug'] keyFields: ['slug']
}, },
RoomEntryNode: { RoomEntryNode: {

View File

@ -7,6 +7,7 @@ fragment ModuleParts on ModuleNode {
slug slug
heroImage heroImage
solutionsEnabled solutionsEnabled
inEditMode @client
topic { topic {
slug slug
title title

View File

@ -2,6 +2,10 @@ fragment ObjectiveGroupParts on ObjectiveGroupNode {
id id
title title
displayTitle displayTitle
module {
slug
inEditMode @client
}
hiddenFor { hiddenFor {
id id
name name