diff --git a/html/webpage/assets/css/bss-overrides.css b/html/webpage/assets/css/bss-overrides.css
new file mode 100644
index 0000000..d06cc3c
--- /dev/null
+++ b/html/webpage/assets/css/bss-overrides.css
@@ -0,0 +1,39 @@
+:root, [data-bs-theme=light] {
+ --bs-primary: #0d6efd;
+ --bs-primary-rgb: 13,110,253;
+ --bs-primary-text-emphasis: #052C65;
+ --bs-primary-bg-subtle: #CFE2FF;
+ --bs-primary-border-subtle: #9EC5FE;
+}
+
+.btn-primary {
+ --bs-btn-color: #fff;
+ --bs-btn-bg: #0d6efd;
+ --bs-btn-border-color: #0d6efd;
+ --bs-btn-hover-color: #fff;
+ --bs-btn-hover-bg: #0B5ED7;
+ --bs-btn-hover-border-color: #0A58CA;
+ --bs-btn-focus-shadow-rgb: 219,233,255;
+ --bs-btn-active-color: #fff;
+ --bs-btn-active-bg: #0A58CA;
+ --bs-btn-active-border-color: #0A53BE;
+ --bs-btn-disabled-color: #fff;
+ --bs-btn-disabled-bg: #0d6efd;
+ --bs-btn-disabled-border-color: #0d6efd;
+}
+
+.btn-outline-primary {
+ --bs-btn-color: #0d6efd;
+ --bs-btn-border-color: #0d6efd;
+ --bs-btn-focus-shadow-rgb: 13,110,253;
+ --bs-btn-hover-color: #fff;
+ --bs-btn-hover-bg: #0d6efd;
+ --bs-btn-hover-border-color: #0d6efd;
+ --bs-btn-active-color: #fff;
+ --bs-btn-active-bg: #0d6efd;
+ --bs-btn-active-border-color: #0d6efd;
+ --bs-btn-disabled-color: #0d6efd;
+ --bs-btn-disabled-bg: transparent;
+ --bs-btn-disabled-border-color: #0d6efd;
+}
+
diff --git a/html/webpage/assets/css/styles.css b/html/webpage/assets/css/styles.css
index 06d32fc..0c12988 100644
--- a/html/webpage/assets/css/styles.css
+++ b/html/webpage/assets/css/styles.css
@@ -62,9 +62,9 @@ body {
.btn-round-basic:focus {
background-color: #f5f5f5;
- border-radius: 20px;
+ border-radius: 8px;
box-shadow: inset 4px 4px 10px #88a5bf7b, inset -4px -4px 10px #ffffff;
- color: #4d4d4d;
+ /*color: #4d4d4d;*/
cursor: pointer;
font-size: 16px;
transition: all 0.2s ease-in-out;
@@ -72,7 +72,7 @@ body {
}
.btn-round-basic {
- border-radius: 20px;
+ border-radius: 08px;
box-shadow: rgba(136, 165, 191, 0.48) 6px 2px 16px 0px, rgba(255, 255, 255, 0.8) -6px -2px 16px 0px;
--bs-btn-hover-bg: #ffffff;
}
@@ -82,24 +82,24 @@ body {
box-shadow: inset 2px 2px 5px #bcbcbc, inset -2px -2px 5px #ffffff, 2px 2px 5px #bcbcbc, -2px -2px 5px #ffffff;
}
-.color-import {
+.color-import, .color-import:hover, .color-import:focus {
color: var(--bs-teal);
}
-.color-remove {
+.color-remove, .color-remove:hover, .color-remove:focus {
color: var(--bs-danger);
}
-.color-edit {
+.color-edit, .color-edit:hover, .color-edit:focus {
color: var(--bs-primary-text-emphasis);
}
-.color-add {
+.color-add, .color-add:hover, .color-add:focus {
color: var(--bs-primary);
}
.input-login {
- border-radius: 50px;
+ border-radius: 8px;
box-shadow: rgba(9, 30, 66, 0.25) 0px 4px 8px -2px, rgba(9, 30, 66, 0.08) 0px 0px 0px 1px;
}
@@ -227,25 +227,23 @@ nav-item:focus {
}
.accordion-item.active {
- /*background: rgba(45, 53, 120, 0.15);*/
- /*box-shadow: inset 4px 4px 10px rgba(45, 53, 120, 0.25), inset -4px -4px 10px rgba(255, 255, 255, 0.8);*/
+ background: rgba(45, 53, 120, 0.15);
+ box-shadow: inset 4px 4px 10px rgba(45, 53, 120, 0.25), inset -4px -4px 10px rgba(255, 255, 255, 0.8);
}
.bg-accordion {
border: white 2px;
- /*border-radius: 10px;*/
+ border-radius: 8px;
background: #f8f9fd;
}
.card-channel {
- border-radius: 12px;
+ border-radius: 8px;
background: #ffffff;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
transition: transform 0.2s ease, box-shadow 0.2s ease;
border: #ffffff solid 2px !important;
- /*padding-left: 2px;*/
- /*padding-right: 5px;*/
padding-top: 12px;
padding-bottom: 12px;
}
@@ -255,3 +253,27 @@ nav-item:focus {
border: white solid 3px;
}
+.progress-bar {
+ background-color: #172066;
+}
+
+table {
+ border-radius: 8px;
+}
+
+.bg-modal-body {
+ background-color: #f8f9fd;
+}
+
+.bg-header-modal {
+ background-color: #f0f2ff;
+}
+
+.pad-row-btn {
+ margin: 0.5rem;
+}
+
+.pad-2 {
+ border-radius: 0 !important;
+}
+
diff --git a/html/webpage/assets/js/broadcastzones.js b/html/webpage/assets/js/broadcastzones.js
index 5a2c07f..f3bf763 100644
--- a/html/webpage/assets/js/broadcastzones.js
+++ b/html/webpage/assets/js/broadcastzones.js
@@ -1,4 +1,17 @@
+/**
+ * @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
@@ -42,7 +55,22 @@ 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);
+ });
+}
$(document).ready(function () {
console.log("broadcastzones.js loaded successfully");
@@ -112,14 +140,11 @@ $(document).ready(function () {
}
}
- reloadBroadcastZones(APIURL_BroadcastZone, () => {
- fill_broadcastzonetablebody(window.BroadcastZoneList);
- });
+ reloadBroadcastZones(APIURL_BroadcastZone);
$btnClear.click(() => {
DoClear(APIURL_BroadcastZone, "BroadcastZones", (okdata) => {
reloadBroadcastZones(APIURL_BroadcastZone);
- fill_broadcastzonetablebody(window.BroadcastZoneList);
alert("Success clear broadcast zones: " + okdata.message);
}, (errdata) => {
alert("Error clear broadcast zones: " + errdata.message);
@@ -165,10 +190,8 @@ $(document).ready(function () {
Relay: relay
};
fetchAPI(APIURL_BroadcastZone + "Add", "POST", {}, bz, (okdata) => {
- reloadBroadcastZones(APIURL_BroadcastZone, () => {
- fill_broadcastzonetablebody(window.BroadcastZoneList);
- alert("Success add new broadcast zone: " + okdata.message);
- });
+ reloadBroadcastZones(APIURL_BroadcastZone);
+ alert("Success add new broadcast zone: " + okdata.message);
}, (errdata) => {
alert("Error add new broadcast zone: " + errdata.message);
});
@@ -193,10 +216,8 @@ $(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, () => {
- fill_broadcastzonetablebody(window.BroadcastZoneList);
- alert("Success delete broadcast zone: " + okdata.message);
- });
+ reloadBroadcastZones(APIURL_BroadcastZone);
+ alert("Success delete broadcast zone: " + okdata.message);
}, (errdata) => {
alert("Error delete broadcast zone: " + errdata.message);
});
@@ -262,10 +283,8 @@ $(document).ready(function () {
Relay: relay
};
fetchAPI(APIURL_BroadcastZone + "UpdateByIndex/" + bz.index, "PATCH", {}, bzUpdate, (okdata) => {
- reloadBroadcastZones(APIURL_BroadcastZone, () => {
- fill_broadcastzonetablebody(window.BroadcastZoneList);
- alert("Success edit broadcast zone: " + okdata.message);
- });
+ reloadBroadcastZones(APIURL_BroadcastZone);
+ alert("Success edit broadcast zone: " + okdata.message);
}, (errdata) => {
alert("Error edit broadcast zone: " + errdata.message);
});
@@ -284,10 +303,8 @@ $(document).ready(function () {
$btnImport.click(() => {
DoImport(APIURL_BroadcastZone, (okdata) => {
- reloadBroadcastZones(APIURL_BroadcastZone, () => {
- fill_broadcastzonetablebody(window.BroadcastZoneList);
- alert("Success import broadcast zones: " + okdata.message);
- });
+ reloadBroadcastZones(APIURL_BroadcastZone);
+ alert("Success import broadcast zones: " + okdata.message);
}, (errdata) => {
alert("Error importing broadcast zones from XLSX: " + errdata.message);
});
diff --git a/html/webpage/assets/js/bs-init.js b/html/webpage/assets/js/bs-init.js
new file mode 100644
index 0000000..3c1498d
--- /dev/null
+++ b/html/webpage/assets/js/bs-init.js
@@ -0,0 +1,7 @@
+document.addEventListener('DOMContentLoaded', function() {
+
+ var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bss-tooltip]'));
+ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
+ return new bootstrap.Tooltip(tooltipTriggerEl);
+ })
+}, false);
\ No newline at end of file
diff --git a/html/webpage/assets/js/languagelink.js b/html/webpage/assets/js/languagelink.js
index 8bdd05d..d48b31c 100644
--- a/html/webpage/assets/js/languagelink.js
+++ b/html/webpage/assets/js/languagelink.js
@@ -1,4 +1,15 @@
+/**
+ * @typedef {Object} LanguageBank
+ * @property {number} index
+ * @property {string} tag
+ * @property {string} language
+ *
+ */
+/** List of Languagebank data loaded from server
+ * @type {LanguageBank[]}
+ */
+window.languagebankdata = [];
/**
* Currently selected languagebank row in the table
* @type {JQuery|null}
@@ -39,7 +50,22 @@ function fill_languagebanktablebody(vv) {
$('#tablesize').text("Table Size: " + vv.length);
}
-
+/**
+ * Reload language bank from server
+ * @param {string} APIURL API URL endpoint, default "LanguageLink/"
+ */
+function reloadLanguageBank(APIURL = "LanguageLink/") {
+ window.languagebankdata = [];
+ fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
+ if (Array.isArray(okdata)) {
+ window.languagebankdata.push(...okdata);
+ window.selectedlanguagerow = null;
+ fill_languagebanktablebody(window.languagebankdata);
+ }
+ }, (errdata) => {
+ alert("Error loading languagebank : " + errdata.message);
+ });
+}
$(document).ready(function () {
console.log('languagebank.js loaded');
@@ -89,15 +115,11 @@ $(document).ready(function () {
}
});
- reloadLanguageBank(APIURL, () => {
- fill_languagebanktablebody(window.languagebankdata);
- });
+ reloadLanguageBank(APIURL);
$btnClear.click(() => {
DoClear(APIURL, "LanguageLink", (okdata) => {
- reloadLanguageBank(APIURL, () => {
- fill_languagebanktablebody(window.languagebankdata);
- alert("Success clear languageLink : " + okdata.message);
- });
+ reloadLanguageBank(APIURL);
+ alert("Success clear languageLink : " + okdata.message);
}, (errdata) => {
alert("Error clear languageLink : " + errdata.message);
});
@@ -134,10 +156,8 @@ $(document).ready(function () {
language: langString
}
fetchAPI(APIURL + "Add", "POST", {}, ll, (okdata) => {
- reloadLanguageBank(APIURL, () => {
- fill_languagebanktablebody(window.languagebankdata);
- alert("Success add language : " + okdata.message);
- });
+ alert("Success add language : " + okdata.message);
+ reloadLanguageBank(APIURL);
}, (errdata) => {
alert("Error add language : " + errdata.message);
});
@@ -161,10 +181,8 @@ $(document).ready(function () {
}
if (confirm(`Are you sure to delete language [${ll.index}] Tag=${ll.tag} Language=${ll.language}?`)) {
fetchAPI(APIURL + "DeleteByIndex/" + ll.index, "DELETE", {}, null, (okdata) => {
- reloadLanguageBank(APIURL, () => {
- fill_languagebanktablebody(window.languagebankdata);
- alert("Success delete language : " + okdata.message);
- });
+ reloadLanguageBank(APIURL);
+ alert("Success delete language : " + okdata.message);
}, (errdata) => {
alert("Error delete language : " + errdata.message);
});
@@ -221,10 +239,8 @@ $(document).ready(function () {
ll.tag = tag;
ll.language = langString;
fetchAPI(APIURL + "UpdateByIndex/" + ll.index, "PATCH", {}, ll, (okdata) => {
- reloadLanguageBank(APIURL, () => {
- fill_languagebanktablebody(window.languagebankdata);
- alert("Success edit language : " + okdata.message);
- });
+ reloadLanguageBank(APIURL);
+ alert("Success edit language : " + okdata.message);
}, (errdata) => {
alert("Error edit language : " + errdata.message);
});
@@ -246,10 +262,8 @@ $(document).ready(function () {
});
$btnImport.click(() => {
DoImport(APIURL, (okdata) => {
- reloadLanguageBank(APIURL, () => {
- fill_languagebanktablebody(window.languagebankdata);
- alert("Success import languagebank : " + okdata.message);
- });
+ reloadLanguageBank(APIURL);
+ alert("Success import languagebank : " + okdata.message);
}, (errdata) => {
alert("Error importing languagebank from XLSX : " + errdata.message);
});
diff --git a/html/webpage/assets/js/messagebank.js b/html/webpage/assets/js/messagebank.js
index 4211edb..1acf321 100644
--- a/html/webpage/assets/js/messagebank.js
+++ b/html/webpage/assets/js/messagebank.js
@@ -1,4 +1,19 @@
+/**
+ * @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}
@@ -44,7 +59,22 @@ 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");
@@ -178,15 +208,11 @@ $(document).ready(function () {
});
- reloadMessageBank(APIURL, () => {
- fill_messagebanktablebody(window.messagebankdata);
- });
+ reloadMessageBank(APIURL);
$btnClear.click(() => {
DoClear(APIURL, "Messagebank", (okdata) => {
- reloadMessageBank(APIURL, () => {
- fill_messagebanktablebody(window.messagebankdata);
- alert("Success clear messagebank : " + okdata.message);
- });
+ reloadMessageBank(APIURL);
+ alert("Success clear messagebank : " + okdata.message);
}, (errdata) => {
alert("Error clear messagebank : " + errdata.message);
});
@@ -261,10 +287,8 @@ $(document).ready(function () {
};
// send to server using fetchAPI
fetchAPI(APIURL + "Add", "POST", mb, null, (okdata) => {
- reloadMessageBank(APIURL, () => {
- fill_messagebanktablebody(window.messagebankdata);
- alert("Success add new messagebank : " + okdata.message);
- });
+ reloadMessageBank(APIURL);
+ alert("Success add new messagebank : " + okdata.message);
}, (errdata) => {
alert("Error add new messagebank : " + errdata.message);
});
@@ -292,10 +316,8 @@ $(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, () => {
- fill_messagebanktablebody(window.messagebankdata);
- alert("Success delete messagebank : " + okdata.message);
- });
+ reloadMessageBank(APIURL);
+ alert("Success delete messagebank : " + okdata.message);
}, (errdata) => {
alert("Error delete messagebank : " + errdata.message);
});
@@ -401,10 +423,8 @@ $(document).ready(function () {
Message_TAGS: messagetags
};
fetchAPI(APIURL + "UpdateByIndex/" + mb.index, "PATCH", mbUpdate, null, (okdata) => {
- reloadMessageBank(APIURL, () => {
- fill_messagebanktablebody(window.messagebankdata);
- alert("Success edit messagebank : " + okdata.message);
- });
+ reloadMessageBank(APIURL);
+ alert("Success edit messagebank : " + okdata.message);
}, (errdata) => {
alert("Error edit messagebank : " + errdata.message);
});
@@ -423,11 +443,8 @@ $(document).ready(function () {
});
$btnImport.click(() => {
DoImport(APIURL, (okdata) => {
- reloadMessageBank(APIURL, () => {
- fill_messagebanktablebody(window.messagebankdata);
- alert("Success import messagebank : " + okdata.message);
- });
-
+ reloadMessageBank(APIURL);
+ 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 7a9bade..6c9e437 100644
--- a/html/webpage/assets/js/schedulebank.js
+++ b/html/webpage/assets/js/schedulebank.js
@@ -1,4 +1,20 @@
+/**
+ * @typedef {Object} ScheduleBank
+ * @property {number} index
+ * @property {string} description
+ * @property {string} day
+ * @property {string} time
+ * @property {string} soundpath
+ * @property {number} repeat
+ * @property {boolean} enable
+ * @property {string} broadcastZones
+ * @property {string} language
+ */
+/** List of Schedulebank data loaded from server
+ * @type {ScheduleBank[]}
+ */
+window.schedulebankdata = [];
/**
* Currently selected schedulebank row in the table
* @type {JQuery|null}
@@ -45,7 +61,22 @@ function fill_schedulebanktablebody(vv) {
$('#tablesize').text("Table Size: " + vv.length);
}
-
+/**
+ * Reload timer bank from server
+ * @param {string} APIURL API URL endpoint, default "ScheduleBank/"
+ */
+function reloadTimerBank(APIURL = "ScheduleBank/") {
+ window.schedulebankdata = [];
+ fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
+ if (Array.isArray(okdata)) {
+ window.schedulebankdata.push(...okdata);
+ selectedschedulerow = null;
+ fill_schedulebanktablebody(window.schedulebankdata);
+ }
+ }, (errdata) => {
+ alert("Error loading schedulebank : " + errdata.message);
+ });
+}
$(document).ready(function () {
console.log("schedulebank.js loaded successfully");
@@ -70,7 +101,7 @@ $(document).ready(function () {
let $schedulehour = $schedulemodal.find('#schedulehour');
// number input 0-59
let $scheduleminute = $schedulemodal.find('#scheduleminute');
- // select for messagebank
+ // text input
let $schedulesoundpath = $schedulemodal.find('#schedulesoundpath');
// number input 0-5
let $schedulerepeat = $schedulemodal.find('#schedulerepeat');
@@ -106,17 +137,8 @@ $(document).ready(function () {
$scheduledescription.val('');
$schedulehour.val('0');
$scheduleminute.val('0');
-
- $schedulesoundpath.empty();
- if (Array.isArray(window.messagebankdata) && window.messagebankdata.length > 0) {
- window.messagebankdata.forEach(item => {
- let str = item.description+" ["+item.aNN_ID+"]";
- let option = ``;
- if ($schedulesoundpath.find(`option[value="${str}"]`).length === 0) $schedulesoundpath.append(option); // check if $schedulesoundpath already has this option
- })
- }
-
- $schedulerepeat.val('1');
+ $schedulesoundpath.val('');
+ $schedulerepeat.val('0');
$scheduleenable.prop('checked', true);
$scheduleeveryday.prop('checked', false);
$schedulesunday.prop('checked', false);
@@ -149,15 +171,11 @@ $(document).ready(function () {
});
- reloadTimerBank(APIURL, () => {
- fill_schedulebanktablebody(window.schedulebankdata);
- });
+ reloadTimerBank(APIURL);
$btnClear.click(() => {
DoClear(APIURL, "Timerbank", (okdata) => {
- reloadTimerBank(APIURL,() => {
- fill_schedulebanktablebody(window.schedulebankdata);
- alert("Success clear schedulebank : " + okdata.message);
- });
+ reloadTimerBank(APIURL);
+ alert("Success clear schedulebank : " + okdata.message);
}, (errdata) => {
alert("Error clear schedulebank : " + errdata.message);
});
@@ -218,10 +236,8 @@ $(document).ready(function () {
};
fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => {
- reloadTimerBank(APIURL, () => {
- fill_schedulebanktablebody(window.schedulebankdata);
- alert("Success add schedule: " + okdata.message);
- });
+ alert("Success add schedule: " + okdata.message);
+ reloadTimerBank(APIURL);
}, (errdata) => {
alert("Error add schedule: " + errdata.message);
});
@@ -246,10 +262,8 @@ $(document).ready(function () {
}
if (confirm(`Are you sure to delete schedule [${sr.index}] Description=${sr.description}?`)) {
fetchAPI(APIURL + "DeleteByIndex/" + sr.index, "DELETE", {}, null, (okdata) => {
- reloadTimerBank(APIURL, () => {
- fill_schedulebanktablebody(window.schedulebankdata);
- alert("Success delete schedule : " + okdata.message);
- });
+ reloadTimerBank(APIURL);
+ alert("Success delete schedule : " + okdata.message);
}, (errdata) => {
alert("Error delete schedule : " + errdata.message);
});
@@ -366,10 +380,8 @@ $(document).ready(function () {
};
fetchAPI(APIURL + "UpdateByIndex/" + sr.index, "PATCH", {}, scheduleObj, (okdata) => {
- reloadTimerBank(APIURL, () => {
- fill_schedulebanktablebody(window.schedulebankdata);
- alert("Success edit schedule: " + okdata.message);
- });
+ alert("Success edit schedule: " + okdata.message);
+ reloadTimerBank(APIURL);
}, (errdata) => {
alert("Error edit schedule: " + errdata.message);
});
@@ -384,10 +396,8 @@ $(document).ready(function () {
});
$btnImport.click(() => {
DoImport(APIURL, (okdata) => {
- reloadTimerBank(APIURL, () => {
- fill_schedulebanktablebody(window.schedulebankdata);
- alert("Success import schedulebank from XLSX : " + okdata.message);
- });
+ reloadTimerBank(APIURL);
+ alert("Success import schedulebank from XLSX : " + okdata.message);
}, (errdata) => {
alert("Error importing schedulebank from XLSX : " + errdata.message);
});
diff --git a/html/webpage/assets/js/script.js b/html/webpage/assets/js/script.js
index d73218b..7f0b14a 100644
--- a/html/webpage/assets/js/script.js
+++ b/html/webpage/assets/js/script.js
@@ -20,263 +20,6 @@ window.languages = [];
*/
window.scheduledays = []
-/**
- * @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
- * taruh di sini karena dipakai di banyak tempat
- * @type {MessageBank[]}
- */
-window.messagebankdata ??= [];
-
-/**
-* Reload message bank from server
-* @param {string} APIURL API URL endpoint, default "MessageBank/"
-* @param {Function|null} callback Optional callback function to execute after loading
-*/
-function reloadMessageBank(APIURL = "MessageBank/", callback=null) {
- window.messagebankdata ??= [];
- fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
- if (Array.isArray(okdata)) {
- window.messagebankdata.push(...okdata);
- console.log("Loaded " + window.messagebankdata.length + " message bank items");
- window.selectedmessagerow = null;
- if (callback && typeof callback === 'function') callback();
- }
- }, (errdata) => {
- alert("Error loading messagebank : " + errdata.message);
- });
-}
-
-/**
- * @typedef {Object} ScheduleBank
- * @property {number} index
- * @property {string} description
- * @property {string} day
- * @property {string} time
- * @property {string} soundpath
- * @property {number} repeat
- * @property {boolean} enable
- * @property {string} broadcastZones
- * @property {string} language
- */
-
-/** List of Schedulebank data loaded from server
- * @type {ScheduleBank[]}
- */
-window.schedulebankdata = [];
-
-/**
- * Reload timer bank from server
- * taruh di sini karena dipakai di banyak tempat
- * @param {string} APIURL API URL endpoint, default "ScheduleBank/"
- * @param {Function|null} callback Optional callback function to execute after loading
- */
-function reloadTimerBank(APIURL = "ScheduleBank/", callback=null) {
- window.schedulebankdata = [];
- fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
- if (Array.isArray(okdata)) {
- window.schedulebankdata.push(...okdata);
- selectedschedulerow = null;
- console.log("Loaded " + window.schedulebankdata.length + " schedule bank items");
- if (callback && typeof callback === 'function') callback();
- }
- }, (errdata) => {
- alert("Error loading schedulebank : " + errdata.message);
- });
-}
-
-/**
- * @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 ??= [];
-
-/**
- * Reload broadcast zones from server
- * taruh di sini karena dipakai di banyak tempat
- * @param {String} APIURL API URL endpoint (default "BroadcastZones/")
- * @param {Function|null} callback Optional callback function to execute after loading
- */
-function reloadBroadcastZones(APIURL = "BroadcastZones/", callback=null) {
- window.BroadcastZoneList = [];
- fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
- if (Array.isArray(okdata)) {
- //console.log("reloadBroadcastZones : ", okdata)
- window.BroadcastZoneList.push(...okdata);
- console.log("Loaded " + window.BroadcastZoneList.length + " broadcast zone items");
- window.selectedbroadcastzonerow = null;
- if (callback && typeof callback === 'function') callback();
- } else console.log("reloadBroadcastZones: okdata is not array");
- }, (errdata) => {
- alert("Error loading broadcast zones : " + errdata.message);
- });
-}
-
-/**
- * @typedef {Object} SoundBank
- * @property {number} index
- * @property {string} description
- * @property {string} tag
- * @property {string} category
- * @property {string} language
- * @property {string} voiceType
- * @property {string} path
- */
-
-/**
- * @typedef {Object} Select2item
- * @property {number} id
- * @property {string} text
- */
-
-/**
- * List of Soundbank data loaded from server
- * taruh di sini karena dipakai di banyak tempat
- * @type {SoundBank[]}
- */
-window.soundbankdata = [];
-
-/**
- * List of sound files in the soundbank directory, that ends with .wav or .mp3
- * taruh di sini karena dipakai di banyak tempat
- * @type {string[]}
- */
-window.soundbankfiles = [];
-
-/**
- * Select2 data source
- * See https://select2.org/data-sources/formats
- * @type {Select2item[]}
- */
-window.select2data = [];
-
-
-
-/**
- * Reload sound bank from server
- * @param {String} APIURL API URL endpoint, default "SoundBank/"
- * @param {Function|null} callback Optional callback function to execute after loading
- */
-function reloadSoundBank(APIURL = "SoundBank/", callback=null) {
- window.soundbankdata = [];
- fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
-
- if (Array.isArray(okdata)) {
- window.soundbankdata.push(...okdata);
- window.selectedsoundrow = null;
- console.log("Loaded " + window.soundbankdata.length + " sound bank items");
- if (callback && typeof callback === 'function') callback();
- }
- }, (errdata) => {
- alert("Error loading soundbank : " + errdata.message);
- });
-}
-
-/**
- * Reload soundbank files from server
- * @param {String} APIURL API URL endpoint (default "SoundBank/")
- * @param {Function|null} callback Optional callback function to execute after loading
- */
-function reloadSoundbankFiles(APIURL = "SoundBank/",callback=null) {
- window.soundbankfiles = [];
- fetchAPI(APIURL + "ListFiles", "GET", {}, null, (okdata) => {
- // okdata is a string contains elements separated by semicolon ;
- if (Array.isArray(okdata)) {
- window.soundbankfiles = okdata.filter(item => item.trim().length > 0);
- // refill select2data
- window.select2data = window.soundbankfiles.map((item, index) => ({ id: index + 1, text: item }));
- console.log("Loaded " + window.soundbankfiles.length + " sound bank files");
- if (callback && typeof callback === 'function') callback();
- } else console.log("reloadSoundbankFiles: okdata is not array");
- }, (errdata) => {
- alert("Error loading soundbank files : " + errdata.message);
- });
-}
-
-/**
- * @typedef {Object} SoundChannel
- * @property {number} index - The index of the sound channel.
- * @property {string} channel - The name of the sound channel.
- * @property {string} ip - The IP address associated with the sound channel.
- */
-
-/**
- * @type {SoundChannel[]}
- */
-window.soundChannels = [];
-
-/**
- * Reload sound channels from server
- * @param {String} APIURL API URL endpoint (default "SoundChannel/")
- * @param {Function|null} callback Optional callback function to execute after loading
- */
-function reloadSoundChannel(APIURL = "SoundChannel/", callback=null) {
- window.soundChannels = [];
- fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
- if (Array.isArray(okdata)) {
- //console.log("reloadSoundChannel : ", okdata)
- window.soundChannels.push(...okdata);
- window.selectedsoundchannelrow = null;
- console.log("Loaded " + window.soundChannels.length + " sound channel items");
- if (callback && typeof callback === 'function') callback();
- } else console.log("reloadSoundChannel: okdata is not array");
- }, (errdata) => {
- alert("Error loading sound channels : " + errdata.message);
- });
-}
-
-/**
- * @typedef {Object} LanguageBank
- * @property {number} index
- * @property {string} tag
- * @property {string} language
- *
- */
-
-/** List of Languagebank data loaded from server
- * @type {LanguageBank[]}
- */
-window.languagebankdata = [];
-
-/**
- * Reload language bank from server
- * @param {string} APIURL API URL endpoint, default "LanguageLink/"
- * @param {Function|null} callback Optional callback function to execute after loading
- */
-function reloadLanguageBank(APIURL = "LanguageLink/", callback=null) {
- window.languagebankdata = [];
- fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
- if (Array.isArray(okdata)) {
- window.languagebankdata.push(...okdata);
- window.selectedlanguagerow = null;
- console.log("Loaded " + window.languagebankdata.length + " language bank items");
- if (callback && typeof callback === 'function') callback();
- }
- }, (errdata) => {
- alert("Error loading languagebank : " + errdata.message);
- });
-}
-
-
/**
* Create a list item element
* @param {String} text Text Content for the list item
@@ -568,13 +311,7 @@ $(document).ready(function () {
getCategories();
getLanguages();
getScheduledDays();
- reloadMessageBank();
- reloadTimerBank();
- reloadBroadcastZones();
- reloadSoundBank();
- reloadSoundbankFiles();
- reloadSoundChannel();
- reloadLanguageBank();
+
// Initialize WebSocket connection
window.ws = new WebSocket(wsURL);
diff --git a/html/webpage/assets/js/soundbank.js b/html/webpage/assets/js/soundbank.js
index 855c951..59ecfb7 100644
--- a/html/webpage/assets/js/soundbank.js
+++ b/html/webpage/assets/js/soundbank.js
@@ -1,11 +1,61 @@
+/**
+ * @typedef {Object} SoundBank
+ * @property {number} index
+ * @property {string} description
+ * @property {string} tag
+ * @property {string} category
+ * @property {string} language
+ * @property {string} voiceType
+ * @property {string} path
+ */
+/**
+ * @typedef {Object} Select2item
+ * @property {number} id
+ * @property {string} text
+ */
+
+/**
+ * List of Soundbank data loaded from server
+ * @type {SoundBank[]}
+ */
+window.soundbankdata = [];
/**
* Currently selected soundbank row in the table
* @type {JQuery|null}
*/
window.selectedsoundrow = null;
+/**
+ * List of sound files in the soundbank directory, that ends with .wav or .mp3
+ * @type {string[]}
+ */
+window.soundbankfiles = [];
+/**
+ * Select2 data source
+ * See https://select2.org/data-sources/formats
+ * @type {Select2item[]}
+ */
+window.select2data = [];
+
+/**
+ * Reload sound bank from server
+ * @param {String} APIURL API URL endpoint, default "SoundBank/"
+ */
+function reloadSoundBank(APIURL = "SoundBank/") {
+ window.soundbankdata = [];
+ fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
+
+ if (Array.isArray(okdata)) {
+ window.soundbankdata.push(...okdata);
+ window.selectedsoundrow = null;
+ fill_soundbanktablebody(window.soundbankdata);
+ }
+ }, (errdata) => {
+ alert("Error loading soundbank : " + errdata.message);
+ });
+}
/**
* Fill soundbank table body with values
@@ -13,7 +63,6 @@ window.selectedsoundrow = null;
*/
function fill_soundbanktablebody(vv) {
$('#soundbanktablebody').empty();
- console.log("Filling soundbank table with " + vv.length + " items");
if (!Array.isArray(vv) || vv.length === 0) return;
vv.forEach(item => {
const row = `
@@ -49,7 +98,23 @@ function fill_soundbanktablebody(vv) {
}
-
+/**
+ * Reload soundbank files from server
+ * @param {String} APIURL API URL endpoint (default "SoundBank/")
+ */
+function reloadSoundbankFiles(APIURL = "SoundBank/") {
+ window.soundbankfiles = [];
+ fetchAPI(APIURL + "ListFiles", "GET", {}, null, (okdata) => {
+ // okdata is a string contains elements separated by semicolon ;
+ if (Array.isArray(okdata)) {
+ window.soundbankfiles = okdata.filter(item => item.trim().length > 0);
+ // refill select2data
+ window.select2data = window.soundbankfiles.map((item, index) => ({ id: index + 1, text: item }));
+ } else console.log("reloadSoundbankFiles: okdata is not array");
+ }, (errdata) => {
+ alert("Error loading soundbank files : " + errdata.message);
+ });
+}
$(document).ready(function () {
console.log("soundbank.js loaded successfully");
@@ -107,10 +172,7 @@ $(document).ready(function () {
})
}
- reloadSoundBank(APIURL, () => {
- fill_soundbanktablebody(window.soundbankdata);
- });
-
+ reloadSoundBank(APIURL);
$('#findsoundbank').on('input', function () {
let searchTerm = $(this).val().trim().toLowerCase();
if (searchTerm.length > 0) {
@@ -124,10 +186,8 @@ $(document).ready(function () {
});
$btnClear.click(() => {
DoClear(APIURL, "Soundbank", (okdata) => {
- reloadSoundBank(APIURL, () => {
- fill_soundbanktablebody(window.soundbankdata);
- alert("Success clear soundbank : " + okdata.message);
- });
+ reloadSoundBank(APIURL);
+ alert("Success clear soundbank : " + okdata.message);
}, (errdata) => {
alert("Error clear soundbank : " + errdata.message);
});
@@ -162,10 +222,8 @@ $(document).ready(function () {
}
if (confirm(`Are you sure to delete soundbank [${sb.index}] Description=${sb.description} Tag=${sb.tag}?`)) {
fetchAPI(APIURL + "DeleteByIndex/" + sb.index, "DELETE", {}, null, (okdata) => {
- reloadSoundBank(APIURL, () => {
- fill_soundbanktablebody(window.soundbankdata);
- alert("Success delete soundbank : " + okdata.message);
- });
+ reloadSoundBank(APIURL);
+ alert("Success delete soundbank : " + okdata.message);
}, (errdata) => {
alert("Error delete soundbank : " + errdata.message);
});
@@ -207,10 +265,8 @@ $(document).ready(function () {
});
$btnImport.click(() => {
DoImport(APIURL, (okdata) => {
- reloadSoundBank(APIURL, () => {
- fill_soundbanktablebody(window.soundbankdata);
- alert("Success import soundbank : " + okdata.message);
- });
+ reloadSoundBank(APIURL);
+ alert("Success import soundbank : " + okdata.message);
}, (errdata) => {
alert("Error importing soundbank from XLSX : " + errdata.message);
});
diff --git a/html/webpage/assets/js/soundchannel.js b/html/webpage/assets/js/soundchannel.js
index a273349..2935eac 100644
--- a/html/webpage/assets/js/soundchannel.js
+++ b/html/webpage/assets/js/soundchannel.js
@@ -1,4 +1,14 @@
+/**
+ * @typedef {Object} SoundChannel
+ * @property {number} index - The index of the sound channel.
+ * @property {string} channel - The name of the sound channel.
+ * @property {string} ip - The IP address associated with the sound channel.
+ */
+/**
+ * @type {SoundChannel[]}
+ */
+window.soundChannels = [];
// Currently selected sound channel row in the table
window.selectedSoundChannel = null;
@@ -41,7 +51,22 @@ function fill_soundchanneltablebody(vv) {
$tablesizeSoundChannel.text("Table Size: " + vv.length);
}
-
+/**
+ * Reload sound channels from server
+ * @param {String} APIURL API URL endpoint (default "SoundChannel/")
+ */
+function reloadSoundChannel(APIURL = "SoundChannel/") {
+ window.soundChannels = [];
+ fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
+ if (Array.isArray(okdata)) {
+ //console.log("reloadSoundChannel : ", okdata)
+ window.soundChannels.push(...okdata);
+ fill_soundchanneltablebody(window.soundChannels);
+ } else console.log("reloadSoundChannel: okdata is not array");
+ }, (errdata) => {
+ alert("Error loading sound channels : " + errdata.message);
+ });
+}
$(document).ready(function () {
console.log("soundchannel.js loaded successfully");
@@ -83,15 +108,11 @@ $(document).ready(function () {
$soundchannelip.val('');
}
- reloadSoundChannel(API_SoundChannel, () => {
- fill_soundchanneltablebody(window.soundChannels);
- });
+ reloadSoundChannel(API_SoundChannel);
$btnReinitializeSoundChannel.click(() => {
DoClear(API_SoundChannel, "SoundChannels", (okdata) => {
- reloadSoundChannel(API_SoundChannel, () => {
- fill_soundchanneltablebody(window.soundChannels);
- alert("Success clear sound channels: " + okdata.message);
- });
+ reloadSoundChannel(API_SoundChannel);
+ alert("Success clear sound channels: " + okdata.message);
}, (errdata) => {
alert("Error clear sound channels: " + errdata.message);
});
@@ -135,10 +156,8 @@ $(document).ready(function () {
fetchAPI(API_SoundChannel + "UpdateByIndex/" + newsc.index, "PATCH", {}, newsc, (okdata) => {
- reloadSoundChannel(API_SoundChannel, () => {
- fill_soundchanneltablebody(window.soundChannels);
- alert("Success edit sound channel: " + okdata.message);
- });
+ reloadSoundChannel(API_SoundChannel);
+ alert("Success edit sound channel: " + okdata.message);
}, (errdata) => {
alert("Error edit sound channel: " + errdata.message);
});
@@ -158,10 +177,8 @@ $(document).ready(function () {
$btnImportSoundChannel.click(() => {
DoImport(API_SoundChannel, (okdata) => {
- reloadSoundChannel(API_SoundChannel, () => {
- fill_soundchanneltablebody(window.soundChannels);
- alert("Success import sound channels: " + okdata.message);
- });
+ reloadSoundChannel(API_SoundChannel);
+ alert("Success import sound channels: " + okdata.message);
}, (errdata) => {
alert("Error importing sound channels from XLSX: " + errdata.message);
});
diff --git a/html/webpage/assets/js/usermanagement.js b/html/webpage/assets/js/usermanagement.js
index 5dc01b3..34c6a55 100644
--- a/html/webpage/assets/js/usermanagement.js
+++ b/html/webpage/assets/js/usermanagement.js
@@ -4,9 +4,10 @@
* @property {string} username Username
* @property {string} password Password (plain)
* @property {string} location Location
- * @property {string} soundbank_tags Soundbank variable tags separated by semicolon ;
- * @property {string} messagebank_ann_id Messagebank announcement ID separated by semicolon ;
- * @property {string} broadcastzones Broadcast zones separated by semicolon ;
+ * @property {string} airline_tags Airline variable tags (string) separated by semicolon ;
+ * @property {string} city_tags City variable tags (string) separated by semicolon ;
+ * @property {string} messagebank_ann_id Messagebank announcement ID (number) separated by semicolon ;
+ * @property {string} broadcastzones Broadcast zones description (string) separated by semicolon ;
*/
/** List of UserDB data loaded from server
@@ -20,13 +21,96 @@ window.userdb = [];
*/
window.selecteduserrow = null;
+/**
+ * @typedef {Object} KeyValueMessage
+ * @property {string} key
+ * @property {string} value
+ */
+
+/**
+ * List of airline tags loaded from server
+ * @type {KeyValueMessage[]}
+ */
+window.airlinetags = [];
+/**
+ * List of city tags loaded from server
+ * @type {KeyValueMessage[]}
+ */
+window.citytags = [];
+/**
+ * List of message bank IDs loaded from server
+ * @type {KeyValueMessage[]}
+ */
+window.messagebankids = [];
+/**
+ * List of broadcast zones description loaded from server
+ * @type {string[]}
+ */
+window.broadcastzones = [];
+
+/**
+ * Get Messagebank ANN_IDs from server
+ */
+function get_messagebankids() {
+ messagebankids = [];
+ fetchAPI("MessageBank/" + "MessageIDs", "GET", {}, null, (okdata) => {
+ if (Array.isArray(okdata)) {
+ messagebankids.push(...okdata);
+ }
+ }, (errdata) => {
+ alert("Error loading message bank IDs : " + errdata.message);
+ });
+}
+
+/**
+ * Get Airline Tags from server
+ */
+function get_airlinetags() {
+ airlinetags = [];
+ fetchAPI("SoundBank/" + "AirlineTags", "GET", {}, null, (okdata) => {
+ if (Array.isArray(okdata)) {
+ airlinetags.push(...okdata);
+ }
+ }, (errdata) => {
+ alert("Error loading airline tags : " + errdata.message);
+ });
+}
+
+/**
+ * Get City Tags from server
+ */
+function get_citytags() {
+ citytags = [];
+ fetchAPI("SoundBank/" + "CityTags", "GET", {}, null, (okdata) => {
+ if (Array.isArray(okdata)) {
+ citytags.push(...okdata);
+ }
+ }, (errdata) => {
+ alert("Error loading city tags : " + errdata.message);
+ });
+}
+
+/**
+ * Get Broadcast Zones descriptions from server
+ */
+function get_broadcastzones_descriptions() {
+ broadcastzones = [];
+ fetchAPI("BroadcastZones/" + "BroadcastZoneDescriptions", "GET", {}, null, (okdata) => {
+ if (Array.isArray(okdata)) {
+ broadcastzones.push(...okdata);
+ }
+ }, (errdata) => {
+ alert("Error loading broadcast zones : " + errdata.message);
+ });
+}
+
/**
* Fill user table body with values
* @param {UserDB[]} vv values to fill
*/
function fill_usertablebody(vv) {
$('#usertablebody').empty();
-
+
if (!Array.isArray(vv) || vv.length === 0) {
$('#btnExport').prop('disabled', true);
return;
@@ -34,10 +118,12 @@ function fill_usertablebody(vv) {
vv.forEach(item => {
const row = `
| ${item.index} |
- ${item.datenya} |
- ${item.timenya} |
- ${item.machine} |
- ${item.description} |
+ ${item.username} |
+ ${item.location} |
+ ${item.airline_tags} |
+ ${item.city_tags} |
+ ${item.messagebank_ann_id} |
+ ${item.broadcastzones} |
`;
$('#usertablebody').append(row);
let $addedrow = $('#usertablebody tr:last');
@@ -63,9 +149,9 @@ function fill_usertablebody(vv) {
/**
* Reload UserDB from server with date and filter
- * @param {String} APIURL API URL endpoint , default "User/"
+ * @param {String} APIURL API URL endpoint , default "UserManagement/"
*/
-function reloaduserDB(APIURL = "User/") {
+function reloaduserDB(APIURL = "UserManagement/") {
window.userdb = [];
fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
if (Array.isArray(okdata)) {
@@ -79,6 +165,12 @@ function reloaduserDB(APIURL = "User/") {
$(document).ready(function () {
console.log("usermanagement.js ready");
+ get_airlinetags();
+ get_citytags();
+ get_messagebankids();
+ get_broadcastzones_descriptions();
+
+
let $usertablebody = $('#usertablebody');
let $finduser = $('#finduser');
let $btnClear = $('#btnClear');
@@ -87,7 +179,7 @@ $(document).ready(function () {
let $btnEdit = $('#btnEdit');
let $btnExport = $('#btnExport');
let $btnImport = $('#btnImport');
- let APIURL = "User/";
+ let APIURL = "UserManagement/";
// add / edit modal elements
let $addmodal = $('#addmodal');
@@ -95,34 +187,407 @@ $(document).ready(function () {
let $modalusername = $('#modalusername');
let $modalpassword = $('#modalpassword');
let $modalverifypassword = $('#modalverifypassword');
- let $modalsoundbank = $('#modalsoundbank');
+ let $modallocation = $('#modallocation');
+ let $modalairlinetags = $('#modalairlinetags');
+ let $modalcitytags = $('#modalcitytags');
let $modalmessagebank = $('#modalmessagebank');
let $modalbroadcastzones = $('#modalbroadcastzones');
let $btnShowSoundbankModal = $('#btnShowSoundbankModal');
let $btnShowMessagebankModal = $('#btnShowMessagebankModal');
let $btnShowBroaadcastZoneModal = $('#btnShowBroaadcastZoneModal');
- let $usermanagementsave = $('#usermanagementsave');
- let $usermanagementclose = $('#usermanagementclose');
-
+
+
+ function clearAddModal() {
+ $modalindex.val("");
+ $modalusername.val("");
+ $modalpassword.val("");
+ $modalverifypassword.val("");
+ $modalairlinetags.val("");
+ $modalcitytags.val("");
+ $modalmessagebank.val("");
+ $modalbroadcastzones.val("");
+ $modallocation.val("");
+ }
+
// soundbank selection modal elements
let $soundbankmodal = $('#soundbankmodal');
- let $soundbankselection = $('#soundbankselection');
- let $soundbankselectionsave = $('#soundbankselectionsave');
- let $soundbankselectionclose = $('#soundbankselectionclose');
-
+ let $citylist = $('#citylist');
+ let $airlinelist = $('#airlinelist');
+
+ function fill_citylist() {
+ $citylist.empty();
+ citytags.forEach(tag => {
+ let value = `${tag.value} [${tag.key}]`;
+ const row = `
+
+
+
`;
+ $citylist.append(row);
+ });
+ }
+
+ function fill_airlinelist() {
+ $airlinelist.empty();
+ airlinetags.forEach(tag => {
+ let value = `${tag.value} [${tag.key}]`;
+ const row = `
+
+
+
`;
+ $airlinelist.append(row);
+ });
+ }
+
// broadcast zone selection modal elements
let $broadcastzonemodal = $('#broadcastzonemodal');
- let $broadcastzoneselection = $('#broadcastzoneselection');
- let $broadcastzoneselectionsave = $('#broadcastzoneselectionsave');
- let $broadcastzoneselectionclose = $('#broadcastzoneselectionclose');
-
+ let $broadcastzonelist = $('#broadcastzonelist');
+
+ function fill_broadcastzonelist() {
+ $broadcastzonelist.empty();
+ broadcastzones.forEach(desc => {
+ const row = `
+
+
+
`;
+ $broadcastzonelist.append(row);
+ });
+ }
+
+
// messagebank selection modal elements
let $messagebankmodal = $('#messagebankmodal');
- let $messagebankselection = $('#messagebankselection');
- let $messagebankselectionsave = $('#messagebankselectionsave');
- let $messagebankselectionclose = $('#messagebankselectionclose');
+ let $messagebanklist = $('#messagebanklist');
+
+ function fill_messagebanklist() {
+ $messagebanklist.empty();
+ messagebankids.forEach(id => {
+ let value = `${id.value} [${id.key}]`;
+ const row = `
+
+
+
`;
+ $messagebanklist.append(row);
+ });
+ }
+
$usertablebody.empty();
+ reloaduserDB();
$finduser.on('input', function () {
+ let searchTerm = $(this).val().toLowerCase();
+ if (searchTerm.length > 0) {
+ let filteredUsers = window.userdb.filter(user =>
+ user.username.toLowerCase().includes(searchTerm) ||
+ user.airline_tags.toLowerCase().includes(searchTerm) ||
+ user.city_tags.toLowerCase().includes(searchTerm)
+ //user.messagebank_ann_id.toLowerCase().includes(searchTerm) ||
+ //user.broadcastzones.toLowerCase().includes(searchTerm)
+ );
+ fill_usertablebody(filteredUsers);
+ } else {
+ fill_usertablebody(window.userdb);
+ }
+
+ });
+
+ /**
+ * Show modal dialog for soundbank, messagebank, broadcastzone selection
+ * @param {boolean} editmode if true, edit mode, else add mode
+ * @param {number} index index of user to edit, default 0
+ */
+ function modalshow(editmode = false, index=0) {
+ // event on click btnShowSoundbankModal
+ $btnShowSoundbankModal.on('click', function () {
+ $soundbankmodal.modal('show');
+ fill_citylist();
+ fill_airlinelist();
+
+ let airline = $modalairlinetags.val().trim();
+ let city = $modalcitytags.val().trim();
+ if (airline.length > 0) {
+ let airlinekeys = airline.split(";");
+ $('#airlinelist input[type=checkbox]').each(function () {
+ let tag = $(this).val();
+ if (airlinekeys.includes(tag)) {
+ $(this).prop('checked', true);
+ }
+ });
+ }
+ if (city.length > 0) {
+ let citykeys = city.split(";");
+ $('#citylist input[type=checkbox]').each(function () {
+ let tag = $(this).val();
+ if (citykeys.includes(tag)) {
+ $(this).prop('checked', true);
+ }
+ });
+ }
+
+ $soundbankmodal.on('click.soundbankselectionsave', '#soundbankselectionsave', function () {
+ let selected_airlinetags = [];
+ $('#airlinelist input[type=checkbox]:checked').each(function () {
+ selected_airlinetags.push($(this).val());
+ });
+ let selected_citytags = [];
+ $('#citylist input[type=checkbox]:checked').each(function () {
+ selected_citytags.push($(this).val());
+ });
+
+ //console.log("Selected airline tags: ", selected_airlinetags);
+ //console.log("Selected city tags: ", selected_citytags);
+
+ if (selected_airlinetags.length == 0 || selected_citytags.length == 0) {
+ alert("Please select at least one airline tag and one city tag.");
+ return;
+ }
+
+ let airlinevalue = selected_airlinetags.join(";");
+ let cityvalue = selected_citytags.join(";");
+ $modalairlinetags.val(airlinevalue);
+ $modalcitytags.val(cityvalue);
+
+
+ $soundbankmodal.modal('hide');
+ });
+ $soundbankmodal.on('click.soundbankselectionclose', '#soundbankselectionclose', function () {
+ $soundbankmodal.modal('hide');
+ });
+ });
+ // event on click btnShowMessagebankModal
+ $btnShowMessagebankModal.on('click', function () {
+ $messagebankmodal.modal('show');
+ fill_messagebanklist();
+ let messagebank = $modalmessagebank.val().trim();
+ if (messagebank.length > 0) {
+ let messagebankkeys = messagebank.split(";");
+ $('#messagebanklist input[type=checkbox]').each(function () {
+ let id = $(this).val();
+ if (messagebankkeys.includes(id)) {
+ $(this).prop('checked', true);
+ }
+ });
+ }
+
+ $messagebankmodal.on('click.messagebankselectionsave', '#messagebankselectionsave', function () {
+ let selected_messagebankids = [];
+ $('#messagebanklist input[type=checkbox]:checked').each(function () {
+ selected_messagebankids.push($(this).val());
+ });
+ //console.log("Selected message bank IDs: ", selected_messagebankids);
+ if (selected_messagebankids.length == 0) {
+ alert("Please select at least one message bank ID.");
+ return;
+ }
+ let messagebankvalue = selected_messagebankids.join(";");
+ $modalmessagebank.val(messagebankvalue);
+
+ $messagebankmodal.modal('hide');
+ });
+ $messagebankmodal.on('click.messagebankselectionclose', '#messagebankselectionclose', function () {
+ $messagebankmodal.modal('hide');
+ });
+ });
+ // event on click btnShowBroaadcastZoneModal
+ $btnShowBroaadcastZoneModal.on('click', function () {
+ $broadcastzonemodal.modal('show');
+ fill_broadcastzonelist();
+ let broadcastzones = $modalbroadcastzones.val().trim();
+ if (broadcastzones.length > 0) {
+ let broadcastzonesvalues = broadcastzones.split(";");
+ $('#broadcastzonelist input[type=checkbox]').each(function () {
+ let desc = $(this).val();
+ if (broadcastzonesvalues.includes(desc)) {
+ $(this).prop('checked', true);
+ }
+ });
+ }
+ $broadcastzonemodal.on('click.broadcastzoneselectionsave', '#broadcastzoneselectionsave', function () {
+ let selected_broadcastzones = [];
+ $('#broadcastzonelist input[type=checkbox]:checked').each(function () {
+ selected_broadcastzones.push($(this).val());
+ });
+ //console.log("Selected broadcast zones: ", selected_broadcastzones);
+ if (selected_broadcastzones.length == 0) {
+ alert("Please select at least one broadcast zone.");
+ return;
+ }
+ let broadcastzonesvalue = selected_broadcastzones.join(";");
+ $modalbroadcastzones.val(broadcastzonesvalue);
+ $broadcastzonemodal.modal('hide');
+ });
+ $broadcastzonemodal.on('click.broadcastzoneselectionclose', '#broadcastzoneselectionclose', function () {
+ $broadcastzonemodal.modal('hide');
+ });
+ });
+
+ // event on Click save button
+ $addmodal.on('click.usermanagementsave', '#usermanagementsave', function () {
+ let username = $modalusername.val().trim();
+ let password = $modalpassword.val();
+ let verifypassword = $modalverifypassword.val();
+ let location = $modallocation.val().trim();
+ let airline_tags = $modalairlinetags.val().trim();
+ let city_tags = $modalcitytags.val().trim();
+ let messagebank_ann_id = $modalmessagebank.val().trim();
+ let broadcastzones = $modalbroadcastzones.val().trim();
+
+ if (username.length === 0) {
+ alert("Username cannot be empty");
+ return;
+ }
+ if (password.length === 0 || verifypassword.length === 0) {
+ alert("Password cannot be empty");
+ return;
+ }
+ if (password !== verifypassword) {
+ alert("Password and Verify Password do not match");
+ return;
+ }
+ if (airline_tags.length === 0) {
+ alert("Airline tags cannot be empty");
+ return;
+ }
+ if (city_tags.length === 0) {
+ alert("City tags cannot be empty");
+ return;
+ }
+ if (messagebank_ann_id.length === 0) {
+ alert("Message bank ANN_ID cannot be empty");
+ return;
+ }
+ if (broadcastzones.length === 0) {
+ alert("Broadcast zones cannot be empty");
+ return;
+ }
+
+ /**
+ * @type {UserDB}
+ */
+ let ll = {
+ index: index,
+ username: username,
+ password: password,
+ location: location,
+ airline_tags: airline_tags,
+ city_tags: city_tags,
+ messagebank_ann_id: messagebank_ann_id,
+ broadcastzones: broadcastzones
+ }
+
+ if (editmode) {
+ fetchAPI(APIURL + "UpdateByIndex/" + index, "PATCH", {}, ll, (okdata) => {
+ alert("Success update User : " + okdata.message);
+ reloaduserDB();
+ }, (errdata) => {
+ alert("Error update User : " + errdata.message);
+ });
+
+ } else {
+ fetchAPI(APIURL + "Add", "POST", {}, ll, (okdata) => {
+ alert("Success add User : " + okdata.message);
+ reloaduserDB();
+ }, (errdata) => {
+ alert("Error add User : " + errdata.message);
+ });
+ }
+
+
+ $addmodal.modal('hide');
+ });
+ // event on Click close button
+ $addmodal.on('click.usermanagementclose', '#usermanagementclose', function () {
+ $addmodal.modal('hide');
+ });
+ }
+
+ $btnClear.on('click', function () {
+ DoClear(APIURL, "UserManagement", (okdata) => {
+ reloaduserDB();
+ alert("Success clear user management : " + okdata.message);
+ }, (errdata) => {
+ alert("Error clear user management : " + errdata.message);
+ });
+ });
+ $btnAdd.click(() => {
+ $addmodal.modal('show');
+ clearAddModal();
+ modalshow(false,0);
+ });
+ $btnRemove.click(() => {
+ if (window.selecteduserrow) {
+ let cells = window.selecteduserrow.find('td');
+ /** @type {UserDB} */
+ let user = {
+ index: parseInt(cells.eq(0).text()),
+ username: cells.eq(1).text(),
+ password: cells.eq(2).text(),
+ airline_tags: cells.eq(3).text(),
+ city_tags: cells.eq(4).text(),
+ messagebank_ann_id: cells.eq(5).text(),
+ broadcastzones: cells.eq(6).text()
+ }
+ if (confirm(`Are you sure to delete user [${user.index}] Username=${user.username} ?`)) {
+ fetchAPI(APIURL + "DeleteByIndex/" + user.index, "DELETE", {}, null, (okdata) => {
+ reloaduserDB();
+ alert("Success delete user : " + okdata.message);
+ }, (errdata) => {
+ alert("Error delete user : " + errdata.message);
+ });
+ }
+ } else {
+ alert("No user selected");
+ }
+ });
+ $btnEdit.click(() => {
+ if (window.selecteduserrow) {
+ let cells = window.selecteduserrow.find('td');
+ let index = parseInt(cells.eq(0).text());
+ if (isNaN(index) || index <= 0) {
+ alert("Invalid user index");
+ return;
+ }
+ /** @type {UserDB} */
+ let user = window.userdb.find(u => u.index === index);
+ if (!user) {
+ alert("User not found");
+ return;
+ }
+ if (confirm(`Are you sure to edit user [${user.index}] Username=${user.username} ?`)) {
+ $addmodal.modal('show');
+ // fill modal with user data
+ $modalindex.val(user.index);
+ $modalusername.val(user.username);
+ $modalpassword.val(user.password);
+ $modalverifypassword.val(user.password);
+ $modallocation.val(user.location);
+ $modalairlinetags.val(user.airline_tags);
+ $modalcitytags.val(user.city_tags);
+ $modalmessagebank.val(user.messagebank_ann_id);
+ $modalbroadcastzones.val(user.broadcastzones);
+ modalshow(true, user.index);
+
+ }
+ } else {
+ alert("No user selected");
+ }
+ });
+ $btnExport.click(() => {
+ DoExport(APIURL, "user.xlsx", {});
+ });
+ $btnImport.click(() => {
+ DoImport(APIURL, (okdata) => {
+ reloaduserDB();
+ alert("Success import user : " + okdata.message);
+ }, (errdata) => {
+ alert("Error importing user from XLSX : " + errdata.message);
+ });
});
});
\ No newline at end of file
diff --git a/html/webpage/broadcastzones.html b/html/webpage/broadcastzones.html
index 70f0bd3..a40cf17 100644
--- a/html/webpage/broadcastzones.html
+++ b/html/webpage/broadcastzones.html
@@ -4,8 +4,9 @@
- AAS_NewGen_30Sept25
+ AAS_NewGen_08OKT25
+
@@ -19,10 +20,10 @@
diff --git a/html/webpage/home.html b/html/webpage/home.html
index b77beae..1f238c5 100644
--- a/html/webpage/home.html
+++ b/html/webpage/home.html
@@ -6,6 +6,7 @@
+
diff --git a/html/webpage/language.html b/html/webpage/language.html
index a9ea020..c0e37d9 100644
--- a/html/webpage/language.html
+++ b/html/webpage/language.html
@@ -4,8 +4,9 @@