mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
use Bootstrap modals
This commit is contained in:
@@ -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>`
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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>`
|
||||
}
|
||||
Reference in New Issue
Block a user