init
This commit is contained in:
346
src/components/MagicoSection.vue
Normal file
346
src/components/MagicoSection.vue
Normal file
@@ -0,0 +1,346 @@
|
||||
<template>
|
||||
<div>
|
||||
<div :class="component_mode ? 'position-relative' : 'card mb-2'">
|
||||
<div :class="component_mode ? '' : 'card-header'">
|
||||
<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">
|
||||
<button class="btn btn-outline-danger" @click="openJSONModal" v-if="showSettings">
|
||||
Pokaż JSONa
|
||||
</button>
|
||||
|
||||
<button class="btn btn-outline-danger" @click="editMode = !editMode" v-if="showSettings">
|
||||
{{ editMode ? 'Zmień na tryb edycji treści' : 'Zmień na tryb edycji struktury' }}
|
||||
</button>
|
||||
</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 }"
|
||||
>
|
||||
<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-pen"></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 ? 'pr-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"
|
||||
>
|
||||
</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"
|
||||
size="lg"
|
||||
hide-footer
|
||||
class="MagicoModal-top"
|
||||
>
|
||||
<div>
|
||||
<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: false,
|
||||
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.schamaSave()
|
||||
},
|
||||
addRowButton: function (section) {
|
||||
this.addSectionGrid = true
|
||||
this.activeAddedSection = section
|
||||
},
|
||||
addSectionButton: function () {
|
||||
this.fields.sections.push({
|
||||
rows: [],
|
||||
label: '',
|
||||
css: '',
|
||||
key: ''
|
||||
})
|
||||
},
|
||||
deleteRow(field, index) {
|
||||
field.rows.splice(index, 1)
|
||||
},
|
||||
loadScheme: function () {
|
||||
if (this.val) {
|
||||
this.fields = this.val
|
||||
return
|
||||
}
|
||||
},
|
||||
schamaSave: function () {
|
||||
this.$emit('input', 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.schamaSave()
|
||||
}
|
||||
},
|
||||
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>
|
||||
Reference in New Issue
Block a user