commit 04/02/2026

This commit is contained in:
2026-02-04 16:41:13 +07:00
parent 3e763c1172
commit 5e128ab36a
16 changed files with 112820 additions and 301 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/**
* 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';
}
}
fetch(url, options)
.then(async (response) => {
if (!response.ok) {
let msg;
try {
let _xxx = await response.json();
msg = _xxx.message || response.statusText;
} catch {
msg = await response.statusText;
}
throw new Error(msg);
}
return response.json();
})
.then(data => {
cbOK(data);
})
.catch(error => {
cbError(error);
});
}

View File

@@ -12,15 +12,14 @@ let $enable_japanese = null;
let $enable_arabic = null;
let $enable_local = null;
let $tbody_message = null;
let $tbody_broadcastzones = null;
message_table = null;
$select_broadcastzones = null;
let $select_airline = null;
let $select_city = null;
let $select_places = null;
let $select_shalat = null;
let $select_reason = null;
let $select_conveyorbelt = null;
let $select_procedure = null;
let $select_compensation = null;
@@ -60,48 +59,7 @@ let selected_messages = [];
* @property {string} value - The value of the variable
*/
/**
* 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';
}
}
fetch(url, options)
.then(async (response) => {
if (!response.ok) {
let msg;
try {
let _xxx = await response.json();
msg = _xxx.message || response.statusText;
} catch {
msg = await response.statusText;
}
throw new Error(msg);
}
return response.json();
})
.then(data => {
cbOK(data);
})
.catch(error => {
cbError(error);
});
}
window.semiautodata = {
/** @type {message[]} */
@@ -146,20 +104,20 @@ window.semiautodata = {
Add_Message: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Message: input must be a non-empty string");
//console.warn("Add_Message: input must be a non-empty string");
return false;
}
const parts = str.split(';');
if (!Array.isArray(parts) || parts.length !== 4) {
console.warn("Add_Message: input must contain exactly 4 semicolon-separated parts");
//console.warn("Add_Message: input must contain exactly 4 semicolon-separated parts");
return false;
}
const [idPart, description, language, message_details] = parts.map(p => p.trim());
const id = Number(idPart);
if (!Number.isInteger(id)) {
console.warn("Add_Message: first part must be an integer id");
//console.warn("Add_Message: first part must be an integer id");
return false;
}
@@ -171,7 +129,7 @@ window.semiautodata = {
});
if (duplicate) {
console.warn(`Add_Message: message with id ${id} and language "${language}" already exists`);
//console.warn(`Add_Message: message with id ${id} and language "${language}" already exists`);
return false;
}
@@ -186,22 +144,22 @@ window.semiautodata = {
Add_Airline: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Airline: input must be a non-empty string");
//console.warn("Add_Airline: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_Airline: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_Airline: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_Airline: both tag and value must be non-empty");
//console.warn("Add_Airline: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.airlines.some(a => (a && (a.tag || "").trim() === tag && (a.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_Airline: airline "${tag}" with value "${value}" already exists`);
//console.warn(`Add_Airline: airline "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.airlines.push({ tag, value });
@@ -210,22 +168,22 @@ window.semiautodata = {
Add_City: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_City: input must be a non-empty string");
//console.warn("Add_City: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_City: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_City: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_City: both tag and value must be non-empty");
//console.warn("Add_City: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.cities.some(c => (c && (c.tag || "").trim() === tag && (c.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_City: city "${tag}" with value "${value}" already exists`);
//console.warn(`Add_City: city "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.cities.push({ tag, value });
@@ -234,22 +192,22 @@ window.semiautodata = {
Add_Place: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Place: input must be a non-empty string");
//console.warn("Add_Place: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_Place: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_Place: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_Place: both tag and value must be non-empty");
//console.warn("Add_Place: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.places.some(p => (p && (p.tag || "").trim() === tag && (p.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_Place: place "${tag}" with value "${value}" already exists`);
//console.warn(`Add_Place: place "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.places.push({ tag, value });
@@ -258,22 +216,22 @@ window.semiautodata = {
Add_Shalat: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Shalat: input must be a non-empty string");
//console.warn("Add_Shalat: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_Shalat: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_Shalat: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_Shalat: both tag and value must be non-empty");
//console.warn("Add_Shalat: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.shalat.some(s => (s && (s.tag || "").trim() === tag && (s.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_Shalat: shalat "${tag}" with value "${value}" already exists`);
//console.warn(`Add_Shalat: shalat "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.shalat.push({ tag, value });
@@ -282,22 +240,22 @@ window.semiautodata = {
Add_Reason: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Reason: input must be a non-empty string");
//console.warn("Add_Reason: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_Reason: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_Reason: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_Reason: both tag and value must be non-empty");
//console.warn("Add_Reason: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.reasons.some(r => (r && (r.tag || "").trim() === tag && (r.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_Reason: reason "${tag}" with value "${value}" already exists`);
//console.warn(`Add_Reason: reason "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.reasons.push({ tag, value });
@@ -306,22 +264,22 @@ window.semiautodata = {
Add_Procedure: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Procedure: input must be a non-empty string");
//console.warn("Add_Procedure: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_Procedure: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_Procedure: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_Procedure: both tag and value must be non-empty");
//console.warn("Add_Procedure: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.procedures.some(p => (p && (p.tag || "").trim() === tag && (p.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_Procedure: procedure "${tag}" with value "${value}" already exists`);
//console.warn(`Add_Procedure: procedure "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.procedures.push({ tag, value });
@@ -330,22 +288,22 @@ window.semiautodata = {
Add_Compensation: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Compensation: input must be a non-empty string");
//console.warn("Add_Compensation: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_Compensation: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_Compensation: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_Compensation: both tag and value must be non-empty");
//console.warn("Add_Compensation: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.compensation.some(c => (c && (c.tag || "").trim() === tag && (c.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_Compensation: compensation "${tag}" with value "${value}" already exists`);
//console.warn(`Add_Compensation: compensation "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.compensation.push({ tag, value });
@@ -354,22 +312,22 @@ window.semiautodata = {
Add_Greeting: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_Greeting: input must be a non-empty string");
//console.warn("Add_Greeting: input must be a non-empty string");
return false;
}
const parts = str.split(';').map(p => p.trim());
if (!Array.isArray(parts) || parts.length !== 2) {
console.warn("Add_Greeting: input must contain exactly 2 semicolon-separated parts");
//console.warn("Add_Greeting: input must contain exactly 2 semicolon-separated parts");
return false;
}
const [tag, value] = parts;
if (!tag || !value) {
console.warn("Add_Greeting: both tag and value must be non-empty");
//console.warn("Add_Greeting: both tag and value must be non-empty");
return false;
}
const duplicate = window.semiautodata.greetings.some(g => (g && (g.tag || "").trim() === tag && (g.value || "").trim() === value));
if (duplicate) {
console.warn(`Add_Greeting: greeting "${tag}" with value "${value}" already exists`);
//console.warn(`Add_Greeting: greeting "${tag}" with value "${value}" already exists`);
return false;
}
window.semiautodata.greetings.push({ tag, value });
@@ -378,18 +336,18 @@ window.semiautodata = {
Add_BroadcastZone: (str) => {
if (str == null || typeof str !== 'string' || str.trim().length === 0) {
console.warn("Add_BroadcastZone: input must be a non-empty string");
//console.warn("Add_BroadcastZone: input must be a non-empty string");
return false;
}
const value = str.trim();
if (value.length === 0) {
console.warn("Add_BroadcastZone: value must be non-empty");
//console.warn("Add_BroadcastZone: value must be non-empty");
return false;
}
const duplicate = window.semiautodata.broadcastzones.some(b => (b || "").trim() === value);
if (duplicate) {
console.warn(`Add_BroadcastZone: broadcast zone "${value}" already exists`);
//console.warn(`Add_BroadcastZone: broadcast zone "${value}" already exists`);
return false;
}
window.semiautodata.broadcastzones.push(value);
@@ -406,34 +364,34 @@ function reload_database() {
fetchAPI("Initialize", "GET", {}, null, (data) => {
//TODO data masih dalam bentuk array of string, mesti diubah ke array of object
window.semiautodata.Clear();
if (data.messages && Array.isArray(data.messages)) {
if (data.messages && Array.isArray(data.messages) && data.messages.length > 0) {
for (let msg of data.messages) window.semiautodata.Add_Message(msg);
}
if (data.airlines && Array.isArray(data.airlines)) {
if (data.airlines && Array.isArray(data.airlines) && data.airlines.length > 0) {
for (let airline of data.airlines) window.semiautodata.Add_Airline(airline);
}
if (data.cities && Array.isArray(data.cities)) {
if (data.cities && Array.isArray(data.cities) && data.cities.length > 0) {
for (let city of data.cities) window.semiautodata.Add_City(city);
}
if (data.places && Array.isArray(data.places)) {
if (data.places && Array.isArray(data.places) && data.places.length > 0) {
for (let place of data.places) window.semiautodata.Add_Place(place);
}
if (data.shalat && Array.isArray(data.shalat)) {
if (data.shalat && Array.isArray(data.shalat) && data.shalat.length > 0) {
for (let shalat of data.shalat) window.semiautodata.Add_Shalat(shalat);
}
if (data.reasons && Array.isArray(data.reasons)) {
if (data.reasons && Array.isArray(data.reasons) && data.reasons.length > 0) {
for (let reason of data.reasons) window.semiautodata.Add_Reason(reason);
}
if (data.procedures && Array.isArray(data.procedures)) {
if (data.procedures && Array.isArray(data.procedures) && data.procedures.length > 0) {
for (let procedure of data.procedures) window.semiautodata.Add_Procedure(procedure);
}
if (data.compensation && Array.isArray(data.compensation)) {
if (data.compensation && Array.isArray(data.compensation) && data.compensation.length > 0) {
for (let compensation of data.compensation) window.semiautodata.Add_Compensation(compensation);
}
if (data.greetings && Array.isArray(data.greetings)) {
if (data.greetings && Array.isArray(data.greetings) && data.greetings.length > 0) {
for (let greeting of data.greetings) window.semiautodata.Add_Greeting(greeting);
}
if (data.broadcastzones && Array.isArray(data.broadcastzones)) {
if (data.broadcastzones && Array.isArray(data.broadcastzones) && data.broadcastzones.length > 0) {
for (let broadcastzone of data.broadcastzones) window.semiautodata.Add_BroadcastZone(broadcastzone);
}
fill_items();
@@ -590,7 +548,7 @@ function update_preview(language) {
}
}
if (text.indexOf('[BCB]') !== -1) {
let bcbTag = $select_bcb.val();
let bcbTag = $input_conveyorbelt.val();
if (ValidString(bcbTag)) {
text = text.replace(/\[BCB\]/g, bcbTag);
}
@@ -668,9 +626,55 @@ function update_all_previews() {
check_complete_message();
}
// helper to map language string to preview & checkbox
function applyLang(lang, value, checked) {
const l = (lang || "").toString().trim().toLowerCase();
if (l.startsWith("indonesia")) {
if (checked) $preview_indonesia.text(value); else $preview_indonesia.empty();
$enable_indonesia.prop("checked", !!checked);
return true;
}
if (l.startsWith("english")) {
if (checked) $preview_english.text(value); else $preview_english.empty();
$enable_english.prop("checked", !!checked);
return true;
}
if (l.startsWith("chinese")) {
if (checked) $preview_chinese.text(value); else $preview_chinese.empty();
$enable_chinese.prop("checked", !!checked);
return true;
}
if (l.startsWith("japanese")) {
if (checked) $preview_japanese.text(value); else $preview_japanese.empty();
$enable_japanese.prop("checked", !!checked);
return true;
}
if (l.startsWith("arabic")) {
if (checked) $preview_arabic.text(value); else $preview_arabic.empty();
$enable_arabic.prop("checked", !!checked);
return true;
}
if (l.startsWith("local")) {
if (checked) $preview_local.text(value); else $preview_local.empty();
$enable_local.prop("checked", !!checked);
return true;
}
return false;
}
// helper to clear previews for a given group id
function clearGroupPreviews(gid) {
if (!window.semiautodata || !Array.isArray(window.semiautodata.messages)) return;
const sameMsgs = window.semiautodata.messages.filter(m => Number(m.id) === Number(gid));
for (let m of sameMsgs) {
applyLang(m.language, "", false);
}
}
function fill_items() {
$tbody_message.empty();
$tbody_broadcastzones.empty();
const annIDSet = new Set();
message_table.clear().draw();
$select_broadcastzones.select2();
$select_airline.select2();
$select_city.select2();
@@ -691,118 +695,59 @@ function fill_items() {
if (window.semiautodata !== null) {
if (window.semiautodata.messages !== null && Array.isArray(window.semiautodata.messages) && window.semiautodata.messages.length > 0) {
for (let msg of window.semiautodata.messages) {
const txt = msg.description + " [" + msg.id + "]";
// check if tbody_message already has a row with the same text
let exists = false;
$("#tbody_message tr td").each(function () {
if ($(this).text() === txt) {
exists = true;
}
});
if (!exists) {
let $tr = $("<tr></tr>");
let $td = $("<td></td>").text(txt);
$tr.append($td);
$tbody_message.append($tr);
$tr.css("cursor", "pointer");
$tr.data("msgid", msg.id);
$tr.on("click", function (e) {
const $row = $(this);
const groupId = $row.data("msgid");
const willSelect = !$row.hasClass("table-active");
// helper to map language string to preview & checkbox
function applyLang(lang, value, checked) {
const l = (lang || "").toString().trim().toLowerCase();
if (l.startsWith("indonesia")) {
if (checked) $preview_indonesia.text(value); else $preview_indonesia.empty();
$enable_indonesia.prop("checked", !!checked);
return true;
}
if (l.startsWith("english")) {
if (checked) $preview_english.text(value); else $preview_english.empty();
$enable_english.prop("checked", !!checked);
return true;
}
if (l.startsWith("chinese")) {
if (checked) $preview_chinese.text(value); else $preview_chinese.empty();
$enable_chinese.prop("checked", !!checked);
return true;
}
if (l.startsWith("japanese")) {
if (checked) $preview_japanese.text(value); else $preview_japanese.empty();
$enable_japanese.prop("checked", !!checked);
return true;
}
if (l.startsWith("arabic")) {
if (checked) $preview_arabic.text(value); else $preview_arabic.empty();
$enable_arabic.prop("checked", !!checked);
return true;
}
if (l.startsWith("local")) {
if (checked) $preview_local.text(value); else $preview_local.empty();
$enable_local.prop("checked", !!checked);
return true;
}
return false;
}
// helper to clear previews for a given group id
function clearGroupPreviews(gid) {
if (!window.semiautodata || !Array.isArray(window.semiautodata.messages)) return;
const sameMsgs = window.semiautodata.messages.filter(m => Number(m.id) === Number(gid));
for (let m of sameMsgs) {
applyLang(m.language, "", false);
}
}
selected_messages = [];
if (willSelect) {
// unselect other selected rows and clear their previews
$tbody_message.find("tr.table-active").each(function () {
if (this === e.currentTarget) return;
const $other = $(this);
const otherId = $other.data("msgid");
$other.removeClass("table-active");
clearGroupPreviews(otherId);
});
// select this row and apply its messages to previews
$row.addClass("table-active");
if (window.semiautodata && Array.isArray(window.semiautodata.messages)) {
const sameMsgs = window.semiautodata.messages.filter(m => Number(m.id) === Number(groupId));
for (let m of sameMsgs) {
applyLang(m.language, m.message_details, true);
selected_messages.push(m);
}
enable_disable_fields();
update_all_previews();
}
} else {
// deselect this row and clear its previews
$row.removeClass("table-active");
clearGroupPreviews(groupId);
}
// check if message_table already has a row with the same id
if (annIDSet.has(msg.id)) continue;
annIDSet.add(msg.id);
message_table.row.add({ id: msg.id, description: msg.description });
}
// redraw the message table
message_table.draw(true);
message_table.on('click', 'tbody tr', function () {
const $row = $(this);
let data = message_table.row(this).data();
const willSelect = !$row.hasClass("table-active");
selected_messages = [];
if (willSelect) {
// unselect other selected rows and clear their previews
message_table.$('tr.table-active').each(function () {
if (this === $row[0]) return;
const $other = $(this);
const otherData = message_table.row(this).data();
$other.removeClass("table-active");
clearGroupPreviews(otherData.id);
});
// select this row and apply its messages to previews
$row.addClass("table-active");
if (window.semiautodata && Array.isArray(window.semiautodata.messages)) {
const sameMsgs = window.semiautodata.messages.filter(m => Number(m.id) === Number(data.id));
for (let m of sameMsgs) {
applyLang(m.language, m.message_details, true);
selected_messages.push(m);
}
enable_disable_fields();
update_all_previews();
}
} else {
$row.removeClass("table-active");
clearGroupPreviews(data.id);
}
}
});
}
if (window.semiautodata.broadcastzones !== null && Array.isArray(window.semiautodata.broadcastzones) && window.semiautodata.broadcastzones.length > 0) {
for (let zone of window.semiautodata.broadcastzones) {
{
const uid = 'bz_' + Math.random().toString(36).slice(2, 9);
let $tr = $("<tr></tr>");
let $checkbox = $("<input>").attr({ type: "checkbox", id: uid, value: zone });
let $label = $("<label></label>").attr("for", uid).text(zone);
let $td = $("<td></td>").append($checkbox).append(" ").append($label);
$tr.append($td);
$tbody_broadcastzones.append($tr);
}
}
$select_broadcastzones.select2({
data: window.semiautodata.broadcastzones,
placeholder: "Select broadcast zones",
width: '100%',
multiple: true
});
// $('#select_broadcastzones').on('change', function () {
// console.log("Selected broadcast zones:", $select_broadcastzones.val());
// });
$select_broadcastzones.val(null).trigger("change");
}
if (window.semiautodata.airlines !== null && Array.isArray(window.semiautodata.airlines) && window.semiautodata.airlines.length > 0) {
const airlinedata = window.semiautodata.airlines.map(a => ({ id: a.tag, text: a.value + " [" + a.tag + "]" }));
@@ -927,19 +872,16 @@ function fill_items() {
}
function send_broadcast_message() {
console.log("send_broadcast_message");
if ($("#send_broadcast").hasClass("btn-disable")) {
alert("Cannot send broadcast message. Please complete all required fields.");
return;
}
// get all checked broadcast zones from tbody_broadcastzones
// get all checked broadcast zones from $select_broadcastzones
let selected_zones = [];
$tbody_broadcastzones.find("input[type='checkbox']").each(function () {
const $checkbox = $(this);
if ($checkbox.is(":checked")) {
selected_zones.push($checkbox.val());
}
$select_broadcastzones.val().forEach(zone => {
selected_zones.push(zone);
});
console.log("Selected zones:", selected_zones);
if (selected_zones.length === 0) {
alert("Please select at least one broadcast zone.");
@@ -967,7 +909,7 @@ function send_broadcast_message() {
let tags = [];
let msg = selected_messages[0];
tags.push("ANN_ID:"+msg.id);
tags.push("ANN_ID:" + msg.id);
if (msg.message_details.indexOf('[CITY]') !== -1) {
let cities = $select_city.val();
if (Array.isArray(cities) && cities.length > 0) {
@@ -1011,7 +953,6 @@ function send_broadcast_message() {
tags: tags.join(" "),
broadcastzones: selected_zones.join(";")
}
console.log("Payload:", payload);
fetchAPI("SemiAuto", "POST", {}, payload, (data) => {
alert("Broadcast message sent successfully.");
}, (error) => {
@@ -1023,7 +964,7 @@ function send_broadcast_message() {
// App start here
$(document).ready(function () {
console.log("javascript loaded");
console.log("index loaded");
$preview_indonesia = $("#message_indonesia");
$preview_english = $("#message_english");
$preview_chinese = $("#message_chinese");
@@ -1037,9 +978,18 @@ $(document).ready(function () {
$enable_arabic = $("#checkbox_arabic");
$enable_local = $("#checkbox_local");
$tbody_message = $("#tbody_message");
$tbody_broadcastzones = $("#tbody_broadcastzones");
message_table = new DataTable('#message_table', {
columns: [
{ title: 'ID', data: 'id' },
{ title: 'Description', data: 'description' }
],
data: [],
pageLength: 25
})
$select_broadcastzones = $("#select_broadcastzones");
$select_airline = $("#select_airline");
$select_city = $("#select_city");
$select_places = $("#select_places");
$select_shalat = $("#select_shalat");
$select_reason = $("#select_reason");
@@ -1070,5 +1020,15 @@ $(document).ready(function () {
send_broadcast_message();
});
$('#selectallzones').off("click").on("click", function () {
$select_broadcastzones.find('option').prop('selected', true);
$select_broadcastzones.trigger('change');
});
$('#clearallzones').off("click").on("click", function () {
$select_broadcastzones.find('option').prop('selected', false);
$select_broadcastzones.trigger('change');
});
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,67 @@
tblog = null;
function load_log_data(datevalue){
// check if format yyyy-mm-dd, convert to dd-mm-yyyy
if (/^\d{4}-\d{2}-\d{2}$/.test(datevalue)) {
const parts = datevalue.split("-");
if (parts.length === 3) {
datevalue = parts[2] + "-" + parts[1] + "-" + parts[0];
}
}
console.log("Loading log data for date:", datevalue);
tblog.clear().draw();
fetchAPI('Log/'+datevalue,'GET',{}, null,function(data){
//console.log("Log data fetched:", data);
if (data && Array.isArray(data) && data.length > 0){
data.forEach(function(item, index){
tblog.row.add({
index: index + 1,
date: item.datenya,
time: item.timenya,
source: item.machine,
message: item.description
})
});
tblog.draw();
}
},function(error){
console.error("Error fetching log data:", error);
});
}
$(document).ready(function () {
console.log("Log.js is loaded");
tblog = new DataTable('#logtable',{
columns: [
{title: 'Index', data: 'index'},
{title: 'Date', data: 'date'},
{title: 'Time', data: 'time'},
{title: 'Source', data: 'source'},
{title: 'Message', data: 'message'}
],
pageLength: 25,
data: [],
buttons: ['excel', 'pdf', 'print'],
layout: {
topStart: 'buttons',
topEnd: 'search'
}
})
$('#reload_log').on('click', function(){
// get value from date_log
let datevalue = $('#date_log').val();
load_log_data(datevalue);
});
let today = new Date().toISOString().split('T')[0];
$('#date_log').val(today);
load_log_data(today);
$('#date_log').on('change', function(){
let datevalue = $(this).val();
load_log_data(datevalue);
});
});