355 lines
11 KiB
Vue
355 lines
11 KiB
Vue
<template>
|
|
<div>
|
|
<div :class="component_mode ? 'position-relative' : 'card mb-2'">
|
|
<div :class="component_mode ? '' : 'card-header '" class="d-flex justify-content-between">
|
|
<h5 class="d-flex align-items-center" v-if="!component_mode">
|
|
{{ name }}
|
|
<div v-if="loading" class="spinner-border spinner-border-sm ml-2" role="status">
|
|
<span class="sr-only">Loading...</span>
|
|
</div>
|
|
</h5>
|
|
<div class="card-header-end">
|
|
<a class=" fs-4 text-dark me-3" @click.prevent="openJSONModal" v-if="showSettings">
|
|
<i class="bi bi-filetype-json"></i>
|
|
</a>
|
|
|
|
<a class=" fs-4 text-dark" @click.prevent="editMode = !editMode" v-if="showSettings">
|
|
<i v-if="editMode" class="bi bi-binoculars"></i>
|
|
<i v-else class="bi bi-pencil-square"></i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<a
|
|
v-if="component_mode"
|
|
href="#"
|
|
@click.prevent="alertClick"
|
|
class="position-absolute"
|
|
style="top: 10px; right: 10px; z-index: 100"
|
|
><span class="material-icons-outlined">settings</span></a
|
|
>
|
|
</div>
|
|
<!-- <div v-if="!component_mode" class="p-2 alert alert-warning" @click="alertClick">
|
|
panel.sections_info
|
|
</div> -->
|
|
|
|
<div class="row">
|
|
<div v-if="editMode" class="col-lg-2 section-elements-div">
|
|
<div class="card section-elements">
|
|
<div class="card-header">
|
|
<h5>Elementy</h5>
|
|
</div>
|
|
<draggable
|
|
class="components_list"
|
|
:list="available_components"
|
|
:group="{ name: 'people', pull: 'clone', put: false, revertClone: true }"
|
|
:clone="clone"
|
|
:item-key="type"
|
|
>
|
|
<template #item="element">
|
|
<div class="d-flex align-items-center py-1 border-bottom p-3">
|
|
<span class="d-inline-flex box-settings-icon box-settings text-secondary"
|
|
><i class="text-primary bi bi-plus"></i></span
|
|
><span class="ml-4">{{ element.element.name }}</span>
|
|
</div>
|
|
</template>
|
|
</draggable>
|
|
</div>
|
|
</div>
|
|
<div :class="editMode ? 'col-lg-10' : 'col-lg-12'">
|
|
<draggable v-model="fields.sections" handle=".handle">
|
|
<template #item="{ element: field, index }">
|
|
<div>
|
|
<div class="row section_header">
|
|
<div class="col-lg-6">
|
|
<h3>
|
|
Sekcja
|
|
{{ index + 1 }} {{ field.label != '' ? '- ' + field.label : '' }}
|
|
</h3>
|
|
<small v-html="field.description"></small>
|
|
</div>
|
|
<div class="col-lg-6 text-end">
|
|
<button v-if="editMode" class="btn btn-icon-sm btn-outline-secondary handle me-2">
|
|
<i class="bi bi-grip-horizontal"></i>
|
|
</button>
|
|
<button
|
|
v-if="editMode"
|
|
@click="deleteSection(index)"
|
|
class="btn btn-icon-sm btn-outline-secondary me-2"
|
|
>
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
<button
|
|
v-if="editMode"
|
|
@click="editSection(field)"
|
|
class="btn btn-icon-sm btn-outline-secondary"
|
|
>
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div v-for="(row, row_index) in field.rows" :key="row_index" class="col-sm-12 p-0">
|
|
<div
|
|
:class="editMode ? 'pe-5' : ''"
|
|
class="row mb-1 position-relative pb_outer_section pb-3"
|
|
>
|
|
<section-row
|
|
class="col-12"
|
|
:edit-mode="editMode"
|
|
:section_index="index"
|
|
:mykey="row_index"
|
|
:section="row"
|
|
@input="update"
|
|
>
|
|
</section-row>
|
|
<div
|
|
v-if="editMode"
|
|
class="pb_section_options position-absolute"
|
|
style="top: 12px; right: 14px; width: 20px"
|
|
>
|
|
<button @click="deleteRow(field, row_index)" class="btn btn-icon-sm float-end">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<SectionGridChoose
|
|
v-if="addSectionGrid && activeAddedSection == field"
|
|
@input="addRowClick"
|
|
></SectionGridChoose>
|
|
<div class="mb-2 text-center">
|
|
<button
|
|
v-if="editMode"
|
|
@click="addRowButton(field)"
|
|
class="btn btn-outline-primary"
|
|
>
|
|
Dodaj wiersz
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</draggable>
|
|
<div class="col-sm-12 w-100 p-3 text-center" style="">
|
|
<button v-if="editMode" @click="addSectionButton()" class="btn btn-outline-primary w-100">
|
|
Dodaj sekcję
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<MagicoModal
|
|
scrollable
|
|
v-model="section_edit.modal"
|
|
title="Parametry sekcji"
|
|
class="MagicoModal-top"
|
|
>
|
|
<div class="p-4">
|
|
<label>Nazwa sekcji:</label>
|
|
<input class="form-control" type="text" v-model="section_edit.field.label" />
|
|
<label>Klucz sekcji:</label>
|
|
<input class="form-control" type="text" v-model="section_edit.field.key" />
|
|
<label>Klasa CSS:</label>
|
|
<input class="form-control" type="text" v-model="section_edit.field.css" />
|
|
<label>Opis HTML:</label>
|
|
<input class="form-control" type="text" v-model="section_edit.field.description" />
|
|
</div>
|
|
<div>
|
|
<div class="text-end p-4">
|
|
<button @click="section_edit.modal = false" class="btn btn-outline-secondary">
|
|
Anuluj
|
|
</button>
|
|
<button class="btn btn-primary" @click="editSectionSave">Zapisz</button>
|
|
</div>
|
|
</div>
|
|
</MagicoModal>
|
|
|
|
<MagicoModal
|
|
scrollable
|
|
v-model="jsonModal"
|
|
title="Dane w JSON"
|
|
class_other="modal-lg"
|
|
hide-footer
|
|
class="MagicoModal-top"
|
|
>
|
|
<div class="p-3">
|
|
<textarea class="form-control" rows="30" v-model="schemaJSONText"></textarea>
|
|
<div class="text-center mt-3">
|
|
<button class="btn btn-danger" @click="loadFromTextarea">Załaduj JSONa</button>
|
|
</div>
|
|
</div>
|
|
</MagicoModal>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import SectionGridChoose from './SectionGridChoose.vue'
|
|
import MagicoModal from './MagicoModal.vue'
|
|
import { ELEMENTS } from './data'
|
|
import { randId } from './helper'
|
|
import draggable from 'vuedraggable'
|
|
import SectionRow from './SectionRow.vue'
|
|
export default {
|
|
components: { SectionGridChoose, MagicoModal, draggable, SectionRow },
|
|
name: 'MagicoSection',
|
|
props: ['modelValue'],
|
|
data() {
|
|
return {
|
|
val: '',
|
|
section_id: 0,
|
|
loading: false,
|
|
editMode: true,
|
|
showSettings: true,
|
|
jsonModal: false,
|
|
schemaJSONText: '',
|
|
component_mode: false,
|
|
item: {},
|
|
items: {
|
|
item: {}
|
|
},
|
|
name: '',
|
|
addSectionGrid: false,
|
|
fields: {
|
|
sections: []
|
|
},
|
|
languageBtn: true,
|
|
activeAddedSection: {},
|
|
available_components: ELEMENTS,
|
|
sections: [],
|
|
next_group: 0,
|
|
groups: [],
|
|
komponenty: false,
|
|
section_edit: {
|
|
modal: false,
|
|
field: {}
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
alertClick: function (e) {
|
|
if (e.ctrlKey) {
|
|
this.showSettings = !this.showSettings
|
|
}
|
|
},
|
|
openJSONModal: function () {
|
|
this.jsonModal = true
|
|
this.schemaJSONText = JSON.stringify(this.fields)
|
|
},
|
|
loadFromTextarea: function () {
|
|
let json = null
|
|
try {
|
|
json = JSON.parse(this.schemaJSONText)
|
|
} catch (e) {
|
|
json = null
|
|
}
|
|
if (json) {
|
|
this.fields = json
|
|
alert('success', 'Super udało się')
|
|
this.jsonModal = false
|
|
} else {
|
|
alert('danger', 'Wystąpił błąd czy to poprawny format JSON?')
|
|
}
|
|
},
|
|
|
|
addRowClick: function (ev) {
|
|
let objCopy = Object.assign({}, ev)
|
|
|
|
objCopy.group = 'sekcja' + this.next_group
|
|
this.addSectionGrid = false
|
|
if (this.fields == null) this.fields = []
|
|
let newIt = JSON.parse(JSON.stringify(objCopy))
|
|
newIt.columns.forEach((item) => {
|
|
item.key = randId('column_')
|
|
})
|
|
this.activeAddedSection.rows.push(newIt)
|
|
this.next_group++
|
|
this.update()
|
|
},
|
|
addRowButton: function (section) {
|
|
this.addSectionGrid = true
|
|
this.activeAddedSection = section
|
|
},
|
|
addSectionButton: function () {
|
|
this.fields.sections.push({
|
|
rows: [],
|
|
label: '',
|
|
css: '',
|
|
key: ''
|
|
})
|
|
this.update()
|
|
},
|
|
deleteRow(field, index) {
|
|
field.rows.splice(index, 1)
|
|
},
|
|
loadScheme: function () {
|
|
if (this.val) {
|
|
this.fields = this.val
|
|
return
|
|
}
|
|
},
|
|
update: function () {
|
|
this.$emit('update:modelValue', this.fields)
|
|
},
|
|
toggleOpen(event, group_item) {
|
|
event.stopPropagation()
|
|
|
|
if (group_item.open) {
|
|
group_item.open = false
|
|
} else {
|
|
group_item.open = true
|
|
}
|
|
},
|
|
dragEvent: function (el) {
|
|
console.log(el)
|
|
},
|
|
deleteSection: function (key) {
|
|
this.fields.sections.splice(key, 1)
|
|
},
|
|
editSection: function (field) {
|
|
this.section_edit.field = field
|
|
this.section_edit.modal = true
|
|
},
|
|
editSectionSave: function () {
|
|
this.section_edit.modal = false
|
|
this.update()
|
|
},
|
|
clone: function (orignal) {
|
|
return JSON.parse(JSON.stringify(orignal))
|
|
}
|
|
},
|
|
created() {
|
|
this.val = this.modelValue
|
|
},
|
|
mounted() {
|
|
window.addEventListener('scroll', function () {
|
|
var scroll = window.pageYOffset || document.documentElement.scrollTop
|
|
var elements = document.querySelectorAll('.section-elements')
|
|
elements.forEach(function (element) {
|
|
element.style.top = scroll + 'px'
|
|
})
|
|
})
|
|
}
|
|
}
|
|
</script>
|
|
<style>
|
|
.components_list {
|
|
padding: 10px 20px;
|
|
}
|
|
|
|
.components_list_item {
|
|
padding: 0px 5px;
|
|
}
|
|
|
|
.section_header {
|
|
background-color: white;
|
|
padding: 5px;
|
|
border-radius: 5px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.section-elements-div {
|
|
position: relative;
|
|
}
|
|
|
|
.section-elements {
|
|
position: relative;
|
|
top: 0px;
|
|
}
|
|
</style>
|