Make modal handling a bit more generic

This commit is contained in:
Ramon Wenger 2018-09-19 14:13:31 +02:00
parent c9d43dd111
commit a760949b84
3 changed files with 96 additions and 68 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<div :class="{'no-scroll': showModal}"> <div :class="{'no-scroll': showModal}">
<component :is="modalComponent" v-if="showModal"></component> <component :is="showModal" v-if="showModal"></component>
<component :is="layout"></component> <component :is="layout"></component>
</div> </div>
</template> </template>
@ -9,7 +9,7 @@
import DefaultLayout from '@/layouts/DefaultLayout'; import DefaultLayout from '@/layouts/DefaultLayout';
import SimpleLayout from '@/layouts/SimpleLayout'; import SimpleLayout from '@/layouts/SimpleLayout';
import Modal from '@/components/Modal'; import Modal from '@/components/Modal';
import NewContentBlockWizard from '@/components/NewContentBlockWizard'; import NewContentBlockWizard from '@/components/content-block-form/NewContentBlockWizard';
export default { export default {
name: 'App', name: 'App',
@ -27,9 +27,6 @@
}, },
showModal() { showModal() {
return this.$store.state.showModal return this.$store.state.showModal
},
modalComponent() {
return 'new-content-block-wizard'
} }
}, },

View File

