400 lines
16 KiB
JavaScript
400 lines
16 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);
|
|
}
|
|
|
|
/**
|
|
* 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');
|
|
$schedulemessage.select2({});
|
|
// number input 0-5
|
|
let $schedulerepeat = $schedulemodal.find('#schedulerepeat');
|
|
// checkbox
|
|
let $scheduleenable = $schedulemodal.find('#scheduleenable');
|
|
// select2 for broadcastzones
|
|
let $schedulezones = $schedulemodal.find('#schedulezones');
|
|
$schedulezones.select2({});
|
|
// radio button for everyday
|
|
let $scheduleeveryday = $schedulemodal.find('#scheduleeveryday');
|
|
// radio button for weekly
|
|
let $scheduleweekly = $schedulemodal.find('#scheduleweekly');
|
|
// select2 for weekly selection
|
|
let $weeklyselect = $schedulemodal.find('#weeklyselect');
|
|
$weeklyselect.select2({});
|
|
// radio button for specific date
|
|
let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
|
|
// date input
|
|
let $scheduledate = $schedulemodal.find('#scheduledate');
|
|
// select2 for language
|
|
let $languageselect = $schedulemodal.find('#languageselect');
|
|
$languageselect.select2({});
|
|
|
|
$schedulespecialdate.on('change', function () {
|
|
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('0');
|
|
$scheduleenable.prop('checked', true);
|
|
$scheduleeveryday.prop('checked', false);
|
|
|
|
$schedulespecialdate.prop('checked', false);
|
|
$scheduledate.prop('disabled', true).val('');
|
|
|
|
|
|
}
|
|
|
|
let $findschedule = $('#findschedule');
|
|
$findschedule.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);
|
|
$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 Soundpath = $schedulesoundpath.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 = $scheduledate.val();
|
|
} else {
|
|
|
|
if ($schedulesunday.is(':checked')) Day = "Sunday";
|
|
if ($schedulemonday.is(':checked')) Day = "Monday";
|
|
if ($scheduletuesday.is(':checked')) Day = "Tuesday";
|
|
if ($schedulewednesday.is(':checked')) Day = "Wednesday";
|
|
if ($schedulethursday.is(':checked')) Day = "Thursday";
|
|
if ($schedulefriday.is(':checked')) Day = "Friday";
|
|
if ($schedulesaturday.is(':checked')) Day = "Saturday";
|
|
}
|
|
// Broadcast zones (assuming comma-separated string)
|
|
const BroadcastZones = $schedulezones.val();
|
|
|
|
// Validate required fields
|
|
if (!Description || !Soundpath || Day === "") {
|
|
alert("Description, sound path, and day are required.");
|
|
return;
|
|
}
|
|
|
|
// 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')}`;
|
|
|
|
// Prepare object
|
|
const scheduleObj = {
|
|
Description,
|
|
Day,
|
|
Time,
|
|
Soundpath,
|
|
Repeat,
|
|
Enable,
|
|
BroadcastZones
|
|
};
|
|
|
|
fetchAPI(APIURL + "Add", "POST", {}, scheduleObj, (okdata) => {
|
|
alert("Success add schedule: " + okdata.message);
|
|
reloadTimerBank(APIURL);
|
|
}, (errdata) => {
|
|
alert("Error add schedule: " + errdata.message);
|
|
});
|
|
|
|
$schedulemodal.modal('hide');
|
|
});
|
|
});
|
|
$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');
|
|
// fill the form with existing data
|
|
$scheduleid.val(sr.index);
|
|
$scheduledescription.val(sr.description);
|
|
let [hour, minute] = sr.time.split(':').map(num => parseInt(num, 10));
|
|
$schedulehour.val(hour.toString());
|
|
$scheduleminute.val(minute.toString());
|
|
$schedulesoundpath.val(sr.soundpath);
|
|
$schedulerepeat.val(sr.repeat.toString());
|
|
$scheduleenable.prop('checked', sr.enable.toLowerCase() === 'true');
|
|
switch (sr.day) {
|
|
case 'Everyday':
|
|
$scheduleeveryday.click();
|
|
break;
|
|
case 'Sunday':
|
|
$schedulesunday.click();
|
|
break;
|
|
case 'Monday':
|
|
$schedulemonday.click();
|
|
break;
|
|
case 'Tuesday':
|
|
$scheduletuesday.click();
|
|
break;
|
|
case 'Wednesday':
|
|
$schedulewednesday.click();
|
|
break;
|
|
case 'Thursday':
|
|
$schedulethursday.click();
|
|
break;
|
|
case 'Friday':
|
|
$schedulefriday.click();
|
|
break;
|
|
case 'Saturday':
|
|
$schedulesaturday.click();
|
|
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(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 = $schedulesoundpath.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 = $scheduledate.val();
|
|
} else {
|
|
if ($schedulesunday.is(':checked')) Day = "Sunday";
|
|
if ($schedulemonday.is(':checked')) Day = "Monday";
|
|
if ($scheduletuesday.is(':checked')) Day = "Tuesday";
|
|
if ($schedulewednesday.is(':checked')) Day = "Wednesday";
|
|
if ($schedulethursday.is(':checked')) Day = "Thursday";
|
|
if ($schedulefriday.is(':checked')) Day = "Friday";
|
|
if ($schedulesaturday.is(':checked')) Day = "Saturday";
|
|
}
|
|
// Broadcast zones (assuming comma-separated string)
|
|
const BroadcastZones = $schedulezones.val();
|
|
|
|
// Validate required fields
|
|
if (!Description || !Soundpath || Day === "") {
|
|
alert("Description, sound path, and day are required.");
|
|
return;
|
|
}
|
|
|
|
// 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')}`;
|
|
|
|
// Prepare object
|
|
const scheduleObj = {
|
|
Description,
|
|
Day,
|
|
Time,
|
|
Soundpath,
|
|
Repeat,
|
|
Enable,
|
|
BroadcastZones
|
|
};
|
|
|
|
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');
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$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);
|
|
});
|
|
});
|
|
}); |