From 19e587fc36820293d641d207988da56de4935bbd Mon Sep 17 00:00:00 2001 From: rdkartono Date: Mon, 20 Oct 2025 16:12:12 +0700 Subject: [PATCH] commit 20/10/2025 TODO Schedule belum beres --- html/webpage/assets/js/broadcastzones.js | 42 +----- html/webpage/assets/js/messagebank.js | 44 +------ html/webpage/assets/js/schedulebank.js | 157 +++++++++++++++-------- html/webpage/assets/js/script.js | 72 +++++++++++ html/webpage/timer.html | 14 +- src/Main.kt | 2 +- src/codes/Somecodes.kt | 4 +- src/database/MariaDB.kt | 19 ++- src/web/WebApp.kt | 42 ++++-- 9 files changed, 250 insertions(+), 146 deletions(-) diff --git a/html/webpage/assets/js/broadcastzones.js b/html/webpage/assets/js/broadcastzones.js index d730642..fd690e3 100644 --- a/html/webpage/assets/js/broadcastzones.js +++ b/html/webpage/assets/js/broadcastzones.js @@ -1,17 +1,4 @@ -/** - * @typedef {Object} BroadcastZone - * @property {number} index - * @property {string} description - * @property {String} SoundChannel - * @property {String} Box - * @property {String} Relay - */ -/** - * List of broadcast zones available - * @type {BroadcastZone[]} - */ -window.BroadcastZoneList ??= []; /** * Currently selected broadcast zone row in the table @@ -61,22 +48,7 @@ function fill_broadcastzonetablebody(vv) { $('#tablesize').text("Table Size: " + vv.length); } -/** - * Reload broadcast zones from server - * @param {String} APIURL API URL endpoint (default "BroadcastZones/") - */ -function reloadBroadcastZones(APIURL = "BroadcastZones/") { - window.BroadcastZoneList = []; - fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => { - if (Array.isArray(okdata)) { - //console.log("reloadBroadcastZones : ", okdata) - window.BroadcastZoneList.push(...okdata); - fill_broadcastzonetablebody(window.BroadcastZoneList); - } else console.log("reloadBroadcastZones: okdata is not array"); - }, (errdata) => { - alert("Error loading broadcast zones : " + errdata.message); - }); -} + function fetchSoundChannels(APIURL = "SoundChannel/") { window.SoundChannelList = []; @@ -160,11 +132,11 @@ $(document).ready(function () { } fetchSoundChannels(); - reloadBroadcastZones(APIURL_BroadcastZone); + reloadBroadcastZones(APIURL_BroadcastZone, () => fill_broadcastzonetablebody(window.BroadcastZoneList)); $btnClear.off('click').on('click', () => { DoClear(APIURL_BroadcastZone, "BroadcastZones", (okdata) => { - reloadBroadcastZones(APIURL_BroadcastZone); + reloadBroadcastZones(APIURL_BroadcastZone, () => fill_broadcastzonetablebody(window.BroadcastZoneList)); alert("Success clear broadcast zones: " + okdata.message); }, (errdata) => { alert("Error clear broadcast zones: " + errdata.message); @@ -210,7 +182,7 @@ $(document).ready(function () { Relay: relay }; fetchAPI(APIURL_BroadcastZone + "Add", "POST", {}, bz, (okdata) => { - reloadBroadcastZones(APIURL_BroadcastZone); + reloadBroadcastZones(APIURL_BroadcastZone, () => fill_broadcastzonetablebody(window.BroadcastZoneList)); alert("Success add new broadcast zone: " + okdata.message); }, (errdata) => { alert("Error add new broadcast zone: " + errdata.message); @@ -236,7 +208,7 @@ $(document).ready(function () { }; if (confirm(`Are you sure to delete broadcast zone [${bz.index}] Description=${bz.description}?`)) { fetchAPI(APIURL_BroadcastZone + "DeleteByIndex/" + bz.index, "DELETE", {}, null, (okdata) => { - reloadBroadcastZones(APIURL_BroadcastZone); + reloadBroadcastZones(APIURL_BroadcastZone, () => fill_broadcastzonetablebody(window.BroadcastZoneList)); alert("Success delete broadcast zone: " + okdata.message); }, (errdata) => { alert("Error delete broadcast zone: " + errdata.message); @@ -303,7 +275,7 @@ $(document).ready(function () { Relay: relay }; fetchAPI(APIURL_BroadcastZone + "UpdateByIndex/" + bz.index, "PATCH", {}, bzUpdate, (okdata) => { - reloadBroadcastZones(APIURL_BroadcastZone); + reloadBroadcastZones(APIURL_BroadcastZone, () => fill_broadcastzonetablebody(window.BroadcastZoneList)); alert("Success edit broadcast zone: " + okdata.message); }, (errdata) => { alert("Error edit broadcast zone: " + errdata.message); @@ -323,7 +295,7 @@ $(document).ready(function () { $btnImport.off('click').on('click', () => { DoImport(APIURL_BroadcastZone, (okdata) => { - reloadBroadcastZones(APIURL_BroadcastZone); + reloadBroadcastZones(APIURL_BroadcastZone, () => fill_broadcastzonetablebody(window.BroadcastZoneList)); alert("Success import broadcast zones: " + okdata.message); }, (errdata) => { alert("Error importing broadcast zones from XLSX: " + errdata.message); diff --git a/html/webpage/assets/js/messagebank.js b/html/webpage/assets/js/messagebank.js index 7022166..5440b55 100644 --- a/html/webpage/assets/js/messagebank.js +++ b/html/webpage/assets/js/messagebank.js @@ -1,19 +1,4 @@ -/** - * @typedef {Object} MessageBank - * @property {number} index - * @property {string} description - * @property {string} language - * @property {number} aNN_ID - * @property {string} voice_Type - * @property {string} message_Detail - * @property {string} message_TAGS - */ -/** - * List of Messagebank data loaded from server - * @type {MessageBank[]} - */ -window.messagebankdata ??= []; /** * Currently selected messagebank row in the table * @type {JQuery|null} @@ -59,22 +44,7 @@ function fill_messagebanktablebody(vv) { $('#tablesize').text("Table Size: " + vv.length); } -/** -* Reload message bank from server -* @param {string} APIURL API URL endpoint, default "MessageBank/" -*/ -function reloadMessageBank(APIURL = "MessageBank/") { - window.messagebankdata ??= []; - fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => { - if (Array.isArray(okdata)) { - window.messagebankdata.push(...okdata); - window.selectedmessagerow = null; - fill_messagebanktablebody(window.messagebankdata); - } - }, (errdata) => { - alert("Error loading messagebank : " + errdata.message); - }); -} + $(document).ready(function () { console.log("messagebank.js loaded"); @@ -223,10 +193,10 @@ $(document).ready(function () { }); - reloadMessageBank(APIURL); + reloadMessageBank(APIURL, () => fill_messagebanktablebody(window.messagebankdata)); $btnClear.click(() => { DoClear(APIURL, "Messagebank", (okdata) => { - reloadMessageBank(APIURL); + reloadMessageBank(APIURL, () => fill_messagebanktablebody(window.messagebankdata) ); alert("Success clear messagebank : " + okdata.message); }, (errdata) => { alert("Error clear messagebank : " + errdata.message); @@ -302,7 +272,7 @@ $(document).ready(function () { }; // send to server using fetchAPI fetchAPI(APIURL + "Add", "POST", mb, null, (okdata) => { - reloadMessageBank(APIURL); + reloadMessageBank(APIURL, () => fill_messagebanktablebody(window.messagebankdata) ); alert("Success add new messagebank : " + okdata.message); }, (errdata) => { alert("Error add new messagebank : " + errdata.message); @@ -331,7 +301,7 @@ $(document).ready(function () { if (confirm(`Are you sure to delete messagebank [${mb.index}] Description=${mb.description}? ANN_ID=${mb.aNN_ID} Language=${mb.language} Voice_Type=${mb.voice_Type} `)) { fetchAPI(APIURL + "DeleteByIndex/" + mb.index, "DELETE", {}, null, (okdata) => { - reloadMessageBank(APIURL); + reloadMessageBank(APIURL, () => fill_messagebanktablebody(window.messagebankdata) ); alert("Success delete messagebank : " + okdata.message); }, (errdata) => { alert("Error delete messagebank : " + errdata.message); @@ -427,7 +397,7 @@ $(document).ready(function () { Message_TAGS: messagetags }; fetchAPI(APIURL + "UpdateByIndex/" + mb.index, "PATCH", mbUpdate, null, (okdata) => { - reloadMessageBank(APIURL); + reloadMessageBank(APIURL, () => fill_messagebanktablebody(window.messagebankdata) ); alert("Success edit messagebank : " + okdata.message); }, (errdata) => { alert("Error edit messagebank : " + errdata.message); @@ -447,7 +417,7 @@ $(document).ready(function () { }); $btnImport.click(() => { DoImport(APIURL, (okdata) => { - reloadMessageBank(APIURL); + reloadMessageBank(APIURL, () => fill_messagebanktablebody(window.messagebankdata) ); alert("Success import messagebank : " + okdata.message); }, (errdata) => { alert("Error importing messagebank from XLSX : " + errdata.message); diff --git a/html/webpage/assets/js/schedulebank.js b/html/webpage/assets/js/schedulebank.js index 41607ee..8cf9863 100644 --- a/html/webpage/assets/js/schedulebank.js +++ b/html/webpage/assets/js/schedulebank.js @@ -103,30 +103,26 @@ $(document).ready(function () { let $scheduleminute = $schedulemodal.find('#scheduleminute'); // select2 for message let $schedulemessage = $schedulemodal.find('#schedulemessage'); - $schedulemessage.select2({}); // number input 0-5 let $schedulerepeat = $schedulemodal.find('#schedulerepeat'); // checkbox let $scheduleenable = $schedulemodal.find('#scheduleenable'); // select2 for broadcastzones let $schedulezones = $schedulemodal.find('#schedulezones'); - $schedulezones.select2({}); // radio button for everyday let $scheduleeveryday = $schedulemodal.find('#scheduleeveryday'); // radio button for weekly let $scheduleweekly = $schedulemodal.find('#scheduleweekly'); // select2 for weekly selection let $weeklyselect = $schedulemodal.find('#weeklyselect'); - $weeklyselect.select2({}); // radio button for specific date let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate'); // date input let $scheduledate = $schedulemodal.find('#scheduledate'); // select2 for language let $languageselect = $schedulemodal.find('#languageselect'); - $languageselect.select2({}); - $schedulespecialdate.on('change', function () { + $schedulespecialdate.off('change').on('change', function () { if ($(this).is(':checked')) { $scheduledate.prop('disabled', false); } else { @@ -139,18 +135,73 @@ $(document).ready(function () { $scheduledescription.val(''); $schedulehour.val('0'); $scheduleminute.val('0'); - $schedulerepeat.val('0'); + $schedulerepeat.val('1'); $scheduleenable.prop('checked', true); $scheduleeveryday.prop('checked', false); - + $scheduleweekly.prop('checked', false); $schedulespecialdate.prop('checked', false); + $weeklyselect.empty().select2({ + data: window.scheduledays.filter(day => day !== 'Everyday').map(day => ({ id: day, text: day })), + placeholder: 'Select days of the week', + multiple: false, + width: '100%', + dropdownParent: $('#schedulemodal') + }); + $languageselect.empty().select2({ + data: window.languages.map(lang => ({ id: lang, text: lang })), + placeholder: 'Select languages', + multiple: true, + width: '100%', + dropdownParent: $('#schedulemodal') + }); + $scheduledate.prop('disabled', true).val(''); + $schedulezones.empty().select2({ + data: window.BroadcastZoneList.map(zone => ({ id: zone.description, text: zone.description })), + placeholder: 'Select broadcast zones', + multiple: true, + width: '100%', + dropdownParent: $('#schedulemodal') + }); + let messageData = [...new Set(window.messagebankdata.filter(mb => !mb.message_Detail.includes('[')).map(mb => `${mb.description} [${mb.aNN_ID}]`))]; + $schedulemessage.empty().select2({ + placeholder: 'Select message', + multiple: false, + width: '100%', + dropdownParent: $('#schedulemodal'), + data: messageData.map(mb => ({ id: mb, text: mb })) + }); + + + + $scheduleeveryday.off('change').on('change', function () { + if ($(this).is(':checked')) { + $weeklyselect.prop('disabled', true); + $scheduledate.prop('disabled', true); + } + }); + $scheduleweekly.off('change').on('change', function () { + if ($(this).is(':checked')) { + $weeklyselect.prop('disabled', false); + $scheduledate.prop('disabled', true); + } else { + $weeklyselect.prop('disabled', true); + } + }); + $schedulespecialdate.off('change').on('change', function () { + if ($(this).is(':checked')) { + $weeklyselect.prop('disabled', true); + $scheduledate.prop('disabled', false); + } else { + $scheduledate.prop('disabled', true); + } + }); } let $findschedule = $('#findschedule'); - $findschedule.on('input', function () { + $findschedule.off('input').on('input', function () { let searchTerm = $findschedule.val().toLowerCase(); if (searchTerm.length > 0) { window.selectedschedulerow = null; @@ -167,6 +218,10 @@ $(document).ready(function () { reloadTimerBank(APIURL); + reloadBroadcastZones(); + getLanguages(); + getScheduledDays(); + reloadMessageBank(); $btnClear.click(() => { DoClear(APIURL, "Timerbank", (okdata) => { reloadTimerBank(APIURL); @@ -186,58 +241,54 @@ $(document).ready(function () { $schedulemodal.off('click.schedulesave').on('click.schedulesave', '#schedulesave', function () { // Gather form values const Description = $scheduledescription.val(); - const Soundpath = $schedulesoundpath.val(); + const Message = $schedulemessage.val(); const Repeat = parseInt($schedulerepeat.val(), 10); const Enable = $scheduleenable.is(':checked'); // Collect selected days - let Day = ""; + let _Day = ""; if ($scheduleeveryday.is(':checked')) { - Day = "Everyday"; + _Day = "Everyday"; } else if ($schedulespecialdate.is(':checked')) { - Day = $scheduledate.val(); - } else { - - if ($schedulesunday.is(':checked')) Day = "Sunday"; - if ($schedulemonday.is(':checked')) Day = "Monday"; - if ($scheduletuesday.is(':checked')) Day = "Tuesday"; - if ($schedulewednesday.is(':checked')) Day = "Wednesday"; - if ($schedulethursday.is(':checked')) Day = "Thursday"; - if ($schedulefriday.is(':checked')) Day = "Friday"; - if ($schedulesaturday.is(':checked')) Day = "Saturday"; + _Day = $scheduledate.val(); + } else if ($scheduleweekly.is(':checked')) { + _Day = $weeklyselect.val(); } - // Broadcast zones (assuming comma-separated string) - const BroadcastZones = $schedulezones.val(); - - // Validate required fields - if (!Description || !Soundpath || Day === "") { - alert("Description, sound path, and day are required."); - return; - } - + const Language = $languageselect.val().join(';'); + const broadcastZones = $schedulezones.val().join(';'); // Format time as HH:mm const hour = parseInt($schedulehour.val(), 10); const minute = parseInt($scheduleminute.val(), 10); - const Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`; + const _Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`; + console.log(`Adding schedule: Description=${Description}, Day=${_Day}, Time=${_Time}, Message=${Message}, Repeat=${Repeat}, Enable=${Enable}, BroadcastZones=${broadcastZones}, Language=${Language}`); + if (Description.length > 0) { + if (_Day.length > 0) { + if (Message.length > 0) { + if (Language.length > 0) { + if (broadcastZones.length > 0) { + // Prepare object + const scheduleObj = { + Description: Description, + Day: _Day, + Time: _Time, + Soundpath: Message, + Repeat: Repeat, + Enable: Enable, + BroadcastZones: broadcastZones, + Language: Language + }; - // Prepare object - const scheduleObj = { - Description, - Day, - Time, - Soundpath, - Repeat, - Enable, - BroadcastZones - }; - - fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => { - alert("Success add schedule: " + okdata.message); - reloadTimerBank(APIURL); - }, (errdata) => { - alert("Error add schedule: " + errdata.message); - }); - - $schedulemodal.modal('hide'); + fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => { + alert("Success add schedule: " + okdata.message); + reloadTimerBank(APIURL); + }, (errdata) => { + alert("Error add schedule: " + errdata.message); + }); + $schedulemodal.modal('hide'); + } else alert("At least one Broadcast Zone is required"); + } else alert("Language is required"); + } else alert("Message is required"); + } else alert("Day is required"); + } else alert("Description is required"); }); }); $btnRemove.click(() => { @@ -282,13 +333,15 @@ $(document).ready(function () { } if (confirm(`Are you sure to edit schedule [${sr.index}] Description=${sr.description}?`)) { $schedulemodal.modal('show'); + clearScheduleModal(); + // fill the form with existing data $scheduleid.val(sr.index); $scheduledescription.val(sr.description); let [hour, minute] = sr.time.split(':').map(num => parseInt(num, 10)); $schedulehour.val(hour.toString()); $scheduleminute.val(minute.toString()); - $schedulesoundpath.val(sr.soundpath); + $schedulemessage.val(sr.soundpath); $schedulerepeat.val(sr.repeat.toString()); $scheduleenable.prop('checked', sr.enable.toLowerCase() === 'true'); switch (sr.day) { @@ -331,7 +384,7 @@ $(document).ready(function () { $schedulemodal.off('click.schedulesave').on('click.schedulesave', '#schedulesave', function () { // Gather form values const Description = $scheduledescription.val(); - const Soundpath = $schedulesoundpath.val(); + const Soundpath = $schedulemessage.val(); const Repeat = parseInt($schedulerepeat.val(), 10); const Enable = $scheduleenable.is(':checked'); // Collect selected days diff --git a/html/webpage/assets/js/script.js b/html/webpage/assets/js/script.js index cb299eb..5ef1826 100644 --- a/html/webpage/assets/js/script.js +++ b/html/webpage/assets/js/script.js @@ -20,6 +20,76 @@ window.languages = []; */ window.scheduledays = [] +/** + * @typedef {Object} BroadcastZone + * @property {number} index + * @property {string} description + * @property {String} SoundChannel + * @property {String} Box + * @property {String} Relay + */ + +/** + * List of broadcast zones available + * @type {BroadcastZone[]} + */ +window.BroadcastZoneList ??= []; + +/** + * @typedef {Object} MessageBank + * @property {number} index + * @property {string} description + * @property {string} language + * @property {number} aNN_ID + * @property {string} voice_Type + * @property {string} message_Detail + * @property {string} message_TAGS + */ + +/** + * List of Messagebank data loaded from server + * @type {MessageBank[]} + */ +window.messagebankdata ??= []; + +/** +* Reload message bank from server +* @param {string} APIURL API URL endpoint, default "MessageBank/" +* @param {function|null} cbOK callback on success, default null +*/ +function reloadMessageBank(APIURL = "MessageBank/", cbOK = null) { + window.messagebankdata ??= []; + fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => { + if (Array.isArray(okdata)) { + window.messagebankdata.push(...okdata); + window.selectedmessagerow = null; + //fill_messagebanktablebody(window.messagebankdata); + if (cbOK) cbOK(); + } + }, (errdata) => { + alert("Error loading messagebank : " + errdata.message); + }); +} + +/** + * Reload broadcast zones from server + * @param {String} APIURL API URL endpoint (default "BroadcastZones/") + * @param {Function} cbOK callback function on success + */ +function reloadBroadcastZones(APIURL = "BroadcastZones/", cbOK = null) { + window.BroadcastZoneList = []; + fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => { + if (Array.isArray(okdata)) { + //console.log("reloadBroadcastZones : ", okdata) + window.BroadcastZoneList.push(...okdata); + if (cbOK) cbOK(); + //fill_broadcastzonetablebody(window.BroadcastZoneList); + } else console.log("reloadBroadcastZones: okdata is not array"); + }, (errdata) => { + alert("Error loading broadcast zones : " + errdata.message); + }); +} + /** * Create a list item element * @param {String} text Text Content for the list item @@ -311,6 +381,8 @@ $(document).ready(function () { getCategories(); getLanguages(); getScheduledDays(); + reloadBroadcastZones(); + reloadMessageBank(); // reconnect handle diff --git a/html/webpage/timer.html b/html/webpage/timer.html index 71903aa..f713229 100644 --- a/html/webpage/timer.html +++ b/html/webpage/timer.html @@ -74,7 +74,7 @@

Description

-
+
@@ -83,12 +83,12 @@
-
+
-
+
@@ -126,7 +126,7 @@

Message

-
+
@@ -148,7 +148,7 @@

Repeat

-
+
@@ -160,7 +160,7 @@

Broadcast Zones

-
diff --git a/src/Main.kt b/src/Main.kt index bfda93f..8a65050 100644 --- a/src/Main.kt +++ b/src/Main.kt @@ -31,7 +31,7 @@ lateinit var audioPlayer: AudioPlayer val StreamerOutputs: MutableMap = HashMap() lateinit var udpreceiver: UDPReceiver lateinit var tcpreceiver: TCPReceiver -const val version = "0.0.8 (16/10/2025)" +const val version = "0.0.9 (20/10/2025)" // AAS 64 channels const val max_channel = 64 diff --git a/src/codes/Somecodes.kt b/src/codes/Somecodes.kt index f689679..53a55d6 100644 --- a/src/codes/Somecodes.kt +++ b/src/codes/Somecodes.kt @@ -476,7 +476,9 @@ class Somecodes { return true } // check if value is in format dd/MM/yyyy - return ValidDate(value) + if (ValidDate(value)) { + return true + } } return false } diff --git a/src/database/MariaDB.kt b/src/database/MariaDB.kt index b80d882..9e79ca6 100644 --- a/src/database/MariaDB.kt +++ b/src/database/MariaDB.kt @@ -1,6 +1,7 @@ package database import codes.Somecodes.Companion.ValiDateForLogHtml +import codes.Somecodes.Companion.ValidScheduleDay import codes.Somecodes.Companion.toJsonString import content.Category import kotlinx.coroutines.Dispatchers @@ -155,6 +156,7 @@ class MariaDB( statement?.setString(6, data.Path) val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { + Add_Log("AAS", "Soundbank added: ${data.Description}; TAG: ${data.TAG}; Category: ${data.Category}; Language: ${data.Language}; VoiceType: ${data.VoiceType}; Path: ${data.Path}") Logger.info("Soundbank added: ${data.Description}" as Any) return true } else { @@ -207,6 +209,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("Soundbank updated at index $index: ${data.Description}" as Any) + Add_Log("AAS", "Soundbank updated at index $index: ${data.Description}; TAG: ${data.TAG}; Category: ${data.Category}; Language: ${data.Language}; VoiceType: ${data.VoiceType}; Path: ${data.Path}") return true } else { Logger.warn("No soundbank entry updated at index $index for: ${data.Description}" as Any) @@ -359,6 +362,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("Messagebank added: ${data.Description}" as Any) + Add_Log("AAS", "Messagebank added: ${data.Description}; Language: ${data.Language}; ANN_ID: ${data.ANN_ID}; Voice_Type: ${data.Voice_Type}") return true } else { Logger.warn("No messagebank entry added for: ${data.Description}" as Any) @@ -565,6 +569,7 @@ class MariaDB( val rowsAffected = statement.executeUpdate() if (rowsAffected > 0) { Logger.info("Language link added: ${data.TAG} -> ${data.Language}" as Any) + Add_Log("AAS", "Language link added: ${data.TAG} -> ${data.Language}") return true } else { Logger.warn("No language link entry added for: ${data.TAG} -> ${data.Language}" as Any) @@ -606,6 +611,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("Language link updated at index $index: ${data.TAG} -> ${data.Language}" as Any) + Add_Log("AAS", "Language link updated at index $index: ${data.TAG} -> ${data.Language}") return true } else { Logger.warn("No language link entry updated at index $index for: ${data.TAG} -> ${data.Language}" as Any) @@ -670,7 +676,7 @@ class MariaDB( val statement = connection.createStatement() val resultSet = statement?.executeQuery("SELECT * FROM ${super.dbName}") val workbook = XSSFWorkbook() - val sheet = workbook.createSheet("languagelinking") + val sheet = workbook.createSheet("LanguageLink") val headerRow = sheet.createRow(0) val headers = arrayOf("Index", "TAG", "Language") for ((colIndex, header) in headers.withIndex()) { @@ -737,7 +743,7 @@ class MariaDB( } override fun Add(data: ScheduleBank): Boolean { - if (!ValidDate(data.Day)) { + if (!ValidScheduleDay(data.Day)) { Logger.error("Error adding schedulebank entry: Invalid date format ${data.Day}" as Any) return false } @@ -759,6 +765,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("Schedulebank added: ${data.Description}" as Any) + Add_Log("AAS", "Schedulebank added: ${data.Description}; Day: ${data.Day}; Time: ${data.Time}; Soundpath: ${data.Soundpath}; Repeat: ${data.Repeat}; Enable: ${data.Enable}; BroadcastZones: ${data.BroadcastZones}; Language: ${data.Language}") return true } else { Logger.warn("No schedulebank entry added for: ${data.Description}" as Any) @@ -826,6 +833,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("Schedulebank updated at index $index: ${data.Description}" as Any) + Add_Log("AAS", "Schedulebank updated at index $index: ${data.Description}; Day: ${data.Day}; Time: ${data.Time}; Soundpath: ${data.Soundpath}; Repeat: ${data.Repeat}; Enable: ${data.Enable}; BroadcastZones: ${data.BroadcastZones}; Language: ${data.Language}") return true } else { Logger.warn("No schedulebank entry updated at index $index for: ${data.Description}" as Any) @@ -1003,6 +1011,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("Broadcast zone added: ${data.description}" as Any) + Add_Log("AAS", "Broadcast zone added: ${data.description}; SoundChannel: ${data.SoundChannel}; id: ${data.id}; bp: ${data.bp}") return true } else { Logger.warn("No broadcast zone entry added for: ${data.description}" as Any) @@ -1049,6 +1058,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("Broadcast zone updated at index $index: ${data.description}" as Any) + Add_Log("AAS", "Broadcast zone updated at index $index: ${data.description}; SoundChannel: ${data.SoundChannel}; id: ${data.id}; bp: ${data.bp}") return true } else { Logger.warn("No broadcast zone entry updated at index $index for: ${data.description}" as Any) @@ -1516,6 +1526,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("SoundChannel updated: ${data.channel} -> ${data.ip}" as Any) + Add_Log("AAS", "SoundChannel updated: ${data.channel} -> ${data.ip}") return true } else { Logger.warn("No SoundChannel entry updated for: ${data.channel} -> ${data.ip}" as Any) @@ -1557,6 +1568,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("SoundChannel updated at index $index: ${data.channel} -> ${data.ip}" as Any) + Add_Log("AAS", "SoundChannel updated at index $index: ${data.channel} -> ${data.ip}") return true } else { Logger.warn("No SoundChannel entry updated at index $index for: ${data.channel} -> ${data.ip}" as Any) @@ -1687,6 +1699,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("${super.dbName} IP cleared for index $index" as Any) + Add_Log("AAS", "${super.dbName} IP cleared for index $index") return true } else { Logger.warn("No ${super.dbName} entry cleared for index $index" as Any) @@ -1901,6 +1914,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("User added: ${data.username}" as Any) + Add_Log("AAS", "User added: ${data.username}") return true } else { Logger.warn("No user entry added for: ${data.username}" as Any) @@ -1951,6 +1965,7 @@ class MariaDB( val rowsAffected = statement?.executeUpdate() if (rowsAffected != null && rowsAffected > 0) { Logger.info("User updated at index $index: ${data.username}" as Any) + Add_Log("AAS", "User updated at index $index: ${data.username}") return true } else { Logger.warn("No user entry updated at index $index for: ${data.username}" as Any) diff --git a/src/web/WebApp.kt b/src/web/WebApp.kt index 32cd3e3..a554dfa 100644 --- a/src/web/WebApp.kt +++ b/src/web/WebApp.kt @@ -319,6 +319,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.soundDB.DeleteByIndex(index.toInt())) { db.soundDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS","Deleted sound bank with index $index") } else { it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete soundbank with index $index"))) } @@ -490,6 +491,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.messageDB.DeleteByIndex(index.toInt())) { db.messageDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS","Deleted message bank with index $index") } else { it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete messagebank with index $index"))) } @@ -645,6 +647,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.languageDB.DeleteByIndex(index.toInt())) { db.languageDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS","Deleted language link with index $index") } else { it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete language link with index $index"))) } @@ -736,8 +739,6 @@ class WebApp(val listenPort: Int, val userlist: List>) { } } post("Add"){ - // TODO add new schedule - // recheck lagi tambahan steph val json: JsonNode = objectmapper.readTree(it.body()) val description = json.get("Description")?.asText("") ?: "" val day = json.get("Day")?.asText("") ?: "" @@ -747,15 +748,16 @@ class WebApp(val listenPort: Int, val userlist: List>) { val enable = json.get("Enable")?.asBoolean() ?: false val broadcast_zones = json.get("BroadcastZones")?.asText("") ?: "" val language = json.get("Language")?.asText("") ?: "" + println("Add ScheduleBank, description=$description, day=$day, time=$time, soundpath=$soundpath, repeat=$repeat, enable=$enable, broadcast_zones=$broadcast_zones, language=$language") if (ValidString(description)){ - if (ValidString(day) && ValidScheduleDay(day)){ - if (ValidString(time) && ValidScheduleTime(time)){ - if (ValidString(soundpath) && ValidFile(soundpath)){ + if (ValidScheduleDay(day)){ + if (ValidScheduleTime(time)){ + if (ValidString(soundpath)){ if (repeat in 0u..127u){ if (ValidString(broadcast_zones)){ val zones = broadcast_zones.split(";") if (zones.all { zz -> db.broadcastDB.List.any { xx -> xx.description.equals(zz,true) } }){ - if (ValidString(language) && Language.entries.any{ lang -> lang.name == language }){ + if (ValidString(language)){ val newvalue = ScheduleBank( 0u, description, @@ -789,6 +791,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.scheduleDB.DeleteByIndex(index.toInt())) { db.scheduleDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS","Deleted schedule bank with index $index") } else { it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete schedule with index $index"))) } @@ -911,6 +914,24 @@ class WebApp(val listenPort: Int, val userlist: List>) { .result(objectmapper.writeValueAsString(resultMessage("Invalid XLSX file"))) } } + get("GetMessageAndBroadcastZones") { + val result = object { + val messages = db.messageDB.List + .filter { mb -> !mb.Message_Detail.contains("[") && !mb.Message_Detail.contains("]")} + .map { mb -> "${mb.Description} [${mb.ANN_ID}]" } + val broadcastzones = db.broadcastDB.List + } + it.result(objectmapper.writeValueAsString(result)) + } + + // Kirim list language dari Messagebank berdasarkan ANN_ID + get("GetLanguageList/{ANN_ID}") { get1 -> + val langlist = db.messageDB.List + .filter { it.ANN_ID == get1.pathParam("ANN_ID").toInt().toUInt() } + .map { it.Language }.distinct() + get1.result(objectmapper.writeValueAsString(langlist)) + } + } path("UserManagement") { get("List") { @@ -988,6 +1009,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.userDB.DeleteByIndex(index.toInt())) { db.userDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS", "Deleted user with index $index") } else it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete user with index $index"))) } } @@ -1078,12 +1100,9 @@ class WebApp(val listenPort: Int, val userlist: List>) { } } - //TODO kirim list message dan broadcast zones untuk ADD/Edit schedule get("GetMessageAndBroadcastZones") { val result = object { - //TODO filter message without input variable val messages = db.messageDB.List - val broadcastzones = db.broadcastDB.List } it.result(objectmapper.writeValueAsString(result)) @@ -1183,6 +1202,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.broadcastDB.DeleteByIndex(index.toInt())) { db.broadcastDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS","Deleted broadcast zone with index $index") } else { it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete broadcast zone with index $index"))) } @@ -1387,7 +1407,6 @@ class WebApp(val listenPort: Int, val userlist: List>) { } } - // Steph : coba tambah untuk QueuePaging Table. Belum ada di JS file(?) path("QueuePaging"){ get("List"){ it.result(MariaDB.ArrayListtoString(db.queuepagingDB.List)) @@ -1410,6 +1429,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.queuepagingDB.DeleteByIndex(index.toInt())) { db.queuepagingDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS", "Deleted queue paging with index $index") } else { it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete queue paging with index $index"))) } @@ -1419,7 +1439,6 @@ class WebApp(val listenPort: Int, val userlist: List>) { } - // Steph : coba tambah untuk QueueTable Table. Belum ada di JS file(?) path("QueueTable"){ get("List"){ it.result(MariaDB.ArrayListtoString(db.queuetableDB.List)) @@ -1442,6 +1461,7 @@ class WebApp(val listenPort: Int, val userlist: List>) { if (db.queuetableDB.DeleteByIndex(index.toInt())) { db.queuetableDB.Resort() it.result(objectmapper.writeValueAsString(resultMessage("OK"))) + db.Add_Log("AAS", "Deleted queue sound with index $index") } else { it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete queue sound with index $index"))) }