mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
Removed Dashboard Testfiles
This commit is contained in:
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
*/
|
||||
class Test extends Auth_Controller
|
||||
{
|
||||
private $_uid; // uid of the logged user
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Set required permissions
|
||||
parent::__construct(
|
||||
array(
|
||||
'index' => 'user:r',
|
||||
)
|
||||
);
|
||||
|
||||
$this->load->library('AuthLib');
|
||||
$this->load->library('WidgetLib');
|
||||
|
||||
$this->_setAuthUID(); // sets property uid
|
||||
|
||||
$this->setControllerId(); // sets the controller id
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('test/Test.php', []);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
/**
|
||||
* Retrieve the UID of the logged user and checks if it is valid
|
||||
*/
|
||||
private function _setAuthUID()
|
||||
{
|
||||
$this->_uid = getAuthUID();
|
||||
|
||||
if (!$this->_uid) show_error('User authentification failed');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FH-Complete
|
||||
*
|
||||
* @package FHC-API
|
||||
* @author FHC-Team
|
||||
* @copyright Copyright (c) 2016, fhcomplete.org
|
||||
* @license GPLv3
|
||||
* @link http://fhcomplete.org
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Dashboard extends API_Controller
|
||||
{
|
||||
/**
|
||||
* Appdaten API constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'Widgets' => 'user:r'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function getWidgets()
|
||||
{
|
||||
$this->load->model('dashboard/Dashboard_model', 'DashboardModel');
|
||||
$result = $this->DashboardModel->loadWhere(['name'=>$this->get('dashboard')]);
|
||||
if (isError($result))
|
||||
return $this->response($result, REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
if (!hasData($result))
|
||||
return $this->response('No Dashboard with the name "' . $this->get('dashboard') . '" found.', REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
$dashboard_id = current(getData($result))->dashboard_id;
|
||||
|
||||
$this->load->model('dashboard/Dashboardwidget_model', 'DashboardwidgetModel');
|
||||
$result = $this->DashboardwidgetModel->loadWidgets($dashboard_id);
|
||||
if (isError($result))
|
||||
return $this->response($result, REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
if (!hasData($result))
|
||||
return $this->response('No Widgets for Dashboard "' . $this->get('dashboard') . '" found.', REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
$this->response(getData($result), REST_Controller::HTTP_OK);
|
||||
}
|
||||
|
||||
protected function _check_whitelist_auth() {}
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* FH-Complete
|
||||
*
|
||||
* @package FHC-API
|
||||
* @author FHC-Team
|
||||
* @copyright Copyright (c) 2016, fhcomplete.org
|
||||
* @license GPLv3
|
||||
* @link http://fhcomplete.org
|
||||
* @since Version 1.0
|
||||
* @filesource
|
||||
*/
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class User extends API_Controller
|
||||
{
|
||||
/**
|
||||
* Appdaten API constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'AuthObj' => 'user:r',
|
||||
'Widget' => 'user:r',
|
||||
'Widgets' => 'user:r'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function getAuthObj()
|
||||
{
|
||||
$result = $this->authlib->getAuthObj();
|
||||
|
||||
$this->response($result, REST_Controller::HTTP_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function getWidget()
|
||||
{
|
||||
$this->load->model('dashboard/Widget_model', 'WidgetModel');
|
||||
$result = $this->WidgetModel->load($this->get('widget_id'));
|
||||
if (isError($result))
|
||||
return $this->response($result, REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
if (!hasData($result))
|
||||
return $this->response('No Widget with the id "' . $this->get('widget_id') . '" found.', REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
$result = current(getData($result));
|
||||
|
||||
$this->response($result, REST_Controller::HTTP_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function getWidgets()
|
||||
{
|
||||
$this->load->model('dashboard/Dashboard_model', 'DashboardModel');
|
||||
$result = $this->DashboardModel->loadWhere(['name'=>$this->get('dashboard')]);
|
||||
if (isError($result))
|
||||
return $this->response($result, REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
if (!hasData($result))
|
||||
return $this->response('No Dashboard with the name "' . $this->get('dashboard') . '" found.', REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
$dashboard_id = current(getData($result))->dashboard_id;
|
||||
|
||||
$authObj = $this->authlib->getAuthObj();
|
||||
|
||||
$this->load->model('dashboard/Dashboardpreset_model', 'DashboardpresetModel');
|
||||
$result = $this->DashboardpresetModel->loadForUser($dashboard_id, $authObj->username);
|
||||
if (isError($result))
|
||||
return $this->response($result, REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
if (!hasData($result))
|
||||
return $this->response('No Dashboard for user "' . $authObj->username . '" found.', REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
$result = (current(getData($result))->config);
|
||||
$result = json_decode($result);
|
||||
if ($result === null)
|
||||
return $this->response(json_last_error_msg(), REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
|
||||
|
||||
$this->response($result, REST_Controller::HTTP_OK);
|
||||
}
|
||||
|
||||
protected function _check_whitelist_auth() {}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
class Dashboard_model extends DB_Model
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->dbTable = "( WITH vals (dashboard_id, name) AS (VALUES
|
||||
(0,'CIS'),
|
||||
(1,'PV21')
|
||||
) SELECT * FROM vals ) AS tbl_dashboard";
|
||||
$this->pk = 'dashboard_id';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
class Dashboardpreset_model extends DB_Model
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->dbTable = "( WITH vals (dashboard_preset_id, config) AS (VALUES
|
||||
(0,CONCAT('[[0',',','0',',','0',',','0',',','[]]',',','[1',',','2',',','2',',','2',',','{\"display\":2}]]')),
|
||||
(1,CONCAT('[[0',',','1',',','0',',','1',',','{}]',',','[1',',','0',',','1',',','0',',','{\"display\":1}]]'))
|
||||
) SELECT * FROM vals ) AS tbl_dashboard_preset";
|
||||
$this->pk = 'dashboard_preset_id';
|
||||
}
|
||||
|
||||
public function loadForUser($dashboard_id, $uid)
|
||||
{
|
||||
$this->addJoin("( WITH vals (dashboard_preset_user_id, uid, dashboard_id, dashboard_preset_id) AS (VALUES
|
||||
(0,'ma0168', 0, 0)
|
||||
) SELECT * FROM vals ) AS tbl_dashboard_preset_user", 'dashboard_preset_id');
|
||||
return $this->loadWhere(['uid' => $uid, 'dashboard_id' => $dashboard_id]);
|
||||
|
||||
return success();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
class Dashboardwidget_model extends DB_Model
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->dbTable = "( WITH vals (dashboard_widget_id, dashboard_id, widget_id) AS (VALUES
|
||||
(0,0,0),
|
||||
(1,0,1),
|
||||
(2,1,0)
|
||||
) SELECT * FROM vals ) AS tbl_dashboard_widget";
|
||||
$this->pk = 'dashboard_widget_id';
|
||||
}
|
||||
|
||||
public function loadWidgets($dashboard_id)
|
||||
{
|
||||
$this->addJoin("( WITH vals (widget_id, name, component_name, component_path, arguments) AS (VALUES
|
||||
(0,'KPI Single','DbwKpi','./DBW/KPI.js',CONCAT('{\"data\":[1]',',','\"display\":0}')),
|
||||
(1,'KPI Multi','DbwKpi','./DBW/KPI.js',CONCAT('{\"data\":[1,2,3]}'))
|
||||
) SELECT * FROM vals ) AS tbl_widget", 'widget_id');
|
||||
|
||||
return $this->loadWhere(['dashboard_id' => $dashboard_id]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
class Widget_model extends DB_Model
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->dbTable = "( WITH vals (widget_id, name, component_name, component_path, arguments) AS (VALUES
|
||||
(0,'KPI Single','DbwKpi','./DBW/KPI.js',CONCAT('{\"data\":[1]',',','\"display\":0}')),
|
||||
(1,'KPI Multi','DbwKpi','./DBW/KPI.js',CONCAT('{\"data\":[1,2,3]}'))
|
||||
) SELECT * FROM vals ) AS tbl_widget";
|
||||
$this->pk = 'widget_id';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
<?php
|
||||
$this->load->view('templates/FHC-Header',
|
||||
array(
|
||||
'title' => 'FH-Complete',
|
||||
'bootstrap5' => true,
|
||||
'fontawesome6' => true,
|
||||
'axios027' => true,
|
||||
'restclient' => true,
|
||||
'vue3' => true,
|
||||
'customJSModules' => ['public/js/apps/Test.js'],
|
||||
'navigationcomponent' => true
|
||||
)
|
||||
);
|
||||
?>
|
||||
|
||||
<style type="text/css">
|
||||
.fixed-h {
|
||||
padding-bottom: 100%;
|
||||
position: relative;
|
||||
height: 0;
|
||||
}
|
||||
.fixed-h > * {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.fixed-h-1 > * {
|
||||
height: 100%;
|
||||
}
|
||||
.fixed-h-2 > * {
|
||||
height: calc(200% + var(--bs-gutter-y));
|
||||
}
|
||||
|
||||
.core-dashboard .row {
|
||||
--bs-gutter-y: 1.5rem;
|
||||
}
|
||||
|
||||
.draganddropcontainer {
|
||||
grid-template-columns:repeat(4,1fr);
|
||||
}
|
||||
@media(max-width: 700px) {
|
||||
.draganddropcontainer {
|
||||
grid-template-columns:repeat(2,1fr);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<core-navigation-cmpt :add-side-menu-entries="appSideMenuEntries"></core-navigation-cmpt>
|
||||
|
||||
<div id="content">
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">Dashboard</h1>
|
||||
</div>
|
||||
|
||||
<core-dashboard dashboard="CIS"></core-dashboard>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php $this->load->view('templates/FHC-Footer'); ?>
|
||||
@@ -1,15 +0,0 @@
|
||||
import {CoreNavigationCmpt} from '../components/navigation/Navigation.js';
|
||||
import CoreDashboard from '../components/CoreDashboard.js';
|
||||
|
||||
Vue.createApp({
|
||||
data: () => ({
|
||||
appSideMenuEntries: {}
|
||||
}),
|
||||
components: {
|
||||
CoreNavigationCmpt,
|
||||
CoreDashboard/*,
|
||||
"CoreFilterCmpt": CoreFilterCmpt,
|
||||
"verticalsplit": verticalsplit,
|
||||
"searchbar": searchbar*/
|
||||
}
|
||||
}).mount('#main');
|
||||
@@ -1,206 +0,0 @@
|
||||
import CoreDashboardItem from './Dashboard/Item.js';
|
||||
import DragAndDrop from './Dashboard/DragAndDrop.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoreDashboardItem,
|
||||
DragAndDrop
|
||||
},
|
||||
data: () => ({
|
||||
widgetCache: {},
|
||||
componentCache: {},
|
||||
widgetWizard: null,
|
||||
allowedWidgets: [],
|
||||
widgets: [],
|
||||
name: '',
|
||||
newMode: false,
|
||||
editMode: false
|
||||
}),
|
||||
computed: {
|
||||
loaded: function() {
|
||||
return this.widgets && this.name;
|
||||
}
|
||||
},
|
||||
props: [
|
||||
"dashboard"
|
||||
],
|
||||
methods: {
|
||||
saveConfig() {
|
||||
// TODO(chris): SAVE!
|
||||
console.log('SAVE', this.widgets);
|
||||
this.editMode = false;
|
||||
},
|
||||
startWidgetWizard() {
|
||||
// TODO(chris): load widgets!
|
||||
let self = this;
|
||||
axios.get('/fhcomplete/index.ci.php/api/v1/dashboard/Dashboard/Widgets', {
|
||||
headers: {
|
||||
'FHC-API-KEY':'itservice@technikum-wien.at'
|
||||
},
|
||||
params: {
|
||||
dashboard: this.dashboard
|
||||
}
|
||||
}).then(function(result) {console.log(result);
|
||||
self.allowedWidgets = result.data;
|
||||
});
|
||||
this.widgetWizard.show();
|
||||
},
|
||||
newWidget(widget) {
|
||||
let self = this;
|
||||
let newWidget = [widget.widget_id, this.widgets.length, this.widgets.length, this.widgets.length, []];
|
||||
// TODO(chris): loadingscreen?
|
||||
(new Promise(function (resolve, reject) {
|
||||
if (self.widgetCache[widget.widget_id]) {
|
||||
resolve(self.widgetCache[widget.widget_id]);
|
||||
} else {
|
||||
this.extendWidgetAndCache(widget).then(widget => {
|
||||
resolve(widget);
|
||||
});
|
||||
}
|
||||
})).then(widget => {
|
||||
newWidget[5] = widget;
|
||||
self.widgets.push(newWidget);
|
||||
self.widgetWizard.hide();
|
||||
});
|
||||
},
|
||||
removeWidget(id) {
|
||||
if (confirm('Are you sure you want to delete this widget?'))
|
||||
this.widgets = this.widgets.filter(widget => widget[0] != id);
|
||||
},
|
||||
getWidget(widget_id) {
|
||||
let self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (self.widgetCache[widget_id])
|
||||
return resolve(self.widgetCache[widget_id]);
|
||||
axios.get('/fhcomplete/index.ci.php/api/v1/dashboard/User/Widget', {
|
||||
headers: {
|
||||
'FHC-API-KEY':'itservice@technikum-wien.at'
|
||||
},
|
||||
params: {
|
||||
widget_id: widget_id
|
||||
}
|
||||
})
|
||||
.then(result => self.extendWidgetAndCache(result.data))
|
||||
.then(widget => resolve(widget));
|
||||
});
|
||||
},
|
||||
extendWidgetAndCache(widget) {
|
||||
let self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
let name = widget.component_name;
|
||||
widget.arguments = JSON.parse(widget.arguments);
|
||||
widget.component_name = widget.component_name.replace(/[A-Z]/g, (m,o) => (o > 0 ? "-" : "") + m.toLowerCase());
|
||||
self.getComponent(name, widget.component_path).then(component => {
|
||||
widget.component = component;
|
||||
return widget;
|
||||
}).then(() => {
|
||||
self.widgetCache[widget.widget_id] = widget;
|
||||
resolve(self.widgetCache[widget.widget_id]);
|
||||
});
|
||||
});
|
||||
},
|
||||
getComponent(name, path) {
|
||||
let self = this;
|
||||
return new Promise(async function(resolve, reject) {
|
||||
if (self.componentCache[name])
|
||||
return resolve(self.componentCache[name]);
|
||||
|
||||
|
||||
self.componentCache[name] = (await import(path)).default;
|
||||
resolve(self.componentCache[name]);
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
this.widgetWizard = new bootstrap.Modal(this.$refs.widgetWizard);
|
||||
axios.get('/fhcomplete/index.ci.php/api/v1/dashboard/User/AuthObj', {
|
||||
headers: {
|
||||
'FHC-API-KEY':'itservice@technikum-wien.at'
|
||||
}
|
||||
}).then(function(result) {
|
||||
self.name = result.data.name;
|
||||
});
|
||||
axios.get('/fhcomplete/index.ci.php/api/v1/dashboard/User/Widgets', {
|
||||
headers: {
|
||||
'FHC-API-KEY':'itservice@technikum-wien.at'
|
||||
},
|
||||
params: {
|
||||
dashboard: this.dashboard
|
||||
}
|
||||
}).then(function(result) {
|
||||
let promises = [];
|
||||
result.data.forEach(function(item) {
|
||||
promises.push(new Promise(function(resolve, reject) {
|
||||
self.getWidget(item[0]).then(function(widget) {
|
||||
item[5] = widget;
|
||||
resolve();
|
||||
});
|
||||
}));
|
||||
});
|
||||
Promise.all(promises).then(function() {
|
||||
self.widgets = result.data;
|
||||
})
|
||||
});
|
||||
},
|
||||
template: `<div class="core-dashboard">
|
||||
<div style="width:500px">
|
||||
<drag-and-drop width="4" height="3" :items="[{id:0,c:'blue',x:1,y:1,w:1,h:1},{id:1,c:'red',x:2,y:1,w:1,h:2},{id:2,c:'green',x:1,y:3,w:2,h:1}]"></drag-and-drop>
|
||||
</div>
|
||||
<h3 v-if="loaded" class="d-flex">
|
||||
<span class="col">Hallo {{name}}!</span>
|
||||
|
||||
<!--div class="dropstart">
|
||||
<button type="button" class="btn btn-secondary" data-bs-display="static" data-bs-auto-close="outside" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fa-solid fa-gear"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><span class="dropdown-item-text">Meine Widgets</span></li>
|
||||
<li v-for="widget in widgets" :key="widget[0]">
|
||||
<button class="dropdown-item" type="button" data-bs-toggle="collapse" :data-bs-target="'#settings-' + widget[0]">Action</button>
|
||||
<core-dashboard-item :id="'settings-' + widget[0]" class="collapse w-100" editMode="true" :config="widget[4]" @change="v => widget[4] = v" :widget="widget[5]" @remove="removeWidget(widget[0])"></core-dashboard-item>
|
||||
</li>
|
||||
</ul>
|
||||
</div-->
|
||||
|
||||
<a href="#" class="link-secondary" v-if="editMode" @click.prevent="saveConfig"><i class="fa-solid fa-floppy-disk"></i></a>
|
||||
<a href="#" class="link-secondary" v-else @click.prevent="editMode = true"><i class="fa-solid fa-gear"></i></a>
|
||||
</h3>
|
||||
<div v-else class="fetch-loader">Loading...</div>
|
||||
<div v-if="loaded" class="core-dashboard-list row">
|
||||
<core-dashboard-item v-for="widget in widgets" :key="widget[0]" :editMode="editMode" :config="widget[4]" @change="v => widget[4] = v" :widget="widget[5]" :style="{'--core-dashboard-order-sm':widget[1],'--core-dashboard-order-md':widget[2],'--core-dashboard-order-lg':widget[3]}" @remove="removeWidget(widget[0])"></core-dashboard-item>
|
||||
<div v-if="editMode" class="core-dashboard-item-add col-sm-6 col-md-3">
|
||||
<div class="fixed-h fixed-h-1">
|
||||
<div class="card d-flex justify-content-center align-items-center" @click="startWidgetWizard">
|
||||
<i class="fa-solid fa-plus h1"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="widgetWizard" class="modal fade" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Add new widget</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<template v-if="allowedWidgets.length">
|
||||
<div v-for="widget in allowedWidgets" :v-key="widget.dashboard_widget_id" class="col">
|
||||
<div class="card" @click="newWidget(widget)">
|
||||
<img src="..." class="card-img-top" alt="...">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center">{{widget.name}}</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="fetch-loader">Loading...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
export default {
|
||||
props: [
|
||||
"configMode",
|
||||
"config"
|
||||
],
|
||||
methods: {
|
||||
changeConfig() {
|
||||
this.config.display = parseInt(this.$refs.display.value);
|
||||
this.$emit('config', this.config);
|
||||
}
|
||||
},
|
||||
template: `<div class="dbw-kpi">
|
||||
<div>KPI Widget</div>
|
||||
<div v-if="configMode">
|
||||
<select ref="display" class="form-control">
|
||||
<option value="0" :selected="config.display == 0">H1</option>
|
||||
<option value="1" :selected="config.display == 1">H2</option>
|
||||
<option value="2" :selected="config.display == 2">H3</option>
|
||||
</select>
|
||||
<button class="btn btn-default" @click="changeConfig">Save</button>
|
||||
</div>
|
||||
<template v-else>
|
||||
<span v-for="val in config.data" :class="'h' + (1 + parseInt(config.display))">{{val}}</span>
|
||||
</template>
|
||||
</div>`
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
export default {
|
||||
data: () => ({
|
||||
isMounted: 0,
|
||||
movedObjects: [],
|
||||
tmpStyle: {
|
||||
display: 'none',
|
||||
background: 'gray',
|
||||
'grid-column-start': 0,
|
||||
'grid-column-end': 0,
|
||||
'grid-row-start': 0,
|
||||
'grid-row-end': 0,
|
||||
}
|
||||
}),
|
||||
props: [
|
||||
"width",
|
||||
"height",
|
||||
"items"
|
||||
],
|
||||
computed: {
|
||||
gridWidth() {
|
||||
if(!this.isMounted)
|
||||
return 0;
|
||||
return window.getComputedStyle(this.$refs.container).getPropertyValue('grid-template-columns').split(" ").length;
|
||||
},
|
||||
gridHeight() {
|
||||
if (!this.gridWidth)
|
||||
return 0;
|
||||
let minH = 0;
|
||||
this.items.forEach(item => {
|
||||
// TODO(chris): item change is not detected?
|
||||
minH = Math.max(minH, item.y + item.h - 1);
|
||||
});
|
||||
return Math.max(1, minH);
|
||||
},
|
||||
gridOccupiers() {
|
||||
let occupiers = [];
|
||||
let gridWidth = this.gridWidth;
|
||||
this.items.forEach(item => {
|
||||
for (var i = 0; i < item.w; i++)
|
||||
for (var j = 0; j < item.h; j++)
|
||||
occupiers[(item.y+j) * gridWidth + (item.x+i)] = item.id;
|
||||
});
|
||||
return occupiers;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
startDrag(evt, item) {
|
||||
evt.dataTransfer.dropEffect = 'move';
|
||||
evt.dataTransfer.effectAllowed = 'move';
|
||||
evt.dataTransfer.setData('itemId', item.id)
|
||||
evt.dataTransfer.setData('itemW', item.w)
|
||||
evt.dataTransfer.setData('itemH', item.h)
|
||||
console.log(evt.target.style.display);
|
||||
},
|
||||
moveItem(item) {
|
||||
// TODO(chris): IMPLEMENT
|
||||
if (!item._x)
|
||||
item._x = item.x;
|
||||
item.x++;
|
||||
},
|
||||
moveItemBack(item) {
|
||||
item.x = item._x;
|
||||
},
|
||||
onDragOver(evt) {
|
||||
this.tmpStyle.display = 'block';
|
||||
|
||||
let x = Math.floor(this.gridWidth * (evt.layerX / this.$refs.container.clientWidth)) + 1;
|
||||
let y = Math.floor(this.gridHeight * (evt.layerY / this.$refs.container.clientHeight)) + 1;
|
||||
let w = parseInt(evt.dataTransfer.getData('itemW'));
|
||||
let h = parseInt(evt.dataTransfer.getData('itemH'));
|
||||
|
||||
while (x + w > this.gridWidth + 1)
|
||||
x--;
|
||||
|
||||
// TODO(chris): start
|
||||
let id = 0;
|
||||
while (id = this.movedObjects.pop())
|
||||
/*this.items[id].c = this.items[id]._c;*/
|
||||
this.moveItemBack(this.items[id]);
|
||||
for (var i = 0; i < w; i++) {
|
||||
for (var j = 0; j < h; j++) {
|
||||
let id = (y+j) * this.gridWidth + (x+i);
|
||||
if (this.gridOccupiers[id] && this.gridOccupiers[id] != evt.dataTransfer.getData('itemID')) {
|
||||
|
||||
/*if (!this.items[this.gridOccupiers[id]]._c)
|
||||
this.items[this.gridOccupiers[id]]._c = this.items[this.gridOccupiers[id]].c;
|
||||
this.items[this.gridOccupiers[id]].c = 'grey';*/
|
||||
this.moveItem(this.items[this.gridOccupiers[id]]);
|
||||
|
||||
this.movedObjects.push(this.gridOccupiers[id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO(chris): end
|
||||
|
||||
this.tmpStyle['grid-column-start'] = x;
|
||||
this.tmpStyle['grid-column-end'] = x + w;
|
||||
this.tmpStyle['grid-row-start'] = y;
|
||||
this.tmpStyle['grid-row-end'] = y + h;
|
||||
},
|
||||
onDrop(evt, list) {
|
||||
this.tmpStyle.display = 'none';
|
||||
|
||||
let id = evt.dataTransfer.getData('itemId');
|
||||
let x = Math.floor(this.gridWidth * (evt.layerX / this.$refs.container.clientWidth)) + 1;
|
||||
let y = Math.floor(this.gridHeight * (evt.layerY / this.$refs.container.clientHeight)) + 1;
|
||||
let w = parseInt(evt.dataTransfer.getData('itemW'));
|
||||
|
||||
while (x + w > this.gridWidth + 1)
|
||||
x--;
|
||||
|
||||
this.items.forEach(item => {
|
||||
if (id == item.id) {
|
||||
item.x = x;
|
||||
item.y = y;
|
||||
console.log(item, id);
|
||||
}
|
||||
});
|
||||
// TODO(chris): find better way to trigger change for gridHeight
|
||||
this.isMounted++
|
||||
}
|
||||
},
|
||||
watchers: {
|
||||
items() {
|
||||
console.log(this.items);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isMounted = 1;
|
||||
window.addEventListener('resize', e => { this.isMounted ? this.isMounted++ : 0 })
|
||||
},
|
||||
template: `<div class="drag-and-drop position-relative" :style="'height:0;padding-bottom:' + (gridHeight * 100/gridWidth) + '%'">
|
||||
<div ref="container" class="position-absolute top-0 left-0 w-100 h-100 draganddropcontainer" :style="'display:grid;grid-template-rows:repeat('+gridHeight+',1fr)'" @drop="onDrop($event, 1)" @dragover.prevent="onDragOver" @dragenter.prevent>
|
||||
<div v-for="item in items" :key="item.id" :style="{'grid-column-start':item.x,'grid-column-end':item.x+item.w,'grid-row-start':item.y,'grid-row-end':item.y+item.h,background:item.c}" @dragstart="startDrag($event, item)" draggable="true">
|
||||
</div>{{gridWidth2}}
|
||||
<div :style="tmpStyle"></div>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
export default {
|
||||
components: {},
|
||||
data: () => ({
|
||||
configMode: false,
|
||||
name: '',
|
||||
component: '',
|
||||
arguments: null
|
||||
}),
|
||||
props: [
|
||||
"widget",
|
||||
"config",
|
||||
"editMode"
|
||||
],
|
||||
computed: {
|
||||
ready() {
|
||||
return this.name && this.component && this.arguments !== null;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeConfig(v) {
|
||||
this.arguments = v;
|
||||
this.configMode = false;
|
||||
// TODO(chris): diff arguments widget.arguments
|
||||
this.$emit('change', v);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
|
||||
if (!this.isPlaceholder) {
|
||||
this.$options.components[this.widget.component_name] = this.widget.component;
|
||||
this.name = this.widget.name;
|
||||
this.component = this.widget.component_name;
|
||||
this.arguments = {...this.widget.arguments, ...this.config};
|
||||
}
|
||||
},
|
||||
template: `<div class="core-dashboard-item col-sm-6 col-md-3">
|
||||
<div class="fixed-h fixed-h-1">
|
||||
<div v-if="ready" class="card">
|
||||
<div class="card-header d-flex">
|
||||
<span v-if="editMode" class="col-auto pe-3"><i class="fa-solid fa-grip-lines-vertical"></i></span>
|
||||
<span class="col">{{name}}</span>
|
||||
<a v-if="editMode" class="col-auto ps-1" href="#" @click.prevent="configMode = !configMode"><i class="fa-solid fa-gear"></i></a>
|
||||
<a v-if="editMode" class="col-auto ps-1" href="#" @click.prevent="$emit('remove')"><i class="fa-solid fa-trash-can"></i></a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<component :is="component" :config="arguments" @config="changeConfig" :configMode="configMode"></component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
}
|
||||
Reference in New Issue
Block a user