diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue index f956e47ed0fde043ba0587bbf2212af54edc3b0b..572e171fc28eddfe3f5e72c79a4a7f2d4f452c92 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue @@ -1,11 +1,11 @@ <template> - <studip-dialog + <studip-dialog :title="$gettext('Darstellung')" :confirmText="$gettext('Speichern')" confirmClass="accept" :closeText="$gettext('Schließen')" closeClass="cancel" - height="470" + height="540" width="870" @close="$emit('close')" @confirm="storeLayout" @@ -23,12 +23,8 @@ <label v-if="showPreviewImage"> <button class="button" @click="deleteImage">{{ $gettext('Bild löschen') }}</button> </label> - <courseware-companion-box - v-if="uploadFileError" - :msgCompanion="uploadFileError" - mood="sad" - /> - <label v-if="!showPreviewImage"> + <courseware-companion-box v-if="uploadFileError" :msgCompanion="uploadFileError" mood="sad" /> + <template v-if="!showPreviewImage"> <img v-if="currentFile" :src="uploadImageURL" @@ -36,14 +32,32 @@ :alt="$gettext('Vorschaubild')" /> <div v-else class="cw-structural-element-image-preview-placeholder"></div> - {{ $gettext('Bild hochladen') }} - <input class="cw-file-input" ref="upload_image" type="file" accept="image/*" @change="checkUploadFile" /> - </label> + <label> + {{ $gettext('Bild hochladen') }} + <input + class="cw-file-input" + ref="upload_image" + type="file" + accept="image/*" + @change="checkUploadFile" + /> + </label> + {{ $gettext('oder') }} + <br /> + <button class="button" type="button" @click="showStockImageSelector = true"> + {{ $gettext('Aus dem Bilderpool auswählen') }} + </button> + <StockImageSelector + v-if="showStockImageSelector" + @close="showStockImageSelector = false" + @select="onSelectStockImage" + /> + </template> </form> <form class="default cw-unit-item-dialog-layout-content-settings" @submit.prevent=""> <label> {{ $gettext('Titel') }} - <input type="text" v-model="currentElement.attributes.title"/> + <input type="text" v-model="currentElement.attributes.title" /> </label> <label> {{ $gettext('Beschreibung') }} @@ -62,13 +76,9 @@ class="cw-vs-select" > <template #open-indicator="selectAttributes"> - <span v-bind="selectAttributes" - ><studip-icon shape="arr_1down" :size="10" - /></span> - </template> - <template #no-options> - {{ $gettext('Es steht keine Auswahl zur Verfügung') }}. + <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10" /></span> </template> + <template #no-options> {{ $gettext('Es steht keine Auswahl zur Verfügung') }}. </template> <template #selected-option="{ name, hex }"> <span class="vs__option-color" :style="{ 'background-color': hex }"></span ><span>{{ name }}</span> @@ -96,19 +106,19 @@ <script> import CoursewareCompanionBox from '../layouts/CoursewareCompanionBox.vue'; - +import StockImageSelector from '../../stock-images/SelectorDialog.vue'; import colorMixin from '@/vue/mixins/courseware/colors.js'; import { mapActions, mapGetters } from 'vuex'; - export default { name: 'courseware-unit-item-dialog-layout', components: { - CoursewareCompanionBox + CoursewareCompanionBox, + StockImageSelector, }, props: { unit: Object, - unitElement: Object + unitElement: Object, }, mixins: [colorMixin], data() { @@ -120,18 +130,26 @@ export default { uploadImageURL: null, currentRootLayout: 'default', loadingInstance: false, - } + showStockImageSelector: false, + selectedStockImage: null, + }; }, computed: { ...mapGetters({ context: 'context', instanceById: 'courseware-instances/byId', - userId: 'userId' + userId: 'userId', }), colors() { - return this.mixinColors.filter(color => color.darkmode); + return this.mixinColors.filter((color) => color.darkmode); }, image() { + if (this.selectedStockImage) { + return this.selectedStockImage.attributes['download-urls'].small + } + if (this.uploadImageURL) { + return this.uploadImageURL; + } return this.currentElement.relationships?.image?.meta?.['download-url'] ?? null; }, @@ -140,15 +158,14 @@ export default { }, instance() { if (this.inCourseContext) { - return this.instanceById({id: 'course_' + this.context.id + '_' + this.unit.id}); + return this.instanceById({ id: 'course_' + this.context.id + '_' + this.unit.id }); } else { - return this.instanceById({id: 'user_' + this.context.id + '_' + this.unit.id}); + return this.instanceById({ id: 'user_' + this.context.id + '_' + this.unit.id }); } - }, inCourseContext() { return this.context.type === 'courses'; - } + }, }, methods: { ...mapActions({ @@ -162,9 +179,10 @@ export default { uploadImageForStructuralElement: 'uploadImageForStructuralElement', deleteImageForStructuralElement: 'deleteImageForStructuralElement', storeCoursewareSettings: 'storeCoursewareSettings', + setStockImageForStructuralElement: 'setStockImageForStructuralElement', }), async loadUnitInstance() { - const context = {type: this.context.type, id: this.context.id, unit: this.unit.id}; + const context = { type: this.context.type, id: this.context.id, unit: this.unit.id }; await this.loadInstance(context); }, initData() { @@ -192,11 +210,13 @@ export default { this.$emit('close'); await this.loadStructuralElement(this.currentElement.id); if ( - this.unitElement.relationships['edit-blocker'].data !== null - && this.unitElement.relationships['edit-blocker'].data?.id !== this.userId + this.unitElement.relationships['edit-blocker'].data !== null && + this.unitElement.relationships['edit-blocker'].data?.id !== this.userId ) { this.companionWarning({ - info: this.$gettext('Ihre Änderungen konnten nicht gespeichert werden, die Daten werden bereits von einem anderen Nutzer bearbeitet.') + info: this.$gettext( + 'Ihre Änderungen konnten nicht gespeichert werden, die Daten werden bereits von einem anderen Nutzer bearbeitet.' + ), }); return false; } else { @@ -207,13 +227,20 @@ export default { this.uploadImageForStructuralElement({ structuralElement: this.currentElement, file: this.currentFile, - }).then(() => { - this.loadStructuralElement(this.currentElement.id) - }).catch((error) => { - console.error(error); - this.companionWarning({ - info: this.$gettext('Beim Hochladen der Bilddatei ist ein Fehler aufgetretten.') + }) + .then(() => { + this.loadStructuralElement(this.currentElement.id); + }) + .catch((error) => { + console.error(error); + this.companionWarning({ + info: this.$gettext('Beim Hochladen der Bilddatei ist ein Fehler aufgetretten.'), + }); }); + } else if (this.selectedStockImage) { + await this.setStockImageForStructuralElement({ + structuralElement: this.currentElement, + stockImage: this.selectedStockImage, }); } else if (this.deletingPreviewImage) { await this.deleteImageForStructuralElement(this.currentElement); @@ -233,13 +260,21 @@ export default { instance: currentInstance, }); } - } + }, + onSelectStockImage(stockImage) { + if (this.$refs?.upload_image) { + this.$refs.upload_image.value = null; + } + this.selectedStockImage = stockImage; + this.showStockImageSelector = false; + this.deletingPreviewImage = false; + }, }, async mounted() { this.loadingInstance = true; await this.loadUnitInstance(); this.loadingInstance = false; this.initData(); - } -} + }, +}; </script>