Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 48 additions & 24 deletions src/pages/tasking/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { CreateRadioLogModalVM } from "./viewmodels/RadioLogModalVM.js";
import { SendSMSModalVM } from "./viewmodels/SMSTeamModalVM.js";
import { JobStatusConfirmModalVM } from "./viewmodels/JobStatusConfirmModalVM.js";
import { TrackableAssetsModalVM } from "./viewmodels/TrackableAssetsModalVM.js";
import IncidentImagesModalVM from "./viewmodels/IncidentImagesModalVM";

import { installAlerts } from './components/alerts.js';
import { LegendControl } from './components/legend.js';
Expand Down Expand Up @@ -198,6 +199,20 @@ function VM() {

self.jobStatusConfirmVM = new JobStatusConfirmModalVM(self);

self.incidentImagesVM = new IncidentImagesModalVM({
getToken,
apiHost,
userId: params.userId,
BeaconClient
});

self.openIncidentImages = function (job, e) {
if (e) { e.stopPropagation?.(); e.preventDefault?.(); }
if (!job || typeof job.id !== "function") return false;
self.incidentImagesVM.openForJob(job);
return false;
};

self.attachJobStatusConfirmModal = function (job, newStatus) {
const modalEl = document.getElementById("JobStatusConfirmModal");
const modal = new bootstrap.Modal(modalEl);
Expand Down Expand Up @@ -688,13 +703,16 @@ function VM() {
if (!teamJson || teamJson.Id == null) return null;

let team = self.teamsById.get(teamJson.Id);
if (team) {
if (team) { //existing team
//if the team is from tasking, ignore as dont want to overwrite with old data
if (source === 'tasking') {
return team;
}
const prevCallsign = team.callsign?.();
team.updateFromJson(teamJson);
self._refreshTeamTrackableAssets(team);
if (team.callsign?.() !== prevCallsign) { //only remap assets if the callsign changes
self._refreshTeamTrackableAssets(team);
}
return team;
}

Expand Down Expand Up @@ -972,14 +990,12 @@ function VM() {
}

let asset = self.assetsById.get(assetJson.properties.id);
if (asset) {
if (asset) { //existing asset - update values
asset.updateFromJson(assetJson);
self._attachAssetToMatchingTeams(asset);
return asset;
} else {
} else { //new asset - create, store, attach to teams
asset = new Asset(assetJson);
self.trackableAssets.push(asset);
self._attachAssetToMatchingTeams(asset);
self.assetsById.set(asset.id(), asset);
}
return asset;
Expand Down Expand Up @@ -1169,31 +1185,35 @@ function VM() {

// recompute one team's asset list :contentReference[oaicite:2]{index=2}
self._refreshTeamTrackableAssets = function (team) {
console.log("Refreshing trackable assets for team:", team?.callsign?.());
if (!team || typeof team.trackableAssets !== 'function') return;

const all = self.trackableAssets?.() || [];
const desired = _computeMatchedAssetsForTeam(team, all); // Set<Asset>
// Defer execution to avoid blocking UI thread
setTimeout(() => {
const all = self.trackableAssets?.() || [];
const desired = _computeMatchedAssetsForTeam(team, all); // Set<Asset>

// Remove no-longer-matching
(team.trackableAssets() || []).slice().forEach(a => {
if (!desired.has(a)) {
a?.matchingTeams?.remove?.(team);
team.trackableAssets.remove(a);
}
});
// Remove no-longer-matching
(team.trackableAssets() || []).slice().forEach(a => {
if (!desired.has(a)) {
a?.matchingTeams?.remove?.(team);
team.trackableAssets.remove(a);
}
});

// Add new matches
for (const a of desired) {
const has = (team.trackableAssets() || []).includes(a);
if (!has) {
team.trackableAssets.push(a);
a?.matchingTeams?.push?.(team);
// Add new matches
for (const a of desired) {
const has = (team.trackableAssets() || []).includes(a);
if (!has) {
team.trackableAssets.push(a);
a?.matchingTeams?.push?.(team);
}
}
}
}, 0);
};

// when a single asset changes/arrives, patch all teams that match :contentReference[oaicite:3]{index=3}
self._attachAssetToMatchingTeams = function (_asset) {
// redo matching assets after an asset update
self._attachAssetsToMatchingTeams = function () {
// For correctness (token consumption + exact-first), reconcile per-team against full asset set
(self.teams?.() || []).forEach(team => self._refreshTeamTrackableAssets(team));
};
Expand Down Expand Up @@ -1644,6 +1664,10 @@ function VM() {
// Remove from observable array and registry
self.trackableAssets.remove(asset);
self.assetsById.delete(id);

//Update Asset/Team mappings only once after all changes
self._attachAssetsToMatchingTeams();

});
myViewModel._markInitialFetchDone();
assetDataRefreshInterlock = false;
Expand Down
Loading