diff --git a/resources/vue/components/courseware/CoursewareAccordionContainer.vue b/resources/vue/components/courseware/CoursewareAccordionContainer.vue index 448555975b74adf22adde1e9d91da53386de998b..de50ae1db8b021b9e05d62da495a4aca6e08a66e 100644 --- a/resources/vue/components/courseware/CoursewareAccordionContainer.vue +++ b/resources/vue/components/courseware/CoursewareAccordionContainer.vue @@ -55,7 +55,7 @@ </template> <template v-slot:containerEditDialog> <form class="default cw-container-dialog-edit-form" @submit.prevent=""> - <fieldset v-for="(section, index) in currentContainer.attributes.payload.sections" :key="index"> + <fieldset v-for="(section, index) in currentContainer.attributes.payload.sections.filter(section => !section.locked)" :key="index"> <label> <translate>Title</translate> <input type="text" v-model="section.name" /> @@ -116,6 +116,7 @@ export default { return { currentContainer: {}, currentSections: [], + unallocatedBlocks: [], sortMode: false, isDragging: false, dragOptions: { @@ -158,10 +159,25 @@ export default { let view = this; let sections = this.currentContainer.attributes.payload.sections; + + const unallocated = new Set(this.blocks.map(({ id }) => id)); + sections.forEach(section => { - section.blocks = section.blocks.map((id) => view.blockById({id})).filter((a) => a); + section.locked = false; + section.blocks = section.blocks.map((id) => view.blockById({id})).filter(Boolean); + section.blocks.forEach(({ id }) => unallocated.delete(id)); }); + if (unallocated.size > 0) { + this.unallocatedBlocks = [...unallocated].map((id) => view.blockById({ id })); + sections.push({ + blocks: this.unallocatedBlocks, + name: this.$gettext('nicht zugewiesene Inhalte'), + icon: 'decline', + locked: true + }); + } + this.currentSections = sections; }, addSection() { @@ -189,8 +205,10 @@ export default { this.currentContainer.attributes.payload.sections.splice(index, 1); }, async storeContainer() { + this.currentContainer.attributes.payload.sections = this.currentContainer.attributes.payload.sections.filter(section => !section.locked); this.currentContainer.attributes.payload.sections.forEach(section => { section.blocks = section.blocks.map((block) => {return block.id;}); + delete section.locked; }); await this.updateContainer({ container: this.currentContainer, diff --git a/resources/vue/components/courseware/CoursewareBlockEdit.vue b/resources/vue/components/courseware/CoursewareBlockEdit.vue index 68934cbde516916a77e2c522d782b6f232c6e17f..55b8b3a1b9b06a4557b5ff4d16681f973b556e1e 100644 --- a/resources/vue/components/courseware/CoursewareBlockEdit.vue +++ b/resources/vue/components/courseware/CoursewareBlockEdit.vue @@ -1,8 +1,10 @@ <template> - <section class="cw-block-edit" @click="deactivateToolbar"> + <section class="cw-block-edit"> <header><translate>Bearbeiten</translate></header> <div class="cw-block-features-content"> - <slot name="edit" /> + <div @click="deactivateToolbar(); exitHandler = true;"> + <slot name="edit" /> + </div> <div class="cw-button-box"> <button class="button accept" @click="$emit('store'); exitHandler = false;"><translate>Speichern</translate></button> <button class="button cancel" @click="$emit('close'); exitHandler = false;"><translate>Abbrechen</translate></button> @@ -20,7 +22,7 @@ export default { data() { return { originalBlock: Object, - exitHandler: true + exitHandler: false }; }, beforeMount() { diff --git a/resources/vue/components/courseware/CoursewareListContainer.vue b/resources/vue/components/courseware/CoursewareListContainer.vue index 00c442e6fd36d4a3015fb84ae1601646096bb732..91947de5fb43642b747671bf4656ebbd14b193ec 100644 --- a/resources/vue/components/courseware/CoursewareListContainer.vue +++ b/resources/vue/components/courseware/CoursewareListContainer.vue @@ -29,7 +29,7 @@ <component :is="component(block)" :block="block" :canEdit="canEdit" :isTeacher="isTeacher" /> </li> </transition-group> - + </draggable> <div v-if="sortMode && canEdit"> <button class="button accept" @click="storeSort"><translate>Sortierung speichern</translate></button> @@ -80,7 +80,7 @@ export default { return []; } - return this.container.attributes.payload.sections[0].blocks.map((id) => this.blockById({ id })).filter((a) => a); + return this.container.relationships.blocks.data.map(({ id }) => this.blockById({ id })).filter(Boolean); }, showEditMode() { return this.$store.getters.viewMode === 'edit'; diff --git a/resources/vue/components/courseware/CoursewareTabsContainer.vue b/resources/vue/components/courseware/CoursewareTabsContainer.vue index 7e49f60ede41648ea9120c6e207e63938fcdf240..66349d95d184843e93449cc459cf40fe3c44a08f 100644 --- a/resources/vue/components/courseware/CoursewareTabsContainer.vue +++ b/resources/vue/components/courseware/CoursewareTabsContainer.vue @@ -66,7 +66,7 @@ </template> <template v-slot:containerEditDialog> <form class="default cw-container-dialog-edit-form" @submit.prevent=""> - <fieldset v-for="(section, index) in currentContainer.attributes.payload.sections" :key="index"> + <fieldset v-for="(section, index) in currentContainer.attributes.payload.sectionsfilter(section => !section.locked)" :key="index"> <label> <translate>Title</translate> <input type="text" v-model="section.name" /> @@ -131,6 +131,7 @@ export default { return { currentContainer: null, currentSections: [], + unallocatedBlocks: [], textDeleteSection: this.$gettext('Sektion entfernen'), selectAttributes: {'ref': 'openIndicator', 'role': 'presentation', 'class': 'vs__open-indicator'}, sortMode: false, @@ -175,10 +176,25 @@ export default { let view = this; let sections = this.currentContainer.attributes.payload.sections; + + const unallocated = new Set(this.blocks.map(({ id }) => id)); + sections.forEach(section => { + section.locked = false; section.blocks = section.blocks.map((id) => view.blockById({id})).filter((a) => a); + section.blocks.forEach(({ id }) => unallocated.delete(id)); }); + if (unallocated.size > 0) { + this.unallocatedBlocks = [...unallocated].map((id) => view.blockById({ id })); + sections.push({ + blocks: this.unallocatedBlocks, + name: this.$gettext('nicht zugewiesene Inhalte'), + icon: 'decline', + locked: true + }); + } + this.currentSections = sections; }, addSection() { @@ -206,8 +222,10 @@ export default { this.currentContainer.attributes.payload.sections.splice(index, 1); }, async storeContainer() { + this.currentContainer.attributes.payload.sections = this.currentContainer.attributes.payload.sections.filter(section => !section.locked); this.currentContainer.attributes.payload.sections.forEach(section => { section.blocks = section.blocks.map((block) => {return block.id;}); + delete section.locked; }); await this.updateContainer({