Removed Dashboard Testfiles

This commit is contained in:
Andreas Österreicher
2022-09-07 09:00:00 +02:00
parent 00f1eb38d1
commit 393eaea91d
13 changed files with 0 additions and 788 deletions
-51
View File
@@ -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';
}
}
-63
View File
@@ -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'); ?>
-15
View File
@@ -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');
-206
View File
@@ -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>`
}
-26
View File
@@ -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>`
}
-52
View File
@@ -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>`
}