import {CoreFilterCmpt} from "../filter/Filter.js"; import FormInput from "../Form/Input.js"; import FormForm from "../Form/Form.js"; import BsModal from "../Bootstrap/Modal.js"; import PvAutoComplete from "../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js"; import ApiCoreFunktion from '../../api/factory/functions.js'; export default { name: 'FunctionComponent', components: { CoreFilterCmpt, FormInput, FormForm, BsModal, PvAutoComplete }, props: { modelValue: { type: Object, default: () => ({}), required: false }, config: {type: Object, default: () => ({}), required: false}, readonlyMode: {type: Boolean, required: false, default: false}, personID: {type: Number, required: true}, personUID: {type: String, required: true}, writePermission: {type: Boolean, required: false}, showDvCompany: {type: Boolean, required: false, default: true}, saveFunctionAsCopy: {type: Boolean, required: false, default: false}, stylePv21: {type: Boolean, required: false, default: false}, companyLinkFormatter: {type: Function || null, default: null} }, data(){ return { isFilterSet: true, listOrgHeads: [], listOrgUnits: [], //Old listAllOrgUnits: [], listOrgUnits_GST: [], listOrgUnits_GMBH: [], formData: { head: 'gst', oe_kurzbz: '', funktion_kurzbz: null, label:'', //funktion_label: '', funktion: null, }, statusNew: true, listAllFunctions: [], abortController: { oes: null, functions: null }, filteredOes: [], filteredFunctions: [], newBtnStyle: '', selectedFunction: null, selectedOe: null, layout: 'fitDataFill', layoutColumnsOnNewData: false, height: '300' } }, computed: { tabulatorOptions() { const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call( ApiCoreFunktion.getAllUserFunctions(this.personUID) ), ajaxResponse: (url, params, response) => response.data, persistenceID: 'core-functions-20260217', columns: [ { title: "dienstverhaeltnis_unternehmen", field: "dienstverhaeltnis_unternehmen", headerFilter: "list", headerFilterParams: { valuesLookup: true, autocomplete: true, sort: "asc" }, width: 140, //Field Company: if visible show link to dv visible: this.showDvCompany, formatter: this.companyLinkFormatter }, { title: "funktion_beschreibung", field: "funktion_beschreibung", headerFilter: "list", headerFilterParams: { valuesLookup: true, autocomplete: true, sort: "asc" }, width: 140 }, { title: "funktion_oebezeichnung", field: "funktion_oebezeichnung", headerFilter: "list", headerFilterParams: { valuesLookup: true, autocomplete: true, sort: "asc" }, width: 140 }, {title: "wochenstunden", field: "wochenstunden", headerFilter: true}, { title: "Von", field: "datum_von", headerFilter: true, formatter: function (cell) { const dateStr = cell.getValue(); if (!dateStr) return ""; const date = new Date(dateStr); return date.toLocaleString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric", }); }, }, { title: "Bis", field: "datum_bis", headerFilter: true, formatter: function (cell) { const dateStr = cell.getValue(); if (!dateStr) return ""; const date = new Date(dateStr); return date.toLocaleString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric", }); }, }, {title: "bezeichnung", field: "bezeichnung", headerFilter: true, width: 140}, {title: "aktiv", field: "aktiv", visible: false}, {title: "benutzerfunktion_id", field: "benutzerfunktion_id", visible: false}, {title: "uid", field: "uid", visible: false}, { //title: 'Aktionen', field: 'actions', minWidth: 150, // Ensures Action-buttons will be always fully displayed headerSort:false, formatter: (cell, formatterParams, onRendered) => { let container = document.createElement('div'); container.className = "d-flex gap-2"; if( cell.getRow().getData().dienstverhaeltnis_unternehmen === null ) { let button = document.createElement('button'); button.className = 'btn btn-outline-secondary btn-action'; if(this.stylePv21) button.innerHTML = ''; else button.innerHTML = ''; button.title = this.$p.t('ui', 'bearbeiten'); button.addEventListener('click', (event) => this.actionEditFunction(cell.getData().benutzerfunktion_id) ); if(this.readonlyMode === true) button.disabled = true; container.append(button); } if( cell.getRow().getData().dienstverhaeltnis_unternehmen === null ) { let button = document.createElement('button'); button.className = 'btn btn-outline-secondary btn-action'; button.innerHTML = ''; button.title = this.$p.t('ui', 'loeschen'); button.addEventListener('click', () => this.actionDeleteFunction(cell.getData().benutzerfunktion_id) ); if(this.readonlyMode === true) button.disabled = true; container.append(button); } if (cell.getRow().getData().dienstverhaeltnis_unternehmen === null && this.saveFunctionAsCopy) { let button = document.createElement('button'); button.className = 'btn btn-outline-secondary btn-action'; button.innerHTML = ''; button.title = this.$p.t('ui', 'saveAsCopy'); button.addEventListener('click', () => this.actionCopyFunction(cell.getData().benutzerfunktion_id) ); if(this.readonlyMode === true) button.disabled = true; container.append(button); } return container; }, frozen: true } ], }; return options; }, tabulatorEvents() { const events = [ { event: 'tableBuilt', handler: async () => { await this.$p.loadCategory(['global', 'lehre', 'person', 'ui']); const setHeader = (field, text) => { const col = this.$refs.table.tabulator.getColumn(field); if (!col) return; const el = col.getElement(); if (!el || !el.querySelector) return; const titleEl = el.querySelector('.tabulator-col-title'); if (titleEl) { titleEl.textContent = text; } }; setHeader('dienstverhaeltnis_unternehmen', this.$p.t('person', 'dv_unternehmen')); setHeader('funktion_beschreibung', this.$p.t('person', 'zuordnung_taetigkeit')); setHeader('funktion_oebezeichnung', this.$p.t('lehre', 'organisationseinheit')); setHeader('wochenstunden', this.$p.t('person', 'wochenstunden')); setHeader('datum_von', this.$p.t('ui', 'from')); setHeader('datum_bis', this.$p.t('global', 'bis')); setHeader('bezeichnung', this.$p.t('ui', 'bezeichnung')); } } ]; return events; }, }, watch: { selectedFunction(newVal) { this.formData.funktion_kurzbz = newVal?.funktion_kurzbz || ''; }, selectedOe(newVal) { this.formData.oe_kurzbz = newVal?.oe_kurzbz || ''; } }, methods: { onSwitchChange() { if (this.isFilterSet) { this.$refs.table.tabulator.setFilter("aktiv", "=", true); } else { this.$refs.table.tabulator.clearFilter(); this.isFilterSet = false; } }, actionNewFunction(){ this.resetModal(); this.statusNew = true; this.formData.datum_von = new Date(); this.$refs.functionModal.show(); }, actionCopyFunction(benutzerfunktion_id) { this.statusNew = true; this.loadFunction(benutzerfunktion_id).then(() => { this.$refs.functionModal.show(); }); }, actionDeleteFunction(benutzerfunktion_id) { this.$fhcAlert .confirmDelete() .then(result => result ? benutzerfunktion_id : Promise.reject({handled: true})) .then(this.deleteFunction) .catch(this.$fhcAlert.handleSystemError); }, actionEditFunction(benutzerfunktion_id) { this.resetModal(); this.statusNew = false; this.loadFunction(benutzerfunktion_id).then(() => { //set selectedFunction and selectedOd to enable viewing label in primevue autocomplete fields this.selectedFunction = this.listAllFunctions.find( item => item.funktion_kurzbz === this.formData.funktion_kurzbz ); this.selectedOe = this.listAllOrgUnits.find( item => item.oe_kurzbz === this.formData.oe_kurzbz ); }); this.$refs.functionModal.show(); }, addFunction() { const dataToSend = { uid: this.personUID, formData: this.formData }; return this.$refs.functionData .call(ApiCoreFunktion.addFunction(dataToSend)) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave')); this.hideModal('functionModal'); this.resetModal(); }).catch(this.$fhcAlert.handleSystemError) .finally(() => { this.reload(); }); }, loadFunction(benutzerfunktion_id) { return this.$api .call(ApiCoreFunktion.loadFunction(benutzerfunktion_id)) .then(result => { this.formData = result.data; }) .catch(this.$fhcAlert.handleSystemError); }, updateFunction(benutzerfunktion_id){ const dataToSend = { uid: this.personUID, formData: this.formData, benutzerfunktion_id: benutzerfunktion_id }; return this.$refs.functionData .call(ApiCoreFunktion.updateFunction(dataToSend)) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave')); this.hideModal('functionModal'); this.resetModal(); }).catch(this.$fhcAlert.handleSystemError) .finally(() => { this.reload(); }); }, deleteFunction(benutzerfunktion_id) { return this.$api .call(ApiCoreFunktion.deleteFunction(benutzerfunktion_id)) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); }) .catch(this.$fhcAlert.handleSystemError) .finally(() => { this.reload(); }); }, hideModal(modalRef) { this.$refs[modalRef].hide(); }, reload() { this.$refs.table.reloadTable(); }, resetModal(){ this.formData = {}; this.formData.head = 'gst'; this.formData.oe_kurzbz = ''; this.formData.funktion_kurzbz = ''; this.selectedFunction = null; this.selectedOe= null; }, filterFunctions(event) { const query = event.query.toLowerCase(); this.filteredFunctions = this.listAllFunctions.filter(item => item.label.toLowerCase().includes(query) ) }, filterOes(event) { const query = event.query.toLowerCase(); if(!this.formData.head) this.$fhcAlert.alertError(this.$p.t('ui', 'bitteUnternehmenWaehlen')); if(this.formData.head == 'gst') { this.filteredOes = this.listOrgUnits_GST.filter(item => item.label.toLowerCase().includes(query) ); } if(this.formData.head == 'gmbh') { this.filteredOes = this.listOrgUnits_GMBH.filter(item => item.label.toLowerCase().includes(query) ); } }, styleNewButton(){ if(this.stylePv21) { this.newBtnStyle = "btn-sm"; } }, //helper function: workaround to trigger validation if input is not a number normalizeStunden() { if (this.formData.wochenstunden === null || this.formData.wochenstunden === '') { this.formData.wochenstunden = 'xxx' } } }, created() { this.$api .call(ApiCoreFunktion.getOrgHeads()) .then(result => { this.listOrgHeads = result.data; }) .catch(this.$fhcAlert.handleSystemError); this.$api .call(ApiCoreFunktion.getAllFunctions()) .then(result => { this.listAllFunctions = result.data; }) .catch(this.$fhcAlert.handleSystemError); this.$api .call(ApiCoreFunktion.getAllOrgUnits()) .then(result => { this.listAllOrgUnits = result.data; }) .catch(this.$fhcAlert.handleSystemError); this.$api .call(ApiCoreFunktion.getOrgetsForCompany('gst')) .then(result => { this.listOrgUnits_GST = result.data; }) .catch(this.$fhcAlert.handleSystemError); this.$api .call(ApiCoreFunktion.getOrgetsForCompany('gmbh')) .then(result => { this.listOrgUnits_GMBH = result.data; }) .catch(this.$fhcAlert.handleSystemError); this.styleNewButton(); }, template: `
{{ $p.t('funktion', 'addFunktion') }}
{{ $p.t('funktion', 'editFunktion') }}