1900 lines
82 KiB
JavaScript
1900 lines
82 KiB
JavaScript
/**
|
|
* @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} 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
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} LanguageBank
|
|
* @property {number} index
|
|
* @property {string} tag
|
|
* @property {string} language
|
|
* @
|
|
*/
|
|
|
|
/**
|
|
* @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
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} Log
|
|
* @property {number} index
|
|
* @property {string} datenya
|
|
* @property {string} timenya
|
|
* @property {string} machine
|
|
* @property {string} description
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} Select2item
|
|
* @property {number} id
|
|
* @property {string} text
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} BroadcastZone
|
|
* @property {number} index
|
|
* @property {string} description
|
|
* @property {String} SoundChannel
|
|
* @property {String} Box
|
|
* @property {String} Relay
|
|
*/
|
|
|
|
/**
|
|
* List of Soundbank data loaded from server
|
|
* @type {SoundBank[]}
|
|
*/
|
|
let soundbankdata = [];
|
|
/**
|
|
* Currently selected soundbank row in the table
|
|
* @type {JQuery<HTMLElement>|null}
|
|
*/
|
|
let selectedsoundrow = null;
|
|
/**
|
|
* List of Messagebank data loaded from server
|
|
* @type {MessageBank[]}
|
|
*/
|
|
let messagebankdata = [];
|
|
/**
|
|
* Currently selected messagebank row in the table
|
|
* @type {JQuery<HTMLElement>|null}
|
|
*/
|
|
let selectedmessagerow = null;
|
|
/** List of Languagebank data loaded from server
|
|
* @type {LanguageBank[]}
|
|
*/
|
|
let languagebankdata = [];
|
|
/**
|
|
* Currently selected languagebank row in the table
|
|
* @type {JQuery<HTMLElement>|null}
|
|
*/
|
|
let selectedlanguagerow = null;
|
|
/** List of Schedulebank data loaded from server
|
|
* @type {ScheduleBank[]}
|
|
*/
|
|
let schedulebankdata = [];
|
|
/**
|
|
* Currently selected schedulebank row in the table
|
|
* @type {JQuery<HTMLElement>|null}
|
|
*/
|
|
let selectedschedulerow = null;
|
|
/** List of Log data loaded from server
|
|
* @type {Log[]}
|
|
*/
|
|
let logdata = [];
|
|
/**
|
|
* List of sound files in the soundbank directory, that ends with .wav or .mp3
|
|
* @type {string[]}
|
|
*/
|
|
let soundbankfiles = [];
|
|
/**
|
|
* Select2 data source
|
|
* See https://select2.org/data-sources/formats
|
|
* @type {Select2item[]}
|
|
*/
|
|
let select2data = [];
|
|
|
|
/**
|
|
* List of voice types available
|
|
* @type {string[]}
|
|
*/
|
|
let voiceTypes = [];
|
|
/**
|
|
* List of categories available
|
|
* @type {string[]}
|
|
*/
|
|
let categories = [];
|
|
/**
|
|
* List of languages available
|
|
* @type {string[]}
|
|
*/
|
|
let languages = [];
|
|
|
|
/**
|
|
* List of scheduled days available
|
|
* @type {string[]}
|
|
*/
|
|
let scheduledays = []
|
|
|
|
/**
|
|
* List of broadcast zones available
|
|
* @type {BroadcastZone[]}
|
|
*/
|
|
let BroadcastZoneList = [];
|
|
|
|
/**
|
|
* Create a list item element
|
|
* @param {String} text Text Content for the list item
|
|
* @param {String} className Specific class name for the list item
|
|
* @returns {JQuery<HTMLElement>}
|
|
*/
|
|
function ListItem(text, className=""){
|
|
return $('<li>').addClass(className).text(text);
|
|
}
|
|
|
|
/**
|
|
* Fill soundbank table body with values
|
|
* @param {SoundBank[]} vv values to fill
|
|
*/
|
|
function fill_soundbanktablebody(vv) {
|
|
$('#soundbanktablebody').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.tag}</td>
|
|
<td>${item.category}</td>
|
|
<td>${item.language}</td>
|
|
<td>${item.voiceType}</td>
|
|
<td>${item.path}</td>
|
|
</tr>`;
|
|
$('#soundbanktablebody').append(row);
|
|
let $addedrow = $('#soundbanktablebody tr:last');
|
|
$addedrow.on('click', function () {
|
|
if (selectedsoundrow) {
|
|
selectedsoundrow.find('td').css('background-color', '');
|
|
if (selectedsoundrow.is($(this))) {
|
|
selectedsoundrow = null;
|
|
$('#btnRemove').prop('disabled', true);
|
|
$('#btnEdit').prop('disabled', true);
|
|
return;
|
|
}
|
|
}
|
|
$(this).find('td').css('background-color', '#ffeeba');
|
|
selectedsoundrow = $(this);
|
|
$('#btnRemove').prop('disabled', false);
|
|
$('#btnEdit').prop('disabled', false);
|
|
});
|
|
});
|
|
|
|
|
|
$('#tablesize').text("Table Size: " + vv.length);
|
|
}
|
|
|
|
/**
|
|
* Fill messagebank table body with values
|
|
* @param {MessageBank[]} vv values to fill
|
|
*/
|
|
function fill_messagebanktablebody(vv) {
|
|
$('#messagebanktablebody').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.language}</td>
|
|
<td>${item.aNN_ID}</td>
|
|
<td>${item.voice_Type}</td>
|
|
<td>${item.message_Detail}</td>
|
|
<td>${item.message_TAGS}</td>
|
|
</tr>`;
|
|
$('#messagebanktablebody').append(row);
|
|
let $addedrow = $('#messagebanktablebody tr:last');
|
|
$addedrow.click(function () {
|
|
if (selectedmessagerow) {
|
|
selectedmessagerow.find('td').css('background-color', '');
|
|
if (selectedmessagerow.is($(this))) {
|
|
selectedmessagerow = null;
|
|
$('#btnRemove').prop('disabled', true);
|
|
$('#btnEdit').prop('disabled', true);
|
|
return;
|
|
}
|
|
}
|
|
$addedrow.find('td').css('background-color', '#ffeeba');
|
|
selectedmessagerow = $addedrow;
|
|
$('#btnRemove').prop('disabled', false);
|
|
$('#btnEdit').prop('disabled', false);
|
|
});
|
|
});
|
|
|
|
$('#tablesize').text("Table Size: " + vv.length);
|
|
}
|
|
|
|
/**
|
|
* Fill languagebank table body with values
|
|
* @param {LanguageBank[]} vv values to fill
|
|
*/
|
|
function fill_languagebanktablebody(vv) {
|
|
$('#languagebanktablebody').empty();
|
|
if (!Array.isArray(vv) || vv.length === 0) return;
|
|
vv.forEach(item => {
|
|
const row = `<tr>
|
|
<td>${item.index}</td>
|
|
<td>${item.tag}</td>
|
|
<td>${item.language}</td>
|
|
</tr>`;
|
|
$('#languagebanktablebody').append(row);
|
|
let $addedrow = $('#languagebanktablebody tr:last');
|
|
$addedrow.click(function () {
|
|
if (selectedlanguagerow) {
|
|
selectedlanguagerow.find('td').css('background-color', '');
|
|
if (selectedlanguagerow.is($(this))) {
|
|
selectedlanguagerow = null;
|
|
$('#btnRemove').prop('disabled', true);
|
|
$('#btnEdit').prop('disabled', true);
|
|
return;
|
|
}
|
|
}
|
|
$addedrow.find('td').css('background-color', '#ffeeba');
|
|
selectedlanguagerow = $addedrow;
|
|
$('#btnRemove').prop('disabled', false);
|
|
$('#btnEdit').prop('disabled', false);
|
|
});
|
|
});
|
|
$('#tablesize').text("Table Size: " + vv.length);
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
/**
|
|
* Fill log table body with values
|
|
* @param {Log[]} vv values to fill
|
|
*/
|
|
function fill_logtablebody(vv) {
|
|
$('#logtablebody').empty();
|
|
if (!Array.isArray(vv) || vv.length === 0) return;
|
|
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>
|
|
</tr>`;
|
|
$('#logtablebody').append(row);
|
|
});
|
|
$('#tablesize').text("Table Size: " + vv.length);
|
|
}
|
|
|
|
/**
|
|
* WebSocket connection
|
|
* @type {WebSocket}
|
|
*/
|
|
let ws = null;
|
|
|
|
/**
|
|
* Send a command to the WebSocket server.
|
|
* @param {String} command command to send
|
|
* @param {String} data data to send
|
|
*/
|
|
function sendCommand(command, data) {
|
|
if (ws.readyState === WebSocket.OPEN) {
|
|
ws.send(JSON.stringify({ command, data }));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch API helper function
|
|
* @param {string} endpoint Endpoint URL
|
|
* @param {string} method Method (GET, POST, etc.)
|
|
* @param {Object} headers Headers to include in the request
|
|
* @param {Object} body Body of the request
|
|
* @param {Function} cbOK Callback function for successful response
|
|
* @param {Function} cbError Callback function for error response
|
|
*/
|
|
function fetchAPI(endpoint, method, headers = {}, body = null, cbOK, cbError) {
|
|
let url = window.location.origin + "/api/" + endpoint;
|
|
let options = {
|
|
method: method,
|
|
headers: headers
|
|
}
|
|
if (body !== null) {
|
|
options.body = JSON.stringify(body);
|
|
if (!options.headers['Content-Type']) {
|
|
options.headers['Content-Type'] = 'application/json';
|
|
}
|
|
}
|
|
//console.log("About to fetch from " + url + " with options", options);
|
|
fetch(url, options)
|
|
.then(response => {
|
|
//console.log("fetchAPI: received response", response);
|
|
if (!response.ok) {
|
|
throw new Error('Network response was not ok ' + response.statusText);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
//console.log("fetchAPI: received data", data);
|
|
cbOK(data);
|
|
})
|
|
.catch(error => {
|
|
// console.error('There was a problem with the fetch operation:', error);
|
|
cbError(error);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload sound bank from server
|
|
* @param {String} APIURL API URL endpoint, default "SoundBank/"
|
|
*/
|
|
function reloadSoundBank(APIURL = "SoundBank/") {
|
|
soundbankdata = [];
|
|
fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
|
|
if (Array.isArray(okdata)) {
|
|
soundbankdata = okdata;
|
|
selectedsoundrow = null;
|
|
fill_soundbanktablebody(soundbankdata);
|
|
}
|
|
}, (errdata) => {
|
|
alert("Error loading soundbank : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload message bank from server
|
|
* @param {string} APIURL API URL endpoint, default "MessageBank/"
|
|
*/
|
|
function reloadMessageBank(APIURL = "MessageBank/") {
|
|
messagebankdata = [];
|
|
fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
|
|
if (Array.isArray(okdata)) {
|
|
messagebankdata = okdata;
|
|
selectedmessagerow = null;
|
|
fill_messagebanktablebody(messagebankdata);
|
|
}
|
|
}, (errdata) => {
|
|
alert("Error loading messagebank : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload language bank from server
|
|
* @param {string} APIURL API URL endpoint, default "LanguageLink/"
|
|
*/
|
|
function reloadLanguageBank(APIURL = "LanguageLink/") {
|
|
languagebankdata = [];
|
|
fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
|
|
if (Array.isArray(okdata)) {
|
|
languagebankdata = okdata;
|
|
selectedlanguagerow = null;
|
|
fill_languagebanktablebody(languagebankdata);
|
|
}
|
|
}, (errdata) => {
|
|
alert("Error loading languagebank : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload timer bank from server
|
|
* @param {string} APIURL API URL endpoint, default "ScheduleBank/"
|
|
*/
|
|
function reloadTimerBank(APIURL = "ScheduleBank/") {
|
|
schedulebankdata = [];
|
|
fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
|
|
if (Array.isArray(okdata)) {
|
|
schedulebankdata = okdata;
|
|
selectedschedulerow = null;
|
|
fill_schedulebanktablebody(schedulebankdata);
|
|
}
|
|
}, (errdata) => {
|
|
alert("Error loading schedulebank : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload logs from server with date and filter
|
|
* @param {String} APIURL API URL endpoint , default "Log/"
|
|
* @param {String} date date in format dd-mm-yyyy
|
|
* @param {String} filter log filter text
|
|
*/
|
|
function reloadLogs(APIURL = "Log/", date, filter) {
|
|
const params = new URLSearchParams({
|
|
date: date,
|
|
filter: filter
|
|
})
|
|
fetchAPI(APIURL + "List?" + params.toString(), "GET", {}, null, (okdata) => {
|
|
//console.log("Logs data received", okdata);
|
|
if (Array.isArray(okdata)) {
|
|
logdata = okdata;
|
|
fill_logtablebody(okdata);
|
|
}
|
|
}, (errdata) => {
|
|
alert("Error loading logs : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload soundbank files from server
|
|
* @param {String} APIURL API URL endpoint (default "SoundBank/")
|
|
*/
|
|
function reloadSoundbankFiles(APIURL = "SoundBank/") {
|
|
soundbankfiles = [];
|
|
fetchAPI(APIURL + "ListFiles", "GET", {}, null, (okdata) => {
|
|
// okdata is a string contains elements separated by semicolon ;
|
|
if (Array.isArray(okdata)) {
|
|
soundbankfiles = okdata.filter(item => item.trim().length > 0);
|
|
// refill select2data
|
|
select2data = 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);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload broadcast zones from server
|
|
* @param {String} APIURL API URL endpoint (default "BroadcastZones/")
|
|
*/
|
|
function reloadBroadcastZones(APIURL = "BroadcastZones/") {
|
|
BroadcastZoneList = [];
|
|
fetchAPI(APIURL + "List", "GET", {}, null, (okdata) => {
|
|
if (Array.isArray(okdata)) {
|
|
BroadcastZoneList = okdata;
|
|
fill_broadcastzonetablebody(BroadcastZoneList);
|
|
} else console.log("reloadBroadcastZones: okdata is not array");
|
|
}, (errdata) => {
|
|
alert("Error loading broadcast zones : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Reload voice types from server
|
|
*/
|
|
function getVoiceTypes() {
|
|
voiceTypes = [];
|
|
fetchAPI("VoiceType", "GET", {}, null, (okdata) => {
|
|
// okdata is a string contains elements separated by semicolon ;
|
|
if (Array.isArray(okdata)) {
|
|
voiceTypes = okdata.filter(item => item.trim().length > 0);
|
|
//console.log("Loaded " + voiceTypes.length + " voice types : " + voiceTypes.join(", "));
|
|
} else console.log("getVoiceTypes: okdata is not array");
|
|
}, (errdata) => {
|
|
alert("Error loading voice types : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload categories from server
|
|
*/
|
|
function getCategories() {
|
|
categories = [];
|
|
fetchAPI("Category", "GET", {}, null, (okdata) => {
|
|
// okdata is a string contains elements separated by semicolon ;
|
|
if (Array.isArray(okdata)) {
|
|
categories = okdata.filter(item => item.trim().length > 0);
|
|
//console.log("Loaded " + categories.length + " categories : " + categories.join(", "));
|
|
} else console.log("getCategories: okdata is not array");
|
|
}, (errdata) => {
|
|
alert("Error loading categories : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload languages from server
|
|
*/
|
|
function getLanguages() {
|
|
languages = [];
|
|
fetchAPI("Language", "GET", {}, null, (okdata) => {
|
|
// okdata is a string contains elements separated by semicolon ;
|
|
if (Array.isArray(okdata)) {
|
|
languages = okdata.filter(item => item.trim().length > 0);
|
|
//console.log("Loaded " + languages.length + " languages : " + languages.join(", ") );
|
|
} else console.log("getLanguages: okdata is not array");
|
|
}, (errdata) => {
|
|
alert("Error loading languages : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reload scheduled days from server
|
|
*/
|
|
function getScheduledDays() {
|
|
scheduledays = [];
|
|
fetchAPI("ScheduleDay", "GET", {}, null, (okdata) => {
|
|
// okdata is a string contains elements separated by semicolon ;
|
|
if (Array.isArray(okdata)) {
|
|
scheduledays = okdata.filter(item => item.trim().length > 0);
|
|
//console.log("Loaded " + scheduledays.length + " scheduled days : " + scheduledays.join(", ") );
|
|
} else console.log("getScheduledDays: okdata is not array");
|
|
}, (errdata) => {
|
|
alert("Error loading scheduled days : " + errdata.message);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Clear database mechanism
|
|
* @param {String} APIURL API URL endpoint
|
|
* @param {String} whattoclear what to clear
|
|
* @param {Function} cbOK callback function on success
|
|
* @param {Function} cbError callback function on error
|
|
*/
|
|
function DoClear(APIURL, whattoclear, cbOK, cbError) {
|
|
if (confirm(`Are you sure want to clear ${whattoclear} ? This procedure is not reversible`)) {
|
|
fetchAPI(APIURL + "List", "DELETE", {}, null, (okdata) => {
|
|
cbOK(okdata);
|
|
}, (errdata) => {
|
|
cbError(errdata);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Export mechanism to XLSX file
|
|
* @param {String} APIURL API URL endpoint
|
|
* @param {String} filename target filename
|
|
* @param {Object} queryParams additional query parameters as object
|
|
*/
|
|
function DoExport(APIURL, filename, queryParams = {}) {
|
|
// send GET request to APIURL + "ExportXLSX"
|
|
// reply Content-Type is application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
|
// reply Content-Disposition: attachment; filename=filename
|
|
// Use fetch to download the XLSX file as a blob and trigger download
|
|
let url = "/api/" + APIURL + "ExportXLSX";
|
|
if (queryParams && Object.keys(queryParams).length > 0) {
|
|
url += "?" + new URLSearchParams(queryParams).toString();
|
|
}
|
|
|
|
fetch(url, {
|
|
method: "GET",
|
|
headers: {}
|
|
})
|
|
.then(response => {
|
|
if (!response.ok) throw new Error('Network response was not ok ' + response.statusText);
|
|
return response.blob();
|
|
})
|
|
.then(blob => {
|
|
const url = window.URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = filename;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
a.remove();
|
|
window.URL.revokeObjectURL(url);
|
|
})
|
|
.catch(error => {
|
|
alert("Error export to " + filename + ": " + error.message);
|
|
});
|
|
return; // prevent the rest of the function from running
|
|
|
|
}
|
|
|
|
/**
|
|
* Import mechanism from XLSX file
|
|
* @param {String} APIURL API URL endpoint
|
|
* @param {Function<Object>} cbOK function that accept object data
|
|
* @param {Function<Error>} cbError function that accept error object
|
|
*/
|
|
function DoImport(APIURL, cbOK, cbError) {
|
|
// Open file selection dialog that accepts only .xlsx files
|
|
// then upload to server using fetchAPI at "api/ImportXLSX" with POST method
|
|
let fileInput = document.createElement('input');
|
|
fileInput.type = 'file';
|
|
fileInput.accept = '.xlsx';
|
|
fileInput.onchange = e => {
|
|
let file = e.target.files[0];
|
|
if (file) {
|
|
let formData = new FormData();
|
|
formData.append('file', file);
|
|
fetch("/api/" + APIURL + "ImportXLSX", { method: 'POST', body: formData })
|
|
.then(response => {
|
|
if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); }
|
|
return response.json();
|
|
})
|
|
.then(data => {
|
|
cbOK(data);
|
|
})
|
|
.catch(error => {
|
|
cbError(error);
|
|
});
|
|
} else {
|
|
cbError(new Error("No file selected"));
|
|
}
|
|
};
|
|
fileInput.click();
|
|
fileInput.remove();
|
|
}
|
|
|
|
|
|
/**
|
|
* App entry point
|
|
*/
|
|
$(document).ready(function () {
|
|
document.title = "Automatic Announcement System"
|
|
$('#onlineindicator').attr('src', '/assets/img/red_circle.png');
|
|
getVoiceTypes();
|
|
getCategories();
|
|
getLanguages();
|
|
getScheduledDays();
|
|
reloadSoundbankFiles();
|
|
|
|
// Initialize WebSocket connection
|
|
ws = new WebSocket(window.location.pathname + '/ws');
|
|
|
|
ws.onopen = () => {
|
|
console.log('WebSocket connection established');
|
|
$('#onlineindicator').attr('src', '/assets/img/green_circle.png');
|
|
};
|
|
ws.onmessage = (event) => {
|
|
let rep = JSON.parse(event.data);
|
|
let cmd = rep.reply
|
|
let data = rep.data;
|
|
if (cmd && cmd.length > 0) {
|
|
switch (cmd) {
|
|
case "getCPUStatus":
|
|
$('#cpustatus').text("CPU Usage: " + data)
|
|
break;
|
|
case "getMemoryStatus":
|
|
$('#ramstatus').text("Memory Usage: " + data)
|
|
break;
|
|
case "getDiskStatus":
|
|
$('#diskstatus').text("Disk Usage: " + data)
|
|
break;
|
|
case "getNetworkStatus":
|
|
$('#networkstatus').text("Network Usage: " + data)
|
|
break;
|
|
case "getSystemTime":
|
|
$('#datetimetext').text(data)
|
|
break;
|
|
|
|
}
|
|
}
|
|
};
|
|
ws.onclose = () => {
|
|
console.log('WebSocket connection closed');
|
|
$('#onlineindicator').attr('src', '/assets/img/red_circle.png');
|
|
};
|
|
// ws.onerror = (error) => {
|
|
// console.error('WebSocket error:', error);
|
|
// };
|
|
|
|
|
|
|
|
setInterval(() => {
|
|
sendCommand("getCPUStatus", "")
|
|
sendCommand("getMemoryStatus", "")
|
|
sendCommand("getDiskStatus", "")
|
|
sendCommand("getNetworkStatus", "")
|
|
sendCommand("getSystemTime", "")
|
|
}, 1000)
|
|
|
|
let sidemenu = new bootstrap.Offcanvas('#offcanvas-menu');
|
|
$('#showmenu').click(() => { sidemenu.show(); })
|
|
|
|
$('#homelink').click(() => {
|
|
sidemenu.hide();
|
|
$('#content').load('overview.html', function (response, status, xhr) {
|
|
if (status === "success") {
|
|
console.log("Overview content loaded successfully");
|
|
}
|
|
});
|
|
});
|
|
$('#soundbanklink').click(() => {
|
|
sidemenu.hide();
|
|
$('#content').load('soundbank.html', function (response, status, xhr) {
|
|
if (status === "success") {
|
|
console.log("Soundbank content loaded successfully");
|
|
// initialize first state of buttons and text input
|
|
$('#soundbanktablebody').empty();
|
|
selectedsoundrow = null;
|
|
let $btnClear = $('#btnClear');
|
|
let $btnAdd = $('#btnAdd');
|
|
let $btnRemove = $('#btnRemove');
|
|
let $btnEdit = $('#btnEdit');
|
|
let $btnExport = $('#btnExport');
|
|
let $btnImport = $('#btnImport');
|
|
$btnRemove.prop('disabled', true);
|
|
$btnEdit.prop('disabled', true);
|
|
let APIURL = "SoundBank/";
|
|
let $modal = $('#soundbankmodal');
|
|
let $modalindex = $modal.find('#modalindex');
|
|
let $modaldescription = $modal.find('#modaldescription');
|
|
let $modaltag = $modal.find('#modaltag');
|
|
let $modalcategory = $modal.find('#modalcategory');
|
|
let $modallanguage = $modal.find('#modallanguage');
|
|
let $modalvoicetype = $modal.find('#modalvoicetype');
|
|
let $modalpath = $modal.find('#modalpath');
|
|
|
|
/**
|
|
* Clear soundbank modal inputs
|
|
*/
|
|
function clearSoundbankModal() {
|
|
$modalindex.val('').prop('disabled', true);
|
|
$modaldescription.val('');
|
|
$modaltag.val('');
|
|
// fill modalcategory options from categories[]
|
|
$modalcategory.empty();
|
|
categories.forEach(cat => {
|
|
$modalcategory.append(new Option(cat, cat));
|
|
});
|
|
$modalcategory.val(null);
|
|
// fill modallanguage options from languages[]
|
|
$modallanguage.empty();
|
|
languages.forEach(lang => {
|
|
$modallanguage.append(new Option(lang, lang));
|
|
});
|
|
$modallanguage.val(null);
|
|
// fill modalvoicetype options from voiceTypes[]
|
|
$modalvoicetype.empty();
|
|
voiceTypes.forEach(vt => {
|
|
$modalvoicetype.append(new Option(vt, vt));
|
|
});
|
|
$modalvoicetype.val(null);
|
|
// fill modalpath options from soundbankfiles[]
|
|
// TODO read https://jeesite.com/front/jquery-select2/4.0/index.htm
|
|
console.log("select2data has " + select2data.length + " items");
|
|
$('#modalpath').select2({
|
|
data: select2data
|
|
})
|
|
}
|
|
|
|
reloadSoundBank(APIURL);
|
|
$('#findsoundbank').on('input', function () {
|
|
let searchTerm = $(this).val().trim().toLowerCase();
|
|
if (searchTerm.length > 0) {
|
|
selectedsoundrow = null;
|
|
let filtered = soundbankdata.filter(item => item.description.toLowerCase().includes(searchTerm) || item.tag.toLowerCase().includes(searchTerm) || item.path.toLowerCase().includes(searchTerm));
|
|
fill_soundbanktablebody(filtered);
|
|
} else {
|
|
selectedsoundrow = null;
|
|
fill_soundbanktablebody(soundbankdata);
|
|
}
|
|
});
|
|
$btnClear.click(() => {
|
|
DoClear(APIURL, "Soundbank", (okdata) => {
|
|
reloadSoundBank(APIURL);
|
|
alert("Success clear soundbank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error clear soundbank : " + errdata.message);
|
|
});
|
|
|
|
});
|
|
$btnAdd.click(() => {
|
|
|
|
$modal.modal('show');
|
|
clearSoundbankModal();
|
|
// event on Click save button
|
|
$modal.off('click.soundbanksave').on('click.soundbanksave', '#soundbanksave', function () {
|
|
//TODO Add soundbank save process here
|
|
$modal.modal('hide');
|
|
});
|
|
// event on Click close button
|
|
$modal.off('click.soundbankclose').on('click.soundbankclose', '#soundbankclose', function () {
|
|
$modal.modal('hide');
|
|
});
|
|
});
|
|
$btnRemove.click(() => {
|
|
if (selectedsoundrow) {
|
|
let cells = selectedsoundrow.find('td');
|
|
/** @type {SoundBank} */
|
|
let sb = {
|
|
index: cells.eq(0).text(),
|
|
description: cells.eq(1).text(),
|
|
tag: cells.eq(2).text(),
|
|
category: cells.eq(3).text(),
|
|
language: cells.eq(4).text(),
|
|
voiceType: cells.eq(5).text(),
|
|
path: cells.eq(6).text()
|
|
}
|
|
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);
|
|
alert("Success delete soundbank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error delete soundbank : " + errdata.message);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$btnEdit.click(() => {
|
|
if (selectedsoundrow) {
|
|
let cells = selectedsoundrow.find('td');
|
|
/** @type {SoundBank} */
|
|
let sb = {
|
|
index: cells.eq(0).text(),
|
|
description: cells.eq(1).text(),
|
|
tag: cells.eq(2).text(),
|
|
category: cells.eq(3).text(),
|
|
language: cells.eq(4).text(),
|
|
voiceType: cells.eq(5).text(),
|
|
path: cells.eq(6).text()
|
|
}
|
|
if (confirm(`Are you sure to edit soundbank [${sb.index}] Description=${sb.description} Tag=${sb.tag}?`)) {
|
|
$modal.modal('show');
|
|
$modal.off('hidden.bs.modal').on('hidden.bs.modal', function () {
|
|
|
|
// event on Click save button
|
|
$modal.off('click.soundbanksave').on('click.soundbanksave', '#soundbanksave', function () {
|
|
//TODO Add soundbank save process here
|
|
$modal.modal('hide');
|
|
});
|
|
// event on Click close button
|
|
$modal.off('click.soundbankclose').on('click.soundbankclose', '#soundbankclose', function () {
|
|
$modal.modal('hide');
|
|
});
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$btnExport.click(() => {
|
|
DoExport(APIURL, "soundbank.xlsx", {});
|
|
});
|
|
$btnImport.click(() => {
|
|
DoImport(APIURL, (okdata) => {
|
|
reloadSoundBank(APIURL);
|
|
alert("Success import soundbank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error importing soundbank from XLSX : " + errdata.message);
|
|
});
|
|
});
|
|
} else {
|
|
console.error("Error loading soundbank content : ", xhr.status, xhr.statusText);
|
|
}
|
|
});
|
|
|
|
})
|
|
$('#messagebanklink').click(() => {
|
|
sidemenu.hide();
|
|
$('#content').load('messagebank.html', function (response, status, xhr) {
|
|
if (status === "success") {
|
|
console.log("Messagebank content loaded successfully");
|
|
// initialize first state of buttons and text input
|
|
$('#messagebanktablebody').empty();
|
|
selectedmessagerow = null;
|
|
let $btnClear = $('#btnClear');
|
|
let $btnAdd = $('#btnAdd');
|
|
let $btnRemove = $('#btnRemove');
|
|
let $btnEdit = $('#btnEdit');
|
|
let $btnExport = $('#btnExport');
|
|
let $btnImport = $('#btnImport');
|
|
$btnRemove.prop('disabled', true);
|
|
$btnEdit.prop('disabled', true);
|
|
let APIURL = "MessageBank/";
|
|
let $findmessage = $('#findmessage');
|
|
|
|
// modal for add / edit messagebank
|
|
let $modal = $('#messagebankmodal');
|
|
// text input, disabled by default
|
|
let $messageindex = $modal.find('#messageindex');
|
|
// text input
|
|
let $messagedescription = $modal.find('#messagedescription');
|
|
// select input, options loaded from languages[]
|
|
let $messagelanguage = $modal.find('#messagelanguage');
|
|
// number input from 1 to 100
|
|
let $messageannid = $modal.find('#messageannid');
|
|
// select input, options loaded from voiceTypes[]
|
|
let $messagevoicetype = $modal.find('#messagevoicetype');
|
|
// list <ul> of available categories and phrases
|
|
let $messageavailablevariables = $modal.find('#messageavailablevariables');
|
|
// list <ul> of selected categories and phrases
|
|
let $messageselectedvariables = $modal.find('#messageselectedvariables');
|
|
// for clearing messageselectedvariables
|
|
let $btnclearlist = $modal.find('#btnclearlist');
|
|
// for removing selected item from messageselectedvariables
|
|
let $btnremovefromlist = $modal.find('#btnremovefromlist');
|
|
// for adding selected item from messageavailablevariables to messageselectedvariables
|
|
let $btnaddtolist = $modal.find('#btnaddtolist');
|
|
|
|
/**
|
|
* Refill messageavailablevariables options from categories[]
|
|
* and soundbankdata with category "Phrase" if messagelanguage and messagevoicetype are selected
|
|
*/
|
|
function refill_messageavailablevariables() {
|
|
$messageavailablevariables.empty();
|
|
categories.forEach(cat => {
|
|
$messageavailablevariables.append(ListItem(`{${cat}}`));
|
|
});
|
|
if ($messagelanguage.val() && $messagevoicetype.val()) {
|
|
soundbankdata
|
|
.filter(sb => sb.language.toLowerCase() === $messagelanguage.val().toLowerCase())
|
|
.filter(sb => sb.voiceType.toLowerCase() === $messagevoicetype.val().toLowerCase())
|
|
.filter(sb => sb.category.toLowerCase() === "phrase")
|
|
.forEach(sb => {
|
|
$messageavailablevariables.append(ListItem(`[${sb.Description}]`));
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Clear message modal to default state
|
|
*/
|
|
function clearMessageModal() {
|
|
$messageindex.val('').prop('disabled', true);
|
|
$messagedescription.val('');
|
|
// fill messagelanguage options from languages[]
|
|
$messagelanguage.empty();
|
|
languages.forEach(lang => {
|
|
$messagelanguage.append(new Option(lang, lang));
|
|
});
|
|
$messagelanguage.val(null);
|
|
$messagelanguage.on('change', function () {
|
|
refill_messageavailablevariables();
|
|
});
|
|
// set default annid to 1
|
|
$messageannid.val(1);
|
|
// fill messagevoicetype options from voiceTypes[]
|
|
$messagevoicetype.empty();
|
|
voiceTypes.forEach(vt => {
|
|
$messagevoicetype.append(new Option(vt, vt));
|
|
});
|
|
$messagevoicetype.val(null);
|
|
$messagevoicetype.on('change', function () {
|
|
refill_messageavailablevariables();
|
|
});
|
|
|
|
refill_messageavailablevariables();
|
|
$messageselectedvariables.empty();
|
|
|
|
// event on btnclearlist
|
|
$btnclearlist.off('click').on('click', function () {
|
|
if ($messageselectedvariables.children().length > 0) {
|
|
if (confirm("Are you sure want to clear selected variables list?")) {
|
|
$messageselectedvariables.empty();
|
|
}
|
|
}
|
|
});
|
|
|
|
// event on btnremovefromlist
|
|
$btnremovefromlist.off('click').on('click', function () {
|
|
let $selected = $messageselectedvariables.find('option:selected');
|
|
if ($selected.length > 0) {
|
|
$selected.remove();
|
|
}
|
|
|
|
});
|
|
|
|
// event on btnaddtolist
|
|
$btnaddtolist.off('click').on('click', function () {
|
|
let $selected = $messageavailablevariables.find('option:selected');
|
|
if ($selected.length > 0) {
|
|
$selected.each(function () {
|
|
$messageselectedvariables.append($(this).clone());
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
$findmessage.on('input', function () {
|
|
let searchTerm = $findmessage.val().toLowerCase();
|
|
if (searchTerm.length > 0) {
|
|
selectedmessagerow = null;
|
|
let filtered = messagebankdata.filter(item => item.description.toLowerCase().includes(searchTerm) || item.message_Detail.toLowerCase().includes(searchTerm) || item.message_TAGS.toLowerCase().includes(searchTerm));
|
|
fill_messagebanktablebody(filtered);
|
|
} else {
|
|
selectedmessagerow = null;
|
|
fill_messagebanktablebody(messagebankdata);
|
|
}
|
|
});
|
|
|
|
|
|
reloadMessageBank(APIURL);
|
|
$btnClear.click(() => {
|
|
DoClear(APIURL, "Messagebank", (okdata) => {
|
|
reloadMessageBank(APIURL);
|
|
alert("Success clear messagebank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error clear messagebank : " + errdata.message);
|
|
});
|
|
|
|
});
|
|
$btnAdd.click(() => {
|
|
|
|
$modal.modal('show');
|
|
clearMessageModal();
|
|
|
|
// event on Click save button
|
|
$modal.off('click.messagebanksave').on('click.messagebanksave', '#messagebanksave', function () {
|
|
let description = $messagedescription.val().trim();
|
|
let language = $messagelanguage.val();
|
|
let annid = parseInt($messageannid.val());
|
|
let voicetype = $messagevoicetype.val();
|
|
let messagedetail = "";
|
|
let messagetags = "";
|
|
|
|
// iterate messageselectedvariables children
|
|
$messageselectedvariables.children().each(function () {
|
|
let val = $(this).text().trim();
|
|
if (val.length > 0) {
|
|
if (val.startsWith('[') && val.endsWith(']')) {
|
|
// categories
|
|
messagetags += (messagetags.length > 0 ? " " : "") + val;
|
|
messagedetail += (messagedetail.length > 0 ? " " : "") + val;
|
|
} else {
|
|
// phrases
|
|
// find in soundbankdata by description with specified language and voicetype
|
|
let sb = soundbankdata
|
|
.filter(sb => sb.language.toLowerCase() === language.toLowerCase())
|
|
.filter(sb => sb.voiceType.toLowerCase() === voicetype.toLowerCase())
|
|
.find(sb => sb.Description.toLowerCase() === val.toLowerCase());
|
|
if (sb) {
|
|
messagedetail += (messagedetail.length > 0 ? " " : "") + sb.Description;
|
|
messagetags += (messagetags.length > 0 ? " " : "") + sb.tag;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
if (description.length === 0) {
|
|
alert("Description cannot be empty");
|
|
return;
|
|
}
|
|
if (!language) {
|
|
alert("Language cannot be empty");
|
|
return;
|
|
}
|
|
if (isNaN(annid) || annid < 1 || annid > 100) {
|
|
alert("ANN_ID must be a number between 1 and 100");
|
|
return;
|
|
}
|
|
if (!voicetype) {
|
|
alert("Voice Type cannot be empty");
|
|
return;
|
|
}
|
|
if (messagedetail.length === 0 || messagetags.length === 0) {
|
|
alert("Message haven't been constructed, please add categories and phrases");
|
|
return;
|
|
}
|
|
|
|
|
|
let mb = {
|
|
Description: description,
|
|
Language: language,
|
|
ANN_ID: annid,
|
|
Voice_Type: voicetype,
|
|
Message_Detail: messagedetail,
|
|
Message_TAGS: messagetags
|
|
};
|
|
// send to server using fetchAPI
|
|
fetchAPI(APIURL + "Add", "POST", mb, null, (okdata) => {
|
|
reloadMessageBank(APIURL);
|
|
alert("Success add new messagebank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error add new messagebank : " + errdata.message);
|
|
});
|
|
|
|
$modal.modal('hide');
|
|
});
|
|
// event on Click close button
|
|
$modal.off('click.messagebankclose').on('click.messagebankclose', '#messagebankclose', function () {
|
|
$modal.modal('hide');
|
|
});
|
|
});
|
|
$btnRemove.click(() => {
|
|
if (selectedmessagerow) {
|
|
let cells = selectedmessagerow.find('td');
|
|
/** @type {MessageBank} */
|
|
let mb = {
|
|
index: cells.eq(0).text(),
|
|
description: cells.eq(1).text(),
|
|
language: cells.eq(2).text(),
|
|
aNN_ID: parseInt(cells.eq(3).text()),
|
|
voice_Type: cells.eq(4).text(),
|
|
message_Detail: cells.eq(5).text(),
|
|
message_TAGS: cells.eq(6).text()
|
|
}
|
|
|
|
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);
|
|
alert("Success delete messagebank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error delete messagebank : " + errdata.message);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$btnEdit.click(() => {
|
|
if (selectedmessagerow) {
|
|
let cells = selectedmessagerow.find('td');
|
|
/** @type {MessageBank} */
|
|
let mb = {
|
|
index: cells.eq(0).text(),
|
|
description: cells.eq(1).text(),
|
|
language: cells.eq(2).text(),
|
|
aNN_ID: parseInt(cells.eq(3).text()),
|
|
voice_Type: cells.eq(4).text(),
|
|
message_Detail: cells.eq(5).text(),
|
|
message_TAGS: cells.eq(6).text()
|
|
}
|
|
if (confirm(`Are you sure to edit messagebank [${mb.index}] Description=${mb.description} ANN_ID=${mb.aNN_ID} Language=${mb.language} Voice_Type=${mb.voice_Type} `)) {
|
|
$modal.modal('show');
|
|
|
|
clearMessageModal();
|
|
// Fill modal fields with selected messagebank data
|
|
$messageindex.val(mb.index).prop('disabled', true);
|
|
$messagedescription.val(mb.description);
|
|
// Fill messagelanguage options and select current
|
|
$messagelanguage.empty();
|
|
languages.forEach(lang => {
|
|
$messagelanguage.append(new Option(lang, lang));
|
|
});
|
|
$messagelanguage.val(mb.language);
|
|
// Fill messagevoicetype options and select current
|
|
$messagevoicetype.empty();
|
|
voiceTypes.forEach(vt => {
|
|
$messagevoicetype.append(new Option(vt, vt));
|
|
});
|
|
$messagevoicetype.val(mb.voice_Type);
|
|
// Set annid
|
|
$messageannid.val(mb.aNN_ID);
|
|
// Refill message available variables
|
|
refill_messageavailablevariables();
|
|
// Fill messageselectedvariables from message_Detail and message_TAGS
|
|
$messageselectedvariables.empty();
|
|
if (mb.message_Detail) {
|
|
mb.message_Detail.split(' ').forEach(val => {
|
|
$messageselectedvariables.append(ListItem(val));
|
|
});
|
|
}
|
|
|
|
// Save button event
|
|
$modal.off('click.messagebanksave').on('click.messagebanksave', '#messagebanksave', function () {
|
|
let description = $messagedescription.val().trim();
|
|
let language = $messagelanguage.val();
|
|
let annid = parseInt($messageannid.val());
|
|
let voicetype = $messagevoicetype.val();
|
|
let messagedetail = "";
|
|
let messagetags = "";
|
|
$messageselectedvariables.children().each(function () {
|
|
let val = $(this).text().trim();
|
|
if (val.length > 0) {
|
|
if (val.startsWith('[') && val.endsWith(']')) {
|
|
messagetags += (messagetags.length > 0 ? " " : "") + val;
|
|
messagedetail += (messagedetail.length > 0 ? " " : "") + val;
|
|
} else {
|
|
let sb = soundbankdata
|
|
.filter(sb => sb.language.toLowerCase() === language.toLowerCase())
|
|
.filter(sb => sb.voiceType.toLowerCase() === voicetype.toLowerCase())
|
|
.find(sb => sb.Description && sb.Description.toLowerCase() === val.toLowerCase());
|
|
if (sb) {
|
|
messagedetail += (messagedetail.length > 0 ? " " : "") + sb.Description;
|
|
messagetags += (messagetags.length > 0 ? " " : "") + sb.tag;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
if (description.length === 0) {
|
|
alert("Description cannot be empty");
|
|
return;
|
|
}
|
|
if (!language) {
|
|
alert("Language cannot be empty");
|
|
return;
|
|
}
|
|
if (isNaN(annid) || annid < 1 || annid > 100) {
|
|
alert("ANN_ID must be a number between 1 and 100");
|
|
return;
|
|
}
|
|
if (!voicetype) {
|
|
alert("Voice Type cannot be empty");
|
|
return;
|
|
}
|
|
if (messagedetail.length === 0 || messagetags.length === 0) {
|
|
alert("Message haven't been constructed, please add categories and phrases");
|
|
return;
|
|
}
|
|
let mbUpdate = {
|
|
Description: description,
|
|
Language: language,
|
|
ANN_ID: annid,
|
|
Voice_Type: voicetype,
|
|
Message_Detail: messagedetail,
|
|
Message_TAGS: messagetags
|
|
};
|
|
fetchAPI(APIURL + "UpdateByIndex/" + mb.index, "PATCH", mbUpdate, null, (okdata) => {
|
|
reloadMessageBank(APIURL);
|
|
alert("Success edit messagebank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error edit messagebank : " + errdata.message);
|
|
});
|
|
$modal.modal('hide');
|
|
});
|
|
// Close button event
|
|
$modal.off('click.messagebankclose').on('click.messagebankclose', '#messagebankclose', function () {
|
|
$modal.modal('hide');
|
|
});
|
|
|
|
}
|
|
}
|
|
});
|
|
$btnExport.click(() => {
|
|
DoExport(APIURL, "messagebank.xlsx", {});
|
|
});
|
|
$btnImport.click(() => {
|
|
DoImport(APIURL, (okdata) => {
|
|
reloadMessageBank(APIURL);
|
|
alert("Success import messagebank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error importing messagebank from XLSX : " + errdata.message);
|
|
});
|
|
});
|
|
} else {
|
|
console.error("Error loading messagebank content : ", xhr.status, xhr.statusText);
|
|
}
|
|
});
|
|
|
|
})
|
|
$('#languagelink').click(() => {
|
|
sidemenu.hide();
|
|
$('#content').load('language.html', function (response, status, xhr) {
|
|
if (status === "success") {
|
|
console.log("Language content loaded successfully");
|
|
// initialize first state of buttons and text input
|
|
$('#languagebanktablebody').empty();
|
|
selectedlanguagerow = null;
|
|
let $btnClear = $('#btnClear');
|
|
let $btnAdd = $('#btnAdd');
|
|
let $btnRemove = $('#btnRemove');
|
|
let $btnEdit = $('#btnEdit');
|
|
let $btnExport = $('#btnExport');
|
|
let $btnImport = $('#btnImport');
|
|
$btnRemove.prop('disabled', true);
|
|
$btnEdit.prop('disabled', true);
|
|
let APIURL = "LanguageLink/";
|
|
let $findlanguage = $('#findlanguage');
|
|
let $modal = $('#languagemodal');
|
|
let $langid = $modal.find('#languagelinkindex');
|
|
let $langtag = $modal.find('#languagelinktag');
|
|
let $cbInd = $modal.find('#langId');
|
|
let $cbLocal = $modal.find('#langLocal');
|
|
let $cbEn = $modal.find('#langEn');
|
|
let $cbArb = $modal.find('#langArb');
|
|
let $cbJap = $modal.find('#langJap');
|
|
let $cbChi = $modal.find('#langChi');
|
|
|
|
function clearLanguageModal() {
|
|
$langid.prop('disabled', true).val('');
|
|
$langtag.val('');
|
|
$cbInd.prop('checked', false);
|
|
$cbLocal.prop('checked', false);
|
|
$cbEn.prop('checked', false);
|
|
$cbArb.prop('checked', false);
|
|
$cbJap.prop('checked', false);
|
|
$cbChi.prop('checked', false);
|
|
}
|
|
|
|
$findlanguage.on('input', function () {
|
|
let searchTerm = $findlanguage.val().toLowerCase();
|
|
if (searchTerm.length > 0) {
|
|
selectedlanguagerow = null;
|
|
let filtered = languagebankdata.filter(item => item.tag.toLowerCase().includes(searchTerm) || item.language.toLowerCase().includes(searchTerm));
|
|
fill_languagebanktablebody(filtered);
|
|
} else {
|
|
selectedlanguagerow = null;
|
|
fill_languagebanktablebody(languagebankdata);
|
|
}
|
|
});
|
|
|
|
reloadLanguageBank(APIURL);
|
|
$btnClear.click(() => {
|
|
DoClear(APIURL, "LanguageLink", (okdata) => {
|
|
reloadLanguageBank(APIURL);
|
|
alert("Success clear languageLink : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error clear languageLink : " + errdata.message);
|
|
});
|
|
|
|
});
|
|
$btnAdd.click(() => {
|
|
// show modal with id 'languagemodal'
|
|
$modal.modal('show');
|
|
clearLanguageModal();
|
|
|
|
// save button click event
|
|
$modal.off('click.languagelinksave').on('click.languagelinksave', '#languagelinksave', function () {
|
|
const tag = $langtag.val();
|
|
const langs = [];
|
|
if ($cbInd.is(':checked')) langs.push('INDONESIA');
|
|
if ($cbLocal.is(':checked')) langs.push('LOCAL');
|
|
if ($cbEn.is(':checked')) langs.push('ENGLISH');
|
|
if ($cbArb.is(':checked')) langs.push('ARABIC');
|
|
if ($cbJap.is(':checked')) langs.push('JAPANESE');
|
|
if ($cbChi.is(':checked')) langs.push('CHINESE');
|
|
|
|
if (tag.length === 0) {
|
|
alert("Tag cannot be empty");
|
|
return;
|
|
}
|
|
if (langs.length === 0) {
|
|
alert("At least one language must be selected");
|
|
return;
|
|
}
|
|
|
|
const langString = langs.join(';');
|
|
let ll = {
|
|
tag: tag,
|
|
language: langString
|
|
}
|
|
fetchAPI(APIURL + "Add", "POST", {}, ll, (okdata) => {
|
|
alert("Success add language : " + okdata.message);
|
|
reloadLanguageBank(APIURL);
|
|
}, (errdata) => {
|
|
alert("Error add language : " + errdata.message);
|
|
});
|
|
$modal.modal('hide');
|
|
|
|
|
|
});
|
|
// close button click event
|
|
$modal.off('click.languagelinkclose').on('click.languagelinkclose', '#languagelinkclose', function () {
|
|
$modal.modal('hide');
|
|
});
|
|
});
|
|
$btnRemove.click(() => {
|
|
if (selectedlanguagerow) {
|
|
let cells = selectedlanguagerow.find('td');
|
|
/** @type {Language} */
|
|
let ll = {
|
|
index: cells.eq(0).text(),
|
|
tag: cells.eq(1).text(),
|
|
language: cells.eq(2).text()
|
|
}
|
|
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);
|
|
alert("Success delete language : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error delete language : " + errdata.message);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$btnEdit.click(() => {
|
|
if (selectedlanguagerow) {
|
|
let cells = selectedlanguagerow.find('td');
|
|
/** @type {Language} */
|
|
let ll = {
|
|
index: cells.eq(0).text(),
|
|
tag: cells.eq(1).text(),
|
|
language: cells.eq(2).text()
|
|
}
|
|
if (confirm(`Are you sure to edit language [${ll.index}] Tag=${ll.tag} Language=${ll.language}?`)) {
|
|
|
|
clearLanguageModal();
|
|
$langid.val(ll.index);
|
|
$langtag.val(ll.tag);
|
|
let langs = ll.language.toUpperCase().split(';');
|
|
$cbInd.prop('checked', langs.includes('INDONESIA'));
|
|
$cbLocal.prop('checked', langs.includes('LOCAL'));
|
|
$cbEn.prop('checked', langs.includes('ENGLISH'));
|
|
$cbArb.prop('checked', langs.includes('ARABIC'));
|
|
$cbJap.prop('checked', langs.includes('JAPANESE'));
|
|
$cbChi.prop('checked', langs.includes('CHINESE'));
|
|
$modal.modal('show');
|
|
// save button click event
|
|
$modal.off('click.languagelinksave').on('click.languagelinksave', '#languagelinksave', function () {
|
|
const tag = $langtag.val();
|
|
const langs = [];
|
|
if ($cbInd.is(':checked')) langs.push('INDONESIA');
|
|
if ($cbLocal.is(':checked')) langs.push('LOCAL');
|
|
if ($cbEn.is(':checked')) langs.push('ENGLISH');
|
|
if ($cbArb.is(':checked')) langs.push('ARABIC');
|
|
if ($cbJap.is(':checked')) langs.push('JAPANESE');
|
|
if ($cbChi.is(':checked')) langs.push('CHINESE');
|
|
if (tag.length === 0) {
|
|
alert("Tag cannot be empty");
|
|
return;
|
|
}
|
|
if (langs.length === 0) {
|
|
alert("At least one language must be selected");
|
|
return;
|
|
}
|
|
const langString = langs.join(';');
|
|
if (ll.tag === tag && ll.language === langString) {
|
|
alert("No changes detected");
|
|
$modal.modal('hide');
|
|
return;
|
|
}
|
|
|
|
ll.tag = tag;
|
|
ll.language = langString;
|
|
fetchAPI(APIURL + "UpdateByIndex/" + ll.index, "PATCH", {}, ll, (okdata) => {
|
|
reloadLanguageBank(APIURL);
|
|
alert("Success edit language : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error edit language : " + errdata.message);
|
|
});
|
|
|
|
$modal.modal('hide');
|
|
});
|
|
// close button click event
|
|
$modal.off('click.languagelinkclose').on('click.languagelinkclose', '#languagelinkclose', function () {
|
|
$modal.modal('hide');
|
|
});
|
|
|
|
|
|
}
|
|
}
|
|
});
|
|
$btnExport.click(() => {
|
|
DoExport(APIURL, "languagebank.xlsx", {});
|
|
|
|
});
|
|
$btnImport.click(() => {
|
|
DoImport(APIURL, (okdata) => {
|
|
reloadLanguageBank(APIURL);
|
|
alert("Success import languagebank : " + okdata.message);
|
|
}, (errdata) => {
|
|
alert("Error importing languagebank from XLSX : " + errdata.message);
|
|
});
|
|
|
|
});
|
|
} else {
|
|
console.error("Error loading language content : ", xhr.status, xhr.statusText);
|
|
}
|
|
});
|
|
})
|
|
$('#timerlink').click(() => {
|
|
sidemenu.hide();
|
|
$('#content').load('timer.html', function (response, status, xhr) {
|
|
if (status === "success") {
|
|
console.log("Timer content loaded successfully");
|
|
// initialize first state of buttons and text input
|
|
$('#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');
|
|
// text input
|
|
let $schedulesoundpath = $schedulemodal.find('#schedulesoundpath');
|
|
// number input 0-5
|
|
let $schedulerepeat = $schedulemodal.find('#schedulerepeat');
|
|
// checkbox
|
|
let $scheduleenable = $schedulemodal.find('#scheduleenable');
|
|
// div for list of checkboxes
|
|
let $schedulezones = $schedulemodal.find('#schedulezones');
|
|
// radio button for everyday
|
|
let $scheduleeveryday = $schedulemodal.find('#scheduleeveryday');
|
|
// radio button for weekdays
|
|
let $schedulesunday = $schedulemodal.find('#schedulesunday');
|
|
let $schedulemonday = $schedulemodal.find('#schedulemonday');
|
|
let $scheduletuesday = $schedulemodal.find('#scheduletuesday');
|
|
let $schedulewednesday = $schedulemodal.find('#schedulewednesday');
|
|
let $schedulethursday = $schedulemodal.find('#schedulethursday');
|
|
let $schedulefriday = $schedulemodal.find('#schedulefriday');
|
|
let $schedulesaturday = $schedulemodal.find('#schedulesaturday');
|
|
// radio button for specific date
|
|
let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
|
|
// date input
|
|
let $scheduledate = $schedulemodal.find('#scheduledate');
|
|
|
|
$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');
|
|
$schedulesoundpath.val('');
|
|
$schedulerepeat.val('0');
|
|
$scheduleenable.prop('checked', true);
|
|
$scheduleeveryday.prop('checked', false);
|
|
$schedulesunday.prop('checked', false);
|
|
$schedulemonday.prop('checked', false);
|
|
$scheduletuesday.prop('checked', false);
|
|
$schedulewednesday.prop('checked', false);
|
|
$schedulethursday.prop('checked', false);
|
|
$schedulefriday.prop('checked', false);
|
|
$schedulesaturday.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) {
|
|
selectedtimerow = null;
|
|
let filtered = schedulebankdata.filter(item =>
|
|
item.description.toLowerCase().includes(searchTerm)
|
|
|| item.soundpath.toLowerCase().includes(searchTerm)
|
|
|| item.broadcastZones.toLowerCase().includes(searchTerm));
|
|
fill_schedulebanktablebody(filtered);
|
|
} else {
|
|
selectedtimerow = null;
|
|
fill_schedulebanktablebody(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 (selectedtimerow) {
|
|
let cells = selectedtimerow.find('td');
|
|
/** @type {ScheduleBank} */
|
|
let sr = {
|
|
index: 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 (selectedtimerow) {
|
|
let cells = selectedtimerow.find('td');
|
|
/** @type {ScheduleBank} */
|
|
let sr = {
|
|
index: 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);
|
|
});
|
|
});
|
|
} else {
|
|
console.error("Error loading timer content : ", xhr.status, xhr.statusText);
|
|
}
|
|
});
|
|
})
|
|
$('#loglink').click(() => {
|
|
sidemenu.hide();
|
|
$('#content').load('log.html', function (response, status, xhr) {
|
|
if (status === "success") {
|
|
console.log("Log content loaded successfully");
|
|
const $logdate = $('#logdate');
|
|
const $searchfilter = $('#searchfilter');
|
|
const $logtable = $('#logtablebody')
|
|
const $btnExport = $('#btnExport');
|
|
let selectedlogdate = "";
|
|
let logfilter = "";
|
|
let APIURL = "Log/";
|
|
$logtable.empty();
|
|
|
|
|
|
if (!$logdate.val()) {
|
|
const today = new Date();
|
|
const dd = String(today.getDate()).padStart(2, '0');
|
|
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
|
const yyyy = today.getFullYear();
|
|
$logdate.val(`${yyyy}-${mm}-${dd}`);
|
|
selectedlogdate = `${dd}-${mm}-${yyyy}`;
|
|
reloadLogs(APIURL, selectedlogdate, logfilter);
|
|
}
|
|
$logdate.off('change').on('change', function () {
|
|
const selected = $(this).val();
|
|
if (selected) {
|
|
const [year, month, day] = selected.split('-');
|
|
selectedlogdate = `${day}-${month}-${year}`;
|
|
reloadLogs(APIURL, selectedlogdate, logfilter);
|
|
}
|
|
});
|
|
|
|
$searchfilter.off('input').on('input', function () {
|
|
logfilter = $(this).val();
|
|
reloadLogs(APIURL, selectedlogdate, logfilter);
|
|
});
|
|
$btnExport.off('click').on('click', function () {
|
|
DoExport(APIURL, "log.xlsx", { date: selectedlogdate, filter: logfilter });
|
|
});
|
|
|
|
} else {
|
|
console.error("Error loading log content:", xhr.status, xhr.statusText);
|
|
}
|
|
});
|
|
})
|
|
$('#settinglink').click(() => {
|
|
sidemenu.hide();
|
|
$('#content').load('setting.html', function (response, status, xhr) {
|
|
if (status === "success") {
|
|
console.log("Setting content loaded successfully");
|
|
//sendCommand("getSetting", "");
|
|
} else {
|
|
console.error("Error loading setting content:", xhr.status, xhr.statusText);
|
|
}
|
|
});
|
|
})
|
|
$('#logoutlink').click(() => {
|
|
window.location.href = "login.html"
|
|
})
|
|
|
|
}); |