Files
MagicoPagebuilder/src/components/MagicoPagebuilder.vue
2024-07-01 12:23:03 +02:00

377 lines
9.8 KiB
Vue

<template>
<section
:class="{ 'pagebuilder-fullscreen': fullscreen }"
class="content card-body p-3"
id="pagebuilder"
>
<div class="pagebuilder-body">
<div class="d-flex justify-content-between">
<button
@click.prevent="fullscreen = !fullscreen"
title="Tryb pełnoekranowy"
class="btn btn-outline-primary btn-icon-sm"
>
<span class="material-icons-outlined">fullscreen</span>
</button>
<div>
<div class="dropdown">
<button
class="btn btn-outline-secondary dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Szablony
</button>
<ul class="dropdown-menu">
<li>
<a
@click.prevent="
modalLoad = !modalLoad;
pageType = { name: null }
"
class="dropdown-item"
href="#"
>Wczytaj szablon</a
>
</li>
<li>
<a
@click.prevent="
modalSave = !modalSave;
pageType = { name: null }
"
class="dropdown-item"
href="#"
>Zapisz jako szablon</a
>
</li>
<li v-if="descriptionAllegro">
<a
@click.prevent="
pasteAllegro
"
class="dropdown-item"
href="#"
>Wklej opis <i>Allegro</i></a
>
</li>
</ul>
</div>
</div>
<!-- <button v-if="showcopy" class="btn btn-outline-secondary mr-1" @click.prevent="modalCopy = !modalCopy;">Kopiuj
układ z innej strony</button> -->
</div>
<draggable
:options="{ handle: '.box-move' }"
v-model.value="comps"
@start="drag = true"
item-key="d"
@end="
drag = false;
onChange()
"
>
<template #item="{ element, index }">
<PagebuilderSection
:value="element"
:key="'g' + index"
:id="'g' + index"
:keyIndex="'g' + index"
v-on:deleteSection="deleteSection"
v-on:copy="copySection"
@change="onChange"
>
</PagebuilderSection>
</template>
</draggable>
<b-modal
v-model.value="modalSave"
title="Zapisz szablon do schowka"
v-on:onClose="modalSave = false"
>
<PagebuilderTemplateSave v-model.value="pageType" :szablon="value">
</PagebuilderTemplateSave>
<div>
<button
@click.prevent="modalSaveSave"
title="Zapisz do schowka"
class="btn btn-success mr-1"
:disabled="!pageType.name"
>
Zapisz do schowka
</button>
</div>
</b-modal>
<b-modal
v-model.value="modalLoad"
title="Wczytaj szablon ze schowka"
v-on:onClose="modalLoad = false"
>
<div>
<PagebuilderTemplateLoad
v-model="pageType"
v-if="modalLoad"
@update:modelValue="modalLoadClick"
></PagebuilderTemplateLoad>
</div>
</b-modal>
<b-modal v-model.value="modalCopy" v-on:onClose="modalCopy = false">
<PagebuilderTemplateLoad v-model="pageType"></PagebuilderTemplateLoad>
<div>
<button class="btn btn-primary mr-1" :disabled="!pageType.id" @click.prevent="changeBody">
Skopiuj układ i treść
</button>
</div>
</b-modal>
<b-modal
class_other="modal-xl"
v-model.value="modalAddSection"
title=" Dodaj sekcję"
v-on:onClose="modalAddSection = false"
hide-footer
>
<div>
<DropdownSectionGrid @choose="addSection"> </DropdownSectionGrid>
</div>
<div></div>
</b-modal>
<div class="text-center">
<!-- <textarea style="display:none" :name="namex">{{ comps }}</textarea> --><button
class="btn btn-block btn-primary mt-4"
@click.prevent="
modalAddSection = !modalAddSection;
optionx = false
"
>
Dodaj sekcję
</button>
</div>
</div>
</section>
</template>
<script>
import draggable from 'vuedraggable'
import grid from './grid.js'
import MagicoModal from './MagicoModal.vue'
import PagebuilderSection from './PagebuilderSection.vue'
import DropdownSectionGrid from './DropdownSectionGrid.vue'
import PagebuilderTemplateSave from './PagebuilderTemplateSave.vue'
import PagebuilderTemplateLoad from './PagebuilderTemplateLoad.vue'
export default {
name: 'MagicoPagebuilder',
emits: ['update:modelValue'],
components: {
'b-modal': MagicoModal,
PagebuilderSection,
draggable,
DropdownSectionGrid,
PagebuilderTemplateSave,
PagebuilderTemplateLoad
},
data: function () {
return {
fullscreen: false,
grid: grid,
namex: 'body', //podmieniane przez name
drag: false,
optionx: '',
comps: [],
modalAddSection: false,
modalCopy: false,
pageType: { id: false },
modalSave: false,
modalLoad: false
}
},
props: ['name', 'modelValue', 'showcopy', 'lang'],
mounted: function () {
//var trimmed = $("#body_pagebuilder").val().replace((/ |\r\n|\n|\r/gm),"");
var trimmed = this.modelValue //.replace((/{2} |\r\n|\n|\r/gm), "");
try {
this.comps = JSON.parse(trimmed)
} catch (e) {
console.warn(e)
this.comps = [
{
label: '1 kolumna ',
name: 'col_1',
columns: [{ name: 'col-md-12', items: [{ name: 'core_section_textarea' }] }]
}
]
}
},
computed: {
descriptionAllegro: function(){
return localStorage.getItem('description_clipboard')
}
},
created: function () {
if (this.name) this.namex = this.name
else this.namxe = 'body'
},
watch: {
// whenever question changes, this function will run
comps: function (newQuestion) {
console.log('nq', newQuestion)
}
},
methods: {
onChange: function () {
this.$emit('update:modelValue', JSON.stringify(this.comps))
this.$emit('change')
},
copySection: function (item) {
this.comps.push(JSON.parse(JSON.stringify(item)))
this.onChange()
},
deleteSection: function (item) {
this.comps.splice(this.comps.indexOf(item), 1)
this.onChange()
},
addSection: function (it) {
this.modalAddSection = false
this.comps.push(JSON.parse(JSON.stringify(it)))
this.onChange()
},
modalSaveSave: function () {
console.log(this.pageType)
var data = {
id: this.pageType.id,
name: this.pageType.name,
source: this.modelValue,
description: this.pageType.description
}
if (this.$pagebuilder.axios) {
this.$pagebuilder.axios.post('api/v1/pagebuilder/template', data).then(() => {
this.pageType = {}
this.modalSave = false
})
} else {
console.error('NO AXIOS INSTACE PROVIDED TO PAGEBUILDER')
}
},
modalLoadClick: function () {
this.pageType.body = this.pageType.source
this.changeBody()
},
pasteAllegro: function(){
let sections = this.descriptionAllegro;
try {
sections = JSON.parse(sections);
} catch (e) {
if (e instanceof SyntaxError) {
sections = [{ name: 'Tekst', cols: [{ type: 'text', value: sections, size: 12 }] }];
}
}
const pagebuilder = sections.map(item => {
const columns = [];
if (item.cols && Array.isArray(item.cols)) {
item.cols.forEach(col => {
const column = {
name: 'col-md-' + col.size,
items: [
{
name: (col.type === 'img' ? 'core_section_image' : 'core_section_textarea'),
text: col.value,
}
]
};
if (col.type === 'img' && col.figcaption) {
column.items[0]['figcaption'] = col.figcaption;
}
columns.push(column);
});
}
return { columns };
});
return this.comps = pagebuilder;
},
changeBody() {
var t = this
var value = this.pageType.body
var trimmed = value
try {
//this.comps.forEach((item)=>{
// this.deleteSection(item);
//})
this.comps = []
setTimeout(function () {
t.comps = JSON.parse(trimmed)
t.onChange()
}, 300)
//this.comps =JSON.parse(trimmed);
} catch (e) {
this.comps = [
{
label: '1 kolumna ',
name: 'col_1',
columns: [{ name: 'col-md-12', items: [{ name: 'core_section_textarea' }] }]
}
]
}
this.modalCopy = false
this.modalSave = false
this.modalLoad = false
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
#pagebuilder {
background-color: #f5f5f5;
}
.pagebuilder-fullscreen {
position: fixed;
top: 10px;
width: 80%;
left: 10%;
right: 10%;
min-height: 100vh;
z-index: 100;
overflow-y: auto;
}
.pagebuilder-fullscreen .pagebuilder-body {
overflow-x: hidden;
overflow-y: auto;
max-height: 95vh;
padding-right: 20px;
}
</style>