Select Git revision
UserDataFieldsUpdate.php
Forked from
Stud.IP / Stud.IP
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CoursewareStructuralElement.vue 40.67 KiB
<template>
<div>
<div :class="{ 'cw-structural-element-consumemode': consumeMode }" class="cw-structural-element" v-if="validContext">
<div class="cw-structural-element-content" v-if="structuralElement">
<courseware-ribbon :canEdit="canEdit">
<template #buttons>
<router-link v-if="prevElement" :to="'/structural_element/' + prevElement.id">
<button class="cw-ribbon-button cw-ribbon-button-prev" :title="textRibbon.perv" />
</router-link>
<button v-else class="cw-ribbon-button cw-ribbon-button-prev-disabled" />
<router-link v-if="nextElement" :to="'/structural_element/' + nextElement.id">
<button class="cw-ribbon-button cw-ribbon-button-next" :title="textRibbon.next" />
</router-link>
<button v-else class="cw-ribbon-button cw-ribbon-button-next-disabled" />
</template>
<template #breadcrumbList>
<li
v-for="ancestor in ancestors"
:key="ancestor.id"
:title="ancestor.attributes.title"
class="cw-ribbon-breadcrumb-item"
>
<span>
<router-link :to="'/structural_element/' + ancestor.id">
{{ ancestor.attributes.title }}
</router-link>
</span>
</li><li class="cw-ribbon-breadcrumb-item cw-ribbon-breadcrumb-item-current" :title="structuralElement.attributes.title">
<span>{{ structuralElement.attributes.title }}</span>
</li>
</template>
<template #breadcrumbFallback>
<li class="cw-ribbon-breadcrumb-item cw-ribbon-breadcrumb-item-current" :title="structuralElement.attributes.title">
<span>{{ structuralElement.attributes.title }}</span>
</li>
</template>
<template #menu>
<studip-action-menu
v-if="!consumeMode"
:items="menuItems"
class="cw-ribbon-action-menu"
@editCurrentElement="menuAction('editCurrentElement')"
@addElement="menuAction('addElement')"
@deleteCurrentElement="menuAction('deleteCurrentElement')"
@showInfo="menuAction('showInfo')"
@showExportOptions="menuAction('showExportOptions')"
@oerCurrentElement="menuAction('oerCurrentElement')"
@setBookmark="menuAction('setBookmark')"
/>
</template>
</courseware-ribbon>
<div v-if="canRead" class="cw-container-wrapper" :class="{ 'cw-container-wrapper-consume': consumeMode }">
<div v-if="structuralElementLoaded" class="cw-companion-box-wrapper">
<courseware-empty-element-box
v-if="(empty && !isRoot && canEdit) || (empty && !canEdit) || (!noContainers && empty && isRoot && canEdit)"
:canEdit="canEdit"
:noContainers="noContainers"
/>
<courseware-wellcome-screen v-if="noContainers && isRoot && canEdit"/>
</div>
<component
v-for="container in containers"
:key="container.id"
:is="containerComponent(container)"
:container="container"
:canEdit="canEdit"
:isTeacher="isTeacher"
class="cw-container-item"
/>
</div>
<div v-else class="cw-container-wrapper" :class="{ 'cw-container-wrapper-consume': consumeMode }">
<div v-if="structuralElementLoaded" class="cw-companion-box-wrapper">
<courseware-companion-box mood="sad" :msgCompanion="$gettext('Diese Seite steht Ihnen leider nicht zur Verfügung')" />
</div>
</div>
</div>
<courseware-companion-overlay />
<studip-dialog
v-if="showEditDialog"
:title="textEdit.title"
:confirmText="textEdit.confirm"
:confirmClass="'accept'"
:closeText="textEdit.close"
:closeClass="'cancel'"
height="500"
width="500"
class="studip-dialog-with-tab"
@close="closeEditDialog"
@confirm="storeCurrentElement"
>
<template v-slot:dialogContent>
<courseware-tabs class="cw-tab-in-dialog">
<courseware-tab :name="textEdit.basic" :selected="true">
<form class="default" @submit.prevent="">
<label>
<translate>Titel</translate>
<input type="text" v-model="currentElement.attributes.title" />
</label>
<label>
<translate>Beschreibung</translate>
<textarea
v-model="currentElement.attributes.payload.description"
class="cw-structural-element-description"
/>
</label>
</form>
</courseware-tab>
<courseware-tab :name="textEdit.meta">
<form class="default" @submit.prevent="">
<label>
<translate>Farbe</translate>
<v-select
v-model="currentElement.attributes.payload.color"
:options="colors"
:reduce="color => color.class"
label="class"
class="cw-vs-select"
>
<template #open-indicator="selectAttributes">
<span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10"/></span>
</template>
<template #no-options="{ search, searching, loading }">
<translate>Es steht keine Auswahl zur Verfügung</translate>.
</template>
<template #selected-option="{name, hex}">
<span class="vs__option-color" :style="{'background-color': hex}"></span><span>{{name}}</span>
</template>
<template #option="{name, hex}">
<span class="vs__option-color" :style="{'background-color': hex}"></span><span>{{name}}</span>
</template>
</v-select>
</label>
<label>
<translate>Zweck</translate>
<select v-model="currentElement.attributes.purpose">
<option value="content"><translate>Inhalt</translate></option>
<option value="template"><translate>Vorlage</translate></option>
<option value="oer"><translate>OER-Material</translate></option>
<option value="portfolio"><translate>ePortfolio</translate></option>
<option value="draft"><translate>Entwurf</translate></option>
<option value="other"><translate>Sonstiges</translate></option>
</select>
</label>
<label>
<translate>Lizenztyp</translate>
<select v-model="currentElement.attributes.payload.license_type">
<option v-for="license in licenses" :key="license.id" :value="license.id">{{license.name}}</option>
</select>
</label>
<label>
<translate>Geschätzter zeitlicher Aufwand</translate>
<input type="text" v-model="currentElement.attributes.payload.required_time" />
</label>
<label>
<translate>Niveau</translate><br>
<translate>von</translate>
<select v-model="currentElement.attributes.payload.difficulty_start">
<option v-for="difficulty_start in 12" :key="difficulty_start" :value="difficulty_start">{{difficulty_start}}</option>
</select>
<translate>bis</translate>
<select v-model="currentElement.attributes.payload.difficulty_end">
<option v-for="difficulty_end in 12" :key="difficulty_end" :value="difficulty_end">{{difficulty_end}}</option>
</select>
</label>
</form>
</courseware-tab>
<courseware-tab :name="textEdit.image">
<form class="default" @submit.prevent="">
<img
v-if="image"
:src="image"
class="cw-structural-element-image-preview"
:alt="$gettext('Vorschaubild')"
/>
<label v-if="image">
<button class="button" @click="deleteImage" v-translate>Bild löschen</button>
</label>
<div v-if="uploadFileError" class="messagebox messagebox_error">
{{ uploadFileError }}
</div>
<label v-if="!image">
<translate>Bild hochladen</translate>
<input ref="upload_image" type="file" accept="image/*" @change="checkUploadFile" />
</label>
</form>
</courseware-tab>
<courseware-tab :name="textEdit.approval">
<courseware-structural-element-permissions
v-if="inCourse"
:element="currentElement"
@updateReadApproval="updateReadApproval"
@updateWriteApproval="updateWriteApproval"
/>
<!-- <h1>
<translate>Lehrende in Stud.IP</translate>
</h1>
<label>
<input
type="checkbox"
class="default"
value="copy_approval"
v-model="currentElement.attributes['copy-approval']"
/>
<translate>Seite zum kopieren für Lehrende freigeben</translate>
</label> -->
</courseware-tab>
<courseware-tab v-if="inCourse" :name="textEdit.visible">
<form class="default" @submit.prevent="">
<label>
<translate>Sichtbar ab</translate>
<input type="date" v-model="currentElement.attributes['release-date']" />
</label>
<label>
<translate>Unsichtbar ab</translate>
<input type="date" v-model="currentElement.attributes['withdraw-date']" />
</label>
</form>
</courseware-tab>
</courseware-tabs>
</template>
</studip-dialog>
<studip-dialog
v-if="showAddDialog"
:title="$gettext('Seite hinzufügen')"
:confirmText="'Erstellen'"
:confirmClass="'accept'"
:closeText="$gettext('Schließen')"
:closeClass="'cancel'"
class="cw-structural-element-dialog"
@close="closeAddDialog"
@confirm="createElement"
>
<template v-slot:dialogContent>
<form class="default" @submit.prevent="">
<label>
<translate>Position der neuen Seite</translate>
<select v-model="newChapterParent">
<option v-if="!isRoot" value="sibling">
<translate>Neben der aktuellen Seite</translate>
</option>
<option value="descendant"><translate>Unterhalb der aktuellen Seite</translate></option>
</select>
</label>
<label>
<translate>Name der neuen Seite</translate><br />
<input v-model="newChapterName" type="text" />
</label>
</form>
</template>
</studip-dialog>
<studip-dialog
v-if="showInfoDialog"
:title="textInfo.title"
:closeText="textInfo.close"
:closeClass="'cancel'"
@close="showElementInfoDialog(false)"
>
<template v-slot:dialogContent>
<table class="cw-structural-element-info">
<tr>
<td><translate>Titel</translate>:</td>
<td>{{ structuralElement.attributes.title }}</td>
</tr>
<tr>
<td><translate>Beschreibung</translate>:</td>
<td>{{ structuralElement.attributes.payload.description }}</td>
</tr>
<tr>
<td><translate>Seite wurde erstellt von</translate>:</td>
<td>{{ owner }}</td>
</tr>
<tr>
<td><translate>Seite wurde erstellt am</translate>:</td>
<td><iso-date :date="structuralElement.attributes.mkdate" /></td>
</tr>
<tr>
<td><translate>Zuletzt bearbeitet von</translate>:</td>
<td>{{ editor }}</td>
</tr>
<tr>
<td><translate>Zuletzt bearbeitet am</translate>:</td>
<td><iso-date :date="structuralElement.attributes.chdate" /></td>
</tr>
</table>
</template>
</studip-dialog>
<studip-dialog
v-if="showExportDialog"
:title="textExport.title"
:confirmText="textExport.confirm"
:confirmClass="'accept'"
:closeText="textExport.close"
:closeClass="'cancel'"
height="350"
@close="showElementExportDialog(false)"
@confirm="exportCurrentElement"
>
<template v-slot:dialogContent>
<div v-show="!exportRunning">
<translate>Hiermit exportieren Sie die Seite "{{ currentElement.attributes.title }}" als ZIP-Datei.</translate>
<div class="cw-element-export">
<label>
<input type="checkbox" v-model="exportChildren">
<translate>Unterseiten exportieren</translate>
</label>
</div>
</div>
<courseware-companion-box v-show="exportRunning" :msgCompanion="$gettext('Export läuft, bitte haben sie einen Moment Geduld...')" mood="pointing"/>
<div v-show="exportRunning" class="cw-import-zip">
<header>{{exportState}}:</header>
<div class="progress-bar-wrapper">
<div class="progress-bar" role="progressbar" :style="{width: exportProgress + '%'}" :aria-valuenow="exportProgress" aria-valuemin="0" aria-valuemax="100">{{ exportProgress }}%</div>
</div>
</div>
</template>
</studip-dialog>
<studip-dialog
v-if="showOerDialog"
height="600"
width="600"
:title="textOer.title"
:confirmText="textOer.confirm"
:confirmClass="'accept'"
:closeText="textOer.close"
:closeClass="'cancel'"
@close="showElementOerDialog(false)"
@confirm="publishCurrentElement"
>
<template v-slot:dialogContent>
<form class="default" @submit.prevent="">
<fieldset>
<legend><translate>Grunddaten</translate></legend>
<label>
<p><translate>Vorschaubild</translate>:</p>
<img
v-if="currentElement.relationships.image.data"
:src="currentElement.relationships.image.meta['download-url']"
width="400"
/>
</label>
<label>
<p><translate>Beschreibung</translate>:</p>
<p> {{ currentElement.attributes.payload.description }}</p>
</label>
<label>
<translate>Niveau</translate>:
<p> {{ currentElement.attributes.payload.difficulty_start }} - {{ currentElement.attributes.payload.difficulty_end }}</p>
</label>
<label>
<translate>Lizenztyp</translate>:
<p>{{currentLicenseName}}</p>
</label>
<label>
<translate>Sie können diese Daten unter "Seite bearbeiten" verändern</translate>.
</label>
</fieldset>
<fieldset>
<legend><translate>Einstellungen</translate></legend>
<label>
<translate>Unterseiten veröffentlichen</translate>
<input type="checkbox" v-model="oerChildren">
</label>
</fieldset>
</form>
</template>
</studip-dialog>
<studip-dialog
v-if="showDeleteDialog"
:title="textDelete.title"
:question="textDelete.alert"
height="180"
@confirm="deleteCurrentElement"
@close="closeDeleteDialog"
></studip-dialog>
</div>
<div v-else>
<courseware-companion-box v-if="currentElement !== ''" :msgCompanion="textCompanionWrongContext" mood="sad"/>
</div>
</div>
</template>
<script>
import ContainerComponents from './container-components.js';
import CoursewarePluginComponents from './plugin-components.js';
import CoursewareStructuralElementPermissions from './CoursewareStructuralElementPermissions.vue';
import CoursewareAccordionContainer from './CoursewareAccordionContainer.vue';
import CoursewareCompanionBox from './CoursewareCompanionBox.vue';
import CoursewareWellcomeScreen from './CoursewareWellcomeScreen.vue';
import CoursewareEmptyElementBox from './CoursewareEmptyElementBox.vue';
import CoursewareCompanionOverlay from './CoursewareCompanionOverlay.vue';
import CoursewareListContainer from './CoursewareListContainer.vue';
import CoursewareTabsContainer from './CoursewareTabsContainer.vue';
import CoursewareRibbon from './CoursewareRibbon.vue';
import CoursewareTabs from './CoursewareTabs.vue';
import CoursewareTab from './CoursewareTab.vue';
import CoursewareExport from '@/vue/mixins/courseware/export.js';
import IsoDate from './IsoDate.vue';
import StudipDialog from '../StudipDialog.vue';
import { mapActions, mapGetters } from 'vuex';
export default {
name: 'courseware-structural-element',
components: {
CoursewareStructuralElementPermissions,
CoursewareRibbon,
CoursewareListContainer,
CoursewareAccordionContainer,
CoursewareTabsContainer,
CoursewareCompanionBox,
CoursewareCompanionOverlay,
CoursewareWellcomeScreen,
CoursewareEmptyElementBox,
CoursewareTabs,
CoursewareTab,
IsoDate,
StudipDialog,
},
props: ['orderedStructuralElements'],
mixins: [CoursewareExport],
data() {
return {
currentId: null,
newChapterName: '',
newChapterParent: 'descendant',
currentElement: '',
uploadFileError: '',
textCompanionWrongContext: this.$gettext('Die angeforderte Seite ist nicht Teil dieser Courseware.'),
textEdit: {
title: this.$gettext('Seite bearbeiten'),
confirm: this.$gettext('Speichern'),
close: this.$gettext('Schließen'),
basic: this.$gettext('Grunddaten'),
image: this.$gettext('Bild'),
meta: this.$gettext('Metadaten'),
approval: this.$gettext('Rechte'),
visible: this.$gettext('Sichtbarkeit'),
},
textInfo: {
title: this.$gettext('Informationen zur Seite'),
close: this.$gettext('Schließen'),
},
textExport: {
title: this.$gettext('Seite exportieren'),
confirm: this.$gettext('Exportieren'),
close: this.$gettext('Schließen'),
},
textAdd: {
title: this.$gettext('Seite hinzufügen'),
confirm: this.$gettext('Erstellen'),
close: this.$gettext('Schließen'),
},
textRibbon: {
perv: this.$gettext('zurück'),
next: this.$gettext('weiter'),
},
exportRunning: false,
exportChildren: false,
oerChildren: true,
};
},
computed: {
...mapGetters({
courseware: 'courseware',
consumeMode: 'consumeMode',
containerById: 'courseware-containers/byId',
relatedContainers: 'courseware-containers/related',
relatedStructuralElements: 'courseware-structural-elements/related',
relatedUsers: 'users/related',
structuralElementById: 'courseware-structural-elements/byId',
userIsTeacher: 'userIsTeacher',
pluginManager: 'pluginManager',
showEditDialog: 'showStructuralElementEditDialog',
showAddDialog: 'showStructuralElementAddDialog',
showExportDialog: 'showStructuralElementExportDialog',
showInfoDialog: 'showStructuralElementInfoDialog',
showDeleteDialog: 'showStructuralElementDeleteDialog',
showOerDialog: 'showStructuralElementOerDialog',
oerEnabled: 'oerEnabled',
oerTitle: 'oerTitle',
licenses: 'licenses',
exportState: 'exportState',
exportProgress: 'exportProgress',
}),
textOer() {
return {
title: this.$gettext('Seite auf') + ' ' + this.oerTitle + ' ' + this.$gettext('veröffentlichen'),
confirm: this.$gettext('Veröffentlichen'),
close: this.$gettext('Schließen'),
};
},
inCourse() {
return this.$store.getters.context.type === 'courses';
},
textDelete() {
let textDelete = {};
textDelete.title = this.$gettext('Seite unwiderruflich löschen');
textDelete.alert = this.$gettext('Möchten Sie die Seite wirklich löschen?');
if (this.structuralElementLoaded) {
textDelete.alert = this.$gettext('Möchten Sie die Seite') +' "'+ this.structuralElement.attributes.title + '" '+ this.$gettext('wirklich löschen?');
}
return textDelete;
},
validContext() {
let valid = false;
let context = this.$store.getters.context;
if (context.type === 'courses' && this.currentElement.relationships) {
if (this.currentElement.relationships.course && context.id === this.currentElement.relationships.course.data.id) {
valid = true;
}
}
if (context.type === 'users' && this.currentElement.relationships) {
if (this.currentElement.relationships.user && context.id === this.currentElement.relationships.user.data.id) {
valid = true;
}
}
return valid;
},
image() {
return this.structuralElement.relationships?.image?.meta?.['download-url'] ?? null;
},
structuralElement() {
if (!this.currentId) {
return null;
}
return this.structuralElementById({ id: this.currentId });
},
structuralElementLoaded() {
return this.structuralElement !== null && this.structuralElement !== {};
},
ancestors() {
if (!this.structuralElement) {
return [];
}
return this.relatedStructuralElements({ parent: this.structuralElement, relationship: 'ancestors' });
},
prevElement() {
const currentIndex = this.orderedStructuralElements.indexOf(this.structuralElement.id);
if (currentIndex <= 0) {
return null;
}
const previousId = this.orderedStructuralElements[currentIndex - 1];
const previous = this.structuralElementById({ id: previousId });
return previous;
},
nextElement() {
const currentIndex = this.orderedStructuralElements.indexOf(this.structuralElement.id);
const lastIndex = this.orderedStructuralElements.length - 1;
if (currentIndex === -1 || currentIndex === lastIndex) {
return null;
}
const nextId = this.orderedStructuralElements[currentIndex + 1];
const next = this.structuralElementById({ id: nextId });
return next;
},
empty() {
if (this.containers === null) {
return true;
} else {
return !this.containers.some((container) => container.relationships.blocks.data.length > 0);
}
},
containers() {
if (!this.structuralElement) {
return [];
}
return (
this.relatedContainers({
parent: this.structuralElement,
relationship: 'containers',
}) ?? []
);
},
noContainers() {
if (this.containers === null) {
return true;
} else {
return this.containers.length === 0;
}
},
canEdit() {
if (!this.structuralElement) {
return false;
}
return this.structuralElement.attributes['can-edit'];
},
canRead() {
if (!this.structuralElement) {
return false;
}
return this.structuralElement.attributes['can-read'];
},
isTeacher() {
return this.userIsTeacher;
},
isRoot() {
return this.structuralElement.relationships.parent.data === null;
},
owner() {
const owner = this.relatedUsers({
parent: this.structuralElement,
relationship: 'owner',
});
return owner?.attributes['formatted-name'] ?? '';
},
editor() {
const editor = this.relatedUsers({
parent: this.structuralElement,
relationship: 'editor',
});
return editor?.attributes['formatted-name'] ?? '';
},
menuItems() {
let menu = [
{ id: 3, label: this.$gettext('Informationen anzeigen'), icon: 'info', emit: 'showInfo' },
{ id: 4, label: this.$gettext('Lesezeichen setzen'), icon: 'star', emit: 'setBookmark' },
];
if (this.canEdit) {
menu.push({ id: 1, label: this.$gettext('Seite bearbeiten'), icon: 'edit', emit: 'editCurrentElement' });
menu.push({ id: 2, label: this.$gettext('Seite hinzufügen'), icon: 'add', emit: 'addElement' });
menu.push({ id: 5, label: this.$gettext('Seite exportieren'), icon: 'export', emit: 'showExportOptions' });
}
if (this.canEdit && this.oerEnabled) {
menu.push({ id: 6, label: this.textOer.title, icon: 'oer-campus', emit: 'oerCurrentElement' });
}
if(!this.isRoot && this.canEdit) {
menu.push({ id: 7, label: this.$gettext('Seite löschen'), icon: 'trash', emit: 'deleteCurrentElement' });
}
menu.sort((a, b) => a.id - b.id);
return menu;
},
colors() {
const colors = [
{name: this.$gettext('Schwarz'), class: 'black', hex: '#000000', level: 100, icon: 'black', darkmode: true},
{name: this.$gettext('Weiß'), class: 'white', hex: '#ffffff', level: 100, icon: 'white', darkmode: false},
{name: this.$gettext('Blau'), class: 'studip-blue', hex: '#28497c', level: 100, icon: 'blue', darkmode: true},
{name: this.$gettext('Hellblau'), class: 'studip-lightblue', hex: '#e7ebf1', level: 40, icon: 'lightblue', darkmode: false},
{name: this.$gettext('Rot'), class: 'studip-red', hex: '#d60000', level: 100, icon: 'red', darkmode: false},
{name: this.$gettext('Grün'), class: 'studip-green', hex: '#008512', level: 100, icon: 'green', darkmode: true},
{name: this.$gettext('Gelb'), class: 'studip-yellow', hex: '#ffbd33', level: 100, icon: 'yellow', darkmode: false},
{name: this.$gettext('Grau'), class: 'studip-gray', hex: '#636a71', level: 100, icon: 'grey', darkmode: true},
{name: this.$gettext('Holzkohle'), class: 'charcoal', hex: '#3c454e', level: 100, icon: false, darkmode: true},
{name: this.$gettext('Königliches Purpur'), class: 'royal-purple', hex: '#8656a2', level: 80, icon: false, darkmode: true},
{name: this.$gettext('Leguangrün'), class: 'iguana-green', hex: '#66b570', level: 60, icon: false, darkmode: true},
{name: this.$gettext('Königin blau'), class: 'queen-blue', hex: '#536d96', level: 80, icon: false, darkmode: true},
{name: this.$gettext('Helles Seegrün'), class: 'verdigris', hex: '#41afaa', level: 80, icon: false, darkmode: true},
{name: this.$gettext('Maulbeere'), class: 'mulberry', hex: '#bf5796', level: 80, icon: false, darkmode: true},
{name: this.$gettext('Kürbis'), class: 'pumpkin', hex: '#f26e00', level: 100, icon: false, darkmode: true},
{name: this.$gettext('Sonnenschein'), class: 'sunglow', hex: '#ffca5c', level: 80, icon: false, darkmode: false},
{name: this.$gettext('Apfelgrün'), class: 'apple-green', hex: '#8bbd40', level: 80, icon: false, darkmode: true},
];
let elementColors = [];
colors.forEach( color => {
if(color.darkmode) {
elementColors.push(color);
}
});
return elementColors;
},
currentLicenseName() {
for(let i = 0; i < this.licenses.length; i++) {
if (this.licenses[i]['id'] == this.currentElement.attributes.payload.license_type) {
return this.licenses[i]['name'];
}
}
return '';
}
},
watch: {
$route(to) {
this.setCurrentId(to.params.id);
},
},
mounted() {
if (!this.currentId) {
this.setCurrentId(this.$route.params.id);
}
},
methods: {
...mapActions({
createStructuralElement: 'createStructuralElement',
updateStructuralElement: 'updateStructuralElement',
deleteStructuralElement: 'deleteStructuralElement',
loadStructuralElement: 'loadStructuralElement',
lockObject: 'lockObject',
unlockObject: 'unlockObject',
addBookmark: 'addBookmark',
companionInfo: 'companionInfo',
uploadImageForStructuralElement: 'uploadImageForStructuralElement',
deleteImageForStructuralElement: 'deleteImageForStructuralElement',
companionSuccess: 'companionSuccess',
showElementEditDialog: 'showElementEditDialog',
showElementAddDialog: 'showElementAddDialog',
showElementExportDialog: 'showElementExportDialog',
showElementInfoDialog: 'showElementInfoDialog',
showElementDeleteDialog: 'showElementDeleteDialog',
showElementOerDialog: 'showElementOerDialog',
}),
async setCurrentId(id) {
this.currentId = id;
await this.loadStructuralElement(this.currentId);
this.initCurrent();
},
initCurrent() {
this.currentElement = _.cloneDeep(this.structuralElement);
this.uploadFileError = '';
},
async menuAction(action) {
switch (action) {
case 'editCurrentElement':
await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
this.showElementEditDialog(true);
break;
case 'addElement':
this.newChapterName = '';
this.newChapterParent = 'descendant';
this.showElementAddDialog(true);
break;
case 'deleteCurrentElement':
await this.lockObject({ id: this.currentId, type: 'courseware-structural-elements' });
this.showElementDeleteDialog(true);
break;
case 'showInfo':
this.showElementInfoDialog(true);
break;
case 'showExportOptions':
this.showElementExportDialog(true);
break;
case 'oerCurrentElement':
this.showElementOerDialog(true);
break;
case 'setBookmark':
this.setBookmark();
break;
}
},
async closeEditDialog() {
await this.unlockObject({ id: this.currentId, type: 'courseware-structural-elements' });
this.showElementEditDialog(false)
this.initCurrent();
},
closeAddDialog() {
this.showElementAddDialog(false);
},
checkUploadFile() {
const file = this.$refs?.upload_image?.files[0];
if (file.size > 2097152) {
this.uploadFileError = this.$gettext('Diese Datei ist zu groß. Bitte wählen Sie eine kleinere Datei.');
} else if (!file.type.includes('image')) {
this.uploadFileError = this.$gettext('Diese Datei ist kein Bild. Bitte wählen Sie ein Bild aus.');
} else {
this.uploadFileError = '';
}
},
deleteImage() {
this.deleteImageForStructuralElement(this.currentElement);
this.initCurrent();
},
async storeCurrentElement() {
const file = this.$refs?.upload_image?.files[0];
if (file) {
if (file.size > 2097152) {
return false;
}
this.uploadFileError = '';
this.uploadImageForStructuralElement({
structuralElement: this.currentElement,
file,
}).catch((error) => {
console.error(error);
this.uploadFileError = this.$gettext('Fehler beim Hochladen der Datei.');
});
}
if (this.currentElement.attributes['release-date'] !== '') {
this.currentElement.attributes['release-date'] =
new Date(this.currentElement.attributes['release-date']).getTime() / 1000;
}
if (this.currentElement.attributes['withdraw-date'] !== '') {
this.currentElement.attributes['withdraw-date'] =
new Date(this.currentElement.attributes['withdraw-date']).getTime() / 1000;
}
await this.updateStructuralElement({
element: this.currentElement,
id: this.currentId,
});
await this.unlockObject({ id: this.currentId, type: 'courseware-structural-elements' });
this.setCurrentId(this.$route.params.id);
this.showElementEditDialog(false);
},
async exportCurrentElement(data) {
if (this.exportRunning) {
return;
}
this.exportRunning = true;
await this.sendExportZip(this.currentElement.id, {
withChildren: this.exportChildren
});
this.exportRunning = false;
this.showElementExportDialog(false);
},
async publishCurrentElement() {
this.exportToOER(this.currentElement, {withChildren: this.oerChildren});
},
async closeDeleteDialog() {
await this.unlockObject({ id: this.currentId, type: 'courseware-structural-elements' });
this.showElementDeleteDialog(false);
},
async deleteCurrentElement() {
let parent_id = this.structuralElement.relationships.parent.data.id;
await this.deleteStructuralElement({
id: this.currentId,
parentId: this.structuralElement.relationships.parent.data.id,
});
this.showElementDeleteDialog(false);
this.$router.push(parent_id);
},
async createElement() {
let title = this.newChapterName; // this is the title of the new element
let parent_id = this.currentId; // new page is descandant as default
if (this.newChapterParent === 'sibling') {
parent_id = this.structuralElement.relationships.parent.data.id;
}
this.showElementAddDialog(false);
await this.createStructuralElement({
attributes: {
title,
},
parentId: parent_id,
currentId: this.currentId,
});
let newElement = this.$store.getters['courseware-structural-elements/lastCreated'];
this.companionSuccess({
info: this.$gettext('Seite') +' "' + newElement.attributes.title + '" ' + this.$gettext('wurde erfolgreich angelegt.'),
});
},
containerComponent(container) {
return 'courseware-' + container.attributes['container-type'] + '-container';
},
setBookmark() {
this.addBookmark(this.structuralElement);
this.companionInfo({ info: this.$gettext('Das Lesezeichen wurde gesetzt') });
},
updateReadApproval(approval) {
this.currentElement.attributes['read-approval'] = approval;
},
updateWriteApproval(approval) {
this.currentElement.attributes['write-approval'] = approval;
},
},
created() {
this.pluginManager.registerComponentsLocally(this);
},
// this line provides all the components to courseware plugins
provide: () => ({ containerComponents: ContainerComponents, coursewarePluginComponents: CoursewarePluginComponents }),
};
</script>