skillbox/client/src/pages/createContentBlock.vue

294 lines
7.7 KiB
Vue

<template>
<div class="create-content-block content-list__parent">
<div class="create-content-block__content">
<h1 class="heading-1 create-content-block__heading">
Inhaltsblock erfassen
</h1>
<toggle
:bordered="false"
:checked="contentBlock.isAssignment"
class="create-content-block__task-toggle"
label="Inhaltsblock als Auftrag formatieren"
@input="contentBlock.isAssignment=$event"
/>
<content-form-section title="Titel">
<input-with-label
:value="contentBlock.title"
label="Name"
placeholder="z.B. Auftrag 3"
@input="contentBlock.title=$event"
/>
</content-form-section>
<add-content-link
class="create-content-block__segment"
@click="addBlock(-1)"
/>
<div
class="content-list content-list--creator create-content-block__segment"
v-for="(block, outer) in contentBlock.contents"
:key="block.id"
>
<ol
class="content-list__item create-content-block__segment"
v-if="block.type === 'content_list_item'"
>
<li
class="create-content-block__segment"
v-for="(content, index) in block.contents"
:key="content.id"
>
<content-element
:element="content"
class="create-content-block__segment"
@update="update(index, $event, outer)"
@remove="remove(outer, index)"
/>
<add-content-link
class="create-content-block__add-button"
@click="addBlock(outer, index)"
/>
</li>
</ol>
<content-element
:element="block"
class="create-content-block__segment"
v-else
@update="update(outer, $event)"
@remove="remove(outer)"
/>
<add-content-link
class="create-content-block__segment"
@click="addBlock(outer)"
/>
</div>
<footer class="create-content-block__footer">
<a
class="button button--primary"
@click="save(contentBlock)"
>Speichern</a>
<a
class="button"
@click="goToModule"
>Abbrechen</a>
</footer>
</div>
</div>
</template>
<script>
import Vue from 'vue';
import Toggle from '@/components/ui/Toggle';
import ContentFormSection from '@/components/content-block-form/ContentFormSection';
import InputWithLabel from '@/components/ui/InputWithLabel';
import AddContentLink from '@/components/content-block-form/AddContentLink';
import ContentElement from '@/components/content-block-form/ContentElement';
import NEW_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/addContentBlock.gql';
import {setUserBlockType} from '@/helpers/content-block';
import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery.gql';
export default Vue.extend({
props: {
parent: {
type: String,
default: ''
},
after: {
type: String,
default: ''
}
},
components: {
ContentElement,
AddContentLink,
InputWithLabel,
ContentFormSection,
Toggle,
},
data: () => ({
contentBlock: {
title: '',
isAssignment: false,
contents: [
{
id: 23,
type: 'content_list_item',
contents: [
{
id: 2,
}
]
}
]},
}),
mounted() {
// this.addBlock(0);
},
methods: {
update(index, element, parent) {
if (parent === undefined) {
this.contentBlock.contents = [
...this.contentBlock.contents.slice(0, index),
element,
...this.contentBlock.contents.slice(index + 1)
];
} else {
const parentBlock = this.contentBlock.contents[parent];
this.contentBlock.contents = [
...this.contentBlock.contents.slice(0, parent),
{
...parentBlock,
contents: [
...parentBlock.contents.slice(0, index),
element,
...parentBlock.contents.slice(index + 1),
]
},
...this.contentBlock.contents.slice(parent + 1)
];
}
},
addBlock(afterOuterIndex, innerIndex) {
if (innerIndex !== undefined) {
const block = this.contentBlock.contents[afterOuterIndex];
this.contentBlock.contents = [
...this.contentBlock.contents.slice(0, afterOuterIndex),
{
...block,
contents: [
...block.contents.slice(0, innerIndex + 1),
{
id: -1,
type: 'content-block-element-chooser-widget',
},
...block.contents.slice(innerIndex + 1)
]
},
...this.contentBlock.contents.slice(afterOuterIndex + 1)
];
} else {
this.contentBlock.contents = [
...this.contentBlock.contents.slice(0, afterOuterIndex+1),
{
id: -1,
type: 'content-block-element-chooser-widget',
includeListOption: true
},
...this.contentBlock.contents.slice(afterOuterIndex+1)
];
}
},
remove(outer, inner) {
if (inner === undefined) {
this.contentBlock.contents = [
...this.contentBlock.contents.slice(0, outer),
...this.contentBlock.contents.slice(outer + 1)
];
} else {
this.contentBlock.contents = [
...this.contentBlock.contents.slice(0, outer),
{
...this.contentBlock.contents[outer],
contents: [
...this.contentBlock.contents[outer].contents.slice(0, inner),
...this.contentBlock.contents[outer].contents.slice(inner+1),
]
},
...this.contentBlock.contents.slice(outer + 1)
];
}
},
save({title, contents, isAssignment}) {
const contentBlock = {
title: title,
contents: contents.filter(value => Object.keys(value).length > 0),
type: setUserBlockType(isAssignment),
};
let input;
const { parent, after, slug} = this.$route.params;
if(after) {
input = {
contentBlock,
after
};
} else {
input = {
contentBlock,
parent
};
}
this.$apollo.mutate({
mutation: NEW_CONTENT_BLOCK_MUTATION,
variables: {
input
},
refetchQueries: [{
query: MODULE_DETAILS_QUERY,
variables: {
slug
}
}]
}).then(this.goToModule);
},
goToModule() {
this.$router.go(-1);
}
},
});
</script>
<style scoped lang="scss">
@import '~styles/helpers';
.create-content-block {
width: 800px;
max-width: 100%;
display: grid;
grid-template-columns: 800px;
grid-template-rows: 1fr auto;
grid-template-areas:
'content'
'footer';
&__heading {
@include heading-1;
}
&__task-toggle {
margin-bottom: $large-spacing;
}
&__add-button {
}
&__segment {
margin-bottom: $large-spacing;
:last-child {
margin-bottom: 0;
}
}
&__content {
grid-area: content;
overflow-x: visible;
overflow-y: auto;
padding: 10px;
}
&__footer {
margin-top: auto;
grid-area: footer;
}
}
</style>