commit 09/10/2025

User Management belum kelar
This commit is contained in:
2025-10-09 15:49:03 +07:00
parent 2ad26c3ef6
commit d549aee42c
29 changed files with 1535 additions and 662 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
});

View File

@@ -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);

View File

@@ -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<HTMLElement>|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);
});

View File

@@ -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<HTMLElement>|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);
});

View File

@@ -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<HTMLElement>|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 = `<option value="${str}">${str}</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);
});

View File

@@ -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);

View File

@@ -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<HTMLElement>|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 = `<tr>
@@ -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);
});

View File

@@ -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);
});

View File

@@ -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 = `<tr>
<td>${item.index}</td>
<td>${item.datenya}</td>
<td>${item.timenya}</td>
<td>${item.machine}</td>
<td>${item.description}</td>
<td>${item.username}</td>
<td>${item.location}</td>
<td>${item.airline_tags}</td>
<td>${item.city_tags}</td>
<td>${item.messagebank_ann_id}</td>
<td>${item.broadcastzones}</td>
</tr>`;
$('#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 = `<div class="form-check">
<input class="form-check-input citytagcheckbox" type="checkbox" value="${tag.key}" id="citytag_${tag.key}">
<label class="form-check-label" for="citytag_${tag.key}">
${value}
</label>
</div>`;
$citylist.append(row);
});
}
function fill_airlinelist() {
$airlinelist.empty();
airlinetags.forEach(tag => {
let value = `${tag.value} [${tag.key}]`;
const row = `<div class="form-check">
<input class="form-check-input airlinetagcheckbox" type="checkbox" value="${tag.key}" id="airlinetag_${tag.key}">
<label class="form-check-label" for="airlinetag_${tag.key}">
${value}
</label>
</div>`;
$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 = `<div class="form-check">
<input class="form-check-input broadcastzonecheckbox" type="checkbox" value="${desc}" id="broadcastzone_${desc}">
<label class="form-check-label" for="broadcastzone_${desc}">
${desc}
</label>
</div>`;
$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 = `<div class="form-check">
<input class="form-check-input messagebankidcheckbox" type="checkbox" value="${id.key}" id="messagebankid_${id.key}">
<label class="form-check-label" for="messagebankid_${id.key}">
${value}
</label>
</div>`;
$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);
});
});
});