This commit is contained in:
Cris
2024-06-11 11:32:47 +02:00
11 changed files with 1591 additions and 15 deletions
@@ -188,4 +188,20 @@ class Organisationseinheit_model extends DB_Model
}
return $this->loadWhere($condition);
}
/**
* Get OEs by eventQuery string. Use with autocomplete event queries.
* @param $eventQuery String
* @return array
*/
public function getAutocompleteSuggestions($eventQuery)
{
$this->addSelect('oe_kurzbz');
$this->addSelect('organisationseinheittyp_kurzbz, oe_kurzbz, bezeichnung, aktiv, lehre');
$this->addOrder('organisationseinheittyp_kurzbz, bezeichnung');
return $this->loadWhere("
oe_kurzbz ILIKE '%". $this->escapeLike($eventQuery). "%'
");
}
}
@@ -127,6 +127,11 @@
generateJSsInclude('vendor/npm-asset/primevue/autocomplete/autocomplete.min.js');
generateJSsInclude('vendor/npm-asset/primevue/overlaypanel/overlaypanel.min.js');
generateJSsInclude('vendor/npm-asset/primevue/datatable/datatable.min.js');
// TODO check ob notwendig
generateJSsInclude('vendor/npm-asset/primevue/toast/toast.min.js');
generateJSsInclude('vendor/npm-asset/primevue/toastservice/toastservice.min.js');
generateJSsInclude('vendor/npm-asset/primevue/confirmdialog/confirmdialog.min.js');
generateJSsInclude('vendor/npm-asset/primevue/confirmationservice/confirmationservice.min.js');
}
// --------------------------------------------------------------------------------------------------------
+1 -1
View File
@@ -270,7 +270,7 @@ if (isset($_POST['titel']))
foreach($addon_obj->result as $addon)
{
if(file_exists('../../../addons/'.$addon->kurzbz.'/cis/init.js.php'))
echo '<script type="application/x-javascript" src="../../../addons/'.$addon->kurzbz.'/cis/init.js.php" ></script>';
echo '<script type="application/x-javascript" src="../../../addons/'.$addon->kurzbz.'/cis/init.js.php"></script>';
}
// Wenn Seite fertig geladen ist Addons aufrufen
+1 -1
View File
@@ -382,7 +382,7 @@ class projekt extends basis_db
JOIN fue.tbl_projekt_ressource USING(ressource_id)
JOIN fue.tbl_projekt USING(projekt_kurzbz)
WHERE (beginn<=now() or beginn is null)
AND (ende + interval '1 month 1 day' >=now() OR ende is null)
AND (ende + interval '2 month 1 day' >=now() OR ende is null)
AND
(
mitarbeiter_uid=" . $this->db_add_param($mitarbeiter_uid) . " OR
+3 -3
View File
@@ -40,7 +40,7 @@
}
.tabulator-cell .btn {
padding: 0 .5rem;
max-height: 22px;
min-width: 30px;
padding: 0 .7rem;
min-height: 25px;
min-width: 25px;
}
+15 -3
View File
@@ -160,12 +160,12 @@ export default {
},
modelValueCmp: {
get() {
if (this.$attrs.modelValue === undefined)
if (!this.$attrs.hasOwnProperty('modelValue'))
return this.modelValueDummy;
return this.$attrs.modelValue;
},
set(v) {
if (this.$attrs.modelValue === undefined)
if (!this.$attrs.hasOwnProperty('modelValue'))
this.modelValueDummy = v;
this.$emit('update:modelValue', v);
}
@@ -236,12 +236,13 @@ export default {
},
template: `
<component :is="!hasContainer ? 'FhcFragment' : 'div'" class="position-relative" :class="autoContainerClass">
<label v-if="$attrs.label && lcType != 'radio' && lcType != 'checkbox'" :for="idCmp">{{$attrs.label}}</label>
<label v-if="$attrs.label && lcType != 'radio' && lcType != 'checkbox'" :class="!noAutoClass && 'form-label'" :for="idCmp">{{$attrs.label}}</label>
<input v-if="tag == 'input'" :type="lcType" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)">
<textarea v-else-if="tag == 'textarea'" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)"></textarea>
<select v-else-if="tag == 'select'" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)">
<slot></slot>
</select>
<component
v-else-if="tag == 'VueDatePicker'"
ref="input"
@@ -272,6 +273,17 @@ export default {
@update:model-value="clearValidationForThisName"
>
<slot></slot>
<template #chip="data"><slot name="chip" v-bind="data"></slot></template>
<template #header="data"><slot name="header" v-bind="data"></slot></template>
<template #footer="data"><slot name="footer" v-bind="data"></slot></template>
<template #option="data"><slot name="option" v-bind="data"></slot></template>
<template #optiongroup="data"><slot name="optiongroup" v-bind="data"></slot></template>
<template #content="data"><slot name="content" v-bind="data"></slot></template>
<template #loader="data"><slot name="loader" v-bind="data"></slot></template>
<template #empty="data"><slot name="empty" v-bind="data"></slot></template>
<template #dropdownicon="data"><slot name="dropdownicon" v-bind="data"></slot></template>
<template #removetokenicon="data"><slot name="removetokenicon" v-bind="data"></slot></template>
<template #loadingicon="data"><slot name="loadingicon" v-bind="data"></slot></template>
</component>
<component
v-else-if="tag == 'UploadDms'"
+1 -1
View File
@@ -75,7 +75,7 @@ export default {
tabs[key] = {
component: Vue.markRaw(Vue.defineAsyncComponent(() => import(item.component))),
title: item.title || key,
title: Vue.computed(() => item.title || key),
config: item.config,
key
}
+1 -1
View File
@@ -17,7 +17,7 @@
import {CoreRESTClient} from '../../RESTClient.js';
//
//
const CORE_FILTER_CMPT_TIMEOUT = 7000;
/**
+76 -4
View File
@@ -62,7 +62,11 @@ export const CoreFilterCmpt = {
newBtnShow: Boolean,
newBtnClass: [String, Array, Object],
newBtnDisabled: Boolean,
newBtnLabel: String
newBtnLabel: String,
uniqueId: String,
// TODO soll im master kommen?
idField: String,
parentIdField: String
},
data: function() {
return {
@@ -209,6 +213,13 @@ export const CoreFilterCmpt = {
if (tabulatorOptions.columns && tabulatorOptions.columns.filter(el => el.formatter == 'rowSelection').length)
this.tabulatorHasSelector = true;
// TODO check ob im core bleiben soll
if (this.idField) {
// enable nested tabulator if parent Id given
if (this.parentIdField) tabulatorOptions.dataTree = true;
// set tabulator index
tabulatorOptions.index = this.idField;
}
// Start the tabulator with the build options
this.tabulator = new Tabulator(
@@ -226,6 +237,33 @@ export const CoreFilterCmpt = {
this.tabulator.on("rowSelectionChanged", data => {
this.selectedData = data;
});
// TODO check ob im core so bleiben soll
// if nested tabulator, restructure data
if (this.parentIdField && this.idField) {
this.tabulator.on("dataLoading", data => {
let toDelete = [];
// loop through all data
for (let childIdx = 0; childIdx < data.length; childIdx++)
{
let child = data[childIdx];
// if it has parent id, it is a child
if (child[this.parentIdField])
{
// append the child on the right place. If parent found, mark original sw child on 0 level for deleting
if (this.appendChild(data, child)) toDelete.push(childIdx);
}
}
// delete the marked children from 0 level
for (let counter = 0; counter < toDelete.length; counter++)
{
// decrease index by counter as index of data array changes after every deletion
data.splice(toDelete[counter] - counter, 1);
}
});
}
if (this.tableOnly) {
this.tabulator.on('tableBuilt', () => {
const cols = this.tabulator.getColumns();
@@ -406,6 +444,9 @@ export const CoreFilterCmpt = {
apiFunctionParameters.filterUniqueId = FHC_JS_DATA_STORAGE_OBJECT.called_path + "/" + FHC_JS_DATA_STORAGE_OBJECT.called_method;
apiFunctionParameters.filterType = this.filterType;
if (this.uniqueId)
apiFunctionParameters.filterUniqueId += '_' + this.uniqueId;
// Assign parameters to the FetchCmpt binded properties
this.fetchCmptApiFunctionParams = apiFunctionParameters;
// Assign data fetch callback to the FetchCmpt binded properties
@@ -484,6 +525,36 @@ export const CoreFilterCmpt = {
},
this.getFilter
);
},
// TODO check ob im core so bleiben soll
// append child to it's parent
appendChild(data, child) {
// get parent id
let parentId = child[this.parentIdField];
// loop thorugh all data
for (let parentIdx = 0; parentIdx < data.length; parentIdx++)
{
let parent = data[parentIdx];
// if it's the parent
if (parent[this.idField] == parentId)
{
// create children array if not done yet
if (!parent._children) parent._children = [];
// if child is not included in children array, append the child
if (!parent._children.includes(child)) parent._children.push(child);
// parent found
return true;
}
// search children for parents
else if (parent._children) this.appendChild(parent._children, child);
}
// parent not found
return false;
}
},
beforeCreate() {
@@ -512,7 +583,7 @@ export const CoreFilterCmpt = {
<div class="row" v-if="title != null && title != ''">
<div class="col-lg-12">
<h3 class="page-header">
<h3 class="page-header mt-1 mb-4">
{{ title }}
</h3>
</div>
@@ -521,7 +592,7 @@ export const CoreFilterCmpt = {
<div :id="'filterCollapsables' + idExtra">
<div class="d-flex flex-row justify-content-between flex-wrap">
<div v-if="newBtnShow || reload || $slots.actions" class="d-flex gap-2 align-items-baseline flex-wrap">
<div v-if="newBtnShow || reload || $slots.search || $slots.actions" class="d-flex gap-2 align-items-baseline flex-wrap">
<button v-if="newBtnShow" class="btn btn-primary" :class="newBtnClass" :title="newBtnLabel ? undefined : 'New'" :aria-label="newBtnLabel ? undefined : 'New'" @click="$emit('click:new', $event)" :disabled="newBtnDisabled">
<span class="fa-solid fa-plus" aria-hidden="true"></span>
{{ newBtnLabel }}
@@ -529,8 +600,9 @@ export const CoreFilterCmpt = {
<button v-if="reload" class="btn btn-outline-secondary" aria-label="Reload" @click="reloadTable">
<span class="fa-solid fa-rotate-right" aria-hidden="true"></span>
</button>
<span v-if="$slots.actions && tabulatorHasSelector">Mit {{selectedData.length}} ausgewählten: </span>
<span v-if="$slots.actions && tabulatorHasSelector">Mit {{selectedData.length}} ausgewählten:</span>
<slot name="actions" v-bind="tabulatorHasSelector ? selectedData : []"></slot>
<slot name="search"></slot>
</div>
<div class="d-flex gap-1 align-items-baseline flex-grow-1 justify-content-end">
<span v-if="!tableOnly">[ {{ filterName }} ]</span>
+71
View File
@@ -1280,6 +1280,77 @@ $filters = array(
',
'oe_kurzbz' => null,
),
array(
'app' => 'core',
'dataset_name' => 'softwareManagement',
'filter_kurzbz' => 'SoftwareManagement',
'description' => '{Software Verwaltung}',
'sort' => 1,
'default_filter' => true,
'filter' => '
{
"name": "SoftwareManagement",
"columns": [
{"name": "software_kurzbz"},
{"name": "version"},
{"name": "beschreibung"},
{"name": "hersteller"},
{"name": "os"},
{"name": "softwarestatus_kurzbz"}
],
"filters": []
}
',
'oe_kurzbz' => null,
),
array(
'app' => 'core',
'dataset_name' => 'imageVerwaltung',
'filter_kurzbz' => 'ImageVerwaltung',
'description' => '{Image Verwaltung}',
'sort' => 1,
'default_filter' => true,
'filter' => '
{
"name": "ImageVerwaltung",
"columns": [
{"name": "bezeichnung"},
{"name": "betriebssystem"},
{"name": "verfuegbarkeit_start"},
{"name": "verfuegbarkeit_ende"},
{"name": "anmerkung"},
{"name": "ort_count"},
{"name": "software_count"}
],
"filters": []
}
',
'oe_kurzbz' => null,
),
array(
'app' => 'core',
'dataset_name' => 'lizenzserverVerwaltung',
'filter_kurzbz' => 'LizenzserverVerwaltung',
'description' => '{Lizenzserver Verwaltung}',
'sort' => 1,
'default_filter' => true,
'filter' => '
{
"name": "LizenzserverVerwaltung",
"columns": [
{"name": "lizenzserver_kurzbz"},
{"name": "bezeichnung"},
{"name": "macadresse"},
{"name": "ipadresse"},
{"name": "ansprechpartner"},
{"name": "anmerkung"},
{"name": "location"}
],
"filters": []
}
',
'oe_kurzbz' => null,
),
array(
'app' => 'fhctemplate',
'dataset_name' => 'exampledata',
+1401 -1
View File
File diff suppressed because it is too large Load Diff