Rename offline status to unavailable

- Update CAD client UI and generated site assets
- Keep dispatcher and sidepanel status lists aligned with server defaults
- Refresh task, assignment, and group repository initialization
This commit is contained in:
Jacob Schmidt 2026-03-31 06:21:43 -05:00
parent 56b560edf2
commit 112488f82e
9 changed files with 40 additions and 12 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<!doctype html><html><head><meta charset="UTF-8"></head><body><div class="logo">FORGE OS</div><div class="header-main"><div class="title-block"><span class="title-kicker">Cad Systems</span> <strong class="title-main">FORGE Command & Dispatch</strong></div><div id="operatorStrip" class="operator-strip is-hidden"><div class="operator-info"><span class="operator-label">Current Group</span> <strong id="operatorGroupName">No Group</strong></div><div class="operator-info"><span class="operator-label">Location</span> <strong id="operatorLocation">Unavailable</strong></div><div id="operatorControls" class="operator-controls is-hidden"><select id="operatorRoleSelect" class="operator-select"><option value="infantry">infantry</option><option value="recon">recon</option><option value="armor">armor</option><option value="air">air</option><option value="logistics">logistics</option><option value="support">support</option></select> <button id="operatorRoleBtn" class="btn btn-operator" type="button">Update Role</button> <select id="operatorStatusSelect" class="operator-select"><option value="available">available</option><option value="en_route">en route</option><option value="on_task">on task</option><option value="holding">holding</option><option value="danger">danger</option><option value="refit">refit</option><option value="offline">offline</option></select> <button id="operatorStatusBtn" class="btn btn-operator" type="button">Update Status</button></div></div></div><div id="modeControls" class="mode-controls is-hidden"><span class="mode-text">Ops</span> <label class="mode-switch" for="modeToggle"><input id="modeToggle" type="checkbox"> <span class="mode-slider"></span></label> <span class="mode-text">Dispatch</span></div><div id="dispatchViewControls" class="dispatch-view-controls is-hidden"><button id="dispatchBoardBtn" class="btn btn-dispatch-view is-active" type="button">Board</button> <button id="dispatchMapBtn" class="btn btn-dispatch-view" type="button">Map</button></div><div class="controls"><button id="dispatchRefreshBtn" class="btn btn-icon btn-refresh" type="button" aria-label="Refresh board" title="Refresh board"></button> <button id="btnClose" class="btn btn-icon btn-close">X</button></div><script>window.MapLoader={loadCSS:e=>A3API.RequestFile(e).then(e=>{const o=document.createElement("style");o.textContent=e,document.head.appendChild(o)}),loadJS(path){return A3API.RequestFile(path).then(js=>{eval(js)})},loadAll(e){return e.reduce((e,o)=>e.then(()=>o.endsWith(".css")?this.loadCSS(o):o.endsWith(".js")?this.loadJS(o):Promise.resolve()),Promise.resolve())}},MapLoader.loadAll(["forge\\forge_client\\addons\\cad\\ui\\_site\\cad-common.css","forge\\forge_client\\addons\\cad\\ui\\_site\\cad-topbar.css","forge\\forge_client\\addons\\cad\\ui\\_site\\cad-shared.js","forge\\forge_client\\addons\\cad\\ui\\_site\\cad-topbar.js"]).catch(e=>console.error("[TOPBAR] Load error:",e))</script></body></html>
<!doctype html><html><head><meta charset="UTF-8"></head><body><div class="logo">FORGE OS</div><div class="header-main"><div class="title-block"><span class="title-kicker">Cad Systems</span> <strong class="title-main">FORGE Command & Dispatch</strong></div><div id="operatorStrip" class="operator-strip is-hidden"><div class="operator-info"><span class="operator-label">Current Group</span> <strong id="operatorGroupName">No Group</strong></div><div class="operator-info"><span class="operator-label">Location</span> <strong id="operatorLocation">Unavailable</strong></div><div id="operatorControls" class="operator-controls is-hidden"><select id="operatorRoleSelect" class="operator-select"><option value="infantry">infantry</option><option value="recon">recon</option><option value="armor">armor</option><option value="air">air</option><option value="logistics">logistics</option><option value="support">support</option></select> <button id="operatorRoleBtn" class="btn btn-operator" type="button">Update Role</button> <select id="operatorStatusSelect" class="operator-select"><option value="available">available</option><option value="en_route">en route</option><option value="on_task">on task</option><option value="holding">holding</option><option value="danger">danger</option><option value="unavailable">unavailable</option></select> <button id="operatorStatusBtn" class="btn btn-operator" type="button">Update Status</button></div></div></div><div id="modeControls" class="mode-controls is-hidden"><span class="mode-text">Ops</span> <label class="mode-switch" for="modeToggle"><input id="modeToggle" type="checkbox"> <span class="mode-slider"></span></label> <span class="mode-text">Dispatch</span></div><div id="dispatchViewControls" class="dispatch-view-controls is-hidden"><button id="dispatchBoardBtn" class="btn btn-dispatch-view is-active" type="button">Board</button> <button id="dispatchMapBtn" class="btn btn-dispatch-view" type="button">Map</button></div><div class="controls"><button id="dispatchRefreshBtn" class="btn btn-icon btn-refresh" type="button" aria-label="Refresh board" title="Refresh board"></button> <button id="btnClose" class="btn btn-icon btn-close">X</button></div><script>window.MapLoader={loadCSS:e=>A3API.RequestFile(e).then(e=>{const o=document.createElement("style");o.textContent=e,document.head.appendChild(o)}),loadJS(path){return A3API.RequestFile(path).then(js=>{eval(js)})},loadAll(e){return e.reduce((e,o)=>e.then(()=>o.endsWith(".css")?this.loadCSS(o):o.endsWith(".js")?this.loadJS(o):Promise.resolve()),Promise.resolve())}},MapLoader.loadAll(["forge\\forge_client\\addons\\cad\\ui\\_site\\cad-common.css","forge\\forge_client\\addons\\cad\\ui\\_site\\cad-topbar.css","forge\\forge_client\\addons\\cad\\ui\\_site\\cad-shared.js","forge\\forge_client\\addons\\cad\\ui\\_site\\cad-topbar.js"]).catch(e=>console.error("[TOPBAR] Load error:",e))</script></body></html>

