2026-05-26 21:12:04 -05:00

344 lines
10 KiB
JavaScript

const dispatcherFormatters = window.cadDispatcherFormatters || {};
const dispatcherModals = window.cadDispatcherModals || {};
const dispatcherRender = window.cadDispatcherRender || {};
const defaultTaskTypes = [
{ value: "attack", label: "Attack" },
{ value: "defend", label: "Defend" },
{ value: "delivery", label: "Delivery" },
{ value: "destroy", label: "Destroy" },
{ value: "defuse", label: "Defuse" },
{ value: "hostage", label: "Hostage" },
{ value: "hvtkill", label: "Kill HVT" },
{ value: "hvtcapture", label: "Capture HVT" },
];
window.cadDispatcher = {
contracts: [],
requests: [],
groups: [],
activity: [],
session: {},
editingGroupId: "",
viewingRequestId: "",
convertingRequestId: "",
taskTypes: defaultTaskTypes.slice(),
statuses: [
"available",
"en_route",
"on_task",
"holding",
"danger",
"unavailable",
],
roles: ["infantry", "recon", "armor", "air", "logistics", "support"],
...dispatcherFormatters,
...dispatcherModals,
...dispatcherRender,
init() {
document
.getElementById("dispatcherRequestTaskBtn")
.addEventListener("click", () => {
this.openTaskModal();
});
document
.getElementById("dispatcherCreateOrderBtn")
.addEventListener("click", () => {
this.openOrderModal();
});
document
.getElementById("dispatcherGroupModalCloseBtn")
.addEventListener("click", () => {
this.closeGroupModal();
});
document
.getElementById("dispatcherGroupModalSaveBtn")
.addEventListener("click", () => {
this.applyGroupUpdates();
});
document
.querySelector("#dispatcherGroupModal .dispatch-modal-backdrop")
.addEventListener("click", () => {
this.closeGroupModal();
});
document
.getElementById("dispatcherOrderModalCloseBtn")
.addEventListener("click", () => {
this.closeOrderModal();
});
document
.getElementById("dispatcherOrderModalSaveBtn")
.addEventListener("click", () => {
this.createDispatchOrder();
});
document
.querySelector("#dispatcherOrderModal .dispatch-modal-backdrop")
.addEventListener("click", () => {
this.closeOrderModal();
});
document
.getElementById("dispatcherTaskModalCloseBtn")
.addEventListener("click", () => {
this.closeTaskModal();
});
document
.getElementById("dispatcherTaskModalSaveBtn")
.addEventListener("click", () => {
this.requestGeneratedTask();
});
document
.querySelector("#dispatcherTaskModal .dispatch-modal-backdrop")
.addEventListener("click", () => {
this.closeTaskModal();
});
document
.getElementById("dispatcherRequestModalCloseBtn")
.addEventListener("click", () => {
this.closeRequestModal();
});
document
.getElementById("dispatcherRequestModalDoneBtn")
.addEventListener("click", () => {
this.closeRequestModal();
});
document
.getElementById("dispatcherRequestConvertBtn")
.addEventListener("click", () => {
this.convertViewedRequestToOrder();
});
document
.querySelector("#dispatcherRequestModal .dispatch-modal-backdrop")
.addEventListener("click", () => {
this.closeRequestModal();
});
window.mapUI.sendEvent("cad::dispatcher::ready", {});
},
receiveHydrate(payload) {
this.contracts = Array.isArray(payload.contracts)
? payload.contracts
: [];
this.requests = Array.isArray(payload.requests) ? payload.requests : [];
this.groups = Array.isArray(payload.groups) ? payload.groups : [];
this.activity = Array.isArray(payload.activity) ? payload.activity : [];
if (Array.isArray(payload.generatedTaskTypes)) {
this.taskTypes = payload.generatedTaskTypes
.map((entry) => ({
value: String(entry?.value || "").trim(),
label: String(entry?.label || entry?.value || "").trim(),
}))
.filter((entry) => entry.value);
}
this.session =
payload.session && typeof payload.session === "object"
? payload.session
: {};
const statusEl = document.getElementById("dispatcherStatusMessage");
if (
statusEl &&
(!statusEl.dataset.type || statusEl.dataset.type === "info")
) {
this.setStatus("", "");
}
this.syncOpenModal();
this.syncOrderModal();
this.syncRequestModal();
this.render();
},
setStatus(message, type) {
const statusEl = document.getElementById("dispatcherStatusMessage");
if (!statusEl) {
return;
}
statusEl.textContent = message || "";
statusEl.dataset.type = type || "";
},
createDispatchOrder() {
const assigneeGroupID = document.getElementById(
"dispatcherOrderAssigneeSelect",
).value;
const targetGroupID = document.getElementById(
"dispatcherOrderTargetSelect",
).value;
const priority = document.getElementById(
"dispatcherOrderPrioritySelect",
).value;
const note = document.getElementById("dispatcherOrderNoteInput").value;
const sourceRequest = this.convertingRequestId
? this.requests.find(
(entry) =>
(entry.requestId || "") === this.convertingRequestId,
) || null
: null;
if (!assigneeGroupID || !targetGroupID) {
this.setStatus(
"Select both an assignee and a target group.",
"error",
);
return;
}
if (assigneeGroupID === targetGroupID) {
this.setStatus(
"Assignee and target groups must be different.",
"error",
);
return;
}
this.setStatus(
this.convertingRequestId
? "Creating dispatch order from request..."
: "Creating dispatch order...",
"info",
);
window.mapUI.sendEvent("cad::dispatchOrder::create", {
assigneeGroupID: assigneeGroupID,
targetGroupID: targetGroupID,
note: note.trim(),
priority: priority,
request: sourceRequest
? {
requestId: sourceRequest.requestId || "",
type: sourceRequest.type || "",
title: sourceRequest.title || "",
summary: sourceRequest.summary || "",
fields:
sourceRequest.fields &&
typeof sourceRequest.fields === "object"
? sourceRequest.fields
: {},
}
: {},
});
this.closeOrderModal();
},
requestGeneratedTask() {
if (!this.taskTypes.length) {
this.setStatus(
"Generated task requests are disabled by server settings.",
"error",
);
return;
}
const taskType = document.getElementById(
"dispatcherTaskTypeSelect",
).value;
if (!taskType) {
this.setStatus(
"Select a task type before requesting a task.",
"error",
);
return;
}
this.setStatus("Requesting generated task...", "info");
window.mapUI.sendEvent("cad::generatedTask::request", {
taskType: taskType,
});
this.closeTaskModal();
},
assignTask(taskID) {
const selector = document.getElementById(
`dispatcher-assign-group-${taskID}`,
);
if (!selector || !selector.value) {
this.setStatus(
"Select a group before assigning a contract.",
"error",
);
return;
}
this.setStatus("Submitting assignment...", "info");
window.mapUI.sendEvent("cad::tasks::assign", {
taskID: taskID,
groupID: selector.value,
note: "",
});
},
applyGroupUpdates() {
if (!this.editingGroupId) {
return;
}
const group = this.groups.find(
(entry) => entry.groupId === this.editingGroupId,
);
if (!group) {
this.closeGroupModal();
return;
}
const roleValue = document.getElementById(
"dispatcherModalRoleSelect",
).value;
const statusValue = document.getElementById(
"dispatcherModalStatusSelect",
).value;
const nextRole =
roleValue && roleValue !== (group.role || "") ? roleValue : "";
const nextStatus =
statusValue && statusValue !== (group.status || "")
? statusValue
: "";
const hasChanges = nextRole || nextStatus;
if (!hasChanges) {
this.setStatus("No group changes to save.", "info");
this.closeGroupModal();
return;
}
this.setStatus("Updating group profile...", "info");
window.mapUI.sendEvent("cad::groups::profile", {
groupID: this.editingGroupId,
role: nextRole,
status: nextStatus,
});
this.closeGroupModal();
},
closeDispatchOrder(taskID) {
if (!taskID) {
return;
}
this.setStatus("Closing dispatch order...", "info");
window.mapUI.sendEvent("cad::dispatchOrder::close", {
taskID: taskID,
});
},
closeSupportRequest(requestID) {
if (!requestID) {
return;
}
this.setStatus("Closing support request...", "info");
window.mapUI.sendEvent("cad::supportRequest::close", {
requestID: requestID,
});
},
};
window.cadDispatcher.init();