From 018220594a82590cffbcbc612f0f767a314387d7 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 6 Feb 2025 08:34:34 +0100 Subject: [PATCH 01/13] prepare basic framework --- .../api/frontend/v1/messages/Messages.php | 45 +++++++ .../api/frontend/v1/stv/Config.php | 4 + .../api/frontend/v1/stv/Favorites.php | 2 +- application/models/system/Message_model.php | 9 +- public/js/api/fhcapifactory.js | 4 +- public/js/api/messages.js | 5 + public/js/api/messages/person.js | 6 + .../components/Messages/Details/NewMessage.js | 13 ++ .../Messages/Details/TableMessages.js | 117 ++++++++++++++++++ public/js/components/Messages/Messages.js | 48 +++++++ .../Studentenverwaltung/Details/Messages.js | 25 ++++ system/phrasesupdate.php | 25 +++- 12 files changed, 297 insertions(+), 6 deletions(-) create mode 100644 application/controllers/api/frontend/v1/messages/Messages.php create mode 100644 public/js/api/messages.js create mode 100644 public/js/api/messages/person.js create mode 100644 public/js/components/Messages/Details/NewMessage.js create mode 100644 public/js/components/Messages/Details/TableMessages.js create mode 100644 public/js/components/Messages/Messages.js create mode 100644 public/js/components/Stv/Studentenverwaltung/Details/Messages.js diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php new file mode 100644 index 000000000..f81e85e9a --- /dev/null +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -0,0 +1,45 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('system/Message_model', 'MessageModel'); + + // Additional Permission Checks + //TODO(manu) check permissions + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $this->load->library('form_validation'); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function getMessages($id, $type_id) + { + //$this->terminateWithError("in backend " . $type_id . ": " . $id, self::ERROR_TYPE_GENERAL); + + if ($type_id != "person_id") + { + $this->terminateWithError("logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); + } + + $result = $this->MessageModel->getMessagesOfPerson($id); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php index c28c49485..9dec3015f 100644 --- a/application/controllers/api/frontend/v1/stv/Config.php +++ b/application/controllers/api/frontend/v1/stv/Config.php @@ -91,6 +91,10 @@ class Config extends FHCAPI_Controller 'title' => $this->p->t('stv', 'tab_resources'), 'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js' ]; + $result['messages'] = [ + 'title' => $this->p->t('stv', 'tab_messages'), + 'component' => './Stv/Studentenverwaltung/Details/Messages.js' + ]; /* TODO(chris): Ausgeblendet für Testing $result['grades'] = [ 'title' => $this->p->t('stv', 'tab_grades'), diff --git a/application/controllers/api/frontend/v1/stv/Favorites.php b/application/controllers/api/frontend/v1/stv/Favorites.php index 8d7a6cd14..b8fe6f3d7 100644 --- a/application/controllers/api/frontend/v1/stv/Favorites.php +++ b/application/controllers/api/frontend/v1/stv/Favorites.php @@ -48,7 +48,7 @@ class Favorites extends FHCAPI_Controller if (!$data) $this->terminateWithSuccess(null); else - $this->terminateWithSuccess($data['stv_favorites']); + $this->terminateWithSuccess($data['stv_favorites'] ?? null); } public function set() diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index d9f8585ed..6288f54f3 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -85,7 +85,7 @@ class Message_model extends DB_Model */ public function getMessagesOfPerson($person_id, $status = null) { - $sql = 'SELECT m.message_id, + $sql = "SELECT m.message_id, m.person_id, m.subject, m.body, @@ -109,7 +109,10 @@ class Message_model extends DB_Model re.vornamen AS revornamen, s.status, s.statusinfo, - s.insertamum AS statusamum + s.insertamum AS statusamum, + CONCAT(se.titelpre, ' ', se.vorname, ' ', se.nachname, ' ', se.titelpost) as sender, + CONCAT(re.titelpre, ' ', re.vorname, ' ', re.nachname, ' ', re.titelpost ) as recipient, + TO_CHAR(s.insertamum::timestamp, 'DD.MM.YYYY HH24:MI') AS format_insertamum FROM public.tbl_msg_message m JOIN public.tbl_msg_recipient r ON m.message_id = r.message_id JOIN public.tbl_person se ON (m.person_id = se.person_id) @@ -122,7 +125,7 @@ class Message_model extends DB_Model ) s ON (m.message_id = s.message_id AND re.person_id = s.person_id) WHERE se.person_id = ? OR re.person_id = ? - '; + "; if (is_numeric($status)) { diff --git a/public/js/api/fhcapifactory.js b/public/js/api/fhcapifactory.js index c4106c3f6..7bc510b6e 100644 --- a/public/js/api/fhcapifactory.js +++ b/public/js/api/fhcapifactory.js @@ -33,6 +33,7 @@ import ort from "./ort.js"; import cms from "./cms.js"; import lehre from "./lehre.js"; import addons from "./addons.js"; +import messages from "./messages.js"; export default { search, @@ -52,5 +53,6 @@ export default { ort, cms, lehre, - addons + addons, + messages }; diff --git a/public/js/api/messages.js b/public/js/api/messages.js new file mode 100644 index 000000000..f1378c69d --- /dev/null +++ b/public/js/api/messages.js @@ -0,0 +1,5 @@ +import person from "./messages/person.js"; + +export default { + person +} \ No newline at end of file diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js new file mode 100644 index 000000000..bfbdaf123 --- /dev/null +++ b/public/js/api/messages/person.js @@ -0,0 +1,6 @@ +export default { + getMessages(url, config, params){ + console.log("in api", params); + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type); + }, +} \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage.js b/public/js/components/Messages/Details/NewMessage.js new file mode 100644 index 000000000..bf60842d2 --- /dev/null +++ b/public/js/components/Messages/Details/NewMessage.js @@ -0,0 +1,13 @@ +export default { + data(){ + return { + + } + }, + template: ` +
+

New Message

+
+ ` + +} \ No newline at end of file diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js new file mode 100644 index 000000000..bc7e6a02a --- /dev/null +++ b/public/js/components/Messages/Details/TableMessages.js @@ -0,0 +1,117 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; + +export default { + components: { + CoreFilterCmpt, + }, + props: { + endpoint: { + type: String, + required: true + }, + typeId: String, + id: { + type: [Number, String], + required: true + }, + }, + //TODO(Manu) endpoint macht Probleme + data(){ + return { + tabulatorOptions: { + ajaxURL: 'dummy', + ajaxRequestFunc: this.$fhcApi.factory.messages.person.getMessages, + ajaxParams: () => { + return { + id: this.id, + type: this.typeId + }; + }, + ajaxResponse: (url, params, response) => response.data, + columns: [ + {title: "subject", field: "subject"}, + {title: "body", field: "body", visible: false}, + {title: "message_id", field: "message_id", visible: false}, + {title: "datum", field: "format_insertamum"}, + {title: "sender", field: "sender"}, + {title: "recipient", field: "recipient"}, + {title: "sepersonid", field: "sepersonid"}, + {title: "repersonid", field: "repersonid"}, + {title: "status", field: "status"}, + { + 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'); + button.className = 'btn btn-outline-secondary btn-action'; + button.title = this.$p.t('ui', 'notiz_edit'); + button.innerHTML = ''; + button.addEventListener( + 'click', + (event) => + this.actionEditNotiz(cell.getData().notiz_id) + ); + container.append(button); + + button = document.createElement('button'); + button.className = 'btn btn-outline-secondary btn-action'; + button.title = this.$p.t('notiz', 'notiz_delete'); + button.innerHTML = ''; + button.addEventListener( + 'click', + () => + this.actionDeleteNotiz(cell.getData().notiz_id) + ); + container.append(button); + + return container; + }, + frozen: true + }], + layout: 'fitColumns', + layoutColumnsOnNewData: false, + height: '250', + selectableRangeMode: 'click', + selectable: true, + index: 'message_id', + persistenceID: 'core-message' + }, + } + }, +/* computed: { + statusText(){ + 0: this.$p.t('messsages', 'unread'), + 1: this.$p.t('messsages', 'read'), + 2: this.$p.t('messsages', 'archived'), + 0: this.$p.t('messsages', 'unread'), + 3: this.$p.t('person', 'deleted'), + } + },*/ + template: ` +
+

Table Messages

+

type_id: {{typeId}}

+

id: {{id}}

+

endpoint: {{endpoint}}

+ + + + + + +
+ ` + +} \ No newline at end of file diff --git a/public/js/components/Messages/Messages.js b/public/js/components/Messages/Messages.js new file mode 100644 index 000000000..6811a3aed --- /dev/null +++ b/public/js/components/Messages/Messages.js @@ -0,0 +1,48 @@ +import TableMessages from "./Details/TableMessages.js"; +import NewMessage from "./Details/NewMessage.js"; + +export default { + components: { + TableMessages, + NewMessage + }, + props: { + endpoint: { + type: String, + required: true + }, + typeId: String, + id: { + type: [Number, String], + required: true + }, + showNew: Boolean, + showTable: Boolean + }, + data() { + return {} + }, + template: ` +
+

endpoint: {{endpoint}}

+
+ + +
+ +
+ + + +
+ +
+ ` + +} \ No newline at end of file diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js new file mode 100644 index 000000000..7bd6d4b4d --- /dev/null +++ b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js @@ -0,0 +1,25 @@ +import CoreMessages from "../../../Messages/Messages.js"; + +export default { + components: { + CoreMessages + }, + props: { + modelValue: Object + }, + template: ` +
+ + + + + +
+ ` +}; \ No newline at end of file diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index cfaf85ec7..f25cc72ec 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -37297,7 +37297,30 @@ array( 'insertvon' => 'system' ) ) - ) + ), + /////////// FHC4 Phrases Messages START /////////// + array( + 'app' => 'core', + 'category' => 'stv', + 'phrase' => 'tab_messages', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nachrichten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Messages', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + /////////// FHC4 Phrases Messages END /////////// + ); From ae3072be924940441968f5d65a352245af043afc Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 11 Feb 2025 09:02:56 +0100 Subject: [PATCH 02/13] listTables with preview in two layouts --- .../api/frontend/v1/messages/Messages.php | 2 +- application/models/system/Message_model.php | 57 +++- public/css/Studentenverwaltung.css | 1 + public/css/components/Messages.css | 4 + public/js/api/messages/person.js | 1 - .../Messages/Details/TableMessages.js | 272 +++++++++++++++--- public/js/components/Messages/Messages.js | 15 +- .../Studentenverwaltung/Details/Messages.js | 3 +- system/phrasesupdate.php | 200 +++++++++++++ 9 files changed, 508 insertions(+), 47 deletions(-) create mode 100644 public/css/components/Messages.css diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index f81e85e9a..adf1d52e9 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -36,7 +36,7 @@ class Messages extends FHCAPI_Controller $this->terminateWithError("logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); } - $result = $this->MessageModel->getMessagesOfPerson($id); + $result = $this->MessageModel->getMessagesForTable($id); $data = $this->getDataOrTerminateWithError($result); diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 6288f54f3..1b201fc1b 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -109,10 +109,7 @@ class Message_model extends DB_Model re.vornamen AS revornamen, s.status, s.statusinfo, - s.insertamum AS statusamum, - CONCAT(se.titelpre, ' ', se.vorname, ' ', se.nachname, ' ', se.titelpost) as sender, - CONCAT(re.titelpre, ' ', re.vorname, ' ', re.nachname, ' ', re.titelpost ) as recipient, - TO_CHAR(s.insertamum::timestamp, 'DD.MM.YYYY HH24:MI') AS format_insertamum + s.insertamum AS statusamum FROM public.tbl_msg_message m JOIN public.tbl_msg_recipient r ON m.message_id = r.message_id JOIN public.tbl_person se ON (m.person_id = se.person_id) @@ -233,4 +230,56 @@ class Message_model extends DB_Model return $this->execQuery($query, $params); } + + /** + * Gets messages for a person for tableMessages. + * @param $person_id + * @param null $status message status. by default, latest status is returned + * @return array|null + */ + public function getMessagesForTable($person_id, $status = null) + { + $sql = " + SELECT + m.message_id AS message_id, + m.subject AS subject, + m.body AS body, + m.insertamum AS insertamum, + m.relationmessage_id AS relationmessage_id, + (SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = m.person_id) as sender, + (SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = r.person_id) as recipient, + m.person_id as sender_id, + r.person_id as recipient_id, + MAX(ss.status) as status, + MAX(ss.insertamum) as statusdatum + FROM public.tbl_msg_message m + JOIN public.tbl_msg_recipient r USING(message_id) + JOIN public.tbl_msg_status ss ON(r.message_id = ss.message_id AND ss.person_id = r.person_id) + WHERE m.person_id = ? + GROUP BY m.message_id, m.subject, m.body, m.insertamum, m.relationmessage_id, sender, recipient, sender_id, recipient_id + UNION ALL + SELECT + m.message_id AS message_id, + m.subject AS subject, + m.body AS body, + m.insertamum AS insertamum, + m.relationmessage_id AS relationmessage_id, + (SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = m.person_id) as sender, + (SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = r.person_id) as recipient, + m.person_id as sender_id, + r.person_id as recipient_id, + MAX(ss.status) as status, + MAX(ss.insertamum) as statusdatum + FROM public.tbl_msg_recipient r + JOIN public.tbl_msg_status ss USING(message_id, person_id) + JOIN public.tbl_msg_message m USING(message_id) + WHERE r.person_id = ? + GROUP BY m.message_id, m.subject, m.body, m.insertamum, m.relationmessage_id, sender, recipient, sender_id, recipient_id + ORDER BY insertamum + "; + + $parametersArray = array($person_id, $person_id); + + return $this->execQuery($sql, $parametersArray); + } } diff --git a/public/css/Studentenverwaltung.css b/public/css/Studentenverwaltung.css index f179c3667..cc2eff51d 100644 --- a/public/css/Studentenverwaltung.css +++ b/public/css/Studentenverwaltung.css @@ -4,6 +4,7 @@ @import './components/FilterComponent.css'; @import './components/Tabs.css'; @import './components/Notiz.css'; +@import './components/Messages.css'; html { font-size: .875em; diff --git a/public/css/components/Messages.css b/public/css/components/Messages.css new file mode 100644 index 000000000..1c004f6b0 --- /dev/null +++ b/public/css/components/Messages.css @@ -0,0 +1,4 @@ +.twoColumns { + height: 400px; + overflow-y: auto; +} diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index bfbdaf123..baf8bd39f 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -1,6 +1,5 @@ export default { getMessages(url, config, params){ - console.log("in api", params); return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type); }, } \ No newline at end of file diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index bc7e6a02a..c4fd4d4d7 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -1,8 +1,12 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; +import FormForm from '../../Form/Form.js'; +//import FormInput from '../../Form/Input.js'; export default { components: { CoreFilterCmpt, + FormForm, + // FormInput }, props: { endpoint: { @@ -14,6 +18,7 @@ export default { type: [Number, String], required: true }, + messageLayout: String, }, //TODO(Manu) endpoint macht Probleme data(){ @@ -32,12 +37,65 @@ export default { {title: "subject", field: "subject"}, {title: "body", field: "body", visible: false}, {title: "message_id", field: "message_id", visible: false}, - {title: "datum", field: "format_insertamum"}, + { + title: "Datum", + field: "insertamum", + 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 + }); + } + }, {title: "sender", field: "sender"}, {title: "recipient", field: "recipient"}, - {title: "sepersonid", field: "sepersonid"}, - {title: "repersonid", field: "repersonid"}, - {title: "status", field: "status"}, + {title: "senderId", field: "sender_id"}, + {title: "recipientId", field: "recipient_id"}, + { + title: "status", + field: "status", + formatter: function (cell) { + //TODO(Manu) get phrases in this context to work? + + /* const statusMap = { + 0: this.$p.t('messsages', 'unread'), + 1: this.$p.t('messsages', 'read'), + 2: this.$p.t('messsages', 'archived'), + 3: this.$p.t('messsages', 'deleted') + };*/ + const statusMap = { + 0: 'unread', + 1: 'read', + 2: 'archived', + 3: 'deleted' + }; + return statusMap[cell.getValue()]; + // return this.$p.t('messsages', 'deleted'); + } + + }, + { + title: "letzte Änderung", + field: "statusdatum", + 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 + }); + } + }, { title: 'Aktionen', field: 'actions', width: 100, @@ -47,23 +105,23 @@ export default { let button = document.createElement('button'); button.className = 'btn btn-outline-secondary btn-action'; - button.title = this.$p.t('ui', 'notiz_edit'); - button.innerHTML = ''; + button.title = this.$p.t('global', 'reply'); + button.innerHTML = ''; button.addEventListener( 'click', (event) => - this.actionEditNotiz(cell.getData().notiz_id) + this.reply(cell.getData().message_id) ); container.append(button); button = document.createElement('button'); button.className = 'btn btn-outline-secondary btn-action'; - button.title = this.$p.t('notiz', 'notiz_delete'); + button.title = this.$p.t('ui', 'loeschen'); button.innerHTML = ''; button.addEventListener( 'click', () => - this.actionDeleteNotiz(cell.getData().notiz_id) + this.deleteMessage(cell.getData().message_id) ); container.append(button); @@ -71,46 +129,186 @@ export default { }, frozen: true }], - layout: 'fitColumns', - layoutColumnsOnNewData: false, - height: '250', + layout: 'fitDataFill', + layoutColumnsOnNewData: false, + // height: 'auto', + height: '400', + selectable: true, + selectableRangeMode: 'click', +/* layoutColumnsOnNewData: false, + selectableRangeMode: 'click', selectable: true, index: 'message_id', - persistenceID: 'core-message' + persistenceID: 'core-message'*/ }, + tabulatorEvents: [ + { + event: 'dataLoaded', + handler: data => this.tabulatorData = data.map(item => { + return item; + }), + }, + { + 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('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; + console.log(selectedMessage); + } + }, + ], + tabulatorData: [], + previewBody: "" } }, -/* computed: { + methods: { + reply(message_id){ + console.log("in reply " + message_id); + }, + deleteMessage(message_id){ + console.log("deleteMessage " + message_id); + }, + actionNewMessage(){ + console.log("action new message"); + }, + }, + computed: { statusText(){ - 0: this.$p.t('messsages', 'unread'), - 1: this.$p.t('messsages', 'read'), - 2: this.$p.t('messsages', 'archived'), - 0: this.$p.t('messsages', 'unread'), - 3: this.$p.t('person', 'deleted'), + 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 + }); + });*/ + }, template: `
-

Table Messages

-

type_id: {{typeId}}

-

id: {{id}}

endpoint: {{endpoint}}

+

{{messageLayout}}

+ + + + + + +
- - - - - +
+ +
+ + +
+ + +
+



+ +
+
+
+ +
+ +
+
+ + +
+ + +
+ + +
+ + +
+ +
+
+
+ +
+
+
` diff --git a/public/js/components/Messages/Messages.js b/public/js/components/Messages/Messages.js index 6811a3aed..3fd6e2a02 100644 --- a/public/js/components/Messages/Messages.js +++ b/public/js/components/Messages/Messages.js @@ -17,14 +17,24 @@ export default { required: true }, showNew: Boolean, - showTable: Boolean + showTable: Boolean, + messageLayout: { + type: String, + default: 'twoColumnsTableLeft', + validator(value) { + return [ + 'twoColumnsTableLeft', + 'listTableTop' + ].includes(value) + } + }, }, data() { return {} }, template: `
-

endpoint: {{endpoint}}

+

endpoint Messages.js: {{endpoint}}

diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js index 7bd6d4b4d..e9f542945 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js @@ -14,12 +14,11 @@ export default { endpoint="$fhcApi.factory.messages.person" type-id="person_id" :id="modelValue.person_id" + messageLayout="listTableTop" show-table > - -
` }; \ No newline at end of file diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index f25cc72ec..95a505a23 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -37319,6 +37319,206 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'unread', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'ungelesen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'unread', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'read', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'gelesen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'read', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'archived', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'archiviert', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'archived', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'deleted', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'gelöscht', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'deleted', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'body', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nachrichtentext', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Body', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'message_id', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Message ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Message ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'sender', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'SenderIn', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Sender', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'recipient', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'EmpfängerIn', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Recipient', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'senderId', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'SenderIn ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Sender ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'messages', + 'phrase' => 'recipientId', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'EmpfängerIn ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Recipient ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), /////////// FHC4 Phrases Messages END /////////// ); From f89c194d3288d83aec44082fd1f8db4b7010618c Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 19 Feb 2025 11:36:00 +0100 Subject: [PATCH 03/13] add Vorlagendropdown Component and Listboxes for Messaging Variables --- .../api/frontend/v1/messages/Messages.php | 246 +++++++++- .../api/frontend/v1/vorlagen/Vorlagen.php | 63 +++ application/models/system/Message_model.php | 42 ++ application/models/system/Vorlage_model.php | 116 +++++ public/js/api/fhcapifactory.js | 4 +- public/js/api/messages/person.js | 29 ++ public/js/api/vorlagen.js | 8 + .../components/Messages/Details/NewMessage.js | 440 +++++++++++++++++- .../Messages/Details/TableMessages.js | 53 ++- public/js/components/Messages/Messages.js | 6 +- .../Studentenverwaltung/Details/Messages.js | 7 +- .../VorlagenDropdown/VorlagenDropdown.js | 109 +++++ system/phrasesupdate.php | 20 + 13 files changed, 1123 insertions(+), 20 deletions(-) create mode 100644 application/controllers/api/frontend/v1/vorlagen/Vorlagen.php create mode 100644 public/js/api/vorlagen.js create mode 100644 public/js/components/VorlagenDropdown/VorlagenDropdown.js diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index adf1d52e9..ac107f687 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -9,6 +9,14 @@ class Messages extends FHCAPI_Controller { parent::__construct([ 'getMessages' => ['admin:r', 'assistenz:r'], + 'getVorlagen' => ['admin:r', 'assistenz:r'], + 'getMessageVarsPerson' => ['admin:r', 'assistenz:r'], + 'getMsgVarsPrestudent' => ['admin:r', 'assistenz:r'], + 'getMsgVarsLoggedInUser' => ['admin:r', 'assistenz:r'], + 'getNameOfDefaultRecipient' => ['admin:r', 'assistenz:r'], + 'sendMessage' => ['admin:r', 'assistenz:r'], + 'deleteMessage' => ['admin:r', 'assistenz:r'], + 'getVorlagentext' => ['admin:r', 'assistenz:r'], ]); //Load Models @@ -20,6 +28,7 @@ class Messages extends FHCAPI_Controller // Load Libraries $this->load->library('VariableLib', ['uid' => getAuthUID()]); $this->load->library('form_validation'); + $this->load->library('MessageLib'); // Load language phrases $this->loadPhrases([ @@ -29,11 +38,17 @@ class Messages extends FHCAPI_Controller public function getMessages($id, $type_id) { - //$this->terminateWithError("in backend " . $type_id . ": " . $id, self::ERROR_TYPE_GENERAL); - - if ($type_id != "person_id") + switch($type_id) { - $this->terminateWithError("logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); + case 'uid': + $id = $this->_getPersonIdFromUid($id); + break; + case 'person_id': + $id = $id; + break; + default: + $this->terminateWithError("MESSAGES::getMessages logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); + break; } $result = $this->MessageModel->getMessagesForTable($id); @@ -42,4 +57,227 @@ class Messages extends FHCAPI_Controller $this->terminateWithSuccess($data); } + + public function getVorlagen() + { + //get oe of user + $uid = getAuthUID(); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung'); + + $data = $this->getDataOrTerminateWithError($result); + $oe_kurzbz = current($data); + + // $this->terminateWithError("oe: ". $oe_kurzbz->oe_kurzbz, self::ERROR_TYPE_GENERAL); + + $this->load->model('system/Vorlage_model', 'VorlageModel'); + + //39 Stück Variante OE + $result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + + //IF ADMIN 167 + $this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC'); + //only HTML-vorlagen -> for admin + $result = $this->VorlageModel->loadWhere( + array( + 'mimetype' => 'text/html' + )); + + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getVorlagentext($vorlage_kurzbz) + { + //$this->terminateWithError("vor " . $vorlage_kurzbz, self::ERROR_TYPE_GENERAL); + //$studiengang_kz = 227; //TODO(Manu) check dynamisieren NULL + $studiengang_kz = 0; + $this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel'); + $this->VorlagestudiengangModel->addOrder('version', 'DESC'); + + $result = $this->VorlagestudiengangModel->loadWhere( + [ + 'vorlage_kurzbz' =>$vorlage_kurzbz, + 'studiengang_kz' => $studiengang_kz + ]); + + $data = $this->getDataOrTerminateWithError($result); + + //not correct with Vorlage + $vorlage = current($data); + + //$this->terminateWithSuccess($data); + $this->terminateWithSuccess($vorlage->text); + } + + public function getMessageVarsPerson() + { + $result = $this->MessageModel->getMessageVarsPerson(); + + $data = $this->getDataOrTerminateWithError($result); + + + $this->terminateWithSuccess($data); + } + + public function getMsgVarsPrestudent($uid) + { + + $prestudent_id = $this-> _getPrestudentIdFromUid($uid); + + // $this->terminateWithError("prestudent_id " . $prestudent_id, self::ERROR_TYPE_GENERAL); + + $result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id); + + $data = $this->getDataOrTerminateWithError($result); + + + $this->terminateWithSuccess($data); + } + + public function getMsgVarsLoggedInUser() + { + $uid = getAuthUID(); + + $result = $this->MessageModel->getMsgVarsLoggedInUser(); + + $data = $this->getDataOrTerminateWithError($result); + + + $this->terminateWithSuccess($data); + } + + public function getNameOfDefaultRecipient($id, $type_id) + { + switch($type_id) + { + case 'uid': + $id = $this->_getPersonIdFromUid($id); + break; + case 'person_id': + $id = $id; + break; + default: + $this->terminateWithError("MESSAGES::getNameOfDefaultRecipient logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); + break; + } + + $this->load->model('person/Person_model', 'PersonModel'); + + $result = $this->PersonModel->load($id); + //$this->terminateWithSuccess($result); + $data = $this->getDataOrTerminateWithError($result); + $name = current($data); + + $this->terminateWithSuccess($name->vorname . " " . $name->nachname ); + } + + public function sendMessage($recipient_id) + { + //TODO(manu) Problems with Vorlagen... + //TODO(Manu) Problems with VARS + $receiversPersonId = $this->_getPersonIdFromUid($recipient_id); + + $uid = getAuthUID(); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $result = $this->BenutzerModel->loadWhere( + ['uid' => $uid] + ); + + $data = $this->getDataOrTerminateWithError($result); + $benutzer = current($data); + + if (isset($_POST['data'])) + { + $data = json_decode($_POST['data']); + unset($_POST['data']); + foreach ($data as $k => $v) { + $_POST[$k] = $v; + } + } + + $subject = $this->input->post('subject'); + + $body = $this->input->post('body'); + + // $this->terminateWithError("rp_id " . $receiversPersonId, self::ERROR_TYPE_GENERAL); + +/* $subject = $this->input->post('subject'); + + $formData = $this->input->post('data');*/ + + //$_POST['subject'] = $formData['subject']; + // $subject = $formData['subject']; + // $body = $formData['body']; + + // $subject = isset($_POST['subject']) ? $_POST['subject'] : null; + // $body = isset($_POST['body']) ? $_POST['body'] : null; + + // $this->terminateWithError("person_id " . $receiversPersonId, self::ERROR_TYPE_GENERAL); + + // $this->terminateWithError("subject " . $subject, self::ERROR_TYPE_GENERAL); + // $this->terminateWithError("body " . $body, self::ERROR_TYPE_GENERAL); + + // $this->terminateWithError("person_id " . $benutzer->person_id, self::ERROR_TYPE_GENERAL); + // $this->terminateWithError("subject " . $subject, self::ERROR_TYPE_GENERAL); + $result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $body, $benutzer->person_id); + + $this->terminateWithSuccess($result); + } + + public function deleteMessage($messageId) + { + // Start DB transaction + $this->db->trans_begin(); + + $result = $this->MessageModel->deleteMessageRecipient($messageId); + if (isError($result)) { + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + + $result = $this->MessageModel->deleteMessageStatus($messageId); + if (isError($result)) { + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + + $result = $this->MessageModel->deleteMessage($messageId); + if (isError($result)) { + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + + $this->db->trans_commit(); + + $this->terminateWithSuccess($result); + } + + private function _getPersonIdFromUid($uid) + { + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $result = $this->BenutzerModel->loadWhere( + ['uid' => $uid] + ); + + $data = $this->getDataOrTerminateWithError($result); + $benutzer = current($data); + + return $benutzer->person_id; + } + + private function _getPrestudentIdFromUid($uid) + { + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->loadWhere( + ['student_uid' => $uid] + ); + + $data = $this->getDataOrTerminateWithError($result); + $student = current($data); + + return $student->prestudent_id; + } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/vorlagen/Vorlagen.php b/application/controllers/api/frontend/v1/vorlagen/Vorlagen.php new file mode 100644 index 000000000..01edb33d1 --- /dev/null +++ b/application/controllers/api/frontend/v1/vorlagen/Vorlagen.php @@ -0,0 +1,63 @@ + ['admin:r', 'assistenz:r'], + 'getVorlagenByLoggedInUser' => ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('system/Vorlage_model', 'VorlageModel'); + + // Additional Permission Checks + //TODO(manu) check permissions + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $this->load->library('form_validation'); + $this->load->library('VorlageLib'); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function getVorlagen() + { + $this->load->model('system/Vorlage_model', 'VorlageModel'); + + $this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC'); + + $result = $this->VorlageModel->loadWhere( + array( + 'mimetype' => 'text/html' + )); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getVorlagenByLoggedInUser() + { + //get oe of user + $uid = getAuthUID(); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung'); + + $data = $this->getDataOrTerminateWithError($result); + $oe_kurzbz = current($data); + + $result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + +} \ No newline at end of file diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 1b201fc1b..7ecb54a9e 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -282,4 +282,46 @@ class Message_model extends DB_Model return $this->execQuery($sql, $parametersArray); } + + /** + * Deletes a messages from tableMessages and tbl_msg_recipient + * TODO(MANU) CHECK IF NECESSARY + * dependency with other tables + * in case of reply... more messages + * maybe anonimize it + * @param $message_id + * @return boolean success + */ + public function deleteMessageRecipient($message_id) + { + $sql = " + DELETE FROM public.tbl_msg_recipient + WHERE message_id = ?; + "; + + return $this->execQuery($sql, array($message_id)); + } + + + public function deleteMessageStatus($message_id) + { + $sql = " + DELETE FROM public.tbl_msg_status + WHERE message_id = ?; + "; + + return $this->execQuery($sql, array($message_id)); + } + + public function deleteMessage($message_id) + { + $sql = " + DELETE FROM public.tbl_msg_message + WHERE message_id = ?; + "; + + return $this->execQuery($sql, array($message_id)); + } + + } diff --git a/application/models/system/Vorlage_model.php b/application/models/system/Vorlage_model.php index 8022e71fc..69aa0aa3f 100644 --- a/application/models/system/Vorlage_model.php +++ b/application/models/system/Vorlage_model.php @@ -21,4 +21,120 @@ class Vorlage_model extends DB_Model return $this->execQuery($query); } + + /** + * Returns all Vorlagen + * that belongs to the organisation units of the user + * and the parents of those organisation units until the root of the + * @param Array Array of $oe_kurzbz + * @return object Array of Vorlagen + */ + public function getAllVorlagenByOe($oe_kurzbz) + { + // Loads library OrganisationseinheitLib + $this->load->library('OrganisationseinheitLib'); + + $vorlage = success(array()); // Default value + + $table = '( + SELECT v.vorlage_kurzbz, + v.bezeichnung, + vs.version, + vs.oe_kurzbz, + vs.aktiv, + vs.subject, + vs.text, + v.mimetype + FROM tbl_vorlagestudiengang vs + JOIN tbl_vorlage v USING(vorlage_kurzbz) + ) templates'; + + $alias = 'templates'; + + $fields = array( + 'templates.vorlage_kurzbz AS id', + 'templates.bezeichnung || \' (\' || UPPER(templates.oe_kurzbz) || \')\' AS description' + ); + + $where = 'templates.aktiv = TRUE + AND templates.subject IS NOT NULL + AND templates.text IS NOT NULL + AND templates.mimetype = \'text/html\' + GROUP BY 1, 2, 3'; + + $order_by = 'description ASC'; + + if (!is_array($oe_kurzbz)) + { + $vorlage = $this->organisationseinheitlib->treeSearchEntire( + $table, + $alias, + $fields, + $where, + $order_by, + $oe_kurzbz + ); + } + else // is an array + { + // Get the vorlage for each organisation unit + foreach($oe_kurzbz as $val) + { + $tmpVorlage = $this->organisationseinheitlib->treeSearchEntire( + $table, + $alias, + $fields, + $where, + $order_by, + $val + ); + + // Everything is ok and data are inside + if (hasData($tmpVorlage)) + { + // If it's the first vorlage copy it + if (!hasData($vorlage)) + { + for ($j = 0; $j < count(getData($tmpVorlage)); $j++) + { + if (getData($tmpVorlage)[$j]->id != '') + { + array_push($vorlage->retval, getData($tmpVorlage)[$j]); + } + } + } + else // checks for duplicates, if it's not already present push it into the array getData($vorlage) + { + for ($j = 0; $j < count(getData($tmpVorlage)); $j++) + { + $found = false; + $currentTmpVorlageData = null; + + for ($i = 0; $i < count(getData($vorlage)); $i++) + { + $currentTmpVorlageData = getData($tmpVorlage)[$j]; + + if (getData($vorlage)[$i]->id == getData($tmpVorlage)[$j]->id + && getData($vorlage)[$i]->_pk == getData($tmpVorlage)[$j]->_pk + && getData($vorlage)[$i]->_ppk == getData($tmpVorlage)[$j]->_ppk + && getData($vorlage)[$i]->_jtpk == getData($tmpVorlage)[$j]->_jtpk) + { + $found = true; + break; + } + } + + if (!$found && $currentTmpVorlageData->id != '') + { + array_push($vorlage->retval, $currentTmpVorlageData); + } + } + } + } + } + } + + return $vorlage; + } + } diff --git a/public/js/api/fhcapifactory.js b/public/js/api/fhcapifactory.js index 7bc510b6e..8a4a2132a 100644 --- a/public/js/api/fhcapifactory.js +++ b/public/js/api/fhcapifactory.js @@ -34,6 +34,7 @@ import cms from "./cms.js"; import lehre from "./lehre.js"; import addons from "./addons.js"; import messages from "./messages.js"; +import vorlagen from "./vorlagen.js"; export default { search, @@ -54,5 +55,6 @@ export default { cms, lehre, addons, - messages + messages, + vorlagen }; diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index baf8bd39f..6a0ac8c7c 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -2,4 +2,33 @@ export default { getMessages(url, config, params){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type); }, + getVorlagen(){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagen/'); + }, + getMsgVarsLoggedInUser(){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsLoggedInUser/'); + }, + getMessageVarsPerson(){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessageVarsPerson/'); + }, + getMsgVarsPrestudent(uid){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + uid); + }, + getVorlagentext(vorlage_kurzbz){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz); + }, + getNameOfDefaultRecipient(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id); + }, + sendMessage(form, id, data) { + console.log("factory " + id); + console.log(JSON.stringify(data)); + + return this.$fhcApi.post(form, 'api/frontend/v1/messages/messages/sendMessage/' + id, + data + ); + }, + deleteMessage(messageId){ + return this.$fhcApi.post('api/frontend/v1/messages/messages/deleteMessage/' + messageId); + } } \ No newline at end of file diff --git a/public/js/api/vorlagen.js b/public/js/api/vorlagen.js new file mode 100644 index 000000000..2933ccf97 --- /dev/null +++ b/public/js/api/vorlagen.js @@ -0,0 +1,8 @@ +export default { + getVorlagen() { + return this.$fhcApi.get('api/frontend/v1/vorlagen/vorlagen/getVorlagen/'); + }, + getVorlagenByLoggedInUser() { + return this.$fhcApi.get('api/frontend/v1/vorlagen/vorlagen/getVorlagenByLoggedInUser/'); + } +} \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage.js b/public/js/components/Messages/Details/NewMessage.js index bf60842d2..2d85c8e00 100644 --- a/public/js/components/Messages/Details/NewMessage.js +++ b/public/js/components/Messages/Details/NewMessage.js @@ -1,12 +1,448 @@ +import FormForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import ListBox from "../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; +import DropdownComponent from '../../VorlagenDropdown/VorlagenDropdown.js'; + + export default { + components: { + FormForm, + FormInput, + ListBox, + DropdownComponent + }, + props: { + endpoint: { + type: String, + required: true + }, + typeId: String, + id: { + type: [Number, String], + required: true + }, + }, data(){ return { - + formData: { + recipient: this.id, + subject: null, + body: null, + vorlage_kurzbz: null, + selectedValue: '', + }, + statusNew: true, + vorlagen: [], + defaultRecipient: null, + editor: null, + isVisible: true, + fieldsUser: [], + fieldsPerson: [], + fieldsPrestudent: [], + selectedFieldPrestudent: null, + selectedFieldUser: null, + selectedFieldPerson: null, + itemsPrestudent: [], + itemsPerson: [], + itemsUser: [], + selectedFieldStudent: null, + itemsStudent: [ + { label: "Variable 1", value: "var1" }, + { label: "Variable 2", value: "var2" }, + { label: "Variable 3", value: "var3" } + ] } }, + methods: { + initTinyMCE() { + const vm = this; + tinymce.init({ + target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component + //height: 800, + //plugins: ['lists'], + toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify', + style_formats: [ + {title: 'Blocks', block: 'div'}, + {title: 'Paragraph', block: 'p'}, + {title: 'Heading 1', block: 'h1'}, + {title: 'Heading 2', block: 'h2'}, + {title: 'Heading 3', block: 'h3'}, + {title: 'Heading 4', block: 'h4'}, + {title: 'Heading 5', block: 'h5'}, + {title: 'Heading 6', block: 'h6'}, + ], + autoresize_bottom_margin: 16, + + setup: (editor) => { + vm.editor = editor; + + editor.on('input', () => { + const newContent = editor.getContent(); + vm.formData.body = newContent; + }); + }, + }); + }, + updateText(value) { + this.formData.body = value; + }, + sendMessage(){ + //TODO(Manu) check default recipient(s) + const data = new FormData(); + + data.append('data', JSON.stringify(this.formData)); + return this.$fhcApi.factory.messages.person.sendMessage(this.$refs.formVorlage, this.id, data) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); + //this.hideModal('messageModal'); + this.resetForm(); + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + } + ); + }, + getVorlagentext(vorlage_kurzbz){ + //console.log(typeof vorlage_kurzbz); + return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) + .then(response => { + //this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); + //this.hideModal('messageModal'); + //this.resetForm(); + //TODO(Manu) CHECK + this.formData.body = response.data; + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + }); + }, + insertVariable(selectedItem){ + if (this.editor) { + this.editor.insertContent(selectedItem.value + " "); + } else { + console.error("Editor instance is not available."); + } + }, + //TODO(Manu) refactor +/* insertVariablePrestudent() { + if (this.editor) { + //const lastVariable = this.selectedFieldsPrestudent[this.selectedFieldsPrestudent.length - 1].value; + const lastVariable = this.selectedFieldPrestudent.value; + + //Use insertContent method + this.editor.insertContent(lastVariable + " "); + } else { + console.error("Editor instance is not available."); + } + },*/ +/* insertVariablePrestudentByClick(selectedItem) { + + if (selectedItem) { + this.editor.insertContent(selectedItem.value + " "); + console.log("Eingefügte Variable:", selectedItem); + } else { + console.warn("Keine Variable ausgewählt!"); + } + }, + + insertVariablePerson() { + if (this.editor) { + //const lastVariable = this.selectedFieldsPrestudent[this.selectedFieldsPrestudent.length - 1].value; + const lastVariable = this.selectedFieldPerson.value; + + //Use insertContent method + this.editor.insertContent(lastVariable + " "); + } else { + console.error("Editor instance is not available."); + } + }, + insertVariableUser() { + if (this.editor) { + console.log(this.selectedFieldUser.value); + const lastVariable = this.selectedFieldUser.value; + + //Multiple + //const lastVariable = this.selectedFieldsPrestudent[this.selectedFieldsPrestudent.length - 1].value; + + //Use insertContent method + this.editor.insertContent(lastVariable + " "); + this.selectedFieldUser = null; + } else { + console.error("Editor instance is not available."); + } + }, + insertVariableStudent(selectedItem) { + if (selectedItem) { + console.log("Eingefügte Variable:", selectedItem); + this.editor.insertContent(selectedItem.value + " "); + } else { + console.warn("Keine Variable ausgewählt!"); + } + },*/ + replyMessage(message_id){ + console.log("auf message " + message_id + " antworten"); + }, + resetForm(){ + this.formData = { + vorlage_kurzbz: null, + body: null, + subject: null, + }; + if (this.editor) { + this.editor.setContent(""); + } + this.$refs.dropdownComp.setValue(null); + + }, + toggleDivNewMessage(){ + this.isVisible = !this.isVisible; + }, + handleSelectedVorlage(vorlage_kurzbz) { + if (typeof vorlage_kurzbz === "string") { + this.getVorlagentext(vorlage_kurzbz); + this.formData.subject = vorlage_kurzbz; + } + }, + }, + watch: { + 'formData.body': { + handler(newVal) { + const tinymcsVal = this.editor.getContent(); + + if (newVal && tinymcsVal != newVal) { + //Inhalt des Editors aktualisieren + this.editor.setContent(newVal); + } + } + }, + 'formData.vorlage_kurzbz': { + handler(newVal){ + // console.log("Vorlage: " + newVal); + + if (newVal && newVal != null) { + this.formData.subject = newVal; + return this.getVorlagentext(newVal); + } + //TODO(Manu) own function or retval to getVorlagentext + //component VorlagenComponent + + } + } + }, + created(){ + + if(this.typeId == 'person_id'){ + this.$fhcApi.factory.messages.person.getMessageVarsPerson() + .then(result => { + this.fieldsPerson = result.data; + this.itemsPerson = Object.entries(this.fieldsPerson).map(([key, value]) => ({ + label: value, + value: '{' + value + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + } + + if(this.typeId == 'uid') { + this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(this.id) + .then(result => { + this.fieldsPrestudent = result.data; + const prestudent = this.fieldsPrestudent[0]; + //Just for testing with inserting values +/* this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ + label: key, + value: value + }));*/ + this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ + label: key, + value: '{' + key + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + } + + this.$fhcApi.factory.messages.person.getMsgVarsLoggedInUser() + .then(result => { + this.fieldsUser = result.data; + const user = this.fieldsUser; + this.itemsUser = Object.entries(user).map(([key, value]) => ({ + label: value, + value: '{' + value + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$fhcApi.factory.messages.person.getNameOfDefaultRecipient({ + id: this.id, + type_id: this.typeId}) + .then(result => { + this.defaultRecipient = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + async mounted() { + this.initTinyMCE(); + }, + beforeDestroy() { + this.editor.destroy(); + }, template: `
-

New Message

+ +
+

New Message

+ + {{typeId}} {{id}} + + {{formData.subject}} + {{formData.vorlage_kurzbz}} + +

+ formData.body befüllt +

+ +
+ +
+ + + +
+ + + +
+ +
+ + +
+ + +
+ + +
+ +
+ + +
+ +
+
+ +
+ +
+ Felder Prestudent +
+ + + + + +
+ + +

{{selectedFieldPrestudent}}

+ +
+ +
+ Felder Person +
+ + + + + +
+ +

{{selectedFieldPerson}}

+
+ +
+ Meine Felder +
+ + + + + +
+ +
+ + +
+ + + + + +
+ +
+ +
+
+ +
+ +
` diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index c4fd4d4d7..0025d7b47 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -1,12 +1,15 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; import FormForm from '../../Form/Form.js'; -//import FormInput from '../../Form/Input.js'; export default { components: { CoreFilterCmpt, FormForm, - // FormInput + }, + inject: { + cisRoot: { + from: 'cisRoot' + }, }, props: { endpoint: { @@ -121,7 +124,7 @@ export default { button.addEventListener( 'click', () => - this.deleteMessage(cell.getData().message_id) + this.actionDeleteMessage(cell.getData().message_id) ); container.append(button); @@ -197,7 +200,6 @@ export default { const selectedMessage = row.getData().message_id; const body = row.getData().body; this.previewBody = body; - console.log(selectedMessage); } }, ], @@ -209,11 +211,45 @@ export default { reply(message_id){ console.log("in reply " + message_id); }, + 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){ - console.log("deleteMessage " + message_id); + // console.log("deleteMessage " + message_id); + return this.$fhcApi.factory.messages.person.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(){ - console.log("action new message"); + //console.log("action new message"); + if (this.openMode == "window") { + console.log("openInNewWindow") + const linkWindowNewMessage = this.cisRoot + '/public/js/components/Messages/Details/NewMessage.js'; + window.open(linkWindowNewMessage, '_blank'); + } + else if (this.openmode == "modal"){ + console.log("open with bootstrap Modal"); + } + else if (this.openmode == "showDiv"){ + console.log("open div in NewMessage.js"); + //emit to NewMessage.js + } + else + console.log("no valid openmode: yet to be developed"); + }, + reload() { + this.$refs.table.reloadTable(); }, }, computed: { @@ -238,8 +274,9 @@ export default { }, template: `
-

endpoint: {{endpoint}}

-

{{messageLayout}}

+ + +
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js index e9f542945..14d74e56c 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js @@ -12,10 +12,11 @@ export default { diff --git a/public/js/components/VorlagenDropdown/VorlagenDropdown.js b/public/js/components/VorlagenDropdown/VorlagenDropdown.js new file mode 100644 index 000000000..e4c48501a --- /dev/null +++ b/public/js/components/VorlagenDropdown/VorlagenDropdown.js @@ -0,0 +1,109 @@ +import {CoreFilterCmpt} from "../filter/Filter.js"; +import FormForm from '../Form/Form'; +import FormInput from '../Form/Input.js'; + +export default { + components: { + FormForm, + FormInput, + CoreFilterCmpt + }, + props: { + label: { + type: String, + required: true + }, + modelValue: { + type: String, + required: true + }, +/* oe: { + type: Array, + required: false + }, */ + isAdmin: { + type: Boolean, + required: true + }, + useLoggedInUserOe: { + type: Boolean, + required: true + } + }, + data() { + return { + vorlagen: [], + selectedValue: null, + vorlagenOe: [] + } + }, + methods: { + updateValue() { + // console.log("in COMPO: update: " + this.selectedValue + ' jetzt ' + 'InfocenterMailErgaenzungsprfEng'); + this.$emit('change', this.selectedValue); + //this.$emit('change', this.selectedValue); // Emit-Event beim Ändern des Wertes + }, + setValue(value) { + this.selectedValue = value; + }, + }, + created() { + + if(this.isAdmin) { + this.$fhcApi.factory.vorlagen.getVorlagen() + .then(result => { + this.vorlagen = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + } + + if(this.useLoggedInUserOe){ + this.$fhcApi.factory.vorlagen.getVorlagenByLoggedInUser() + .then(result => { + console.log(this.vorlagenOe); + this.vorlagenOe = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + } + }, +template: ` +
+
+ + + +
+ +
+ + + +
+ +
+ `, +} \ No newline at end of file diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 95a505a23..63cf34038 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -37519,6 +37519,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'successSent', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nachricht erfolgreich versandt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Message sent successfully', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), /////////// FHC4 Phrases Messages END /////////// ); From 3c34b17d2d37dcc87489cdf26d478e44a01fbe33 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 21 Feb 2025 14:58:59 +0100 Subject: [PATCH 04/13] add Preview-logic, update function sendMessage --- .../api/frontend/v1/messages/Messages.php | 96 +++- application/models/system/Message_model.php | 1 - public/js/api/messages/person.js | 12 +- .../components/Messages/Details/NewMessage.js | 411 +++++++++++------- .../Messages/Details/TableMessages.js | 10 +- public/js/components/Messages/Messages.js | 33 +- .../Studentenverwaltung/Details/Messages.js | 2 + .../VorlagenDropdown/VorlagenDropdown.js | 8 +- 8 files changed, 368 insertions(+), 205 deletions(-) diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index ac107f687..788c8861e 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -17,10 +17,12 @@ class Messages extends FHCAPI_Controller 'sendMessage' => ['admin:r', 'assistenz:r'], 'deleteMessage' => ['admin:r', 'assistenz:r'], 'getVorlagentext' => ['admin:r', 'assistenz:r'], + 'getPreviewText' => ['admin:r', 'assistenz:r'], ]); //Load Models $this->load->model('system/Message_model', 'MessageModel'); + $this->load->model('CL/Messages_model', 'MessagesModel'); // Additional Permission Checks //TODO(manu) check permissions @@ -179,8 +181,7 @@ class Messages extends FHCAPI_Controller public function sendMessage($recipient_id) { - //TODO(manu) Problems with Vorlagen... - //TODO(Manu) Problems with VARS + //default setting $receiversPersonId = $this->_getPersonIdFromUid($recipient_id); $uid = getAuthUID(); @@ -201,35 +202,94 @@ class Messages extends FHCAPI_Controller } } - $subject = $this->input->post('subject'); + $this->load->library('form_validation'); + $this->form_validation->set_rules('subject', 'Betreff', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Betreff']) + ]); + + $this->form_validation->set_rules('body', 'Text', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Text']) + ]); + + if ($this->form_validation->run() == false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $subject = $this->input->post('subject'); $body = $this->input->post('body'); - // $this->terminateWithError("rp_id " . $receiversPersonId, self::ERROR_TYPE_GENERAL); -/* $subject = $this->input->post('subject'); - $formData = $this->input->post('data');*/ + $typeId = $this->input->post('type_id'); + $id = $this->input->post('id'); - //$_POST['subject'] = $formData['subject']; - // $subject = $formData['subject']; - // $body = $formData['body']; + if($typeId == 'uid') + { + //$this->terminateWithError("uid ", self::ERROR_TYPE_GENERAL); + $prestudent_id = $this-> _getPrestudentIdFromUid($id); - // $subject = isset($_POST['subject']) ? $_POST['subject'] : null; - // $body = isset($_POST['body']) ? $_POST['body'] : null; + //parseMessagetext for variables Prestudent + $result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $body); + $bodyParsed = $this->getDataOrTerminateWithError($result); + } + elseif($typeId == 'person_id') + { + $this->terminateWithError("person_id ", self::ERROR_TYPE_GENERAL); - // $this->terminateWithError("person_id " . $receiversPersonId, self::ERROR_TYPE_GENERAL); + $result = $this->MessagesModel->parseMessageTextPerson($id, $body); + $bodyParsed = $this->getDataOrTerminateWithError($result); + } + elseif($typeId == 'prestudent_id') + { + $this->terminateWithError("prestudent_id ", self::ERROR_TYPE_GENERAL); - // $this->terminateWithError("subject " . $subject, self::ERROR_TYPE_GENERAL); - // $this->terminateWithError("body " . $body, self::ERROR_TYPE_GENERAL); + $result = $this->MessagesModel->parseMessageTextPrestudent($id, $body); + $bodyParsed = $this->getDataOrTerminateWithError($result); + } + else + { + $this->terminateWithError("type_id " . $typeId . " not valid", self::ERROR_TYPE_GENERAL); + } - // $this->terminateWithError("person_id " . $benutzer->person_id, self::ERROR_TYPE_GENERAL); - // $this->terminateWithError("subject " . $subject, self::ERROR_TYPE_GENERAL); - $result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $body, $benutzer->person_id); + $result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $bodyParsed, $benutzer->person_id); $this->terminateWithSuccess($result); } + public function getPreviewText($id, $type_id) + { + if (isset($_POST['data'])) + { + $data = json_decode($_POST['data']); + unset($_POST['data']); + + } + else + $this->terminateWithError("Textbody missing ", self::ERROR_TYPE_GENERAL); + + switch($type_id) + { + case 'uid': + $prestudent_id = $this->_getPrestudentIdFromUid($id); + $result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $data); + + break; + case 'person_id': + $id = $id; + break; + default: + $this->terminateWithError("MESSAGES::getPreviewText logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); + break; + } + + //$this->terminateWithSuccess($result); + $bodyParsed = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($bodyParsed); + } + public function deleteMessage($messageId) { // Start DB transaction @@ -238,6 +298,7 @@ class Messages extends FHCAPI_Controller $result = $this->MessageModel->deleteMessageRecipient($messageId); if (isError($result)) { return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } $result = $this->MessageModel->deleteMessageStatus($messageId); @@ -265,6 +326,7 @@ class Messages extends FHCAPI_Controller $data = $this->getDataOrTerminateWithError($result); $benutzer = current($data); + //return $data->person_id; return $benutzer->person_id; } diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 7ecb54a9e..0fdb39736 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -323,5 +323,4 @@ class Message_model extends DB_Model return $this->execQuery($sql, array($message_id)); } - } diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index 6a0ac8c7c..5cbb49550 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -20,13 +20,13 @@ export default { getNameOfDefaultRecipient(params){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id); }, + getPreviewText(params, data){ + return this.$fhcApi.post('api/frontend/v1/messages/messages/getPreviewText/' + params.id + '/' + params.type_id, + data); + }, sendMessage(form, id, data) { - console.log("factory " + id); - console.log(JSON.stringify(data)); - - return this.$fhcApi.post(form, 'api/frontend/v1/messages/messages/sendMessage/' + id, - data - ); + return this.$fhcApi.post(form,'api/frontend/v1/messages/messages/sendMessage/' + id, + data); }, deleteMessage(messageId){ return this.$fhcApi.post('api/frontend/v1/messages/messages/deleteMessage/' + messageId); diff --git a/public/js/components/Messages/Details/NewMessage.js b/public/js/components/Messages/Details/NewMessage.js index 2d85c8e00..c8aae2124 100644 --- a/public/js/components/Messages/Details/NewMessage.js +++ b/public/js/components/Messages/Details/NewMessage.js @@ -3,7 +3,6 @@ import FormInput from '../../Form/Input.js'; import ListBox from "../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; import DropdownComponent from '../../VorlagenDropdown/VorlagenDropdown.js'; - export default { components: { FormForm, @@ -21,6 +20,7 @@ export default { type: [Number, String], required: true }, + openMode: String, }, data(){ return { @@ -45,12 +45,14 @@ export default { itemsPrestudent: [], itemsPerson: [], itemsUser: [], - selectedFieldStudent: null, +/* selectedFieldStudent: null, itemsStudent: [ { label: "Variable 1", value: "var1" }, { label: "Variable 2", value: "var2" }, { label: "Variable 3", value: "var3" } - ] + ]*/ + previewText: null, + previewBody: "" } }, methods: { @@ -86,22 +88,35 @@ export default { updateText(value) { this.formData.body = value; }, - sendMessage(){ + sendMessage() { //TODO(Manu) check default recipient(s) const data = new FormData(); + const params = { + id: this.id, + type_id: this.typeId + }; + const merged = { + ...this.formData, + ...params + }; + data.append('data', JSON.stringify(merged)); - data.append('data', JSON.stringify(this.formData)); - return this.$fhcApi.factory.messages.person.sendMessage(this.$refs.formVorlage, this.id, data) + return this.$fhcApi.factory.messages.person.sendMessage( + this.$refs.formMessage, + this.id, + data) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); //this.hideModal('messageModal'); + this.hideTemplate(); this.resetForm(); }).catch(this.$fhcAlert.handleSystemError) .finally(() => { - //this.resetForm(); - //closeModal - //closewindwo - } + //this.resetForm(); + //closeModal + //closewindwo + this.$emit('reloadTable'); + } ); }, getVorlagentext(vorlage_kurzbz){ @@ -120,9 +135,37 @@ export default { //closewindwo }); }, + getPreviewText(){ + const data = new FormData(); + + data.append('data', JSON.stringify(this.formData.body)); + return this.$fhcApi.factory.messages.person.getPreviewText({ + id: this.id, + type_id: this.typeId}, data) + .then(response => { + this.previewText = response.data; + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + }); + }, insertVariable(selectedItem){ if (this.editor) { this.editor.insertContent(selectedItem.value + " "); + //TODO(Manu) check: nicht mal mit Punkt adden gehts ohne eintrag nach vars +/* this.editor.focus(); + this.editor.setDirty(true);*/ + + //this.editor.fire('change'); //forces + + //this.editor.undoManager.add(); + + //this.editor.insertContent(selectedItem.value + "\u00A0"); + //this.editor.insertContent(`${selectedItem.value} `); + //this.editor.selection.setCursorLocation(this.editor.getBody(), 1); + } else { console.error("Editor instance is not available."); } @@ -207,6 +250,19 @@ export default { this.formData.subject = vorlage_kurzbz; } }, + hideTemplate(){ + if (this.openMode == "showDiv") + this.isVisible = false; + }, + showTemplate(){ + if (this.openMode == "showDiv") + this.isVisible = true; + }, + showPreview(){ + this.getPreviewText().then(() => { + this.previewBody = this.previewText; + }); + } }, watch: { 'formData.body': { @@ -227,14 +283,10 @@ export default { this.formData.subject = newVal; return this.getVorlagentext(newVal); } - //TODO(Manu) own function or retval to getVorlagentext - //component VorlagenComponent - } } }, created(){ - if(this.typeId == 'person_id'){ this.$fhcApi.factory.messages.person.getMessageVarsPerson() .then(result => { @@ -246,7 +298,6 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); } - if(this.typeId == 'uid') { this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(this.id) .then(result => { @@ -258,8 +309,8 @@ export default { value: value }));*/ this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ - label: key, - value: '{' + key + '}' + label: key.toLowerCase(), + value: '{' + key.toLowerCase() + '}' })); }) .catch(this.$fhcAlert.handleSystemError); @@ -292,157 +343,185 @@ export default { }, template: `
- -
-

New Message

- - {{typeId}} {{id}} - - {{formData.subject}} - {{formData.vorlage_kurzbz}} - -

- formData.body befüllt -

- -
- -
- - - -
- - - -
- -
- - -
- - -
- - -
- -
- - -
- -
-
- -
- -
- Felder Prestudent -
- - - - - -
- - -

{{selectedFieldPrestudent}}

- -
- -
- Felder Person -
- - - - - -
- -

{{selectedFieldPerson}}

-
- -
- Meine Felder -
- - - - - -
- -
- - -
- - - - - -
- -
- -
-
- -
+

+ +
+
+ +

New Message

+ + +
+
+ + + +
+ + + +
+ +
+ + +
+ + +
+ + +
+ +
+ + +
+ +
+
+ +
+
+ Felder Prestudent +
+ + + + + +
+ + +

{{selectedFieldPrestudent}}

+ +
+ +
+ Felder Person +
+ + + + + +
+ +

{{selectedFieldPerson}}

+
+ +
+ Meine Felder +
+ + + + + +
+ +
+ +
+ + + + + +
+ +
+ +
+ +
+ +

Vorschau:

+
+ + +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+ +
+ +
+ +
+
` diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index 0025d7b47..10210ece4 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -22,6 +22,7 @@ export default { required: true }, messageLayout: String, + openMode: String }, //TODO(Manu) endpoint macht Probleme data(){ @@ -238,15 +239,14 @@ export default { const linkWindowNewMessage = this.cisRoot + '/public/js/components/Messages/Details/NewMessage.js'; window.open(linkWindowNewMessage, '_blank'); } - else if (this.openmode == "modal"){ + else if (this.openMode == "modal"){ console.log("open with bootstrap Modal"); } - else if (this.openmode == "showDiv"){ - console.log("open div in NewMessage.js"); - //emit to NewMessage.js + else if (this.openMode == "showDiv"){ + this.$emit('showNewMessageTemplate'); } else - console.log("no valid openmode: yet to be developed"); + console.log("no valid openMode"); }, reload() { this.$refs.table.reloadTable(); diff --git a/public/js/components/Messages/Messages.js b/public/js/components/Messages/Messages.js index a7cccb8cb..f862ebc46 100644 --- a/public/js/components/Messages/Messages.js +++ b/public/js/components/Messages/Messages.js @@ -28,31 +28,56 @@ export default { ].includes(value) } }, + openMode: { + type: String, + default: 'window', + validator(value) { + return [ + 'window', + 'modal', + 'showDiv' + ].includes(value) + } + } }, data() { return {} }, + methods: { + showNewMessageTemplate(){ + this.$refs.templateNewMessage.showTemplate(); + }, + reloadTable(){ + this.$refs.templateTableMessage.reload(); + } + }, template: `
- - +
- - +
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js index 14d74e56c..bc07401e6 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js @@ -1,4 +1,5 @@ import CoreMessages from "../../../Messages/Messages.js"; +//import CoreMessages from "@/Messages/Messages.js"; export default { components: { @@ -17,6 +18,7 @@ export default { messageLayout="twoColumnsTableLeft" show-table show-new + open-mode="showDiv" > diff --git a/public/js/components/VorlagenDropdown/VorlagenDropdown.js b/public/js/components/VorlagenDropdown/VorlagenDropdown.js index e4c48501a..b074711f4 100644 --- a/public/js/components/VorlagenDropdown/VorlagenDropdown.js +++ b/public/js/components/VorlagenDropdown/VorlagenDropdown.js @@ -1,5 +1,5 @@ import {CoreFilterCmpt} from "../filter/Filter.js"; -import FormForm from '../Form/Form'; +import FormForm from '../Form/Form.js'; import FormInput from '../Form/Input.js'; export default { @@ -39,16 +39,13 @@ export default { }, methods: { updateValue() { - // console.log("in COMPO: update: " + this.selectedValue + ' jetzt ' + 'InfocenterMailErgaenzungsprfEng'); this.$emit('change', this.selectedValue); - //this.$emit('change', this.selectedValue); // Emit-Event beim Ändern des Wertes }, setValue(value) { this.selectedValue = value; }, }, - created() { - + created() { if(this.isAdmin) { this.$fhcApi.factory.vorlagen.getVorlagen() .then(result => { @@ -103,7 +100,6 @@ template: `
-
`, } \ No newline at end of file From f9f185bfef0291274011e99fe057da8a3b42f994 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 27 Feb 2025 14:06:25 +0100 Subject: [PATCH 05/13] Views modal, new tab, new page, app and controller for newMessage to open in tab or window --- application/controllers/NeueNachricht.php | 30 ++ .../api/frontend/v1/messages/Messages.php | 2 +- application/views/Nachrichten.php | 48 ++ public/js/apps/Messages/NewMessage.js | 27 + public/js/apps/Nachrichten.js | 25 + .../components/Messages/Details/NewMessage.js | 92 +--- .../Messages/Details/NewMessage/Modal.js | 468 +++++++++++++++++ .../Messages/Details/NewMessage/NewDiv.js | 488 ++++++++++++++++++ .../Messages/Details/TableMessages.js | 32 +- public/js/components/Messages/Messages.js | 108 +++- .../Studentenverwaltung/Details/Messages.js | 2 +- .../VorlagenDropdown/VorlagenDropdown.js | 2 +- 12 files changed, 1218 insertions(+), 106 deletions(-) create mode 100644 application/controllers/NeueNachricht.php create mode 100644 application/views/Nachrichten.php create mode 100644 public/js/apps/Messages/NewMessage.js create mode 100644 public/js/apps/Nachrichten.js create mode 100644 public/js/components/Messages/Details/NewMessage/Modal.js create mode 100644 public/js/components/Messages/Details/NewMessage/NewDiv.js diff --git a/application/controllers/NeueNachricht.php b/application/controllers/NeueNachricht.php new file mode 100644 index 000000000..9e9e0a39b --- /dev/null +++ b/application/controllers/NeueNachricht.php @@ -0,0 +1,30 @@ +method] = ['vertrag/mitarbeiter:r']; + parent::__construct($permissions); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + } + + /** + * @return void + */ + public function _remap() + { + //now working + $this->load->view('Nachrichten', [ + 'permissions' => [ + 'vertragsverwaltung_schreibrechte' => $this->permissionlib->isBerechtigt('vertrag/mitarbeiter', 'suid') + ] + ]); + } +} diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index 788c8861e..4bc9a13ab 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -129,7 +129,7 @@ class Messages extends FHCAPI_Controller public function getMsgVarsPrestudent($uid) { - + //$this->terminateWithError($uid, self::ERROR_TYPE_GENERAL); $prestudent_id = $this-> _getPrestudentIdFromUid($uid); // $this->terminateWithError("prestudent_id " . $prestudent_id, self::ERROR_TYPE_GENERAL); diff --git a/application/views/Nachrichten.php b/application/views/Nachrichten.php new file mode 100644 index 000000000..cf34bfd53 --- /dev/null +++ b/application/views/Nachrichten.php @@ -0,0 +1,48 @@ + 'Nachrichten', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'primevue3' => true, + #'filtercomponent' => true, + 'tabulator5' => true, + 'tinymce5' => true, + 'phrases' => array( + 'global', + 'ui', + ), + 'customCSSs' => [ + 'public/css/components/vue-datepicker.css', + 'public/css/components/primevue.css', + ], + 'customJSs' => [ + #'vendor/npm-asset/primevue/tree/tree.min.js', + #'vendor/npm-asset/primevue/toast/toast.min.js' + ], + 'customJSModules' => [ + 'public/js/apps/Nachrichten.js' + ] +); + +$this->load->view('templates/FHC-Header', $includesArray); +?> + + !defined('DOMAIN') ? 'notDefined' : DOMAIN, +]; +?> + +
+ + +
+ +load->view('templates/FHC-Footer', $includesArray); ?> + diff --git a/public/js/apps/Messages/NewMessage.js b/public/js/apps/Messages/NewMessage.js new file mode 100644 index 000000000..693c8b0e2 --- /dev/null +++ b/public/js/apps/Messages/NewMessage.js @@ -0,0 +1,27 @@ +//TODO Manu +//use this instead of Nachrichten.js +import NewMessage from "../../components/Messages/Details/NewMessage/NewDiv.js"; +import Phrasen from "../../plugin/Phrasen.js"; + +const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + +const router = VueRouter.createRouter({ + history: VueRouter.createWebHistory(), + routes: [ + { path: `/${ciPath}/NeueNachricht`, component: NewMessage }, + { path: `/${ciPath}/NeueNachricht/:id`, component: NewMessage }, + { path: `/${ciPath}/NeueNachricht/:id/:typeId`, component: NewMessage }, + ] +}); + +const app = Vue.createApp(); + +app + .use(router) + .use(primevue.config.default, { + zIndex: { + overlay: 1100 + } + }) + .use(Phrasen) + .mount('#main'); diff --git a/public/js/apps/Nachrichten.js b/public/js/apps/Nachrichten.js new file mode 100644 index 000000000..0f921a9f8 --- /dev/null +++ b/public/js/apps/Nachrichten.js @@ -0,0 +1,25 @@ +import NewMessage from "../components/Messages/Details/NewMessage/NewDiv.js"; + +import Phrasen from "../plugin/Phrasen.js"; + +const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + +const router = VueRouter.createRouter({ + history: VueRouter.createWebHistory(), + routes: [ + { path: `/${ciPath}/NeueNachricht/:id/:typeId`, component: NewMessage }, + ] +}); + + +const app = Vue.createApp(); + +app + .use(router) + .use(primevue.config.default, { + zIndex: { + overlay: 1100 + } + }) + .use(Phrasen) + .mount('#main'); \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage.js b/public/js/components/Messages/Details/NewMessage.js index c8aae2124..33ff74d9c 100644 --- a/public/js/components/Messages/Details/NewMessage.js +++ b/public/js/components/Messages/Details/NewMessage.js @@ -2,13 +2,15 @@ import FormForm from '../../Form/Form.js'; import FormInput from '../../Form/Input.js'; import ListBox from "../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; import DropdownComponent from '../../VorlagenDropdown/VorlagenDropdown.js'; +import MessageModal from "../Details/NewMessage/Modal.js"; export default { components: { FormForm, FormInput, ListBox, - DropdownComponent + DropdownComponent, + MessageModal, }, props: { endpoint: { @@ -35,7 +37,7 @@ export default { vorlagen: [], defaultRecipient: null, editor: null, - isVisible: true, + isVisible: false, fieldsUser: [], fieldsPerson: [], fieldsPrestudent: [], @@ -45,12 +47,6 @@ export default { itemsPrestudent: [], itemsPerson: [], itemsUser: [], -/* selectedFieldStudent: null, - itemsStudent: [ - { label: "Variable 1", value: "var1" }, - { label: "Variable 2", value: "var2" }, - { label: "Variable 3", value: "var3" } - ]*/ previewText: null, previewBody: "" } @@ -170,62 +166,6 @@ export default { console.error("Editor instance is not available."); } }, - //TODO(Manu) refactor -/* insertVariablePrestudent() { - if (this.editor) { - //const lastVariable = this.selectedFieldsPrestudent[this.selectedFieldsPrestudent.length - 1].value; - const lastVariable = this.selectedFieldPrestudent.value; - - //Use insertContent method - this.editor.insertContent(lastVariable + " "); - } else { - console.error("Editor instance is not available."); - } - },*/ -/* insertVariablePrestudentByClick(selectedItem) { - - if (selectedItem) { - this.editor.insertContent(selectedItem.value + " "); - console.log("Eingefügte Variable:", selectedItem); - } else { - console.warn("Keine Variable ausgewählt!"); - } - }, - - insertVariablePerson() { - if (this.editor) { - //const lastVariable = this.selectedFieldsPrestudent[this.selectedFieldsPrestudent.length - 1].value; - const lastVariable = this.selectedFieldPerson.value; - - //Use insertContent method - this.editor.insertContent(lastVariable + " "); - } else { - console.error("Editor instance is not available."); - } - }, - insertVariableUser() { - if (this.editor) { - console.log(this.selectedFieldUser.value); - const lastVariable = this.selectedFieldUser.value; - - //Multiple - //const lastVariable = this.selectedFieldsPrestudent[this.selectedFieldsPrestudent.length - 1].value; - - //Use insertContent method - this.editor.insertContent(lastVariable + " "); - this.selectedFieldUser = null; - } else { - console.error("Editor instance is not available."); - } - }, - insertVariableStudent(selectedItem) { - if (selectedItem) { - console.log("Eingefügte Variable:", selectedItem); - this.editor.insertContent(selectedItem.value + " "); - } else { - console.warn("Keine Variable ausgewählt!"); - } - },*/ replyMessage(message_id){ console.log("auf message " + message_id + " antworten"); }, @@ -241,9 +181,9 @@ export default { this.$refs.dropdownComp.setValue(null); }, - toggleDivNewMessage(){ +/* toggleDivNewMessage(){ this.isVisible = !this.isVisible; - }, + },*/ handleSelectedVorlage(vorlage_kurzbz) { if (typeof vorlage_kurzbz === "string") { this.getVorlagentext(vorlage_kurzbz); @@ -254,15 +194,17 @@ export default { if (this.openMode == "showDiv") this.isVisible = false; }, - showTemplate(){ + showTemplate(id, typeId){ if (this.openMode == "showDiv") this.isVisible = true; + //just for testing: + this.isVisible = true; }, showPreview(){ this.getPreviewText().then(() => { this.previewBody = this.previewText; }); - } + }, }, watch: { 'formData.body': { @@ -343,9 +285,19 @@ export default { }, template: `
-
+ + + +
diff --git a/public/js/components/Messages/Details/NewMessage/Modal.js b/public/js/components/Messages/Details/NewMessage/Modal.js new file mode 100644 index 000000000..9bfe49929 --- /dev/null +++ b/public/js/components/Messages/Details/NewMessage/Modal.js @@ -0,0 +1,468 @@ +import BsModal from "../../../Bootstrap/Modal.js"; +import FormForm from "../../../Form/Form.js"; +import FormInput from '../../../Form/Input.js'; +import ListBox from "../../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; +import DropdownComponent from "../../../VorlagenDropdown/VorlagenDropdown.js"; + +export default { + components: { + BsModal, + FormForm, + DropdownComponent, + FormInput, + ListBox + }, + props: { + endpoint: { + type: String, + required: true + }, + typeId: String, + id: { + type: [Number, String], + required: true + }, + openMode: String, + }, + data(){ + return { + formData: { + recipient: this.id, + subject: null, + body: null, + vorlage_kurzbz: null, + selectedValue: '', + }, + statusNew: true, + vorlagen: [], + defaultRecipient: null, + editor: null, + fieldsUser: [], + fieldsPerson: [], + fieldsPrestudent: [], + selectedFieldPrestudent: null, + selectedFieldUser: null, + selectedFieldPerson: null, + itemsPrestudent: [], + itemsPerson: [], + itemsUser: [], + previewText: null, + previewBody: "" + } + }, + methods: { + initTinyMCE() { + const vm = this; + tinymce.init({ + target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component + //height: 800, + //plugins: ['lists'], + toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify', + style_formats: [ + {title: 'Blocks', block: 'div'}, + {title: 'Paragraph', block: 'p'}, + {title: 'Heading 1', block: 'h1'}, + {title: 'Heading 2', block: 'h2'}, + {title: 'Heading 3', block: 'h3'}, + {title: 'Heading 4', block: 'h4'}, + {title: 'Heading 5', block: 'h5'}, + {title: 'Heading 6', block: 'h6'}, + ], + autoresize_bottom_margin: 16, + + setup: (editor) => { + vm.editor = editor; + + editor.on('input', () => { + const newContent = editor.getContent(); + vm.formData.body = newContent; + }); + }, + }); + }, + updateText(value) { + this.formData.body = value; + }, + sendMessage() { + //TODO(Manu) check default recipient(s) + const data = new FormData(); + const params = { + id: this.id, + type_id: this.typeId + }; + const merged = { + ...this.formData, + ...params + }; + data.append('data', JSON.stringify(merged)); + + return this.$fhcApi.factory.messages.person.sendMessage( + this.$refs.formMessage, + this.id, + data) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); + //this.hideModal('messageModal'); + this.hideTemplate(); + this.resetForm(); + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + this.$emit('reloadTable'); + } + ); + }, + getVorlagentext(vorlage_kurzbz){ + //console.log(typeof vorlage_kurzbz); + return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) + .then(response => { + //this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); + //this.hideModal('messageModal'); + //this.resetForm(); + //TODO(Manu) CHECK + this.formData.body = response.data; + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + }); + }, + getPreviewText(){ + const data = new FormData(); + + data.append('data', JSON.stringify(this.formData.body)); + return this.$fhcApi.factory.messages.person.getPreviewText({ + id: this.id, + type_id: this.typeId}, data) + .then(response => { + this.previewText = response.data; + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + }); + }, + insertVariable(selectedItem){ + if (this.editor) { + this.editor.insertContent(selectedItem.value + " "); + //TODO(Manu) check: nicht mal mit Punkt adden gehts ohne eintrag nach vars + /* this.editor.focus(); + this.editor.setDirty(true);*/ + + //this.editor.fire('change'); //forces + + //this.editor.undoManager.add(); + + //this.editor.insertContent(selectedItem.value + "\u00A0"); + //this.editor.insertContent(`${selectedItem.value} `); + //this.editor.selection.setCursorLocation(this.editor.getBody(), 1); + + } else { + console.error("Editor instance is not available."); + } + }, + replyMessage(message_id){ + console.log("auf message " + message_id + " antworten"); + }, + resetForm(){ + this.formData = { + vorlage_kurzbz: null, + body: null, + subject: null, + }; + if (this.editor) { + this.editor.setContent(""); + } + this.$refs.dropdownComp.setValue(null); + + }, + handleSelectedVorlage(vorlage_kurzbz) { + if (typeof vorlage_kurzbz === "string") { + this.getVorlagentext(vorlage_kurzbz); + this.formData.subject = vorlage_kurzbz; + } + }, + hideTemplate(){ + if (this.openMode == "showDiv") + this.isVisible = false; + }, + showTemplate(){ + if (this.openMode == "showDiv") + this.isVisible = true; + }, + showPreview(){ + this.getPreviewText().then(() => { + this.previewBody = this.previewText; + }); + }, + show(){ + this.$refs.modalNewMessage.show(); + } + }, + watch: { + 'formData.body': { + handler(newVal) { + const tinymcsVal = this.editor.getContent(); + + if (newVal && tinymcsVal != newVal) { + //Inhalt des Editors aktualisieren + this.editor.setContent(newVal); + } + } + }, + 'formData.vorlage_kurzbz': { + handler(newVal){ + // console.log("Vorlage: " + newVal); + + if (newVal && newVal != null) { + this.formData.subject = newVal; + return this.getVorlagentext(newVal); + } + } + } + }, + created(){ + if(this.typeId == 'person_id'){ + this.$fhcApi.factory.messages.person.getMessageVarsPerson() + .then(result => { + this.fieldsPerson = result.data; + this.itemsPerson = Object.entries(this.fieldsPerson).map(([key, value]) => ({ + label: value, + value: '{' + value + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + } + if(this.typeId == 'uid') { + this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(this.id) + .then(result => { + this.fieldsPrestudent = result.data; + const prestudent = this.fieldsPrestudent[0]; + //Just for testing with inserting values + /* this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ + label: key, + value: value + }));*/ + this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ + label: key.toLowerCase(), + value: '{' + key.toLowerCase() + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + } + + this.$fhcApi.factory.messages.person.getMsgVarsLoggedInUser() + .then(result => { + this.fieldsUser = result.data; + const user = this.fieldsUser; + this.itemsUser = Object.entries(user).map(([key, value]) => ({ + label: value, + value: '{' + value + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$fhcApi.factory.messages.person.getNameOfDefaultRecipient({ + id: this.id, + type_id: this.typeId}) + .then(result => { + this.defaultRecipient = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + async mounted() { + this.initTinyMCE(); + }, + beforeDestroy() { + this.editor.destroy(); + }, + template: ` + + + + + + +
+ + +
+
+ + + +
+ + + +
+ +
+ + +
+ + +
+ + +
+ +
+ + +
+ +
+
+ +
+
+ Felder Prestudent +
+ + + + + +
+ + +

{{selectedFieldPrestudent}}

+ +
+ +
+ Felder Person +
+ + + + + +
+ +

{{selectedFieldPerson}}

+
+ +
+ Meine Felder +
+ + + + + +
+ +
+ +
+ +
+ +
+ +

Vorschau:

+
+ + +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+ +
+ +
+ +
+ + + +
+ +
+ `, +} \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage/NewDiv.js b/public/js/components/Messages/Details/NewMessage/NewDiv.js new file mode 100644 index 000000000..b31cd9932 --- /dev/null +++ b/public/js/components/Messages/Details/NewMessage/NewDiv.js @@ -0,0 +1,488 @@ +import FormForm from '../../../Form/Form.js'; +import FormInput from '../../../Form/Input.js'; +import ListBox from "../../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; +import DropdownComponent from '../../../VorlagenDropdown/VorlagenDropdown.js'; + +export default { + components: { + FormForm, + FormInput, + ListBox, + DropdownComponent, + }, + props: { + endpoint: { + type: String, + required: true + }, + //for open in div and modal +/* typeId: String, + id: { + type: [Number, String], + required: true + },*/ + openMode: String, + }, + computed: { + //params with routes for new tab and new window AND props +/* id(){ + return this.$route.params.id || this.id; + }, + typeId(){ + return this.$route.params.typeId || this.typeId; + },*/ + id(){ + return this.$route.params.id || this.$props.id; + }, + typeId(){ + return this.$route.params.typeId || this.$props.id; + } + }, + data(){ + return { + formData: { + recipient: this.id, + subject: null, + body: null, + vorlage_kurzbz: null, + selectedValue: '', + }, + statusNew: true, + vorlagen: [], + defaultRecipient: null, + editor: null, + isVisible: false, + fieldsUser: [], + fieldsPerson: [], + fieldsPrestudent: [], + selectedFieldPrestudent: null, + selectedFieldUser: null, + selectedFieldPerson: null, + itemsPrestudent: [], + itemsPerson: [], + itemsUser: [], + previewText: null, + previewBody: "" + } + }, + methods: { + initTinyMCE() { + const vm = this; + tinymce.init({ + target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component + //height: 800, + //plugins: ['lists'], + toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify', + style_formats: [ + {title: 'Blocks', block: 'div'}, + {title: 'Paragraph', block: 'p'}, + {title: 'Heading 1', block: 'h1'}, + {title: 'Heading 2', block: 'h2'}, + {title: 'Heading 3', block: 'h3'}, + {title: 'Heading 4', block: 'h4'}, + {title: 'Heading 5', block: 'h5'}, + {title: 'Heading 6', block: 'h6'}, + ], + autoresize_bottom_margin: 16, + + setup: (editor) => { + vm.editor = editor; + + editor.on('input', () => { + const newContent = editor.getContent(); + vm.formData.body = newContent; + }); + }, + }); + }, + updateText(value) { + this.formData.body = value; + }, + sendMessage() { + //TODO(Manu) check default recipient(s) + const data = new FormData(); + const params = { + id: this.id, + type_id: this.typeId + }; + const merged = { + ...this.formData, + ...params + }; + data.append('data', JSON.stringify(merged)); + + return this.$fhcApi.factory.messages.person.sendMessage( + this.$refs.formMessage, + this.id, + data) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); + //this.hideModal('messageModal'); + this.hideTemplate(); + this.resetForm(); + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + this.$emit('reloadTable'); + } + ); + }, + getVorlagentext(vorlage_kurzbz){ + return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) + .then(response => { + //this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); + //this.hideModal('messageModal'); + //this.resetForm(); + //TODO(Manu) CHECK + this.formData.body = response.data; + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + }); + }, + getPreviewText(){ + const data = new FormData(); + + data.append('data', JSON.stringify(this.formData.body)); + return this.$fhcApi.factory.messages.person.getPreviewText({ + id: this.id, + type_id: this.typeId}, data) + .then(response => { + this.previewText = response.data; + }).catch(this.$fhcAlert.handleSystemError) + .finally(() => { + //this.resetForm(); + //closeModal + //closewindwo + }); + }, + insertVariable(selectedItem){ + if (this.editor) { + this.editor.insertContent(selectedItem.value + " "); + //TODO(Manu) check: nicht mal mit Punkt adden gehts ohne eintrag nach vars + /* this.editor.focus(); + this.editor.setDirty(true);*/ + + //this.editor.fire('change'); //forces + + //this.editor.undoManager.add(); + + //this.editor.insertContent(selectedItem.value + "\u00A0"); + //this.editor.insertContent(`${selectedItem.value} `); + //this.editor.selection.setCursorLocation(this.editor.getBody(), 1); + + } else { + console.error("Editor instance is not available."); + } + }, + replyMessage(message_id){ + console.log("auf message " + message_id + " antworten"); + }, + resetForm(){ + this.formData = { + vorlage_kurzbz: null, + body: null, + subject: null, + }; + if (this.editor) { + this.editor.setContent(""); + } + this.$refs.dropdownComp.setValue(null); + + this.previewBody = null; + + }, + toggleDivNewMessage(){ + this.isVisible = !this.isVisible; + }, + handleSelectedVorlage(vorlage_kurzbz) { + if (typeof vorlage_kurzbz === "string") { + this.getVorlagentext(vorlage_kurzbz); + this.formData.subject = vorlage_kurzbz; + } + }, + hideTemplate(){ + if (this.openMode == "showDiv") + this.isVisible = false; + }, + showTemplate(){ + if (this.openMode == "showDiv") + this.isVisible = true; + //just for testing: + this.isVisible = true; + }, + showPreview(){ + this.getPreviewText().then(() => { + this.previewBody = this.previewText; + }); + }, + }, + watch: { + 'formData.body': { + handler(newVal) { + const tinymcsVal = this.editor.getContent(); + + if (newVal && tinymcsVal != newVal) { + //Inhalt des Editors aktualisieren + this.editor.setContent(newVal); + } + } + }, + 'formData.vorlage_kurzbz': { + handler(newVal){ + // console.log("Vorlage: " + newVal); + + if (newVal && newVal != null) { + this.formData.subject = newVal; + return this.getVorlagentext(newVal); + } + } + }, + }, + created(){ + if(this.typeId == 'person_id'){ + this.$fhcApi.factory.messages.person.getMessageVarsPerson() + .then(result => { + this.fieldsPerson = result.data; + this.itemsPerson = Object.entries(this.fieldsPerson).map(([key, value]) => ({ + label: value, + value: '{' + value + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + } + if(this.typeId == 'uid') { + this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(this.id) + .then(result => { + this.fieldsPrestudent = result.data; + const prestudent = this.fieldsPrestudent[0]; + //Just for testing with inserting values + /* this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ + label: key, + value: value + }));*/ + this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ + label: key.toLowerCase(), + value: '{' + key.toLowerCase() + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + } + + this.$fhcApi.factory.messages.person.getMsgVarsLoggedInUser() + .then(result => { + this.fieldsUser = result.data; + const user = this.fieldsUser; + this.itemsUser = Object.entries(user).map(([key, value]) => ({ + label: value, + value: '{' + value + '}' + })); + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$fhcApi.factory.messages.person.getNameOfDefaultRecipient({ + id: this.id, + type_id: this.typeId + }) + .then(result => { + this.defaultRecipient = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + }, + async mounted() { + this.initTinyMCE(); + }, + beforeDestroy() { + this.editor.destroy(); + }, + template: ` + +
+ + + + + +
+ + {{id}} || {{typeId}} + +

New Message

+ + +
+
+ + + +
+ + + +
+ +
+ + +
+ + +
+ + +
+ +
+ + +
+ +
+
+ +
+
+ Felder Prestudent +
+ + + + + +
+ +
+ +
+ +
+ Felder Person +
+ + + + + +
+ +
+ +
+ Meine Felder +
+ + + + + +
+ +
+ +
+ +
+ + + + + +
+ +
+ +
+ +
+ +

Vorschau:

+
+ + +
+ + +
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+ +
+ +
+ +
+ ` + +} \ No newline at end of file diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index 10210ece4..7994cbe1d 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -1,10 +1,12 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; import FormForm from '../../Form/Form.js'; +import NewMessage from "../Details/NewMessage.js"; export default { components: { CoreFilterCmpt, FormForm, + NewMessage, }, inject: { cisRoot: { @@ -205,7 +207,8 @@ export default { }, ], tabulatorData: [], - previewBody: "" + previewBody: "", + open: false } }, methods: { @@ -233,20 +236,9 @@ export default { }); }, actionNewMessage(){ + this.$emit('newMessage', this.id, this.typeId); //console.log("action new message"); - if (this.openMode == "window") { - console.log("openInNewWindow") - const linkWindowNewMessage = this.cisRoot + '/public/js/components/Messages/Details/NewMessage.js'; - window.open(linkWindowNewMessage, '_blank'); - } - else if (this.openMode == "modal"){ - console.log("open with bootstrap Modal"); - } - else if (this.openMode == "showDiv"){ - this.$emit('showNewMessageTemplate'); - } - else - console.log("no valid openMode"); + }, reload() { this.$refs.table.reloadTable(); @@ -274,19 +266,10 @@ export default { }, template: `
- - - - - - -
- +
@@ -307,7 +290,6 @@ export default {




-
diff --git a/public/js/components/Messages/Messages.js b/public/js/components/Messages/Messages.js index f862ebc46..49fdbdf79 100644 --- a/public/js/components/Messages/Messages.js +++ b/public/js/components/Messages/Messages.js @@ -1,10 +1,20 @@ import TableMessages from "./Details/TableMessages.js"; import NewMessage from "./Details/NewMessage.js"; - +import FormOnly from "./Details/NewMessage/NewDiv.js"; +import FhcApi from "../../../../public/js/plugin/FhcApi.js"; +import Phrasen from "../../../../public/js/plugin/Phrasen.js"; export default { components: { TableMessages, - NewMessage + NewMessage, + FormOnly, + FhcApi, + Phrasen + }, + inject: { + cisRoot: { + from: 'cisRoot' + } }, props: { endpoint: { @@ -34,6 +44,7 @@ export default { validator(value) { return [ 'window', + 'newTab', 'modal', 'showDiv' ].includes(value) @@ -41,18 +52,85 @@ export default { } }, data() { - return {} + return { + showDiv: false + } }, methods: { - showNewMessageTemplate(){ - this.$refs.templateNewMessage.showTemplate(); - }, reloadTable(){ this.$refs.templateTableMessage.reload(); - } + }, + newMessage(id, typeId){ + if (this.openMode == "window") { + this.openInNewWindow(id, typeId); + } + else if (this.openMode == "newTab"){ + this.openInNewTab(id, typeId); + } + else if (this.openMode == "modal"){ + this.openInModal(id, typeId); + } + else if (this.openMode == "showDiv"){ + this.$refs.templateNewMessage.showTemplate(id, typeId); + } + else + console.log("no valid openMode"); + }, + openInDiv(id, typeId){ + this.$refs.templateNewMessage.showTemplate(id, typeId); + //this.showDiv = true; //local variante + //this.$refs.templateNewMessage.showTemplate(); + }, + openInModal(id, typeId){ + //TODO(manu) define bs-modal in this component + this.$refs.templateNewMessage.$refs.modalMsg.show(); + }, + openInNewTab(id, typeId){ + //TODO(MANU) check if array of ids... +/* let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + path += "/NeueNachricht/" + this.id + "/" + this.typeId;*/ + + //als param + let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + path += "/NeueNachricht/" + id + "/" + typeId; + + const newTab = window.open(path, "_blank"); + }, + openInNewWindow(id, typeId){ + //TODO(MANU) check if array of ids... + let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + path += "/NeueNachricht/" + id + "/" + typeId; + + const newTab = window.open(path, "_blank"); + + const width = Math.round(window.innerWidth * 0.75); + const height = Math.round(window.innerHeight * 0.75); + const left = Math.round((window.innerWidth - width) / 2); + const top = Math.round((window.innerHeight - height) / 2); + + const newWindow = window.open(path, "_blank", `width=${width},height=${height},left=${left},top=${top}`); + }, + }, template: `
+ + + + +
+ + +
+ + +
+
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js index bc07401e6..44f1a6aa2 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js @@ -18,7 +18,7 @@ export default { messageLayout="twoColumnsTableLeft" show-table show-new - open-mode="showDiv" + open-mode="newTab" > diff --git a/public/js/components/VorlagenDropdown/VorlagenDropdown.js b/public/js/components/VorlagenDropdown/VorlagenDropdown.js index b074711f4..e5d80077e 100644 --- a/public/js/components/VorlagenDropdown/VorlagenDropdown.js +++ b/public/js/components/VorlagenDropdown/VorlagenDropdown.js @@ -57,7 +57,7 @@ export default { if(this.useLoggedInUserOe){ this.$fhcApi.factory.vorlagen.getVorlagenByLoggedInUser() .then(result => { - console.log(this.vorlagenOe); + //console.log(this.vorlagenOe); this.vorlagenOe = result.data; }) .catch(this.$fhcAlert.handleSystemError); From 815307e392cb245dd696e10edf1ae018040bd5fb Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 4 Mar 2025 07:32:14 +0100 Subject: [PATCH 06/13] Reply functionality and Pagination --- application/controllers/NeueNachricht.php | 2 +- .../api/frontend/v1/messages/Messages.php | 82 +++++++++++++++++-- application/models/system/Message_model.php | 4 +- public/js/api/messages/person.js | 7 ++ public/js/apps/Nachrichten.js | 1 + .../Messages/Details/NewMessage/NewDiv.js | 29 +++++-- .../Messages/Details/TableMessages.js | 29 +++++-- public/js/components/Messages/Messages.js | 41 ++++++++-- 8 files changed, 162 insertions(+), 33 deletions(-) diff --git a/application/controllers/NeueNachricht.php b/application/controllers/NeueNachricht.php index 9e9e0a39b..9b61b78ef 100644 --- a/application/controllers/NeueNachricht.php +++ b/application/controllers/NeueNachricht.php @@ -23,7 +23,7 @@ class NeueNachricht extends Auth_Controller //now working $this->load->view('Nachrichten', [ 'permissions' => [ - 'vertragsverwaltung_schreibrechte' => $this->permissionlib->isBerechtigt('vertrag/mitarbeiter', 'suid') + 'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'), ] ]); } diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index 4bc9a13ab..d080cbee3 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -18,6 +18,8 @@ class Messages extends FHCAPI_Controller 'deleteMessage' => ['admin:r', 'assistenz:r'], 'getVorlagentext' => ['admin:r', 'assistenz:r'], 'getPreviewText' => ['admin:r', 'assistenz:r'], + 'getReplyData' => ['admin:r', 'assistenz:r'], + 'getPersonIdFromUid' => ['admin:r', 'assistenz:r'], ]); //Load Models @@ -70,8 +72,6 @@ class Messages extends FHCAPI_Controller $data = $this->getDataOrTerminateWithError($result); $oe_kurzbz = current($data); - // $this->terminateWithError("oe: ". $oe_kurzbz->oe_kurzbz, self::ERROR_TYPE_GENERAL); - $this->load->model('system/Vorlage_model', 'VorlageModel'); //39 Stück Variante OE @@ -129,11 +129,8 @@ class Messages extends FHCAPI_Controller public function getMsgVarsPrestudent($uid) { - //$this->terminateWithError($uid, self::ERROR_TYPE_GENERAL); $prestudent_id = $this-> _getPrestudentIdFromUid($uid); - // $this->terminateWithError("prestudent_id " . $prestudent_id, self::ERROR_TYPE_GENERAL); - $result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id); $data = $this->getDataOrTerminateWithError($result); @@ -290,6 +287,46 @@ class Messages extends FHCAPI_Controller $this->terminateWithSuccess($bodyParsed); } + public function getReplyData($messageId) + { + // return $this->terminateWithError("in get ReplyBody" . $messageId, self::ERROR_TYPE_GENERAL); + //TODO(Manu) validation of messageId: if number + + + $this->MessageModel->addSelect('public.tbl_msg_message.*'); + $this->MessageModel->addSelect('r.*'); + $this->MessageModel->addSelect('p.nachname'); + $this->MessageModel->addSelect('p.vorname'); + $this->MessageModel->addJoin('public.tbl_msg_recipient r', 'ON (r.message_id = public.tbl_msg_message.message_id)'); + $this->MessageModel->addJoin('public.tbl_person p', 'ON (p.person_id = public.tbl_msg_message.person_id)'); + + $result = $this->MessageModel->loadWhere( + array('r.message_id' => $messageId) + ); + + // $this->terminateWithSuccess((getData($result) ?: [])); + $dataMessage = $this->getDataOrTerminateWithError($result); + + $prefix = "Re: "; // reply subject prefix + +/* $body = current($dataMessage->body); + $subject = $dataMessage->subject;*/ + + $subject = $dataMessage[0]->subject; + $body = $dataMessage[0]->body; + + + $replyBody = $this->_getReplyBody($body, $dataMessage[0]->nachname, $dataMessage[0]->vorname, $dataMessage[0]->insertamum); + + $dataMessage[0]->replyBody = $replyBody; + $dataMessage[0]->rest = "Help Manu"; + $dataMessage[0]->replySubject = $prefix . $subject; + + $this->terminateWithSuccess($dataMessage); + + + } + public function deleteMessage($messageId) { // Start DB transaction @@ -298,7 +335,7 @@ class Messages extends FHCAPI_Controller $result = $this->MessageModel->deleteMessageRecipient($messageId); if (isError($result)) { return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } $result = $this->MessageModel->deleteMessageStatus($messageId); @@ -316,6 +353,19 @@ class Messages extends FHCAPI_Controller $this->terminateWithSuccess($result); } + public function getPersonIdFromUid($uid) + { + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $result = $this->BenutzerModel->loadWhere( + ['uid' => $uid] + ); + + $data = $this->getDataOrTerminateWithError($result); + $benutzer = current($data); + + $this->terminateWithSuccess($benutzer->person_id); + } + private function _getPersonIdFromUid($uid) { $this->load->model('person/Benutzer_model', 'BenutzerModel'); @@ -326,7 +376,6 @@ class Messages extends FHCAPI_Controller $data = $this->getDataOrTerminateWithError($result); $benutzer = current($data); - //return $data->person_id; return $benutzer->person_id; } @@ -342,4 +391,23 @@ class Messages extends FHCAPI_Controller return $student->prestudent_id; } + + private function _getReplyBody($body, $receiverName, $receiverSurname, $sentDate) + { + // To quote a reply body message + $bodyFormat = "
+
+
+ + On %s %s %s wrote: + +
+
+ %s +
"; + return sprintf( + $bodyFormat, + date_format(date_create($sentDate), 'd.m.Y H:i'), $receiverName, $receiverSurname, $body + ); + } } \ No newline at end of file diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 0fdb39736..38defa383 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -275,7 +275,7 @@ class Message_model extends DB_Model JOIN public.tbl_msg_message m USING(message_id) WHERE r.person_id = ? GROUP BY m.message_id, m.subject, m.body, m.insertamum, m.relationmessage_id, sender, recipient, sender_id, recipient_id - ORDER BY insertamum + ORDER BY insertamum DESC "; $parametersArray = array($person_id, $person_id); @@ -287,7 +287,7 @@ class Message_model extends DB_Model * Deletes a messages from tableMessages and tbl_msg_recipient * TODO(MANU) CHECK IF NECESSARY * dependency with other tables - * in case of reply... more messages + * in case of reply... more messages?? delete all dependent ones? * maybe anonimize it * @param $message_id * @return boolean success diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index 5cbb49550..7693c5189 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -14,6 +14,9 @@ export default { getMsgVarsPrestudent(uid){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + uid); }, + getPersonIdFromUid(uid){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getPersonIdFromUid/' + uid); + }, getVorlagentext(vorlage_kurzbz){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz); }, @@ -24,6 +27,10 @@ export default { return this.$fhcApi.post('api/frontend/v1/messages/messages/getPreviewText/' + params.id + '/' + params.type_id, data); }, + getReplyData(messageId){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getReplyData/' + messageId); + + }, sendMessage(form, id, data) { return this.$fhcApi.post(form,'api/frontend/v1/messages/messages/sendMessage/' + id, data); diff --git a/public/js/apps/Nachrichten.js b/public/js/apps/Nachrichten.js index 0f921a9f8..84b9ddee5 100644 --- a/public/js/apps/Nachrichten.js +++ b/public/js/apps/Nachrichten.js @@ -8,6 +8,7 @@ const router = VueRouter.createRouter({ history: VueRouter.createWebHistory(), routes: [ { path: `/${ciPath}/NeueNachricht/:id/:typeId`, component: NewMessage }, + { path: `/${ciPath}/NeueNachricht/:id/:typeId/:messageId`, component: NewMessage }, ] }); diff --git a/public/js/components/Messages/Details/NewMessage/NewDiv.js b/public/js/components/Messages/Details/NewMessage/NewDiv.js index b31cd9932..1eb59aa20 100644 --- a/public/js/components/Messages/Details/NewMessage/NewDiv.js +++ b/public/js/components/Messages/Details/NewMessage/NewDiv.js @@ -36,6 +36,9 @@ export default { }, typeId(){ return this.$route.params.typeId || this.$props.id; + }, + messageId(){ + return this.$route.params.messageId; } }, data(){ @@ -62,7 +65,8 @@ export default { itemsPerson: [], itemsUser: [], previewText: null, - previewBody: "" + previewBody: "", + replyData: null } }, methods: { @@ -179,9 +183,9 @@ export default { console.error("Editor instance is not available."); } }, - replyMessage(message_id){ +/* replyMessage(message_id){ console.log("auf message " + message_id + " antworten"); - }, + },*/ resetForm(){ this.formData = { vorlage_kurzbz: null, @@ -293,6 +297,19 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); + if(this.messageId != null) { + + //get replayBody.. body receivername, receiverSurname, sentDate of message + this.$fhcApi.factory.messages.person.getReplyData(this.messageId) + .then(result => { + this.replyData = result.data; + this.formData.subject = this.replyData[0].replySubject; + this.formData.body = this.replyData[0].replyBody; + }) + .catch(this.$fhcAlert.handleSystemError); + + } + }, async mounted() { this.initTinyMCE(); @@ -309,13 +326,7 @@ export default {
- - {{id}} || {{typeId}} -

New Message

-
diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index 7994cbe1d..ab6a76599 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -1,12 +1,12 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; import FormForm from '../../Form/Form.js'; -import NewMessage from "../Details/NewMessage.js"; +//import NewMessage from "../Details/NewMessage.js"; export default { components: { CoreFilterCmpt, FormForm, - NewMessage, + // NewMessage, }, inject: { cisRoot: { @@ -110,13 +110,15 @@ export default { container.className = "d-flex gap-2"; let button = document.createElement('button'); + if (this.personId != cell.getData().recipient_id) + button.disabled = true; button.className = 'btn btn-outline-secondary btn-action'; button.title = this.$p.t('global', 'reply'); button.innerHTML = ''; button.addEventListener( 'click', (event) => - this.reply(cell.getData().message_id) + this.actionReplyToMessage(cell.getData().message_id) ); container.append(button); @@ -141,6 +143,8 @@ export default { height: '400', selectable: true, selectableRangeMode: 'click', + pagination: true, + // paginationSize: 5, /* layoutColumnsOnNewData: false, selectableRangeMode: 'click', @@ -208,13 +212,11 @@ export default { ], tabulatorData: [], previewBody: "", - open: false + open: false, + personId: null } }, methods: { - reply(message_id){ - console.log("in reply " + message_id); - }, actionDeleteMessage(message_id){ this.$fhcAlert .confirmDelete() @@ -225,7 +227,6 @@ export default { .catch(this.$fhcAlert.handleSystemError); }, deleteMessage(message_id){ - // console.log("deleteMessage " + message_id); return this.$fhcApi.factory.messages.person.deleteMessage(message_id) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); @@ -240,6 +241,9 @@ export default { //console.log("action new message"); }, + actionReplyToMessage(message_id){ + this.$emit('replyToMessage', this.id, this.typeId, message_id); + }, reload() { this.$refs.table.reloadTable(); }, @@ -264,6 +268,15 @@ export default { }); });*/ }, + created(){ + if(this.typeId == 'uid') { + this.$fhcApi.factory.messages.person.getPersonIdFromUid(this.id) + .then(result => { + this.personId = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + } + }, template: `
diff --git a/public/js/components/Messages/Messages.js b/public/js/components/Messages/Messages.js index 49fdbdf79..e6947a72a 100644 --- a/public/js/components/Messages/Messages.js +++ b/public/js/components/Messages/Messages.js @@ -76,6 +76,23 @@ export default { else console.log("no valid openMode"); }, + handleMessage(id, typeId, messageId){ + console.log("in handleMessage " + messageId); + if (this.openMode == "window") { + this.openInNewWindow(id, typeId, messageId); + } + else if (this.openMode == "newTab"){ + this.openInNewTab(id, typeId, messageId); + } + else if (this.openMode == "modal"){ + this.openInModal(id, typeId, messageId); + } + else if (this.openMode == "showDiv"){ + this.$refs.templateNewMessage.showTemplate(id, typeId, messageId); + } + else + console.log("no valid openMode"); + }, openInDiv(id, typeId){ this.$refs.templateNewMessage.showTemplate(id, typeId); //this.showDiv = true; //local variante @@ -85,15 +102,26 @@ export default { //TODO(manu) define bs-modal in this component this.$refs.templateNewMessage.$refs.modalMsg.show(); }, - openInNewTab(id, typeId){ +/* openInNewTab(id, typeId){ //TODO(MANU) check if array of ids... -/* let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; - path += "/NeueNachricht/" + this.id + "/" + this.typeId;*/ - - //als param let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; path += "/NeueNachricht/" + id + "/" + typeId; + const newTab = window.open(path, "_blank"); + },*/ + openInNewTab(id, typeId, messageId=null){ + //TODO(MANU) check if array of ids... + let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + + if (messageId){ + path += "/NeueNachricht/" + id + "/" + typeId + "/" + messageId; + } + + else { + path += "/NeueNachricht/" + id + "/" + typeId; + } + + const newTab = window.open(path, "_blank"); }, openInNewWindow(id, typeId){ @@ -152,7 +180,8 @@ export default { :endpoint="endpoint" :messageLayout="messageLayout" :openMode="openMode" - @newMessage="newMessage" + @newMessage="newMessage" + @replyToMessage="handleMessage" > From 1989e65d72d1532ab943c71eaaff4b6207581c79 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 10 Mar 2025 07:51:53 +0100 Subject: [PATCH 07/13] Tree structure for messages, preview in NewDiv, Note to close window, check recipient_id, save relationmessage_id --- .../api/frontend/v1/messages/Messages.php | 163 ++++++++++-------- public/js/api/messages/person.js | 12 +- .../Messages/Details/NewMessage/NewDiv.js | 117 ++++++++++--- .../Messages/Details/TableMessages.js | 144 +++++++++++++--- public/js/components/Messages/Messages.js | 3 +- .../Studentenverwaltung/Details/Messages.js | 14 +- 6 files changed, 329 insertions(+), 124 deletions(-) diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index d080cbee3..65c354c4f 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -19,7 +19,8 @@ class Messages extends FHCAPI_Controller 'getVorlagentext' => ['admin:r', 'assistenz:r'], 'getPreviewText' => ['admin:r', 'assistenz:r'], 'getReplyData' => ['admin:r', 'assistenz:r'], - 'getPersonIdFromUid' => ['admin:r', 'assistenz:r'], + 'getPersonId' => ['admin:r', 'assistenz:r'], + 'getUid' => ['admin:r', 'assistenz:r'], ]); //Load Models @@ -42,17 +43,8 @@ class Messages extends FHCAPI_Controller public function getMessages($id, $type_id) { - switch($type_id) - { - case 'uid': - $id = $this->_getPersonIdFromUid($id); - break; - case 'person_id': - $id = $id; - break; - default: - $this->terminateWithError("MESSAGES::getMessages logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); - break; + if($type_id != 'person_id'){ + $id = $this->_getPersonId($id, $type_id); } $result = $this->MessageModel->getMessagesForTable($id); @@ -74,15 +66,13 @@ class Messages extends FHCAPI_Controller $this->load->model('system/Vorlage_model', 'VorlageModel'); - //39 Stück Variante OE $result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz); $data = $this->getDataOrTerminateWithError($result); $this->terminateWithSuccess($data); - //IF ADMIN 167 + //If admin $this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC'); - //only HTML-vorlagen -> for admin $result = $this->VorlageModel->loadWhere( array( 'mimetype' => 'text/html' @@ -97,7 +87,7 @@ class Messages extends FHCAPI_Controller public function getVorlagentext($vorlage_kurzbz) { //$this->terminateWithError("vor " . $vorlage_kurzbz, self::ERROR_TYPE_GENERAL); - //$studiengang_kz = 227; //TODO(Manu) check dynamisieren NULL + //$studiengang_kz = 227; //TODO(Manu) dynamisieren NULL $studiengang_kz = 0; $this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel'); $this->VorlagestudiengangModel->addOrder('version', 'DESC'); @@ -127,49 +117,32 @@ class Messages extends FHCAPI_Controller $this->terminateWithSuccess($data); } - public function getMsgVarsPrestudent($uid) + public function getMsgVarsPrestudent($id, $typeId) { - $prestudent_id = $this-> _getPrestudentIdFromUid($uid); + $prestudent_id = ($typeId == 'prestudent_id') ? $id : $this->_getPrestudentIdFromUid($id); $result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id); $data = $this->getDataOrTerminateWithError($result); - $this->terminateWithSuccess($data); } public function getMsgVarsLoggedInUser() { - $uid = getAuthUID(); - $result = $this->MessageModel->getMsgVarsLoggedInUser(); - $data = $this->getDataOrTerminateWithError($result); - $this->terminateWithSuccess($data); } public function getNameOfDefaultRecipient($id, $type_id) { - switch($type_id) - { - case 'uid': - $id = $this->_getPersonIdFromUid($id); - break; - case 'person_id': - $id = $id; - break; - default: - $this->terminateWithError("MESSAGES::getNameOfDefaultRecipient logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); - break; - } + $id = $type_id!='person_id)' ? $this->_getPersonId($id, $type_id) : $id; $this->load->model('person/Person_model', 'PersonModel'); $result = $this->PersonModel->load($id); - //$this->terminateWithSuccess($result); $data = $this->getDataOrTerminateWithError($result); $name = current($data); @@ -178,8 +151,11 @@ class Messages extends FHCAPI_Controller public function sendMessage($recipient_id) { + //is always uid in FAS + //TODO(Manu) make dynamic for other ids + //default setting - $receiversPersonId = $this->_getPersonIdFromUid($recipient_id); + $receiversPersonId = $this->_getPersonId($recipient_id, 'uid'); $uid = getAuthUID(); $this->load->model('person/Benutzer_model', 'BenutzerModel'); @@ -216,15 +192,13 @@ class Messages extends FHCAPI_Controller $subject = $this->input->post('subject'); $body = $this->input->post('body'); - - + $relationmessage_id = $this->input->post('relationmessage_id'); $typeId = $this->input->post('type_id'); $id = $this->input->post('id'); if($typeId == 'uid') { - //$this->terminateWithError("uid ", self::ERROR_TYPE_GENERAL); $prestudent_id = $this-> _getPrestudentIdFromUid($id); //parseMessagetext for variables Prestudent @@ -240,7 +214,7 @@ class Messages extends FHCAPI_Controller } elseif($typeId == 'prestudent_id') { - $this->terminateWithError("prestudent_id ", self::ERROR_TYPE_GENERAL); + // $this->terminateWithError("prestudent_id ", self::ERROR_TYPE_GENERAL); $result = $this->MessagesModel->parseMessageTextPrestudent($id, $body); $bodyParsed = $this->getDataOrTerminateWithError($result); @@ -250,7 +224,7 @@ class Messages extends FHCAPI_Controller $this->terminateWithError("type_id " . $typeId . " not valid", self::ERROR_TYPE_GENERAL); } - $result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $bodyParsed, $benutzer->person_id); + $result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $bodyParsed, $benutzer->person_id, null, $relationmessage_id); $this->terminateWithSuccess($result); } @@ -271,17 +245,15 @@ class Messages extends FHCAPI_Controller case 'uid': $prestudent_id = $this->_getPrestudentIdFromUid($id); $result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $data); - break; - case 'person_id': - $id = $id; + case 'prestudent_id': + $result = $this->MessagesModel->parseMessageTextPrestudent($id, $data); break; default: $this->terminateWithError("MESSAGES::getPreviewText logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); break; } - //$this->terminateWithSuccess($result); $bodyParsed = $this->getDataOrTerminateWithError($result); $this->terminateWithSuccess($bodyParsed); @@ -289,10 +261,8 @@ class Messages extends FHCAPI_Controller public function getReplyData($messageId) { - // return $this->terminateWithError("in get ReplyBody" . $messageId, self::ERROR_TYPE_GENERAL); //TODO(Manu) validation of messageId: if number - $this->MessageModel->addSelect('public.tbl_msg_message.*'); $this->MessageModel->addSelect('r.*'); $this->MessageModel->addSelect('p.nachname'); @@ -304,14 +274,9 @@ class Messages extends FHCAPI_Controller array('r.message_id' => $messageId) ); - // $this->terminateWithSuccess((getData($result) ?: [])); $dataMessage = $this->getDataOrTerminateWithError($result); - $prefix = "Re: "; // reply subject prefix -/* $body = current($dataMessage->body); - $subject = $dataMessage->subject;*/ - $subject = $dataMessage[0]->subject; $body = $dataMessage[0]->body; @@ -323,8 +288,6 @@ class Messages extends FHCAPI_Controller $dataMessage[0]->replySubject = $prefix . $subject; $this->terminateWithSuccess($dataMessage); - - } public function deleteMessage($messageId) @@ -353,30 +316,94 @@ class Messages extends FHCAPI_Controller $this->terminateWithSuccess($result); } - public function getPersonIdFromUid($uid) + public function getPersonId($id, $typeId) { - $this->load->model('person/Benutzer_model', 'BenutzerModel'); - $result = $this->BenutzerModel->loadWhere( - ['uid' => $uid] - ); + if ($typeId == 'uid') + { + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $result = $this->BenutzerModel->loadWhere( + ['uid' => $id] + ); + } + elseif($typeId == 'prestudent_id') + { + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $result = $this->PrestudentModel->loadWhere( + ['prestudent_id' => $id] + ); + } $data = $this->getDataOrTerminateWithError($result); - $benutzer = current($data); + $person = current($data); - $this->terminateWithSuccess($benutzer->person_id); + $this->terminateWithSuccess($person->person_id); } - private function _getPersonIdFromUid($uid) + public function getUid($id, $typeId) { - $this->load->model('person/Benutzer_model', 'BenutzerModel'); - $result = $this->BenutzerModel->loadWhere( - ['uid' => $uid] - ); + if (!$typeId) + { + $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Type ID']), self::ERROR_TYPE_GENERAL); + } + elseif ($typeId == 'person_id') + { + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $result = $this->BenutzerModel->loadWhere( + ['person_id' => $id] + ); + } + elseif($typeId == 'prestudent_id') + { + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $result = $this->PrestudentModel->loadWhere( + ['prestudent_id' => $id] + ); + + $data = $this->getDataOrTerminateWithError($result); + $person = current($data); + $person_id = $person->person_id; + + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $result = $this->BenutzerModel->loadWhere( + ['person_id' => $person_id] + ); + } + elseif($typeId == 'uid') + { + $this->terminateWithSuccess($id); + } + else + { + $this->terminateWithError("MESSAGES::getUID logic for type_id " . $typeId . " not defined yet", self::ERROR_TYPE_GENERAL); + } $data = $this->getDataOrTerminateWithError($result); $benutzer = current($data); - return $benutzer->person_id; + $this->terminateWithSuccess($benutzer->uid); + } + + private function _getPersonId($id, $typeId) + { + if ($typeId == 'uid') + { + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $result = $this->BenutzerModel->loadWhere( + ['uid' => $id] + ); + } + elseif($typeId == 'prestudent_id') + { + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $result = $this->PrestudentModel->loadWhere( + ['prestudent_id' => $id] + ); + } + + $data = $this->getDataOrTerminateWithError($result); + $person = current($data); + + return $person->person_id; } private function _getPrestudentIdFromUid($uid) diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index 7693c5189..e53f23f6a 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -11,11 +11,14 @@ export default { getMessageVarsPerson(){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessageVarsPerson/'); }, - getMsgVarsPrestudent(uid){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + uid); + getMsgVarsPrestudent(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + params.id + '/' + params.type_id); }, - getPersonIdFromUid(uid){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getPersonIdFromUid/' + uid); + getPersonId(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getPersonId/'+ params.id + '/' + params.type_id); + }, + getUid(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getUid/'+ params.id + '/' + params.type_id); }, getVorlagentext(vorlage_kurzbz){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz); @@ -29,7 +32,6 @@ export default { }, getReplyData(messageId){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getReplyData/' + messageId); - }, sendMessage(form, id, data) { return this.$fhcApi.post(form,'api/frontend/v1/messages/messages/sendMessage/' + id, diff --git a/public/js/components/Messages/Details/NewMessage/NewDiv.js b/public/js/components/Messages/Details/NewMessage/NewDiv.js index 1eb59aa20..d8611d611 100644 --- a/public/js/components/Messages/Details/NewMessage/NewDiv.js +++ b/public/js/components/Messages/Details/NewMessage/NewDiv.js @@ -44,14 +44,16 @@ export default { data(){ return { formData: { - recipient: this.id, + recipient: null, subject: null, body: null, vorlage_kurzbz: null, selectedValue: '', + relationmessage_id: null }, statusNew: true, vorlagen: [], + recipientsArray: [], defaultRecipient: null, editor: null, isVisible: false, @@ -66,7 +68,9 @@ export default { itemsUser: [], previewText: null, previewBody: "", - replyData: null + replyData: null, + uid: null, + messageSent: false } }, methods: { @@ -105,19 +109,22 @@ export default { sendMessage() { //TODO(Manu) check default recipient(s) const data = new FormData(); + const params = { id: this.id, type_id: this.typeId }; + const merged = { ...this.formData, ...params }; data.append('data', JSON.stringify(merged)); + //this.uid is important for existing sendFunction return this.$fhcApi.factory.messages.person.sendMessage( this.$refs.formMessage, - this.id, + this.uid, data) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); @@ -129,6 +136,10 @@ export default { //this.resetForm(); //closeModal //closewindwo + this.messageSent = true; + //TODO(Manu) hier route definieren? ist kein child sondern mit route aufgerufen + //würde allerdings neues fenster aktualisiert öffnen, altes bleibt ohne reload gleich + //Reload vorheriges tab??? this.$emit('reloadTable'); } ); @@ -148,13 +159,13 @@ export default { //closewindwo }); }, - getPreviewText(){ + getPreviewText(id, typeId){ const data = new FormData(); data.append('data', JSON.stringify(this.formData.body)); return this.$fhcApi.factory.messages.person.getPreviewText({ - id: this.id, - type_id: this.typeId}, data) + id: id, + type_id: typeId}, data) .then(response => { this.previewText = response.data; }).catch(this.$fhcAlert.handleSystemError) @@ -167,7 +178,8 @@ export default { insertVariable(selectedItem){ if (this.editor) { this.editor.insertContent(selectedItem.value + " "); - //TODO(Manu) check: nicht mal mit Punkt adden gehts ohne eintrag nach vars + //TODO(Manu) check: Laden von Variblen geht nicht wenn kein Zeichen danach kommt + // nicht mal mit Punkt adden gehts ohne eintrag nach vars /* this.editor.focus(); this.editor.setDirty(true);*/ @@ -183,9 +195,6 @@ export default { console.error("Editor instance is not available."); } }, -/* replyMessage(message_id){ - console.log("auf message " + message_id + " antworten"); - },*/ resetForm(){ this.formData = { vorlage_kurzbz: null, @@ -219,11 +228,22 @@ export default { //just for testing: this.isVisible = true; }, - showPreview(){ - this.getPreviewText().then(() => { + showPreview(id, typeId){ + this.getPreviewText(id, typeId).then(() => { this.previewBody = this.previewText; }); }, + getUid(id, typeId){ + const params = { + id: id, + type_id: typeId + }; + this.$fhcApi.factory.messages.person.getUid(params) + .then(result => { + this.uid = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + } }, watch: { 'formData.body': { @@ -238,7 +258,6 @@ export default { }, 'formData.vorlage_kurzbz': { handler(newVal){ - // console.log("Vorlage: " + newVal); if (newVal && newVal != null) { this.formData.subject = newVal; @@ -248,6 +267,9 @@ export default { }, }, created(){ + if(this.typeId != 'uid') + this.getUid(this.id, this.typeId); + if(this.typeId == 'person_id'){ this.$fhcApi.factory.messages.person.getMessageVarsPerson() .then(result => { @@ -259,8 +281,13 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); } - if(this.typeId == 'uid') { - this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(this.id) + + if(this.typeId == 'uid' || this.typeId == 'prestudent_id') { + const params = { + id: this.id, + type_id: this.typeId + }; + this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(params) .then(result => { this.fieldsPrestudent = result.data; const prestudent = this.fieldsPrestudent[0]; @@ -294,20 +321,21 @@ export default { }) .then(result => { this.defaultRecipient = result.data; + this.recipientsArray.push({'uid': this.uid, + 'details': this.defaultRecipient}); }) .catch(this.$fhcAlert.handleSystemError); + //case of reply if(this.messageId != null) { - - //get replayBody.. body receivername, receiverSurname, sentDate of message this.$fhcApi.factory.messages.person.getReplyData(this.messageId) .then(result => { this.replyData = result.data; this.formData.subject = this.replyData[0].replySubject; this.formData.body = this.replyData[0].replyBody; + this.formData.relationmessage_id = this.messageId; }) .catch(this.$fhcAlert.handleSystemError); - } }, @@ -320,12 +348,11 @@ export default { template: `
- -
+

New Message

@@ -465,19 +492,26 @@ export default {
-
+
+ +

- +
@@ -492,6 +526,43 @@ export default {
+ + +
+
+
+
+
+ Message sent successfully! +
+
+ Nachricht erfolgreich versandt! +
+
+ +
+
+ You can safely close this window. +
+
+ Sie können dieses Fenster schließen. +
+
+
+
+

+ Fachhochschule Technikum Wien | University of Applied Sciences Technikum Wien +
Hoechstaedtplatz 6, 1200 Wien, AUSTRIA +
www.technikum-wien.at +

+ +
+ + +
+ +
+
` diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index ab6a76599..317291c56 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -26,7 +26,6 @@ export default { messageLayout: String, openMode: String }, - //TODO(Manu) endpoint macht Probleme data(){ return { tabulatorOptions: { @@ -38,7 +37,7 @@ export default { type: this.typeId }; }, - ajaxResponse: (url, params, response) => response.data, + ajaxResponse: (url, params, response) => this.buildTreemap(response.data), columns: [ {title: "subject", field: "subject"}, {title: "body", field: "body", visible: false}, @@ -63,6 +62,7 @@ export default { {title: "recipient", field: "recipient"}, {title: "senderId", field: "sender_id"}, {title: "recipientId", field: "recipient_id"}, + {title: "relationmessage_id", field: "relationmessage_id"}, { title: "status", field: "status", @@ -110,7 +110,7 @@ export default { container.className = "d-flex gap-2"; let button = document.createElement('button'); - if (this.personId != cell.getData().recipient_id) + if (this.personId != cell.getData().sender_id) button.disabled = true; button.className = 'btn btn-outline-secondary btn-action'; button.title = this.$p.t('global', 'reply'); @@ -136,29 +136,23 @@ export default { return container; }, frozen: true - }], + } + ], layout: 'fitDataFill', layoutColumnsOnNewData: false, - // height: 'auto', height: '400', - selectable: true, selectableRangeMode: 'click', - pagination: true, - // paginationSize: 5, -/* layoutColumnsOnNewData: false, - - selectableRangeMode: 'click', - selectable: true, index: 'message_id', - persistenceID: 'core-message'*/ + pagination: true, + dataTree: true, + headerSort: true, + dataTreeChildField: "children", + dataTreeCollapseElement:"", + dataTreeChildIndent: 15, + dataTreeStartExpanded: false, + persistenceID: 'core-message' }, tabulatorEvents: [ - { - event: 'dataLoaded', - handler: data => this.tabulatorData = data.map(item => { - return item; - }), - }, { event: 'tableBuilt', handler: async() => { @@ -213,7 +207,59 @@ export default { tabulatorData: [], previewBody: "", open: false, - personId: null + personId: null, + //Testdata +/* messages: [ + { + message_id: 7, + subject: "Antwort auf 4", + body: "Text 5", + insertamum: "2024-03-05", + relationmessage_id: 6, + }, + { + message_id: 1, + subject: "Hauptnachricht", + body: "Text 1", + insertamum: "2024-03-05", + relationmessage_id: null, + }, + { + message_id: 2, + subject: "Antwort auf 1", + body: "Text 2", + insertamum: "2024-03-05", + relationmessage_id: 1, + }, + { + message_id: 3, + subject: "Antwort auf 2", + body: "Text 3", + insertamum: "2024-03-05", + relationmessage_id: 2, + }, + { + message_id: 4, + subject: "Neue Nachricht", + body: "Text 4", + insertamum: "2024-03-05", + relationmessage_id: null, + }, + { + message_id: 5, + subject: "Antwort auf 4", + body: "Text 5", + insertamum: "2024-03-05", + relationmessage_id: 4, + }, + { + message_id: 6, + subject: "Antwort auf 4", + body: "Text 5", + insertamum: "2024-03-05", + relationmessage_id: 5, + }, + ],*/ } }, methods: { @@ -237,7 +283,11 @@ export default { }); }, actionNewMessage(){ + // this.$emit('newMessage', this.id, this.typeId); + + //here already use person_id?? this.$emit('newMessage', this.id, this.typeId); + //console.log("action new message"); }, @@ -247,6 +297,47 @@ export default { reload() { this.$refs.table.reloadTable(); }, + buildTreemap(messages) { + 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 messageNested; +} + + }, computed: { statusText(){ @@ -256,7 +347,7 @@ export default { 2: this.$p.t('messsages', 'archived'), 3: this.$p.t('messsages', 'deleted') } - } + }, }, mounted() { // change to target="_blank" @@ -269,8 +360,12 @@ export default { });*/ }, created(){ - if(this.typeId == 'uid') { - this.$fhcApi.factory.messages.person.getPersonIdFromUid(this.id) + if(this.typeId == 'uid' || this.typeId == 'prestudent_id') { + const params = { + id: this.id, + type_id: this.typeId + }; + this.$fhcApi.factory.messages.person.getPersonId(params) .then(result => { this.personId = result.data; }) @@ -279,7 +374,7 @@ export default { }, template: `
- +
@@ -313,6 +408,7 @@ export default {
+
diff --git a/public/js/components/Messages/Messages.js b/public/js/components/Messages/Messages.js index e6947a72a..fc73768f1 100644 --- a/public/js/components/Messages/Messages.js +++ b/public/js/components/Messages/Messages.js @@ -58,6 +58,7 @@ export default { }, methods: { reloadTable(){ + console.log("in parent reload"); this.$refs.templateTableMessage.reload(); }, newMessage(id, typeId){ @@ -121,7 +122,6 @@ export default { path += "/NeueNachricht/" + id + "/" + typeId; } - const newTab = window.open(path, "_blank"); }, openInNewWindow(id, typeId){ @@ -160,6 +160,7 @@ export default {
--> +
+ + +
` From a0ce635c7eb60460cd8075c7f208d9f721979e3d Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 12 Mar 2025 15:04:37 +0100 Subject: [PATCH 08/13] Refactor and Cleanup - adapt tabulator and queries for remote pagination - use formatterParams for messageStati to enable phrase logic - adapt logic for mitarbeiter_uid - refactor logic to use new Page, new Tab and newDiv with one child component - add phrases --- .../api/frontend/v1/messages/Messages.php | 59 +++++-- application/models/system/Message_model.php | 62 ++++++-- public/js/api/messages/person.js | 14 +- .../{NewMessage.js => Depr_NewMessage.js} | 0 .../Messages/Details/NewMessage/Modal.js | 148 +++++++++++++----- .../Messages/Details/NewMessage/NewDiv.js | 116 +++++++------- .../Messages/Details/TableMessages.js | 108 ++++--------- public/js/components/Messages/Messages.js | 140 +++++++---------- .../Studentenverwaltung/Details/Messages.js | 31 +++- system/phrasesupdate.php | 80 ++++++++++ 10 files changed, 459 insertions(+), 299 deletions(-) rename public/js/components/Messages/Details/{NewMessage.js => Depr_NewMessage.js} (100%) diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index 65c354c4f..7834ba5f7 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -41,17 +41,27 @@ class Messages extends FHCAPI_Controller ]); } - public function getMessages($id, $type_id) + public function getMessages($id, $type_id, $size, $page) { if($type_id != 'person_id'){ $id = $this->_getPersonId($id, $type_id); } - $result = $this->MessageModel->getMessagesForTable($id); + $offset = $size * ($page - 1); + $limit = $size; + + $result = $this->MessageModel->getMessagesForTable($id, $offset, $limit); $data = $this->getDataOrTerminateWithError($result); - $this->terminateWithSuccess($data); + //return null if count == 0 + if($data['count'] == 0){ + $this->terminateWithSuccess([]); + } + + $this->addMeta('count', $data['count']); + + $this->terminateWithSuccess($data['data']); } public function getVorlagen() @@ -107,9 +117,10 @@ class Messages extends FHCAPI_Controller $this->terminateWithSuccess($vorlage->text); } - public function getMessageVarsPerson() + public function getMessageVarsPerson($id, $typeId) { - $result = $this->MessageModel->getMessageVarsPerson(); + $person_id = ($typeId == 'mitarbeiter_uid') ? $this->_getPersonId($id, $typeId) : $id; + $result = $this->MessageModel->getMessageVarsPerson($person_id); $data = $this->getDataOrTerminateWithError($result); @@ -119,7 +130,7 @@ class Messages extends FHCAPI_Controller public function getMsgVarsPrestudent($id, $typeId) { - $prestudent_id = ($typeId == 'prestudent_id') ? $id : $this->_getPrestudentIdFromUid($id); + $prestudent_id = ($typeId == 'uid') ? $this->_getPrestudentIdFromUid($id) : $id; $result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id); @@ -138,7 +149,7 @@ class Messages extends FHCAPI_Controller public function getNameOfDefaultRecipient($id, $type_id) { - $id = $type_id!='person_id)' ? $this->_getPersonId($id, $type_id) : $id; + $id = ($type_id != 'person_id') ? $this->_getPersonId($id, $type_id) : $id; $this->load->model('person/Person_model', 'PersonModel'); @@ -151,8 +162,8 @@ class Messages extends FHCAPI_Controller public function sendMessage($recipient_id) { - //is always uid in FAS - //TODO(Manu) make dynamic for other ids + //has to be uid + // $this->terminateWithError("uid", $recipient_id, self::ERROR_TYPE_GENERAL); //default setting $receiversPersonId = $this->_getPersonId($recipient_id, 'uid'); @@ -205,10 +216,17 @@ class Messages extends FHCAPI_Controller $result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $body); $bodyParsed = $this->getDataOrTerminateWithError($result); } + if($typeId == 'mitarbeiter_uid') + { + $person_id = $this->_getPersonId($id, $typeId); + + $result = $this->MessagesModel->parseMessageTextPerson($person_id, $body); + $bodyParsed = $this->getDataOrTerminateWithError($result); + $this->terminateWithError($bodyParsed, self::ERROR_TYPE_GENERAL); + + } elseif($typeId == 'person_id') { - $this->terminateWithError("person_id ", self::ERROR_TYPE_GENERAL); - $result = $this->MessagesModel->parseMessageTextPerson($id, $body); $bodyParsed = $this->getDataOrTerminateWithError($result); } @@ -235,7 +253,6 @@ class Messages extends FHCAPI_Controller { $data = json_decode($_POST['data']); unset($_POST['data']); - } else $this->terminateWithError("Textbody missing ", self::ERROR_TYPE_GENERAL); @@ -249,6 +266,15 @@ class Messages extends FHCAPI_Controller case 'prestudent_id': $result = $this->MessagesModel->parseMessageTextPrestudent($id, $data); break; + case 'person_id': + $result = $this->MessagesModel->parseMessageTextPerson($id, $data); + break; + case 'mitarbeiter_uid': + { + $person_id = $this->_getPersonId($id, $type_id); + $result = $this->MessagesModel->parseMessageTextPerson($person_id, $data); + } + break; default: $this->terminateWithError("MESSAGES::getPreviewText logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL); break; @@ -318,7 +344,7 @@ class Messages extends FHCAPI_Controller public function getPersonId($id, $typeId) { - if ($typeId == 'uid') + if ($typeId == 'uid' || $typeId == 'mitarbeiter_uid') { $this->load->model('person/Benutzer_model', 'BenutzerModel'); $result = $this->BenutzerModel->loadWhere( @@ -368,7 +394,7 @@ class Messages extends FHCAPI_Controller ['person_id' => $person_id] ); } - elseif($typeId == 'uid') + elseif($typeId == 'uid' || $typeId == 'mitarbeiter_uid') { $this->terminateWithSuccess($id); } @@ -385,7 +411,7 @@ class Messages extends FHCAPI_Controller private function _getPersonId($id, $typeId) { - if ($typeId == 'uid') + if ($typeId == 'uid' || $typeId == 'mitarbeiter_uid') { $this->load->model('person/Benutzer_model', 'BenutzerModel'); $result = $this->BenutzerModel->loadWhere( @@ -408,6 +434,7 @@ class Messages extends FHCAPI_Controller private function _getPrestudentIdFromUid($uid) { + // $this->terminateWithError($uid, self::ERROR_TYPE_GENERAL); $this->load->model('crm/Student_model', 'StudentModel'); $result = $this->StudentModel->loadWhere( ['student_uid' => $uid] @@ -415,7 +442,7 @@ class Messages extends FHCAPI_Controller $data = $this->getDataOrTerminateWithError($result); $student = current($data); - + // $this->terminateWithError($student->prestudent_id, self::ERROR_TYPE_GENERAL); return $student->prestudent_id; } diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 38defa383..acbe3a44c 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -234,12 +234,15 @@ class Message_model extends DB_Model /** * Gets messages for a person for tableMessages. * @param $person_id - * @param null $status message status. by default, latest status is returned + * paginationInitialPage: 1, + * @param $offset number to skip, calculated by tabulatorParam paginationInitialPage and paginationSize, refers to specified numer of skipped items + * and page + * @param $limit refers to tabulatorParam paginationSize * @return array|null */ - public function getMessagesForTable($person_id, $status = null) + public function getMessagesForTable($person_id, $offset, $limit) { - $sql = " + $sql_base = " SELECT m.message_id AS message_id, m.subject AS subject, @@ -275,20 +278,45 @@ class Message_model extends DB_Model JOIN public.tbl_msg_message m USING(message_id) WHERE r.person_id = ? GROUP BY m.message_id, m.subject, m.body, m.insertamum, m.relationmessage_id, sender, recipient, sender_id, recipient_id - ORDER BY insertamum DESC + "; + $sql = " + SELECT COUNT(*) AS count FROM ( + " . $sql_base . " + ) a "; $parametersArray = array($person_id, $person_id); - return $this->execQuery($sql, $parametersArray); + $count = $this->execQuery($sql, $parametersArray); + + if (isError($count)) + return $count; + + $count = floor(current(getData($count))->count/$limit); + $sql = " + SELECT * FROM ( + " . $sql_base . " + ) a + ORDER BY insertamum DESC + LIMIT ? + OFFSET ? + "; + + $parametersArray = array($person_id, $person_id, $limit, $offset); + + $data = $this->execQuery($sql, $parametersArray); + + if (isError($data)) + return $data; + + $data = getData($data); + + return success(['data' => $data, 'count' => $count]); } /** - * Deletes a messages from tableMessages and tbl_msg_recipient - * TODO(MANU) CHECK IF NECESSARY - * dependency with other tables - * in case of reply... more messages?? delete all dependent ones? - * maybe anonimize it + * Deletes entry in dependency table tbl_msg_recipient + * * @param $message_id * @return boolean success */ @@ -302,7 +330,12 @@ class Message_model extends DB_Model return $this->execQuery($sql, array($message_id)); } - + /** + * Deletes entry in dependency table tbl_msg_status + * + * @param $message_id + * @return boolean success + */ public function deleteMessageStatus($message_id) { $sql = " @@ -312,7 +345,12 @@ class Message_model extends DB_Model return $this->execQuery($sql, array($message_id)); } - + /** + * Deletes entry in dependency table tbl_msg_message + * + * @param $message_id + * @return boolean success + */ public function deleteMessage($message_id) { $sql = " diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index e53f23f6a..6fa39c6ba 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -1,6 +1,7 @@ export default { - getMessages(url, config, params){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type); + getMessages(url, config, params) { + console.log('page ' + params.page + ' size ' + params.size); + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type + '/' + params.size + '/' + params.page); }, getVorlagen(){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagen/'); @@ -8,8 +9,8 @@ export default { getMsgVarsLoggedInUser(){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsLoggedInUser/'); }, - getMessageVarsPerson(){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessageVarsPerson/'); + getMessageVarsPerson(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessageVarsPerson/' + params.id + '/' + params.type_id); }, getMsgVarsPrestudent(params){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + params.id + '/' + params.type_id); @@ -34,9 +35,14 @@ export default { return this.$fhcApi.get('api/frontend/v1/messages/messages/getReplyData/' + messageId); }, sendMessage(form, id, data) { + console.log("id" + id); return this.$fhcApi.post(form,'api/frontend/v1/messages/messages/sendMessage/' + id, data); }, +/* sendMessage(id, data) { + return this.$fhcApi.post('api/frontend/v1/messages/messages/sendMessage/' + id, + data); + },*/ deleteMessage(messageId){ return this.$fhcApi.post('api/frontend/v1/messages/messages/deleteMessage/' + messageId); } diff --git a/public/js/components/Messages/Details/NewMessage.js b/public/js/components/Messages/Details/Depr_NewMessage.js similarity index 100% rename from public/js/components/Messages/Details/NewMessage.js rename to public/js/components/Messages/Details/Depr_NewMessage.js diff --git a/public/js/components/Messages/Details/NewMessage/Modal.js b/public/js/components/Messages/Details/NewMessage/Modal.js index 9bfe49929..c6d3e1210 100644 --- a/public/js/components/Messages/Details/NewMessage/Modal.js +++ b/public/js/components/Messages/Details/NewMessage/Modal.js @@ -22,19 +22,25 @@ export default { type: [Number, String], required: true }, + messageId: { + type: Number, + required: false, + }, openMode: String, }, data(){ return { formData: { - recipient: this.id, + recipient: null, subject: null, body: null, vorlage_kurzbz: null, selectedValue: '', + relationmessage_id: null }, statusNew: true, vorlagen: [], + recipientsArray: [], defaultRecipient: null, editor: null, fieldsUser: [], @@ -47,7 +53,9 @@ export default { itemsPerson: [], itemsUser: [], previewText: null, - previewBody: "" + previewBody: "", + replyData: null, + uid: null, } }, methods: { @@ -98,12 +106,14 @@ export default { return this.$fhcApi.factory.messages.person.sendMessage( this.$refs.formMessage, - this.id, + this.uid, data) +/* return this.$fhcApi.factory.messages.person.sendMessage( + this.uid, + data)*/ .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); - //this.hideModal('messageModal'); - this.hideTemplate(); + this.hideModal('modalNewMessage'); this.resetForm(); }).catch(this.$fhcAlert.handleSystemError) .finally(() => { @@ -119,7 +129,7 @@ export default { return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) .then(response => { //this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); - //this.hideModal('messageModal'); + //this.hideModal('modalNewMessage'); //this.resetForm(); //TODO(Manu) CHECK this.formData.body = response.data; @@ -165,20 +175,22 @@ export default { console.error("Editor instance is not available."); } }, - replyMessage(message_id){ - console.log("auf message " + message_id + " antworten"); - }, resetForm(){ this.formData = { vorlage_kurzbz: null, body: null, subject: null, }; + this.$emit('resetMessageId'); + if (this.editor) { this.editor.setContent(""); } + this.$refs.dropdownComp.setValue(null); + this.previewBody = null; + }, handleSelectedVorlage(vorlage_kurzbz) { if (typeof vorlage_kurzbz === "string") { @@ -186,22 +198,28 @@ export default { this.formData.subject = vorlage_kurzbz; } }, - hideTemplate(){ - if (this.openMode == "showDiv") - this.isVisible = false; - }, - showTemplate(){ - if (this.openMode == "showDiv") - this.isVisible = true; - }, showPreview(){ this.getPreviewText().then(() => { this.previewBody = this.previewText; }); }, + getUid(id, typeId){ + const params = { + id: id, + type_id: typeId + }; + this.$fhcApi.factory.messages.person.getUid(params) + .then(result => { + this.uid = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + }, show(){ this.$refs.modalNewMessage.show(); - } + }, + hideModal(modalRef){ + this.$refs[modalRef].hide(); + }, }, watch: { 'formData.body': { @@ -223,11 +241,37 @@ export default { return this.getVorlagentext(newVal); } } + }, + messageId: { + immediate: true, + handler: async function (newMessageId) { + if (!newMessageId) return; + + try { + const result = await this.$fhcApi.factory.messages.person.getReplyData(newMessageId); + this.replyData = result.data; + console.log(this.replyData); + + if (this.replyData.length > 0) { + this.formData.subject = this.replyData[0].replySubject; + this.formData.body = this.replyData[0].replyBody; + this.formData.relationmessage_id = newMessageId; + } + } catch (error) { + this.$fhcAlert.handleSystemError(error); + } + } } }, created(){ - if(this.typeId == 'person_id'){ - this.$fhcApi.factory.messages.person.getMessageVarsPerson() + this.getUid(this.id, this.typeId); + + if(this.typeId == 'person_id' || this.typeId == 'mitarbeiter_uid'){ + const params = { + id: this.id, + type_id: this.typeId + }; + this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) .then(result => { this.fieldsPerson = result.data; this.itemsPerson = Object.entries(this.fieldsPerson).map(([key, value]) => ({ @@ -237,16 +281,16 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); } - if(this.typeId == 'uid') { - this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(this.id) + + if(this.typeId == 'prestudent_id' || this.typeId == 'uid'){ + const params = { + id: this.id, + type_id: this.typeId + }; + this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(params) .then(result => { this.fieldsPrestudent = result.data; const prestudent = this.fieldsPrestudent[0]; - //Just for testing with inserting values - /* this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ - label: key, - value: value - }));*/ this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ label: key.toLowerCase(), value: '{' + key.toLowerCase() + '}' @@ -271,8 +315,25 @@ export default { type_id: this.typeId}) .then(result => { this.defaultRecipient = result.data; + // console.log("check " + this.uid + "|" + this.defaultRecipient); + this.recipientsArray.push({ + 'uid': this.uid, + 'details': this.defaultRecipient}); + // console.log(JSON.stringify(this.recipientsArray)); }) .catch(this.$fhcAlert.handleSystemError); + + //case of reply + if(this.messageId) { + this.$fhcApi.factory.messages.person.getReplyData(this.messageId) + .then(result => { + this.replyData = result.data; + this.formData.subject = this.replyData[0].replySubject; + this.formData.body = this.replyData[0].replyBody; + this.formData.relationmessage_id = this.messageId; + }) + .catch(this.$fhcAlert.handleSystemError); + } }, async mounted() { this.initTinyMCE(); @@ -281,10 +342,15 @@ export default { this.editor.destroy(); }, template: ` - + @@ -296,7 +362,6 @@ export default {
-
- Felder Prestudent + {{$p.t('ui', 'felder')}} {{$p.t('lehre', 'prestudent')}}
- -

{{selectedFieldPrestudent}}

-
@@ -387,12 +449,10 @@ export default {
- -

{{selectedFieldPerson}}

- Meine Felder + {{$p.t('messages', 'meineFelder')}}
-
@@ -417,7 +476,7 @@ export default {
-

Vorschau:

+

{{ $p.t('global', 'vorschau') }}:

@@ -428,12 +487,19 @@ export default { :label="$p.t('messages/recipient')" v-model="defaultRecipient" > + +

- +
@@ -454,7 +520,7 @@ export default { - -
`, } \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage/NewDiv.js b/public/js/components/Messages/Details/NewMessage/NewDiv.js index f1dc4c88a..4331dd734 100644 --- a/public/js/components/Messages/Details/NewMessage/NewDiv.js +++ b/public/js/components/Messages/Details/NewMessage/NewDiv.js @@ -104,7 +104,6 @@ export default { this.formData.body = value; }, sendMessage() { - //TODO(Manu) check default recipient(s) const data = new FormData(); const params = { @@ -118,42 +117,34 @@ export default { }; data.append('data', JSON.stringify(merged)); - //this.uid is important for existing sendFunction + //this.uid is necessary for existing sendFunction return this.$fhcApi.factory.messages.person.sendMessage( - this.$refs.formMessage, this.uid, data) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); - //this.hideModal('messageModal'); this.hideTemplate(); this.resetForm(); + this.messageSent = true; }).catch(this.$fhcAlert.handleSystemError) .finally(() => { - //this.resetForm(); - //closeModal - //closewindwo - this.messageSent = true; - //TODO(Manu) hier route definieren? ist kein child sondern mit route aufgerufen + //TODO(Manu) hier route definieren für openmode in Tab, Page? + // ist kein child sondern mit route aufgerufen //würde allerdings neues fenster aktualisiert öffnen, altes bleibt ohne reload gleich //Reload vorheriges tab??? + if(this.openMode == "inSamePage"){ this.$emit('reloadTable'); + } } ); }, getVorlagentext(vorlage_kurzbz){ return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) .then(response => { - //this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); - //this.hideModal('messageModal'); - //this.resetForm(); - //TODO(Manu) CHECK this.formData.body = response.data; }).catch(this.$fhcAlert.handleSystemError) .finally(() => { //this.resetForm(); - //closeModal - //closewindwo }); }, getPreviewText(id, typeId){ @@ -168,8 +159,6 @@ export default { }).catch(this.$fhcAlert.handleSystemError) .finally(() => { //this.resetForm(); - //closeModal - //closewindwo }); }, insertVariable(selectedItem){ @@ -275,9 +264,10 @@ export default { this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) .then(result => { this.fieldsPerson = result.data; - this.itemsPerson = Object.entries(this.fieldsPerson).map(([key, value]) => ({ - label: value, - value: '{' + value + '}' + const person = this.fieldsPerson[0]; + this.itemsPerson = Object.entries(person).map(([key, value]) => ({ + label: key.toLowerCase(), + value: '{' + key.toLowerCase() + '}' })); }) .catch(this.$fhcAlert.handleSystemError); @@ -345,9 +335,6 @@ export default { template: `
- - -

{{ $p.t('messages', 'neueNachricht') }}

@@ -356,7 +343,6 @@ export default {
-
-
+
- + + + + diff --git a/public/js/components/VorlagenDropdown/VorlagenDropdown.js b/public/js/components/VorlagenDropdown/VorlagenDropdown.js index e5d80077e..03d8564d6 100644 --- a/public/js/components/VorlagenDropdown/VorlagenDropdown.js +++ b/public/js/components/VorlagenDropdown/VorlagenDropdown.js @@ -23,11 +23,11 @@ export default { }, */ isAdmin: { type: Boolean, - required: true + required: false }, useLoggedInUserOe: { type: Boolean, - required: true + required: false } }, data() { From 3b8b8d7882ee052e930da2c0df2b5f4b16ee9527 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 13 Mar 2025 09:34:06 +0100 Subject: [PATCH 10/13] remove testdata in getFunction --- .../controllers/api/frontend/v1/messages/Messages.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/application/controllers/api/frontend/v1/messages/Messages.php b/application/controllers/api/frontend/v1/messages/Messages.php index 101a47185..dbc11735a 100644 --- a/application/controllers/api/frontend/v1/messages/Messages.php +++ b/application/controllers/api/frontend/v1/messages/Messages.php @@ -54,11 +54,6 @@ class Messages extends FHCAPI_Controller $data = $this->getDataOrTerminateWithError($result); - //return null if count == 0 - if($data['count'] == 0){ - $this->terminateWithSuccess([]); - } - $this->addMeta('count', $data['count']); $this->terminateWithSuccess($data['data']); From b2fef71b4779aaadbe662b606935a84a019700e3 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 4 Apr 2025 09:53:54 +0200 Subject: [PATCH 11/13] added name attribute to components --- .../Messages/Details/Depr_NewMessage.js | 480 ------------------ .../Messages/Details/NewMessage/Modal.js | 1 + .../Messages/Details/NewMessage/NewDiv.js | 1 + .../Messages/Details/TableMessages.js | 3 +- public/js/components/Messages/Messages.js | 1 + .../Studentenverwaltung/Details/Messages.js | 1 + 6 files changed, 5 insertions(+), 482 deletions(-) delete mode 100644 public/js/components/Messages/Details/Depr_NewMessage.js diff --git a/public/js/components/Messages/Details/Depr_NewMessage.js b/public/js/components/Messages/Details/Depr_NewMessage.js deleted file mode 100644 index 33ff74d9c..000000000 --- a/public/js/components/Messages/Details/Depr_NewMessage.js +++ /dev/null @@ -1,480 +0,0 @@ -import FormForm from '../../Form/Form.js'; -import FormInput from '../../Form/Input.js'; -import ListBox from "../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; -import DropdownComponent from '../../VorlagenDropdown/VorlagenDropdown.js'; -import MessageModal from "../Details/NewMessage/Modal.js"; - -export default { - components: { - FormForm, - FormInput, - ListBox, - DropdownComponent, - MessageModal, - }, - props: { - endpoint: { - type: String, - required: true - }, - typeId: String, - id: { - type: [Number, String], - required: true - }, - openMode: String, - }, - data(){ - return { - formData: { - recipient: this.id, - subject: null, - body: null, - vorlage_kurzbz: null, - selectedValue: '', - }, - statusNew: true, - vorlagen: [], - defaultRecipient: null, - editor: null, - isVisible: false, - fieldsUser: [], - fieldsPerson: [], - fieldsPrestudent: [], - selectedFieldPrestudent: null, - selectedFieldUser: null, - selectedFieldPerson: null, - itemsPrestudent: [], - itemsPerson: [], - itemsUser: [], - previewText: null, - previewBody: "" - } - }, - methods: { - initTinyMCE() { - const vm = this; - tinymce.init({ - target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component - //height: 800, - //plugins: ['lists'], - toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify', - style_formats: [ - {title: 'Blocks', block: 'div'}, - {title: 'Paragraph', block: 'p'}, - {title: 'Heading 1', block: 'h1'}, - {title: 'Heading 2', block: 'h2'}, - {title: 'Heading 3', block: 'h3'}, - {title: 'Heading 4', block: 'h4'}, - {title: 'Heading 5', block: 'h5'}, - {title: 'Heading 6', block: 'h6'}, - ], - autoresize_bottom_margin: 16, - - setup: (editor) => { - vm.editor = editor; - - editor.on('input', () => { - const newContent = editor.getContent(); - vm.formData.body = newContent; - }); - }, - }); - }, - updateText(value) { - this.formData.body = value; - }, - sendMessage() { - //TODO(Manu) check default recipient(s) - const data = new FormData(); - const params = { - id: this.id, - type_id: this.typeId - }; - const merged = { - ...this.formData, - ...params - }; - data.append('data', JSON.stringify(merged)); - - return this.$fhcApi.factory.messages.person.sendMessage( - this.$refs.formMessage, - this.id, - data) - .then(response => { - this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); - //this.hideModal('messageModal'); - this.hideTemplate(); - this.resetForm(); - }).catch(this.$fhcAlert.handleSystemError) - .finally(() => { - //this.resetForm(); - //closeModal - //closewindwo - this.$emit('reloadTable'); - } - ); - }, - getVorlagentext(vorlage_kurzbz){ - //console.log(typeof vorlage_kurzbz); - return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) - .then(response => { - //this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); - //this.hideModal('messageModal'); - //this.resetForm(); - //TODO(Manu) CHECK - this.formData.body = response.data; - }).catch(this.$fhcAlert.handleSystemError) - .finally(() => { - //this.resetForm(); - //closeModal - //closewindwo - }); - }, - getPreviewText(){ - const data = new FormData(); - - data.append('data', JSON.stringify(this.formData.body)); - return this.$fhcApi.factory.messages.person.getPreviewText({ - id: this.id, - type_id: this.typeId}, data) - .then(response => { - this.previewText = response.data; - }).catch(this.$fhcAlert.handleSystemError) - .finally(() => { - //this.resetForm(); - //closeModal - //closewindwo - }); - }, - insertVariable(selectedItem){ - if (this.editor) { - this.editor.insertContent(selectedItem.value + " "); - //TODO(Manu) check: nicht mal mit Punkt adden gehts ohne eintrag nach vars -/* this.editor.focus(); - this.editor.setDirty(true);*/ - - //this.editor.fire('change'); //forces - - //this.editor.undoManager.add(); - - //this.editor.insertContent(selectedItem.value + "\u00A0"); - //this.editor.insertContent(`${selectedItem.value} `); - //this.editor.selection.setCursorLocation(this.editor.getBody(), 1); - - } else { - console.error("Editor instance is not available."); - } - }, - replyMessage(message_id){ - console.log("auf message " + message_id + " antworten"); - }, - resetForm(){ - this.formData = { - vorlage_kurzbz: null, - body: null, - subject: null, - }; - if (this.editor) { - this.editor.setContent(""); - } - this.$refs.dropdownComp.setValue(null); - - }, -/* toggleDivNewMessage(){ - this.isVisible = !this.isVisible; - },*/ - handleSelectedVorlage(vorlage_kurzbz) { - if (typeof vorlage_kurzbz === "string") { - this.getVorlagentext(vorlage_kurzbz); - this.formData.subject = vorlage_kurzbz; - } - }, - hideTemplate(){ - if (this.openMode == "showDiv") - this.isVisible = false; - }, - showTemplate(id, typeId){ - if (this.openMode == "showDiv") - this.isVisible = true; - //just for testing: - this.isVisible = true; - }, - showPreview(){ - this.getPreviewText().then(() => { - this.previewBody = this.previewText; - }); - }, - }, - watch: { - 'formData.body': { - handler(newVal) { - const tinymcsVal = this.editor.getContent(); - - if (newVal && tinymcsVal != newVal) { - //Inhalt des Editors aktualisieren - this.editor.setContent(newVal); - } - } - }, - 'formData.vorlage_kurzbz': { - handler(newVal){ - // console.log("Vorlage: " + newVal); - - if (newVal && newVal != null) { - this.formData.subject = newVal; - return this.getVorlagentext(newVal); - } - } - } - }, - created(){ - if(this.typeId == 'person_id'){ - this.$fhcApi.factory.messages.person.getMessageVarsPerson() - .then(result => { - this.fieldsPerson = result.data; - this.itemsPerson = Object.entries(this.fieldsPerson).map(([key, value]) => ({ - label: value, - value: '{' + value + '}' - })); - }) - .catch(this.$fhcAlert.handleSystemError); - } - if(this.typeId == 'uid') { - this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(this.id) - .then(result => { - this.fieldsPrestudent = result.data; - const prestudent = this.fieldsPrestudent[0]; - //Just for testing with inserting values -/* this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ - label: key, - value: value - }));*/ - this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({ - label: key.toLowerCase(), - value: '{' + key.toLowerCase() + '}' - })); - }) - .catch(this.$fhcAlert.handleSystemError); - } - - this.$fhcApi.factory.messages.person.getMsgVarsLoggedInUser() - .then(result => { - this.fieldsUser = result.data; - const user = this.fieldsUser; - this.itemsUser = Object.entries(user).map(([key, value]) => ({ - label: value, - value: '{' + value + '}' - })); - }) - .catch(this.$fhcAlert.handleSystemError); - - this.$fhcApi.factory.messages.person.getNameOfDefaultRecipient({ - id: this.id, - type_id: this.typeId}) - .then(result => { - this.defaultRecipient = result.data; - }) - .catch(this.$fhcAlert.handleSystemError); - }, - async mounted() { - this.initTinyMCE(); - }, - beforeDestroy() { - this.editor.destroy(); - }, - template: ` -
- - - - - -
-
- -

New Message

- - -
-
- - - -
- - - -
- -
- - -
- - -
- - -
- -
- - -
- -
-
- -
-
- Felder Prestudent -
- - - - - -
- - -

{{selectedFieldPrestudent}}

- -
- -
- Felder Person -
- - - - - -
- -

{{selectedFieldPerson}}

-
- -
- Meine Felder -
- - - - - -
- -
- -
- - - - - -
- -
- -
- -
- -

Vorschau:

-
- - -
- - -
- -
-
- -
-
- -
-
-
-
-
- -
- -
- -
- -
- -
- ` - -} \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage/Modal.js b/public/js/components/Messages/Details/NewMessage/Modal.js index 03345e9d4..33698f1c8 100644 --- a/public/js/components/Messages/Details/NewMessage/Modal.js +++ b/public/js/components/Messages/Details/NewMessage/Modal.js @@ -5,6 +5,7 @@ import ListBox from "../../../../../../index.ci.php/public/js/components/primevu import DropdownComponent from "../../../VorlagenDropdown/VorlagenDropdown.js"; export default { + name: "ModalNewMessages", components: { BsModal, FormForm, diff --git a/public/js/components/Messages/Details/NewMessage/NewDiv.js b/public/js/components/Messages/Details/NewMessage/NewDiv.js index 4331dd734..d8db657df 100644 --- a/public/js/components/Messages/Details/NewMessage/NewDiv.js +++ b/public/js/components/Messages/Details/NewMessage/NewDiv.js @@ -4,6 +4,7 @@ import ListBox from "../../../../../../index.ci.php/public/js/components/primevu import DropdownComponent from '../../../VorlagenDropdown/VorlagenDropdown.js'; export default { + name: "ComponentNewMessages", components: { FormForm, FormInput, diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index 89a118fd1..9047d6726 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -1,12 +1,11 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; import FormForm from '../../Form/Form.js'; -//import NewMessage from "../Details/NewMessage.js"; export default { + name: "TableMessages", components: { CoreFilterCmpt, FormForm, - // NewMessage, }, inject: { cisRoot: { diff --git a/public/js/components/Messages/Messages.js b/public/js/components/Messages/Messages.js index 5aa7eb7de..337883be3 100644 --- a/public/js/components/Messages/Messages.js +++ b/public/js/components/Messages/Messages.js @@ -2,6 +2,7 @@ import TableMessages from "./Details/TableMessages.js"; import FormOnly from "./Details/NewMessage/NewDiv.js"; import MessageModal from "../Messages/Details/NewMessage/Modal.js"; export default { + name: "MessagesComponent", components: { TableMessages, FormOnly, diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js index 4c1d9bd6b..0c46a6333 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Messages.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Messages.js @@ -1,6 +1,7 @@ import CoreMessages from "../../../Messages/Messages.js"; export default { + name: "TabMessages", components: { CoreMessages }, From 65c398498fc538df8e93e543cb01b45a6a412ce6 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 23 Apr 2025 09:32:49 +0200 Subject: [PATCH 12/13] Refactoring FhcApi_Factory View Modal --- public/js/api/factory/messages/messages.js | 112 ++++++++++++++++++ public/js/api/messages/person.js | 4 +- .../Messages/Details/NewMessage/Modal.js | 47 +++++--- .../Messages/Details/NewMessage/NewDiv.js | 45 ++++--- .../Messages/Details/TableMessages.js | 42 ++++--- 5 files changed, 201 insertions(+), 49 deletions(-) create mode 100644 public/js/api/factory/messages/messages.js diff --git a/public/js/api/factory/messages/messages.js b/public/js/api/factory/messages/messages.js new file mode 100644 index 000000000..8424e14f2 --- /dev/null +++ b/public/js/api/factory/messages/messages.js @@ -0,0 +1,112 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + //TODO(manu) check how to get params size and page + getMessages(params) { + console.log('page ' + params.page + ' size ' + params.size); + return { + method: 'get', + url: 'api/frontend/v1/messages/messages/getMessages/' + + params.id + '/' + + params.type + '/' + + params.size + '/' + + params.page + }; + }, + getVorlagen(){ + return { + method: 'get', + url: 'api/frontend/v1/messages/messages/getVorlagen/' + }; + }, + getMsgVarsLoggedInUser(){ + return { + method: 'get', + url: 'api/frontend/v1/messages/messages/getMsgVarsLoggedInUser/' + }; + }, + getMessageVarsPerson(userParams){ + return { + method: 'post', + url: 'api/frontend/v1/messages/messages/getMessageVarsPerson/' + userParams.id + '/' + userParams.type_id + }; + }, + getMsgVarsPrestudent(userParams){ + return { + method: 'post', + url: 'api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + userParams.id + '/' + userParams.type_id + }; + }, + getPersonId(params){ + return { + method: 'post', + url: 'api/frontend/v1/messages/messages/getPersonId/' + params.id + '/' + params.type_id + }; + }, + getUid(userParams){ + return { + method: 'get', + url: 'api/frontend/v1/messages/messages/getUid/' + userParams.id + '/' + userParams.type_id + }; + }, + getVorlagentext(vorlage_kurzbz){ + return { + method: 'get', + url: 'api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz + }; + }, + getNameOfDefaultRecipient(params){ + return { + method: 'get', + url: 'api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id + }; + }, + getPreviewText(userParams, params){ + return { + method: 'post', + url: 'api/frontend/v1/messages/messages/getPreviewText/' + userParams.id + '/' + userParams.type_id, + params + }; + }, + getReplyData(messageId){ + return { + method: 'get', + url: 'api/frontend/v1/messages/messages/getReplyData/' + messageId + }; + }, + sendMessageFromModalContext(id, params) { + return { + method: 'post', + url: 'api/frontend/v1/messages/messages/sendMessage/' + id, + params + }; + }, + sendMessage(id, params) { + return { + method: 'post', + url: 'api/frontend/v1/messages/messages/sendMessage/' + id, + params + }; + }, + deleteMessage(messageId){ + return { + method: 'post', + url: 'api/frontend/v1/messages/messages/deleteMessage/' + messageId + }; + } +} \ No newline at end of file diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index 9bfae6f38..f41050770 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -3,7 +3,7 @@ export default { console.log('page ' + params.page + ' size ' + params.size); return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type + '/' + params.size + '/' + params.page); }, - getVorlagen(){ +/* getVorlagen(){ return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagen/'); }, getMsgVarsLoggedInUser(){ @@ -44,5 +44,5 @@ export default { }, deleteMessage(messageId){ return this.$fhcApi.post('api/frontend/v1/messages/messages/deleteMessage/' + messageId); - } + }*/ } \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage/Modal.js b/public/js/components/Messages/Details/NewMessage/Modal.js index 33698f1c8..5bbf29f16 100644 --- a/public/js/components/Messages/Details/NewMessage/Modal.js +++ b/public/js/components/Messages/Details/NewMessage/Modal.js @@ -4,6 +4,8 @@ import FormInput from '../../../Form/Input.js'; import ListBox from "../../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; import DropdownComponent from "../../../VorlagenDropdown/VorlagenDropdown.js"; +import ApiMessages from '../../../../api/factory/messages/messages.js'; + export default { name: "ModalNewMessages", components: { @@ -104,10 +106,8 @@ export default { }; data.append('data', JSON.stringify(merged)); - return this.$fhcApi.factory.messages.person.sendMessageFromModalContext( - this.$refs.formMessage, - this.uid, - data) + return this.$refs.formMessage + .call(ApiMessages.sendMessageFromModalContext(this.uid, data)) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); this.hideModal('modalNewMessage'); @@ -122,7 +122,8 @@ export default { ); }, getVorlagentext(vorlage_kurzbz){ - return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) + return this.$api + .call(ApiMessages.getVorlagentext(vorlage_kurzbz)) .then(response => { this.formData.body = response.data; }).catch(this.$fhcAlert.handleSystemError) @@ -136,9 +137,10 @@ export default { const data = new FormData(); data.append('data', JSON.stringify(this.formData.body)); - return this.$fhcApi.factory.messages.person.getPreviewText({ - id: this.id, - type_id: this.typeId}, data) + return this.$api + .call(ApiMessages.getPreviewText({ + id: this.id, + type_id: this.typeId}, data)) .then(response => { this.previewText = response.data; }).catch(this.$fhcAlert.handleSystemError) @@ -200,7 +202,8 @@ export default { id: id, type_id: typeId }; - this.$fhcApi.factory.messages.person.getUid(params) + this.$api + .call(ApiMessages.getUid(params)) .then(result => { this.uid = result.data; }) @@ -238,9 +241,9 @@ export default { if (!newMessageId) return; try { - const result = await this.$fhcApi.factory.messages.person.getReplyData(newMessageId); + //const result = await this.$fhcApi.factory.messages.person.getReplyData(newMessageId); + const result = await this.$api.call(ApiMessages.getReplyData(newMessageId)); this.replyData = result.data; - console.log(this.replyData); if (this.replyData.length > 0) { this.formData.subject = this.replyData[0].replySubject; @@ -261,7 +264,9 @@ export default { id: this.id, type_id: this.typeId }; - this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) + //this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) + this.$api + .call(ApiMessages.getMessageVarsPerson(params)) .then(result => { this.fieldsPerson = result.data; const person = this.fieldsPerson[0]; @@ -278,7 +283,8 @@ export default { id: this.id, type_id: this.typeId }; - this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(params) + this.$api + .call(ApiMessages.getMsgVarsPrestudent(params)) .then(result => { this.fieldsPrestudent = result.data; const prestudent = this.fieldsPrestudent[0]; @@ -290,7 +296,8 @@ export default { .catch(this.$fhcAlert.handleSystemError); } - this.$fhcApi.factory.messages.person.getMsgVarsLoggedInUser() + this.$api + .call(ApiMessages.getMsgVarsLoggedInUser()) .then(result => { this.fieldsUser = result.data; const user = this.fieldsUser; @@ -301,9 +308,10 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); - this.$fhcApi.factory.messages.person.getNameOfDefaultRecipient({ - id: this.id, - type_id: this.typeId}) + this.$api + .call(ApiMessages.getNameOfDefaultRecipient({ + id: this.id, + type_id: this.typeId})) .then(result => { this.defaultRecipient = result.data; this.recipientsArray.push({ @@ -314,7 +322,8 @@ export default { //case of reply if(this.messageId) { - this.$fhcApi.factory.messages.person.getReplyData(this.messageId) + this.$api + .call(ApiMessages.getReplyData(this.messageId)) .then(result => { this.replyData = result.data; this.formData.subject = this.replyData[0].replySubject; @@ -380,7 +389,7 @@ export default { :label="$p.t('global','nachricht') + ' *'" type="textarea" v-model="formData.body" - name="text" + name="body" rows="15" cols="75" > diff --git a/public/js/components/Messages/Details/NewMessage/NewDiv.js b/public/js/components/Messages/Details/NewMessage/NewDiv.js index d8db657df..11335ed2a 100644 --- a/public/js/components/Messages/Details/NewMessage/NewDiv.js +++ b/public/js/components/Messages/Details/NewMessage/NewDiv.js @@ -2,6 +2,7 @@ import FormForm from '../../../Form/Form.js'; import FormInput from '../../../Form/Input.js'; import ListBox from "../../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js"; import DropdownComponent from '../../../VorlagenDropdown/VorlagenDropdown.js'; +import ApiMessages from "../../../../api/factory/messages/messages"; export default { name: "ComponentNewMessages", @@ -119,9 +120,11 @@ export default { data.append('data', JSON.stringify(merged)); //this.uid is necessary for existing sendFunction - return this.$fhcApi.factory.messages.person.sendMessage( +/* return this.$fhcApi.factory.messages.person.sendMessage( this.uid, - data) + data)*/ + return this.$api + .call(ApiMessages.sendMessage(this.uid, data)) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent')); this.hideTemplate(); @@ -140,7 +143,9 @@ export default { ); }, getVorlagentext(vorlage_kurzbz){ - return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) + // return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) + return this.$api + .call(ApiMessages.getVorlagentext(vorlage_kurzbz)) .then(response => { this.formData.body = response.data; }).catch(this.$fhcAlert.handleSystemError) @@ -152,9 +157,13 @@ export default { const data = new FormData(); data.append('data', JSON.stringify(this.formData.body)); - return this.$fhcApi.factory.messages.person.getPreviewText({ +/* return this.$fhcApi.factory.messages.person.getPreviewText({ id: id, - type_id: typeId}, data) + type_id: typeId}, data)*/ + return this.$api + .call(ApiMessages.getPreviewText({ + id: this.id, + type_id: this.typeId}, data)) .then(response => { this.previewText = response.data; }).catch(this.$fhcAlert.handleSystemError) @@ -226,7 +235,8 @@ export default { id: id, type_id: typeId }; - this.$fhcApi.factory.messages.person.getUid(params) + this.$api + .call(ApiMessages.getUid(params)) .then(result => { this.uid = result.data; }) @@ -262,7 +272,9 @@ export default { id: this.id, type_id: this.typeId }; - this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) + // this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) + this.$api + .call(ApiMessages.getMessageVarsPerson(params)) .then(result => { this.fieldsPerson = result.data; const person = this.fieldsPerson[0]; @@ -279,7 +291,9 @@ export default { id: this.id, type_id: this.typeId }; - this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(params) + //this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(params) + this.$api + .call(ApiMessages.getMsgVarsPrestudent(params)) .then(result => { this.fieldsPrestudent = result.data; const prestudent = this.fieldsPrestudent[0]; @@ -292,7 +306,8 @@ export default { .catch(this.$fhcAlert.handleSystemError); } - this.$fhcApi.factory.messages.person.getMsgVarsLoggedInUser() + this.$api + .call(ApiMessages.getMsgVarsLoggedInUser()) .then(result => { this.fieldsUser = result.data; const user = this.fieldsUser; @@ -303,10 +318,11 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); - this.$fhcApi.factory.messages.person.getNameOfDefaultRecipient({ - id: this.id, - type_id: this.typeId - }).then(result => { + this.$api + .call(ApiMessages.getNameOfDefaultRecipient({ + id: this.id, + type_id: this.typeId})) + .then(result => { this.defaultRecipient = result.data; this.recipientsArray.push({ 'uid': this.uid, @@ -316,7 +332,8 @@ export default { //case of reply if(this.messageId != null) { - this.$fhcApi.factory.messages.person.getReplyData(this.messageId) + this.$api + .call(ApiMessages.getReplyData(this.messageId)) .then(result => { this.replyData = result.data; this.formData.subject = this.replyData[0].replySubject; diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index 9047d6726..07fdd8f20 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -1,6 +1,8 @@ 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: { @@ -27,8 +29,20 @@ export default { }, data(){ return { +/* paginationSize: 15, + paginationInitialPage: 1,*/ tabulatorOptions: { ajaxURL: 'dummy', + //TODO(Manu) how to handle size and page? +/* ajaxRequestFunc: () => this.$api.call( + ApiMessages.getMessages({ + id: this.id, + type: this.typeId, + size: this.paginationSize, + page: this.paginationInitialPage + }) + ),*/ + //OLD WORKING VERSION ajaxRequestFunc: this.$fhcApi.factory.messages.person.getMessages, ajaxParams: () => { return { @@ -36,6 +50,7 @@ export default { type: this.typeId }; }, + ajaxResponse: (url, params, response) => this.buildTreemap(response), //ajaxResponse: (url, params, response) => this.buildTreemap(response.data), columns: [ @@ -222,7 +237,8 @@ export default { .catch(this.$fhcAlert.handleSystemError); }, deleteMessage(message_id){ - return this.$fhcApi.factory.messages.person.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) @@ -276,13 +292,11 @@ export default { } }); - // to avoid endless loop - if (iteration > messages.length) break; - } - return {data: messageNested, last_page}; -} - - + // to avoid endless loop + if (iteration > messages.length) break; + } + return {data: messageNested, last_page}; + } }, computed: { statusText(){ @@ -310,11 +324,12 @@ export default { id: this.id, type_id: this.typeId }; - this.$fhcApi.factory.messages.person.getPersonId(params) - .then(result => { - this.personId = result.data; - }) - .catch(this.$fhcAlert.handleSystemError); + this.$api + .call(ApiMessages.getPersonId(params)) + .then(result => { + this.personId = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); } }, template: ` @@ -353,7 +368,6 @@ export default {
-
From d48a0b62fd68566d0412b5cf944c979bda553ebd Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 24 Apr 2025 12:59:47 +0200 Subject: [PATCH 13/13] Refactoring FhcApi_Factory --- public/js/api/factory/messages/messages.js | 2 - public/js/api/messages/person.js | 91 +++++++++---------- .../Messages/Details/NewMessage/Modal.js | 2 - .../Messages/Details/NewMessage/NewDiv.js | 13 +-- .../Messages/Details/TableMessages.js | 33 ++++--- 5 files changed, 64 insertions(+), 77 deletions(-) diff --git a/public/js/api/factory/messages/messages.js b/public/js/api/factory/messages/messages.js index 8424e14f2..cec34ad8b 100644 --- a/public/js/api/factory/messages/messages.js +++ b/public/js/api/factory/messages/messages.js @@ -16,9 +16,7 @@ */ export default { - //TODO(manu) check how to get params size and page getMessages(params) { - console.log('page ' + params.page + ' size ' + params.size); return { method: 'get', url: 'api/frontend/v1/messages/messages/getMessages/' diff --git a/public/js/api/messages/person.js b/public/js/api/messages/person.js index f41050770..e2d2fd0c4 100644 --- a/public/js/api/messages/person.js +++ b/public/js/api/messages/person.js @@ -1,48 +1,47 @@ export default { - getMessages(url, config, params) { - console.log('page ' + params.page + ' size ' + params.size); - return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type + '/' + params.size + '/' + params.page); - }, -/* getVorlagen(){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagen/'); - }, - getMsgVarsLoggedInUser(){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsLoggedInUser/'); - }, - getMessageVarsPerson(params){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessageVarsPerson/' + params.id + '/' + params.type_id); - }, - getMsgVarsPrestudent(params){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + params.id + '/' + params.type_id); - }, - getPersonId(params){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getPersonId/'+ params.id + '/' + params.type_id); - }, - getUid(params){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getUid/'+ params.id + '/' + params.type_id); - }, - getVorlagentext(vorlage_kurzbz){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz); - }, - getNameOfDefaultRecipient(params){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id); - }, - getPreviewText(params, data){ - return this.$fhcApi.post('api/frontend/v1/messages/messages/getPreviewText/' + params.id + '/' + params.type_id, - data); - }, - getReplyData(messageId){ - return this.$fhcApi.get('api/frontend/v1/messages/messages/getReplyData/' + messageId); - }, - sendMessageFromModalContext(form, id, data) { - return this.$fhcApi.post(form,'api/frontend/v1/messages/messages/sendMessage/' + id, - data); - }, - sendMessage(id, data) { - return this.$fhcApi.post('api/frontend/v1/messages/messages/sendMessage/' + id, - data); - }, - deleteMessage(messageId){ - return this.$fhcApi.post('api/frontend/v1/messages/messages/deleteMessage/' + messageId); - }*/ + getMessages(url, config, params) { + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type + '/' + params.size + '/' + params.page); + }, + getVorlagen(){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagen/'); + }, + getMsgVarsLoggedInUser(){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsLoggedInUser/'); + }, + getMessageVarsPerson(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessageVarsPerson/' + params.id + '/' + params.type_id); + }, + getMsgVarsPrestudent(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + params.id + '/' + params.type_id); + }, + getPersonId(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getPersonId/'+ params.id + '/' + params.type_id); + }, + getUid(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getUid/'+ params.id + '/' + params.type_id); + }, + getVorlagentext(vorlage_kurzbz){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz); + }, + getNameOfDefaultRecipient(params){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id); + }, + getPreviewText(params, data){ + return this.$fhcApi.post('api/frontend/v1/messages/messages/getPreviewText/' + params.id + '/' + params.type_id, + data); + }, + getReplyData(messageId){ + return this.$fhcApi.get('api/frontend/v1/messages/messages/getReplyData/' + messageId); + }, + sendMessageFromModalContext(form, id, data) { + return this.$fhcApi.post(form,'api/frontend/v1/messages/messages/sendMessage/' + id, + data); + }, + sendMessage(id, data) { + return this.$fhcApi.post('api/frontend/v1/messages/messages/sendMessage/' + id, + data); + }, + deleteMessage(messageId){ + return this.$fhcApi.post('api/frontend/v1/messages/messages/deleteMessage/' + messageId); + } } \ No newline at end of file diff --git a/public/js/components/Messages/Details/NewMessage/Modal.js b/public/js/components/Messages/Details/NewMessage/Modal.js index 5bbf29f16..d44d0faeb 100644 --- a/public/js/components/Messages/Details/NewMessage/Modal.js +++ b/public/js/components/Messages/Details/NewMessage/Modal.js @@ -241,7 +241,6 @@ export default { if (!newMessageId) return; try { - //const result = await this.$fhcApi.factory.messages.person.getReplyData(newMessageId); const result = await this.$api.call(ApiMessages.getReplyData(newMessageId)); this.replyData = result.data; @@ -264,7 +263,6 @@ export default { id: this.id, type_id: this.typeId }; - //this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) this.$api .call(ApiMessages.getMessageVarsPerson(params)) .then(result => { diff --git a/public/js/components/Messages/Details/NewMessage/NewDiv.js b/public/js/components/Messages/Details/NewMessage/NewDiv.js index 11335ed2a..34401f6ea 100644 --- a/public/js/components/Messages/Details/NewMessage/NewDiv.js +++ b/public/js/components/Messages/Details/NewMessage/NewDiv.js @@ -118,11 +118,6 @@ export default { ...params }; data.append('data', JSON.stringify(merged)); - - //this.uid is necessary for existing sendFunction -/* return this.$fhcApi.factory.messages.person.sendMessage( - this.uid, - data)*/ return this.$api .call(ApiMessages.sendMessage(this.uid, data)) .then(response => { @@ -143,7 +138,6 @@ export default { ); }, getVorlagentext(vorlage_kurzbz){ - // return this.$fhcApi.factory.messages.person.getVorlagentext(vorlage_kurzbz) return this.$api .call(ApiMessages.getVorlagentext(vorlage_kurzbz)) .then(response => { @@ -157,9 +151,6 @@ export default { const data = new FormData(); data.append('data', JSON.stringify(this.formData.body)); -/* return this.$fhcApi.factory.messages.person.getPreviewText({ - id: id, - type_id: typeId}, data)*/ return this.$api .call(ApiMessages.getPreviewText({ id: this.id, @@ -174,7 +165,6 @@ export default { insertVariable(selectedItem){ if (this.editor) { this.editor.insertContent(selectedItem.value + " "); - // this.editor.insertContent(selectedItem.value + ". "); //TODO(Manu) check: Laden von Variblen geht nicht wenn kein Zeichen danach kommt // nicht mal mit Punkt adden gehts ohne eintrag nach vars //this.editor.focus(); @@ -272,7 +262,7 @@ export default { id: this.id, type_id: this.typeId }; - // this.$fhcApi.factory.messages.person.getMessageVarsPerson(params) + this.$api .call(ApiMessages.getMessageVarsPerson(params)) .then(result => { @@ -291,7 +281,6 @@ export default { id: this.id, type_id: this.typeId }; - //this.$fhcApi.factory.messages.person.getMsgVarsPrestudent(params) this.$api .call(ApiMessages.getMsgVarsPrestudent(params)) .then(result => { diff --git a/public/js/components/Messages/Details/TableMessages.js b/public/js/components/Messages/Details/TableMessages.js index 07fdd8f20..ac3d616ec 100644 --- a/public/js/components/Messages/Details/TableMessages.js +++ b/public/js/components/Messages/Details/TableMessages.js @@ -29,30 +29,17 @@ export default { }, data(){ return { -/* paginationSize: 15, - paginationInitialPage: 1,*/ + pageNo: 1, tabulatorOptions: { ajaxURL: 'dummy', - //TODO(Manu) how to handle size and page? -/* ajaxRequestFunc: () => this.$api.call( - ApiMessages.getMessages({ - id: this.id, - type: this.typeId, - size: this.paginationSize, - page: this.paginationInitialPage - }) - ),*/ - //OLD WORKING VERSION - ajaxRequestFunc: this.$fhcApi.factory.messages.person.getMessages, + ajaxRequestFunc: this.loadAjaxCall, ajaxParams: () => { return { id: this.id, type: this.typeId }; }, - ajaxResponse: (url, params, response) => this.buildTreemap(response), - //ajaxResponse: (url, params, response) => this.buildTreemap(response.data), columns: [ {title: "subject", field: "subject"}, {title: "body", field: "body", visible: false}, @@ -220,6 +207,12 @@ export default { this.previewBody = body; } }, + { + event: 'pageLoaded', + handler: (pageno) => { + this.pageNo = pageno+1; + } + } ], previewBody: "", open: false, @@ -296,6 +289,16 @@ export default { if (iteration > messages.length) break; } return {data: messageNested, last_page}; + }, + loadAjaxCall(params){ + return this.$api.call( + ApiMessages.getMessages({ + id: this.id, + type: this.typeId, + size: this.tabulatorOptions.paginationSize, + page: this.pageNo + }) + ); } }, computed: {