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 @@
-
+
@@ -83,12 +83,12 @@
@@ -160,7 +160,7 @@
-