View File

@ -10,8 +10,7 @@ window.cadDispatcher = {
"on_task",
"holding",
"danger",
"refit",
"offline",
"unavailable",
],
roles: ["infantry", "recon", "armor", "air", "logistics", "support"],
init() {

View File

@ -12,8 +12,7 @@ window.cadTasks = {
"on_task",
"holding",
"danger",
"refit",
"offline",
"unavailable",
],
roles: ["infantry", "recon", "armor", "air", "logistics", "support"],
init() {

View File

@ -41,8 +41,7 @@
<option value="on_task">on task</option>
<option value="holding">holding</option>
<option value="danger">danger</option>
<option value="refit">refit</option>
<option value="offline">offline</option>
<option value="unavailable">unavailable</option>
</select>
<button
id="operatorStatusBtn"

View File

@ -105,6 +105,17 @@ GVAR(AssignmentRepositoryBaseClass) = compileFinal createHashMapFromArray [
_result
};
private _assignmentRegistry = _self getOrDefault ["assignmentRegistry", createHashMap];
private _existingAssignment = +(_assignmentRegistry getOrDefault [_taskID, createHashMap]);
if (
_existingAssignment isNotEqualTo createHashMap
&& { (_existingAssignment getOrDefault ["state", ""]) in ["assigned", "acknowledged"] }
) exitWith {
_result set ["message", "Task is already assigned and must be declined or completed before reassignment."];
_result set ["assignment", _existingAssignment];
_result
};
private _groupRepository = _self getOrDefault ["groupRepository", createHashMap];
private _groupRecord = _groupRepository call ["getGroupRecord", [_groupID]];
if (_groupRecord isEqualTo createHashMap) exitWith {
@ -119,7 +130,6 @@ GVAR(AssignmentRepositoryBaseClass) = compileFinal createHashMapFromArray [
};
private _requesterPlayer = [_requesterUid] call EFUNC(common,getPlayer);
private _assignmentRegistry = _self getOrDefault ["assignmentRegistry", createHashMap];
private _assignment = createHashMapFromArray [
["taskId", _taskID],
["groupId", _groupID],
@ -221,6 +231,7 @@ GVAR(AssignmentRepositoryBaseClass) = compileFinal createHashMapFromArray [
_assignment set ["state", "declined"];
_assignment set ["declinedAt", serverTime];
EGVAR(task,TaskStore) call ["releaseTaskOwnership", [_taskID]];
_assignmentRegistry deleteAt _taskID;
_self set ["assignmentRegistry", _assignmentRegistry];

View File

@ -32,8 +32,7 @@ GVAR(GroupRepositoryBaseClass) = compileFinal createHashMapFromArray [
"on_task",
"holding",
"danger",
"refit",
"offline"
"unavailable"
]];
_self set ["validRoles", [
"infantry",

View File

@ -99,6 +99,27 @@ GVAR(TaskStore) = createHashMapObject [[
_result set ["orgID", _orgID];
_result
}],
["releaseTaskOwnership", compileFinal {
params [["_taskID", "", [""]]];
if (_taskID isEqualTo "") exitWith { false };
private _taskOwnershipRegistry = _self getOrDefault ["taskOwnershipRegistry", createHashMap];
_taskOwnershipRegistry deleteAt _taskID;
_self set ["taskOwnershipRegistry", _taskOwnershipRegistry];
private _taskCatalogRegistry = _self getOrDefault ["taskCatalogRegistry", createHashMap];
private _catalogEntry = +(_taskCatalogRegistry getOrDefault [_taskID, createHashMap]);
if (_catalogEntry isNotEqualTo createHashMap) then {
_catalogEntry set ["requesterUid", ""];
_catalogEntry set ["orgID", "default"];
_catalogEntry set ["accepted", false];
_taskCatalogRegistry set [_taskID, _catalogEntry];
_self set ["taskCatalogRegistry", _taskCatalogRegistry];
};
true
}],
["registerTaskCatalogEntry", compileFinal {
params [["_taskID", "", [""]], ["_entry", createHashMap, [createHashMap]]];