294 lines
8.1 KiB
Vue
294 lines
8.1 KiB
Vue
<template>
|
|
<modal>
|
|
<template slot="header">
|
|
<modal-input v-on:input="updateTitle"
|
|
:placeholder="titlePlaceholder"
|
|
:value="localContentBlock.title"
|
|
:error="error"></modal-input>
|
|
<checkbox :checked="localContentBlock.isAssignment"
|
|
:item="localContentBlock"
|
|
:label="'Aufgabe'"
|
|
@input="setContentBlockType"
|
|
class="contents-form__task"
|
|
></checkbox>
|
|
<modal-input v-if="blockType === 'RoomEntry'"
|
|
placeholder="Untertitel für Raumeintrag erfassen"
|
|
v-model="localContentBlock.subtitle"></modal-input>
|
|
</template>
|
|
|
|
<add-content-element class="contents-form__add"
|
|
v-on:add-element="addElement"
|
|
:index="-1"
|
|
></add-content-element>
|
|
<div v-for="(element, index) in localContentBlock.contents" :key="index" class="contents-form__element">
|
|
<component
|
|
class="contents-form__element-component"
|
|
:is="type(element)"
|
|
:class="{'contents-form__chooser': type(element) === 'content-block-element-chooser-widget'}"
|
|
v-bind="element" :index="index"
|
|
v-on:change-type="changeType"
|
|
|
|
v-on:link-change-url="changeLinkUrl"
|
|
v-on:link-change-text="changeLinkText"
|
|
|
|
v-on:text-change-value="changeTextValue"
|
|
|
|
v-on:document-change-url="changeDocumentUrl"
|
|
|
|
v-on:image-change-url="changeImageUrl"
|
|
|
|
v-on:video-change-url="changeVideoUrl"
|
|
|
|
v-on:assignment-change-title="changeAssignmentTitle"
|
|
v-on:assignment-change-assignment="changeAssignmentAssignment"
|
|
>
|
|
</component>
|
|
<a class="contents-form__remove" v-on:click="removeElement(index)">
|
|
<trash-icon v-if="type(element) !== 'content-block-element-chooser-widget'"
|
|
class="contents-form__trash-icon"></trash-icon>
|
|
</a>
|
|
|
|
<add-content-element class="contents-form__add"
|
|
v-on:add-element="addElement"
|
|
:index="index"
|
|
></add-content-element>
|
|
</div>
|
|
|
|
<div slot="footer">
|
|
<a class="button button--primary" v-on:click="save">Speichern</a>
|
|
<a class="button" v-on:click="$emit('hide')">Abbrechen</a>
|
|
</div>
|
|
</modal>
|
|
</template>
|
|
|
|
<script>
|
|
import Modal from '@/components/Modal';
|
|
import ContentBlockElementChooserWidget from '@/components/content-forms/ContentBlockElementChooserWidget';
|
|
import ModalInput from '@/components/ModalInput';
|
|
import AddContentElement from '@/components/AddContentElement';
|
|
import LinkForm from '@/components/content-forms/LinkForm';
|
|
import VideoForm from '@/components/content-forms/VideoForm';
|
|
import ImageForm from '@/components/content-forms/ImageForm';
|
|
import DocumentForm from '@/components/content-forms/DocumentForm';
|
|
import AssignmentForm from '@/components/content-forms/AssignmentForm';
|
|
import TextForm from '@/components/content-forms/TextForm';
|
|
import TrashIcon from '@/components/icons/TrashIcon';
|
|
import Checkbox from '@/components/Checkbox';
|
|
|
|
export default {
|
|
props: {
|
|
'content-block': Object,
|
|
'block-type': {
|
|
type: String,
|
|
default: 'ContentBlock'
|
|
}
|
|
},
|
|
|
|
components: {
|
|
Modal,
|
|
ContentBlockElementChooserWidget,
|
|
ModalInput,
|
|
AddContentElement,
|
|
LinkForm,
|
|
VideoForm,
|
|
ImageForm,
|
|
DocumentForm,
|
|
AssignmentForm,
|
|
TextForm,
|
|
TrashIcon,
|
|
Checkbox
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
error: false,
|
|
localContentBlock: Object.assign({}, {
|
|
title: this.contentBlock.title,
|
|
contents: [...this.contentBlock.contents],
|
|
id: this.contentBlock.id || undefined,
|
|
subtitle: this.contentBlock.subtitle,
|
|
isAssignment: this.contentBlock.type && this.contentBlock.type === 'TASK'
|
|
})
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
titlePlaceholder() {
|
|
return this.blockType === 'RoomEntry' ? 'Titel für Raumeintrag erfassen' : 'Titel für Inhaltsblock erfassen';
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
type(element) {
|
|
switch (element.type) {
|
|
case 'link_block':
|
|
return 'link-form';
|
|
case 'video_block':
|
|
return 'video-form';
|
|
case 'image_url_block':
|
|
return 'image-form';
|
|
case 'text_block':
|
|
return 'text-form';
|
|
case 'assignment':
|
|
return 'assignment-form';
|
|
case 'document_block':
|
|
return 'document-form';
|
|
}
|
|
return 'content-block-element-chooser-widget'
|
|
},
|
|
_updateProperty(value, index, key) {
|
|
const content = this.localContentBlock.contents[index];
|
|
this.localContentBlock.contents.splice(index, 1, {
|
|
...content,
|
|
value: {
|
|
...content.value,
|
|
[key]: value
|
|
}
|
|
});
|
|
},
|
|
changeLinkUrl(value, index) {
|
|
this._updateProperty(value, index, 'url')
|
|
},
|
|
changeLinkText(value, index) {
|
|
this._updateProperty(value, index, 'text')
|
|
},
|
|
changeVideoUrl(value, index) {
|
|
this._updateProperty(value, index, 'url')
|
|
},
|
|
changeImageUrl(value, index) {
|
|
this._updateProperty(value, index, 'url')
|
|
},
|
|
changeDocumentUrl(value, index) {
|
|
this._updateProperty(value, index, 'url')
|
|
},
|
|
changeTextValue(value, index) {
|
|
this._updateProperty(value, index, 'text')
|
|
},
|
|
changeAssignmentTitle(value, index) {
|
|
this._updateProperty(value, index, 'title')
|
|
},
|
|
changeAssignmentAssignment(value, index) {
|
|
this._updateProperty(value, index, 'assignment')
|
|
},
|
|
removeElement(index) {
|
|
this.localContentBlock.contents.splice(index, 1);
|
|
},
|
|
addElement(index) {
|
|
this.localContentBlock.contents.splice(index + 1, 0, {})
|
|
},
|
|
updateTitle(title) {
|
|
this.localContentBlock.title = title;
|
|
this.error = false;
|
|
},
|
|
changeType(index, type) {
|
|
let el = {
|
|
type: type,
|
|
value: {}
|
|
};
|
|
switch (type) {
|
|
case 'text_block':
|
|
el = {
|
|
...el,
|
|
value: {
|
|
text: ''
|
|
}
|
|
};
|
|
break;
|
|
case 'link_block':
|
|
el = {
|
|
...el,
|
|
value: {
|
|
text: '',
|
|
url: ''
|
|
}
|
|
};
|
|
break;
|
|
case 'video_block':
|
|
el = {
|
|
...el,
|
|
value: {
|
|
url: ''
|
|
}
|
|
};
|
|
break;
|
|
case 'document_block':
|
|
el = {
|
|
...el,
|
|
value: {
|
|
url: ''
|
|
}
|
|
};
|
|
break;
|
|
case 'image_url_block':
|
|
el = {
|
|
...el,
|
|
value: {
|
|
url: ''
|
|
}
|
|
};
|
|
break;
|
|
}
|
|
|
|
this.localContentBlock.contents.splice(index, 1, el);
|
|
},
|
|
save() {
|
|
if (!this.localContentBlock.title) {
|
|
this.error = true;
|
|
return false;
|
|
}
|
|
this.$emit('save', this.localContentBlock);
|
|
},
|
|
setContentBlockType(checked, localContentBlock) {
|
|
this.localContentBlock.isAssignment = checked;
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
@import "@/styles/_variables.scss";
|
|
|
|
.contents-form {
|
|
/* top level does not exist, because of the modal */
|
|
|
|
&__element {
|
|
display: grid;
|
|
grid-template-columns: 1fr 50px;
|
|
grid-auto-rows: auto;
|
|
/*width: 95%; // reserve space for scrollbar*/
|
|
}
|
|
|
|
&__element-component {
|
|
margin-bottom: 25px;
|
|
}
|
|
|
|
&__remove {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: 50px;
|
|
height: 50px;
|
|
}
|
|
|
|
&__trash-icon {
|
|
width: 25px;
|
|
height: 25px;
|
|
fill: $color-grey;
|
|
cursor: pointer;
|
|
justify-self: center;
|
|
}
|
|
|
|
&__chooser {
|
|
grid-column: 1 / span 2;
|
|
}
|
|
|
|
&__add {
|
|
grid-column: 1 / span 2;
|
|
}
|
|
|
|
&__task {
|
|
margin: 15px 0 10px;
|
|
}
|
|
}
|
|
</style>
|