480 lines
20 KiB
JavaScript
480 lines
20 KiB
JavaScript
/**
|
|
* @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}
|
|
*/
|
|
window.selectedschedulerow = null;
|
|
|
|
/**
|
|
* Fill schedulebank table body with values
|
|
* @param {ScheduleBank[]} vv values to fill
|
|
*/
|
|
function fill_schedulebanktablebody(vv) {
|
|
$('#schedulebanktablebody').empty();
|
|
if (!Array.isArray(vv) || vv.length === 0) return;
|
|
vv.forEach(item => {
|
|
const row = `<tr>
|
|
<td>${item.index}</td>
|
|
<td>${item.description}</td>
|
|
<td>${item.day}</td>
|
|
<td>${item.time}</td>
|
|
<td>${item.soundpath}</td>
|
|
<td>${item.repeat}</td>
|
|
<td>${item.enable}</td>
|
|
<td>${item.broadcastZones}</td>
|
|
<td>${item.language}</td>
|
|
</tr>`;
|
|
$('#schedulebanktablebody').append(row);
|
|
let $addedrow = $('#schedulebanktablebody tr:last');
|
|
$addedrow.click(function () {
|
|
if (selectedschedulerow) {
|
|
selectedschedulerow.find('td').css('background-color', '');
|
|
if (selectedschedulerow.is($(this))) {
|
|
selectedschedulerow = null;
|
|
$('#btnRemove').prop('disabled', true);
|
|
$('#btnEdit').prop('disabled', true);
|
|
return;
|
|
}
|
|
}
|
|
$addedrow.find('td').css('background-color', '#ffeeba');
|
|
selectedschedulerow = $addedrow;
|
|
$('#btnRemove').prop('disabled', false);
|
|
$('#btnEdit').prop('disabled', false);
|
|
});
|
|
});
|
|
$('#tablesize').text("Table Size: " + vv.length);
|
|
}
|
|
|
|
/**
|
|
* Convert input date string yyyy-mm-dd to dd/mm/yyyy
|
|
* @param {String} value from input date, which is in format yyyy-mm-dd
|
|
* @returns {String} converted date in format dd/mm/yyyy
|
|
*/
|
|
function Convert_input_date_to_string(value) {
|
|
if (value && value.length > 0 && value.includes('-')) {
|
|
let parts = value.split('-');
|
|
if (parts.length === 3) {
|
|
let year = parts[0];
|
|
let month = parts[1];
|
|
let day = parts[2];
|
|
return `${day}/${month}/${year}`;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* Convert string date dd/mm/yyyy to input date yyyy-mm-dd
|
|
* @param {String} value string date in format dd/mm/yyyy
|
|
* @returns {String} converted date in format yyyy-mm-dd
|
|
*/
|
|
function Convert_string_to_input_date(value) {
|
|
if (value && value.length > 0 && value.includes('/')) {
|
|
let parts = value.split('/');
|
|
if (parts.length === 3) {
|
|
let day = parts[0];
|
|
let month = parts[1];
|
|
let year = parts[2];
|
|
return `${year}-${month}-${day}`;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* 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");
|
|
$('#schedulebanktablebody').empty();
|
|
selectedschedulerow = null;
|
|
let $btnClear = $('#btnClear');
|
|
let $btnAdd = $('#btnAdd');
|
|
let $btnEdit = $('#btnEdit');
|
|
let $btnRemove = $('#btnRemove');
|
|
let $btnExport = $('#btnExport');
|
|
let $btnImport = $('#btnImport');
|
|
$btnEdit.prop('disabled', true);
|
|
$btnRemove.prop('disabled', true);
|
|
let APIURL = "ScheduleBank/";
|
|
|
|
let $schedulemodal = $('#schedulemodal');
|
|
// text input
|
|
let $scheduleid = $schedulemodal.find('#scheduleid');
|
|
// text input
|
|
let $scheduledescription = $schedulemodal.find('#scheduledescription');
|
|
// number input 0-23
|
|
let $schedulehour = $schedulemodal.find('#schedulehour');
|
|
// number input 0-59
|
|
let $scheduleminute = $schedulemodal.find('#scheduleminute');
|
|
// select2 for message
|
|
let $schedulemessage = $schedulemodal.find('#schedulemessage');
|
|
// number input 0-5
|
|
let $schedulerepeat = $schedulemodal.find('#schedulerepeat');
|
|
// checkbox
|
|
let $scheduleenable = $schedulemodal.find('#scheduleenable');
|
|
// select2 for broadcastzones
|
|
let $schedulezones = $schedulemodal.find('#schedulezones');
|
|
// radio button for everyday
|
|
let $scheduleeveryday = $schedulemodal.find('#scheduleeveryday');
|
|
// radio button for weekly
|
|
let $scheduleweekly = $schedulemodal.find('#scheduleweekly');
|
|
// select2 for weekly selection
|
|
let $weeklyselect = $schedulemodal.find('#weeklyselect');
|
|
// radio button for specific date
|
|
let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
|
|
// date input
|
|
let $scheduledate = $schedulemodal.find('#scheduledate');
|
|
// select2 for language
|
|
let $languageselect = $schedulemodal.find('#languageselect');
|
|
|
|
$schedulespecialdate.off('change').on('change', function () {
|
|
if ($(this).is(':checked')) {
|
|
$scheduledate.prop('disabled', false);
|
|
} else {
|
|
$scheduledate.prop('disabled', true);
|
|
}
|
|
});
|
|
|
|
function clearScheduleModal() {
|
|
$scheduleid.prop('disabled', true).val('');
|
|
$scheduledescription.val('');
|
|
$schedulehour.val('0');
|
|
$scheduleminute.val('0');
|
|
$schedulerepeat.val('1');
|
|
$scheduleenable.prop('checked', true);
|
|
$scheduleeveryday.prop('checked', false);
|
|
$scheduleweekly.prop('checked', false);
|
|
$schedulespecialdate.prop('checked', false);
|
|
$weeklyselect.empty().select2({
|
|
data: window.scheduledays.filter(day => day !== 'Everyday').map(day => ({ id: day, text: day })),
|
|
placeholder: 'Select days of the week',
|
|
multiple: false,
|
|
width: '100%',
|
|
dropdownParent: $('#schedulemodal')
|
|
});
|
|
$languageselect.empty().select2({
|
|
data: window.languages.map(lang => ({ id: lang, text: lang })),
|
|
placeholder: 'Select languages',
|
|
multiple: true,
|
|
width: '100%',
|
|
dropdownParent: $('#schedulemodal')
|
|
});
|
|
|
|
$scheduledate.prop('disabled', true).val('');
|
|
$schedulezones.empty().select2({
|
|
data: window.BroadcastZoneList.map(zone => ({ id: zone.description, text: zone.description })),
|
|
placeholder: 'Select broadcast zones',
|
|
multiple: true,
|
|
width: '100%',
|
|
dropdownParent: $('#schedulemodal')
|
|
});
|
|
let messageData = [...new Set(window.messagebankdata.filter(mb => !mb.message_Detail.includes('[')).map(mb => `${mb.description} [${mb.aNN_ID}]`))];
|
|
$schedulemessage.empty().select2({
|
|
placeholder: 'Select message',
|
|
multiple: false,
|
|
width: '100%',
|
|
dropdownParent: $('#schedulemodal'),
|
|
data: messageData.map(mb => ({ id: mb, text: mb }))
|
|
|
|
});
|
|
|
|
|
|
|
|
$scheduleeveryday.off('change').on('change', function () {
|
|
if ($(this).is(':checked')) {
|
|
$weeklyselect.prop('disabled', true);
|
|
$scheduledate.prop('disabled', true);
|
|
}
|
|
});
|
|
$scheduleweekly.off('change').on('change', function () {
|
|
if ($(this).is(':checked')) {
|
|
$weeklyselect.prop('disabled', false);
|
|
$scheduledate.prop('disabled', true);
|
|
} else {
|
|
$weeklyselect.prop('disabled', true);
|
|
}
|
|
});
|
|
$schedulespecialdate.off('change').on('change', function () {
|
|
if ($(this).is(':checked')) {
|
|
$weeklyselect.prop('disabled', true);
|
|
$scheduledate.prop('disabled', false);
|
|
} else {
|
|
$scheduledate.prop('disabled', true);
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
let $findschedule = $('#findschedule');
|
|
$findschedule.off('input').on('input', function () {
|
|
let searchTerm = $findschedule.val().toLowerCase();
|
|
if (searchTerm.length > 0) {
|
|
window.selectedschedulerow = null;
|
|
let filtered = window.schedulebankdata.filter(item =>
|
|
item.description.toLowerCase().includes(searchTerm)
|
|
|| item.soundpath.toLowerCase().includes(searchTerm)
|
|
|| item.broadcastZones.toLowerCase().includes(searchTerm));
|
|
fill_schedulebanktablebody(filtered);
|
|
} else {
|
|
window.selectedschedulerow = null;
|
|
fill_schedulebanktablebody(window.schedulebankdata);
|
|
}
|
|
});
|
|
|
|
|
|
reloadTimerBank(APIURL);
|
|
reloadBroadcastZones();
|
|
getLanguages();
|
|
getScheduledDays();
|
|
reloadMessageBank();
|
|
$btnClear.click(() => {
|
|
DoClear(APIURL, "Timerbank", (okdata) => {
|
|
reloadTimerBank(APIURL);
|
|
alert("Success clear schedulebank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error clear schedulebank : " + errdata.message);
|
|
});
|
|
|
|
});
|
|
$btnAdd.click(() => {
|
|
$schedulemodal.modal('show');
|
|
clearScheduleModal();
|
|
|
|
$schedulemodal.off('click.scheduleclose').on('click.scheduleclose', '#scheduleclose', function () {
|
|
$schedulemodal.modal('hide');
|
|
});
|
|
$schedulemodal.off('click.schedulesave').on('click.schedulesave', '#schedulesave', function () {
|
|
// Gather form values
|
|
const Description = $scheduledescription.val();
|
|
const Message = $schedulemessage.val();
|
|
const Repeat = parseInt($schedulerepeat.val(), 10);
|
|
const Enable = $scheduleenable.is(':checked');
|
|
// Collect selected days
|
|
let _Day = "";
|
|
if ($scheduleeveryday.is(':checked')) {
|
|
_Day = "Everyday";
|
|
} else if ($schedulespecialdate.is(':checked')) {
|
|
_Day = Convert_input_date_to_string($scheduledate.val());
|
|
} else if ($scheduleweekly.is(':checked')) {
|
|
_Day = $weeklyselect.val();
|
|
}
|
|
const Language = $languageselect.val().join(';');
|
|
const broadcastZones = $schedulezones.val().join(';');
|
|
// Format time as HH:mm
|
|
const hour = parseInt($schedulehour.val(), 10);
|
|
const minute = parseInt($scheduleminute.val(), 10);
|
|
const _Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
|
|
if (Description.length > 0) {
|
|
if (_Day.length > 0) {
|
|
if (Message.length > 0) {
|
|
if (Language.length > 0) {
|
|
if (broadcastZones.length > 0) {
|
|
// Prepare object
|
|
const scheduleObj = {
|
|
Description: Description,
|
|
Day: _Day,
|
|
Time: _Time,
|
|
Soundpath: Message,
|
|
Repeat: Repeat,
|
|
Enable: Enable,
|
|
BroadcastZones: broadcastZones,
|
|
Language: Language
|
|
};
|
|
|
|
fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => {
|
|
alert("Success add schedule: " + okdata.message);
|
|
reloadTimerBank(APIURL);
|
|
}, (errdata) => {
|
|
alert("Error add schedule: " + errdata.message);
|
|
});
|
|
$schedulemodal.modal('hide');
|
|
} else alert("At least one Broadcast Zone is required");
|
|
} else alert("Language is required");
|
|
} else alert("Message is required");
|
|
} else alert("Day is required");
|
|
} else alert("Description is required");
|
|
});
|
|
});
|
|
$btnRemove.click(() => {
|
|
if (window.selectedschedulerow) {
|
|
let cells = window.selectedschedulerow.find('td');
|
|
/** @type {ScheduleBank} */
|
|
let sr = {
|
|
index: Number(cells.eq(0).text()),
|
|
description: cells.eq(1).text(),
|
|
day: cells.eq(2).text(),
|
|
time: cells.eq(3).text(),
|
|
soundpath: cells.eq(4).text(),
|
|
repeat: cells.eq(5).text(),
|
|
enable: cells.eq(6).text(),
|
|
broadcastZones: cells.eq(7).text(),
|
|
language: cells.eq(8).text()
|
|
}
|
|
if (confirm(`Are you sure to delete schedule [${sr.index}] Description=${sr.description}?`)) {
|
|
fetchAPI(APIURL + "DeleteByIndex/" + sr.index, "DELETE", {}, null, (okdata) => {
|
|
reloadTimerBank(APIURL);
|
|
alert("Success delete schedule : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error delete schedule : " + errdata.message);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$btnEdit.click(() => {
|
|
if (window.selectedschedulerow) {
|
|
let cells = window.selectedschedulerow.find('td');
|
|
/** @type {ScheduleBank} */
|
|
let sr = {
|
|
index: Number(cells.eq(0).text()),
|
|
Description: cells.eq(1).text(),
|
|
Day: cells.eq(2).text(),
|
|
Time: cells.eq(3).text(),
|
|
Soundpath: cells.eq(4).text(),
|
|
Repeat: cells.eq(5).text(),
|
|
Enable: cells.eq(6).text(),
|
|
BroadcastZones: cells.eq(7).text(),
|
|
Language: cells.eq(8).text()
|
|
}
|
|
if (confirm(`Are you sure to edit schedule [${sr.index}] Description=${sr.Description}?`)) {
|
|
$schedulemodal.modal('show');
|
|
clearScheduleModal();
|
|
|
|
// fill the form with existing data
|
|
$scheduleid.val(sr.index);
|
|
$scheduledescription.val(sr.Description);
|
|
let [hour, minute] = sr.Time.split(':').map(num => parseInt(num, 10));
|
|
$schedulehour.val(hour.toString());
|
|
$scheduleminute.val(minute.toString());
|
|
$schedulemessage.val(sr.Soundpath).trigger('change');
|
|
$schedulerepeat.val(sr.Repeat);
|
|
$scheduleenable.prop('checked', sr.Enable.toLowerCase() === 'true');
|
|
$languageselect.val(sr.Language.split(';')).trigger('change');
|
|
$schedulezones.val(sr.BroadcastZones.split(';')).trigger('change');
|
|
switch (sr.Day) {
|
|
case 'Everyday':
|
|
$scheduleeveryday.click();
|
|
break;
|
|
case 'Sunday' :
|
|
case 'Monday':
|
|
case 'Tuesday':
|
|
case 'Wednesday':
|
|
case 'Thursday':
|
|
case 'Friday':
|
|
case 'Saturday':
|
|
$scheduleweekly.click();
|
|
$weeklyselect.val(sr.Day).trigger('change');
|
|
break;
|
|
default:
|
|
// check if the day is in format dd/mm/yyyy
|
|
// and set the special date radio button and date input
|
|
if (/^\d{2}\/\d{2}\/\d{4}$/.test(sr.Day)) {
|
|
$schedulespecialdate.click();
|
|
$scheduledate.val(Convert_string_to_input_date(sr.Day));
|
|
}
|
|
}
|
|
|
|
$schedulemodal.off('click.scheduleclose').on('click.scheduleclose', '#scheduleclose', function () {
|
|
$schedulemodal.modal('hide');
|
|
});
|
|
$schedulemodal.off('click.schedulesave').on('click.schedulesave', '#schedulesave', function () {
|
|
// Gather form values
|
|
const Description = $scheduledescription.val();
|
|
const Soundpath = $schedulemessage.val();
|
|
const Repeat = parseInt($schedulerepeat.val(), 10);
|
|
const Enable = $scheduleenable.is(':checked');
|
|
// Collect selected days
|
|
let Day = "";
|
|
if ($scheduleeveryday.is(':checked')) {
|
|
Day = "Everyday";
|
|
} else if ($schedulespecialdate.is(':checked')) {
|
|
// convert date from yyyy-mm-dd to dd/mm/yyyy
|
|
Day = Convert_input_date_to_string($scheduledate.val());
|
|
} else if ($scheduleweekly.is(':checked')) {
|
|
Day = $weeklyselect.val();
|
|
}
|
|
// Broadcast zones (assuming comma-separated string)
|
|
const BroadcastZones = $schedulezones.val().join(';');
|
|
const Language = $languageselect.val().join(';');
|
|
// Format time as HH:mm
|
|
const hour = parseInt($schedulehour.val(), 10);
|
|
const minute = parseInt($scheduleminute.val(), 10);
|
|
const Time = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
|
|
if (Description && Description.length > 0) {
|
|
if (Day && Day.length > 0) {
|
|
if (Soundpath && Soundpath.length > 0) {
|
|
if (Time && Time.length > 0) {
|
|
if (Language && Language.length > 0) {
|
|
if (BroadcastZones && BroadcastZones.length > 0) {
|
|
// Prepare object
|
|
const scheduleObj = {
|
|
Description,
|
|
Day,
|
|
Time,
|
|
Soundpath,
|
|
Repeat,
|
|
Enable,
|
|
BroadcastZones,
|
|
Language
|
|
};
|
|
|
|
fetchAPI(APIURL + "UpdateByIndex/" + sr.index, "PATCH", {}, scheduleObj, (okdata) => {
|
|
alert("Success edit schedule: " + okdata.message);
|
|
reloadTimerBank(APIURL);
|
|
}, (errdata) => {
|
|
alert("Error edit schedule: " + errdata.message);
|
|
});
|
|
$schedulemodal.modal('hide');
|
|
} else alert("At least one Broadcast Zone is required");
|
|
} else alert("At least one Language is required");
|
|
} else alert("Time is invalid");
|
|
} else alert("Message is not selected");
|
|
} else alert("Day is invalid");
|
|
} else alert("Description is empty");
|
|
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$btnExport.click(() => {
|
|
DoExport(APIURL, "schedulebank.xlsx", {});
|
|
});
|
|
$btnImport.click(() => {
|
|
DoImport(APIURL, (okdata) => {
|
|
reloadTimerBank(APIURL);
|
|
alert("Success import schedulebank from XLSX : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error importing schedulebank from XLSX : " + errdata.message);
|
|
});
|
|
});
|
|
}); |