import {CoreFilterCmpt} from "../../filter/Filter.js"; import FormForm from '../../Form/Form.js'; import ApiMessages from "../../../api/factory/messages/messages.js" export default { name: "TableMessages", components: { CoreFilterCmpt, FormForm, }, inject: { cisRoot: { from: 'cisRoot' }, }, props: { typeId: String, id: { type: Array, required: true }, messageLayout: String, openMode: String }, data(){ return { tabulatorOptions: { ajaxURL: 'dummy', ajaxRequestFunc: this.loadAjaxCall, ajaxParams: () => { return { id: this.id, type: this.typeId }; }, ajaxResponse: (url, params, response) => this.buildTreemap(response), columns: [ {title: "subject", field: "subject", headerFilter: true}, {title: "body", field: "body", formatter: "html", visible: false, headerFilter: true}, {title: "message_id", field: "message_id", visible: false, headerFilter: true}, { title: "Datum", field: "insertamum", headerFilter: true, formatter: function (cell) { const dateStr = cell.getValue(); const date = new Date(dateStr); // Convert to Date object return date.toLocaleString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", hour12: false }); }, headerFilterFunc(headerValue, rowValue) { const matches = headerValue.match(/^(([0-9]{2})\.)?([0-9]{2})\.([0-9]{4})?$/); let comparestr = headerValue; if(matches !== null) { const year = (matches[4] !== undefined) ? matches[4] : ''; const month = matches[3]; const day = (matches[2] !== undefined) ? matches[2] : ''; comparestr = year + '-' + month + '-' + day; } return rowValue.match(comparestr); } }, {title: "sender", field: "sender", headerFilter: true}, {title: "recipient", field: "recipient", headerFilter: true}, {title: "senderId", field: "sender_id", headerFilter: true}, {title: "recipientId", field: "recipient_id", headerFilter: true}, {title: "Relationmessage ID", field: "relationmessage_id", headerFilter: true}, { title: "Status", field: "status", headerFilter: true, formatterParams: [ "unread", "read", "archived", "deleted" ], formatter: (cell, formatterParams) => { return formatterParams[cell.getValue()]; }, }, { title: "letzte Änderung", field: "statusdatum", headerFilter: true, formatter: function (cell) { const dateStr = cell.getValue(); const date = new Date(dateStr); // Convert to Date object return date.toLocaleString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", hour12: false }); }, headerFilterFunc(headerValue, rowValue) { const matches = headerValue.match(/^(([0-9]{2})\.)?([0-9]{2})\.([0-9]{4})?$/); let comparestr = headerValue; if(matches !== null) { const year = (matches[4] !== undefined) ? matches[4] : ''; const month = matches[3]; const day = (matches[2] !== undefined) ? matches[2] : ''; comparestr = year + '-' + month + '-' + day; } return rowValue.match(comparestr); } }, { title: 'Aktionen', field: 'actions', width: 100, formatter: (cell, formatterParams, onRendered) => { let container = document.createElement('div'); container.className = "d-flex gap-2"; let button = document.createElement('button'); if (this.personId != cell.getData().sender_id) { button.disabled = true; button.style = "visibility: hidden"; button.ariaHidden = true; } button.className = 'btn btn-outline-secondary btn-action'; button.title = this.$p.t('global', 'reply'); button.innerHTML = ''; button.addEventListener( 'click', (event) => this.actionReplyToMessage(cell.getData().message_id) ); container.append(button); button = document.createElement('button'); button.className = 'btn btn-outline-secondary btn-action'; button.title = this.$p.t('ui', 'loeschen'); button.innerHTML = ''; button.addEventListener( 'click', () => this.actionDeleteMessage(cell.getData().message_id) ); container.append(button); return container; }, frozen: true } ], layout: 'fitDataStretchFrozen', layoutColumnsOnNewData: false, height: '400', selectable: 1, selectableRangeMode: 'click', index: 'message_id', pagination: true, paginationMode: "remote", paginationSize: 15, paginationInitialPage: 1, dataTree: true, headerSort: true, dataTreeChildField: "children", dataTreeCollapseElement:"", dataTreeChildIndent: 15, dataTreeStartExpanded: false, persistenceID: 'core-message-2025112401', locale: 'de', "langs": { "de":{ //German language definition "data":{ "loading":"Lädt", //data loader text "error":"Fehler", //data error text }, "pagination":{ "first":"Erste", "first_title":"Erste Seite", "last":"Letzte", "last_title":"Letzte Seite", "prev":"Vorige", "prev_title":"Vorige Seite", "next":"Nächste", "next_title":"Nächste Seite", "all":"Alle" }, }, } }, tabulatorEvents: [ { event: 'tableBuilt', handler: async() => { await this.$p.loadCategory(['global', 'person', 'stv', 'messages', 'ui', 'notiz']); let cm = this.$refs.table.tabulator.columnManager; cm.getColumnByField('subject').component.updateDefinition({ title: this.$p.t('global', 'betreff') }); cm.getColumnByField('body').component.updateDefinition({ title: this.$p.t('messages', 'body') }); cm.getColumnByField('message_id').component.updateDefinition({ title: this.$p.t('messages', 'message_id') }); cm.getColumnByField('insertamum').component.updateDefinition({ title: this.$p.t('global', 'datum') }); cm.getColumnByField('sender').component.updateDefinition({ title: this.$p.t('messages', 'sender') }); cm.getColumnByField('recipient').component.updateDefinition({ title: this.$p.t('messages', 'recipient') }); cm.getColumnByField('sender_id').component.updateDefinition({ title: this.$p.t('messages', 'senderId') }); cm.getColumnByField('recipient_id').component.updateDefinition({ title: this.$p.t('messages', 'recipientId') }); cm.getColumnByField('statusdatum').component.updateDefinition({ title: this.$p.t('notiz', 'letzte_aenderung') }); cm.getColumnByField('status').component.updateDefinition({ formatterParams: [ this.$p.t('messages/unread'), this.$p.t('messages/read'), this.$p.t('messages/archived'), this.$p.t('messages/deleted') ] }); this.$refs.table.tabulator.rowManager.getDisplayRows(); /* cm.getColumnByField('actions').component.updateDefinition({ title: this.$p.t('global', 'aktionen') }); */ } }, { event: 'rowClick', handler: (e, row) => { const selectedMessage = row.getData().message_id; const body = row.getData().body; this.previewBody = body; } }, /* { event: 'pageLoaded', handler: (pageno) => { this.pageNo = pageno+1; } } */ ], previewBody: "", open: false, personId: null, } }, methods: { actionDeleteMessage(message_id){ this.$fhcAlert .confirmDelete() .then(result => result ? message_id : Promise.reject({handled: true})) .then(this.deleteMessage) .catch(this.$fhcAlert.handleSystemError); }, deleteMessage(message_id){ return this.$api .call(ApiMessages.deleteMessage(message_id)) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); }).catch(this.$fhcAlert.handleSystemError) .finally(()=> { window.scrollTo(0, 0); this.reload(); }); }, actionNewMessage(){ this.$emit('newMessage', this.id, this.typeId); }, actionReplyToMessage(message_id){ this.$emit('replyToMessage', this.id, this.typeId, message_id); }, reload() { this.$refs.table.reloadTable(); }, buildTreemap(messages) { if (!messages || !messages.data || messages.data.length === 0) { return {data: [], last_page: 0}; } const last_page = messages.meta.count; messages = messages.data; const messageMap = new Map(); const messageNested = []; const remainingMessages = new Set(messages); //save all Data in Map messages.forEach(msg => messageMap.set(msg.message_id, msg)); let iteration = 0; let changes = true; // do until each relationmessage_id finds message_id (not sensitive to order) while (changes) { changes = false; iteration++; remainingMessages.forEach(msg => { if (msg.relationmessage_id === null) { messageNested.push(messageMap.get(msg.message_id)); remainingMessages.delete(msg); changes = true; } else if (messageMap.has(msg.relationmessage_id)) { const parent = messageMap.get(msg.relationmessage_id); if (!parent.children) { parent.children = []; } parent.children.push(messageMap.get(msg.message_id)); remainingMessages.delete(msg); changes = true; } }); // to avoid endless loop if (iteration > messages.length) break; } return {data: messageNested, last_page: last_page}; }, loadAjaxCall(url, config, params){ return this.$api.call( ApiMessages.getMessages(params) ); } }, computed: { statusText(){ return { 0: this.$p.t('messsages', 'unread'), 1: this.$p.t('messsages', 'read'), 2: this.$p.t('messsages', 'archived'), 3: this.$p.t('messsages', 'deleted') } }, }, mounted() { // change to target="_blank" /* this.$nextTick(() => { const links = document.querySelectorAll('.preview a'); links.forEach(link => { link.setAttribute('target', '_blank'); link.setAttribute('rel', 'noopener noreferrer'); // Sicherheitsmaßnahme }); });*/ }, created(){ if(this.typeId != 'person_id' && Array.isArray(this.id) && this.id.length === 1) { const params = { id: this.id, type_id: this.typeId }; this.$api .call(ApiMessages.getPersonId(params)) .then(result => { this.personId = result.data; }) .catch(this.$fhcAlert.handleSystemError); } }, template: `




` }