use Bootstrap modals

This commit is contained in:
cgfhtw
2022-10-24 15:44:12 +02:00
parent 4aa7b9854a
commit a3722273e9
4 changed files with 127 additions and 101 deletions
+32 -65
View File
@@ -1,4 +1,5 @@
import DashboardSection from "./Section.js";
import DashboardWidgetPicker from "./Widget/Picker.js";
import CachedWidgetLoader from "../../composables/Dashboard/CachedWidgetLoader.js";
import ObjectUtils from "../../composables/ObjectUtils.js";
@@ -9,21 +10,15 @@ export default {
],
data: () => ({
sections: [],
widgets: [],
isLoading: 0,
tmpCreate: null,
widgets: null
}),
components: {
DashboardSection
},
computed: {
listReady() {
return this.widgets.length && !this.isLoading;
}
DashboardSection,
DashboardWidgetPicker
},
methods: {
widgetAdd(section_name, widget) {
if (!this.widgets.length) {
if (this.widgets === null) {
axios.get(this.apiurl + '/Widget/getWidgetsForDashboard', {params:{
db: this.dashboard
}}).then(res => {
@@ -35,34 +30,32 @@ export default {
this.widgets = res.data.retval;
}).catch(err => console.error('ERROR:', err));
}
this.tmpCreate = {section_name,widget};
this.listModal.show();
},
widgetCreate(widget) {
this.isLoading = 1;
this.tmpCreate.widget.widget = widget;
axios.post(this.apiurl + '/Config/addWidgetsToUserOverride', {
db: this.dashboard,
funktion_kurzbz: this.tmpCreate.section_name,
widgets: [this.tmpCreate.widget]
}).then(result => {
let newId = 0;
let sec = result.data.retval.data.widgets[this.tmpCreate.section_name];
for (var i in sec) {
newId = i;
break;
}
this.tmpCreate.widget.id = newId;
this.$refs.widgetpicker.getWidget().then(widget_id => {
widget.widget = widget_id;
let loading = {...widget};
loading.loading = true;
this.sections.forEach(section => {
if (section.name == this.tmpCreate.section_name)
section.widgets.push(this.tmpCreate.widget);
if (section.name == section_name)
section.widgets.push(loading);
});
axios.post(this.apiurl + '/Config/addWidgetsToUserOverride', {
db: this.dashboard,
funktion_kurzbz: section_name,
widgets: [widget]
}).then(result => {
let newId = Object.keys(result.data.retval.data.widgets[section_name]).pop();
widget.id = newId;
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.splice(section.widgets.indexOf(loading),1);
section.widgets.push(widget);
}
});
}).catch(error => {
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
});
}).catch(error => {
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
}).finally(() => {
this.listModal.hide();
this.isLoading = 0;
});
},
widgetUpdate(section_name, payload) {
@@ -89,7 +82,7 @@ export default {
db: this.dashboard,
funktion_kurzbz: section_name,
widgets: payload
}).then(result => {
}).then(() => {
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.forEach((widget, i) => {
@@ -112,7 +105,7 @@ export default {
db: this.dashboard,
funktion_kurzbz: section_name,
widgetid: id
}).then(result => {
}).then(() => {
this.sections.forEach(section => {
if (section.name == section_name)
section.widgets = section.widgets.filter(widget => widget.id != id);
@@ -142,34 +135,8 @@ export default {
}
}).catch(err => console.error('ERROR:', err));
},
mounted() {
this.listModal = new bootstrap.Modal(this.$refs.widgetlist);
},
template: `<div class="core-dashboard">
<dashboard-section v-for="section in sections" :key="section.name" :name="section.name" :widgets="section.widgets" @widgetAdd="widgetAdd" @widgetUpdate="widgetUpdate" @widgetRemove="widgetRemove"></dashboard-section>
<div ref="widgetlist" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create new widget</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div v-if="listReady" class="row">
<div v-for="widget in widgets" :v-key="widget.widget_id" class="col">
<div class="card h-100" @click="widgetCreate(widget.widget_id)">
<img class="card-img-top" :src="widget.setup.icon" :alt="'pictogram for ' + (widget.setup.name || widget.widget_kurzbz)">
<div class="card-body">
<h5 class="card-title">{{ widget.setup.name || widget.widget_kurzbz }}</h5>
<p class="card-text">{{ widget.beschreibung }}</p>
</div>
</div>
</div>
</div>
<div v-else class="text-center"><i class="fa-solid fa-spinner fa-pulse fa-3x"></i></div>
</div>
</div>
</div>
</div>
<dashboard-widget-picker ref="widgetpicker" :widgets="widgets"></dashboard-widget-picker>
</div>`
}
+27 -27
View File
@@ -1,11 +1,13 @@
import BsModal from "../Bootstrap/Modal.js";
import CachedWidgetLoader from "../../composables/Dashboard/CachedWidgetLoader.js";
export default {
components: {},
components: {
BsModal
},
data: () => ({
component: '',
arguments: null,
configModal: null,
target: false,
widget: null,
tmpConfig: {},
@@ -25,7 +27,8 @@ export default {
"height",
"custom",
"hidden",
"editMode"
"editMode",
"loading"
],
computed: {
isResizeable() {
@@ -55,7 +58,7 @@ export default {
},
openConfig() {
this.tmpConfig = {...this.arguments};
this.configModal.show();
this.$refs.config.show();
},
setConfig(hasConfig) {
this.hasConfig = hasConfig;
@@ -82,7 +85,7 @@ export default {
config() {
this.arguments = {...this.widget.arguments, ...this.config};
this.tmpConfig = {...this.arguments};
this.configModal.hide();
this.$refs.config.hide();
this.isLoading = false;
}
},
@@ -94,10 +97,12 @@ export default {
this.arguments = {...this.widget.arguments, ...this.config};
this.tmpConfig = {...this.arguments};
},
mounted() {
this.configModal = new bootstrap.Modal(this.$refs.config);
},
template: `<div v-if="!hidden || editMode" :class="'dashboard-item card overflow-hidden ' + (arguments ? arguments.className : '')" @mousedown="mouseDown($event)" @dragstart="startDrag($event)" :draggable="!!editMode">
template: `<div v-if="loading">
<div class="d-flex justify-content-center align-items-center h-100">
<i class="fa-solid fa-spinner fa-pulse fa-3x"></i>
</div>
</div>
<div v-else-if="!hidden || editMode" :class="'dashboard-item card overflow-hidden ' + (arguments ? arguments.className : '')" @mousedown="mouseDown($event)" @dragstart="startDrag($event)" :draggable="!!editMode">
<div v-if="editMode && widget" class="card-header d-flex">
<span ref="dragHandle" class="col-auto pe-3"><i class="fa-solid fa-grip-vertical"></i></span>
<span class="col">{{ widget.setup.name }}</span>
@@ -113,24 +118,19 @@ export default {
<component :is="component" :config="arguments" :width="width" :height="height" @setConfig="setConfig" @change="changeConfigManually"></component>
</div>
<div v-else class="card-body overflow-hidden text-center d-flex flex-column justify-content-center"><i class="fa-solid fa-spinner fa-pulse fa-3x"></i></div>
<div ref="config" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 v-if="widget" class="modal-title">Config for {{ widget.setup.name }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<component v-if="ready && !isLoading" :is="component" :config="tmpConfig" @change="changeConfig" :configMode="true"></component>
<div v-else class="text-center"><i class="fa-solid fa-spinner fa-pulse fa-3x"></i></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" @click="changeConfig">Save changes</button>
</div>
</div>
</div>
</div>
<bs-modal ref="config">
<template v-slot:title>
{{ widget ? 'Config for ' + widget.setup.name : '' }}
</template>
<template v-slot:default>
<component v-if="ready && !isLoading" :is="component" :config="tmpConfig" @change="changeConfig" :configMode="true"></component>
<div v-else class="text-center"><i class="fa-solid fa-spinner fa-pulse fa-3x"></i></div>
</template>
<template v-slot:footer>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" @click="changeConfig">Save changes</button>
</template>
</bs-modal>
<div v-if="editMode && isResizeable" class="card-footer d-flex justify-content-end p-0">
<span ref="resizeHandle" class="col-auto ps-1" @dragstart.prevent="$emit('resize')"><i class="fa-solid fa-up-right-and-down-left-from-center"></i></span>
</div>
+14 -9
View File
@@ -1,3 +1,4 @@
import BsConfirm from "../Bootstrap/Confirm.js";
import DashboardItem from "./Item.js";
import CachedWidgetLoader from "../../composables/Dashboard/CachedWidgetLoader.js";
@@ -14,6 +15,7 @@ export default {
dataTransfer: {}
}),
props: [
"adminMode",
"name",
"widgets"
],
@@ -66,9 +68,9 @@ export default {
let h = item._h !== undefined ? item._h : itemCoords[item.index].h;
for (var c = 0; c < occupiers.length + gridWidth; c++) {
if (occupiers[c] === undefined) {
var occupied = false;
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
var occupied = false, i, j;
for (i = 0; i < w; i++) {
for (j = 0; j < h; j++) {
if (occupiers[c + i + j * gridWidth] !== undefined) {
i = w;
occupied = true;
@@ -79,8 +81,8 @@ export default {
if (!occupied) {
item.place[gridWidth].x = c%gridWidth + 1;
item.place[gridWidth].y = Math.floor(c/gridWidth) + 1;
for (var i = 0; i < w; i++) {
for (var j = 0; j < h; j++) {
for (i = 0; i < w; i++) {
for (j = 0; j < h; j++) {
occupiers[c + i + j * gridWidth] = item.index;
}
}
@@ -295,7 +297,7 @@ export default {
this.itemCoords[id].h = h;
}
},
onDrop(evt) {
onDrop() {
let id = 0;
let update = {};
while ((id = this.movedObjects.pop())) {
@@ -346,9 +348,7 @@ export default {
},
removeWidget(item, revert) {
if (item.custom) {
if (confirm('Are you sure you want to delete this widget?')) {
this.$emit('widgetRemove', this.name, item.id);
}
BsConfirm.popup('Are you sure you want to delete this widget?').then(() => this.$emit('widgetRemove', this.name, item.id));
} else {
let update = {};
update[item.id] = { hidden: !revert };
@@ -366,6 +366,10 @@ export default {
this.$emit('widgetUpdate', this.name, payload);
}
},
created() {
if (this.adminMode)
this.editMode = 1;
},
mounted() {
let self = this;
let cont = self.$refs.container;
@@ -401,6 +405,7 @@ export default {
v-for="item in items"
:key="item.id"
:id="item.widget"
:loading="item.loading"
:config="item.config"
:custom="item.custom"
:hidden="item.hidden"
@@ -0,0 +1,54 @@
import BsModal from "../../Bootstrap/Modal.js";
export default {
components: {
BsModal
},
props: [
"widgets"
],
data: () => ({
callbacks: {}
}),
methods: {
getWidget() {
return new Promise((resolve,reject) => {
this.callbacks = {resolve,reject};
this.$refs.modal.show();
});
},
close() {
if (this.callbacks.reject)
this.callbacks.reject();
this.callbacks = {};
},
pick(widget_id) {
if (this.callbacks.resolve)
this.callbacks.resolve(widget_id);
this.callbacks = {};
this.$refs.modal.hide();
}
},
template: `<div class="dashboard-widget-picker">
<bs-modal ref="modal" class="fade" :dialog-class="{'modal-fullscreen-sm-down': 1, 'modal-dialog modal-xl': widgets && widgets.length > 5}" @hiddenBsModal="close">
<template v-slot:title>Create new widget</template>
<template v-slot:default>
<div v-if="widgets" class="row">
<div v-if="!widgets.length">
No Widgets available
</div>
<div v-for="widget in widgets" :key="widget.widget_id" class="col-sm-6 col-md-4 col-lg-3 col-xl-2">
<div class="card h-100" @click="pick(widget.widget_id)">
<img class="card-img-top" :src="widget.setup.icon" :alt="'pictogram for ' + (widget.setup.name || widget.widget_kurzbz)">
<div class="card-body">
<h5 class="card-title">{{ widget.setup.name || widget.widget_kurzbz }}</h5>
<p class="card-text">{{ widget.beschreibung }}</p>
</div>
</div>
</div>
</div>
<div v-else class="text-center"><i class="fa-solid fa-spinner fa-pulse fa-3x"></i></div>
</template>
</bs-modal>
</div>`
}