@ -1,15 +1,16 @@
<template> <template>
<modal> <modal>
<content-block-title-input slot="header" v-on:update-title="updateTitle" :title="title" :error="error"></content-block-title-input> <content-block-title-input slot="header" v-on:update-title="updateTitle" :title="contentBlock.title"
<add-content-element class="new-content-block-wizard__add" :error="error"></content-block-title-input>
<add-content-element class="content-block-form__add"
v-on:add-element="addElement" v-on:add-element="addElement"
:index="-1" :index="-1"
></add-content-element> ></add-content-element>
<div v-for="(element, index) in elements" :key="index" class="new-content-block-wizard__element"> <div v-for="(element, index) in contentBlock.elements" :key="index" class="content-block-form__element">
<component <component
class="new-content-block-wizard__element-component" class="content-block-form__element-component"
:is="type(element)" :is="type(element)"
:class="{'new-content-block-wizard__chooser': type(element) === 'content-block-element-chooser-widget'}" :class="{'content-block-form__chooser': type(element) === 'content-block-element-chooser-widget'}"
:element="element" v-bind="element" :index="index" :element="element" v-bind="element" :index="index"
v-on:change-type="changeType" v-on:change-type="changeType"
v-on:link-change-url="changeLinkUrl" v-on:link-change-url="changeLinkUrl"
@ -18,20 +19,20 @@
v-on:document-change-url="changeDocumentUrl" v-on:document-change-url="changeDocumentUrl"
v-on:video-change-url="changeVideoUrl"> v-on:video-change-url="changeVideoUrl">
</component> </component>
<a class="new-content-block-wizard__remove" v-on:click="removeElement(index)"> <a class="content-block-form__remove" v-on:click="removeElement(index)">
<trash-icon v-if="type(element) !== 'content-block-element-chooser-widget'" <trash-icon v-if="type(element) !== 'content-block-element-chooser-widget'"
class="new-content-block-wizard__trash-icon"></trash-icon> class="content-block-form__trash-icon"></trash-icon>
</a> </a>
<add-content-element class="new-content-block-wizard__add" <add-content-element class="content-block-form__add"
v-on:add-element="addElement" v-on:add-element="addElement"
:index="index" :index="index"
></add-content-element> ></add-content-element>
</div> </div>
<div slot="footer"> <div slot="footer">
<a class="button" v-on:click="saveContentBlock">Speichern</a> <a class="button" v-on:click="save">Speichern</a>
<a class="button" v-on:click="hideModal">Abbrechen</a> <a class="button" v-on:click="$emit('hide')">Abbrechen</a>
</div> </div>
</modal> </modal>
</template> </template>
@ -49,9 +50,9 @@
import TextForm from '@/components/content-forms/TextForm'; import TextForm from '@/components/content-forms/TextForm';
import TrashIcon from '@/components/icons/TrashIcon'; import TrashIcon from '@/components/icons/TrashIcon';
import NEW_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/addContentBlock.gql';
export default { export default {
props: ['content-block'],
components: { components: {
Modal, Modal,
ContentBlockElementChooserWidget, ContentBlockElementChooserWidget,
@ -66,6 +67,13 @@
TrashIcon TrashIcon
}, },
data() {
return {
error: false,
localContentBlock: Object.assign({}, this.contentBlock)
}
},
methods: { methods: {
type(element) { type(element) {
switch (element.type) { switch (element.type) {
@ -85,8 +93,8 @@
return 'content-block-element-chooser-widget' return 'content-block-element-chooser-widget'
}, },
_updateProperty(value, index, key) { _updateProperty(value, index, key) {
this.elements.splice(index, 1, { this.localContentBlock.elements.splice(index, 1, {
...this.elements[index], ...this.localContentBlock.elements[index],
[key]: value [key]: value
}); });
}, },
@ -94,6 +102,7 @@
this._updateProperty(value, index, 'url') this._updateProperty(value, index, 'url')
}, },
changeLinkText(value, index) { changeLinkText(value, index) {
// debugger;
this._updateProperty(value, index, 'text') this._updateProperty(value, index, 'text')
}, },
changeVideoUrl(value, index) { changeVideoUrl(value, index) {
@ -106,13 +115,13 @@
this._updateProperty(value, index, 'text') this._updateProperty(value, index, 'text')
}, },
removeElement(index) { removeElement(index) {
this.elements.splice(index, 1); this.localContentBlock.elements.splice(index, 1);
}, },
addElement(index) { addElement(index) {
this.elements.splice(index + 1, 0, {}) this.localContentBlock.elements.splice(index + 1, 0, {})
}, },
updateTitle(title) { updateTitle(title) {
this.title = title; this.localContentBlock.title = title;
this.error = false; this.error = false;
}, },
changeType(index, type) { changeType(index, type) {
@ -147,55 +156,14 @@
break; break;
} }
this.elements.splice(index, 1, el); this.localContentBlock.elements.splice(index, 1, el);
}, },
hideModal() { save() {
this.$store.dispatch('resetContentBlock'); if (!this.localContentBlock.title) {
this.$store.dispatch('hideModal');
},
saveContentBlock() {
if (!this.title) {
this.error = true; this.error = true;
return false; return false;
} }
this.$apollo.mutate({ this.$emit('save', this.localContentBlock);
mutation: NEW_CONTENT_BLOCK_MUTATION,
variables: {
input: {
contentBlock: {
title: this.title,
contents: this.elements.filter(value => Object.keys(value).length > 0)
},
after: this.$store.state.contentBlockPosition.after,
parent: this.$store.state.contentBlockPosition.parent
}
},
update: () => {
this.$store.dispatch('updateContentBlocks');
this.hideModal();
}
});
}
},
data() {
return {
title: '',
elements: [
{}
// {
// type: 'image'
// },
// {
// type: 'video',
// url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
// },
// {
// type: 'video',
// url: 'https://vimeo.com/267384185'
// }
],
error: false
} }
} }
} }
@ -204,7 +172,7 @@
<style scoped lang="scss"> <style scoped lang="scss">
@import "@/styles/_variables.scss"; @import "@/styles/_variables.scss";
.new-content-block-wizard { .content-block-form {
/* top level does not exist, because of the modal */ /* top level does not exist, because of the modal */
&__element { &__element {

View File

@ -0,0 +1,63 @@
<template>
<content-block-form
:content-block="contentBlock"
@save="saveContentBlock"
@hide="hideModal"
></content-block-form>
</template>
<script>
import ContentBlockForm from '@/components/content-block-form/ContentBlockForm';
import store from '@/store/index';
import NEW_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/addContentBlock.gql';
import MODULE_DETAILS_QUERY from '@/graphql/gql/moduleDetailsQuery.gql';
export default {
components: {
ContentBlockForm
},
methods: {
hideModal() {
this.$store.dispatch('resetContentBlock');
this.$store.dispatch('hideModal');
},
saveContentBlock(contentBlock) {
this.$apollo.mutate({
mutation: NEW_CONTENT_BLOCK_MUTATION,
variables: {
input: {
contentBlock: {
title: contentBlock.title,
contents: contentBlock.elements.filter(value => Object.keys(value).length > 0)
},
after: this.$store.state.contentBlockPosition.after,
parent: this.$store.state.contentBlockPosition.parent
}
},
refetchQueries: [{
query: MODULE_DETAILS_QUERY,
variables: {
slug: store.state.moduleSlug
}
}]
}).then(() => {
this.hideModal();
});
}
},
data() {
return {
contentBlock: {
title: '',
elements: [
{}
]
}
}
}
}
</script>