This commit is contained in:
gsinghpal
2026-03-09 15:21:22 -04:00
parent a3e85a23ef
commit acd3fc455e
243 changed files with 20459 additions and 4197 deletions

View File

@@ -180,9 +180,22 @@ const SOURCE_COLORS = {
mobility: "#198754",
};
/** Extract unique technicians from task data, sorted by name */
function extractTechnicians(tasksData) {
const map = {};
for (const t of tasksData) {
if (t.technician_id) {
const [id, name] = t.technician_id;
if (!map[id]) {
map[id] = { id, name, initials: initialsOf(name) };
}
}
}
return Object.values(map).sort((a, b) => a.name.localeCompare(b.name));
}
/** Group + sort tasks, returning { groupKey: { label, tasks[], count } } */
function groupTasks(tasksData, localInstanceId) {
// Sort by date ASC, time ASC
function groupTasks(tasksData, localInstanceId, visibleTechIds) {
const sorted = [...tasksData].sort((a, b) => {
const da = a.scheduled_date || "";
const db = b.scheduled_date || "";
@@ -190,6 +203,8 @@ function groupTasks(tasksData, localInstanceId) {
return (a.time_start || 0) - (b.time_start || 0);
});
const hasTechFilter = visibleTechIds && Object.keys(visibleTechIds).length > 0;
const groups = {};
const order = [GROUP_PENDING, GROUP_YESTERDAY, GROUP_TODAY, GROUP_TOMORROW, GROUP_THIS_WEEK, GROUP_LATER];
for (const key of order) {
@@ -205,12 +220,15 @@ function groupTasks(tasksData, localInstanceId) {
const dayCounters = {};
for (const task of sorted) {
const techId = task.technician_id ? task.technician_id[0] : 0;
if (hasTechFilter && !visibleTechIds[techId]) continue;
const g = classifyTask(task);
const dayKey = task.scheduled_date || "none";
dayCounters[dayKey] = (dayCounters[dayKey] || 0) + 1;
task._scheduleNum = dayCounters[dayKey];
task._group = g;
task._dayColor = DAY_COLORS[g] || "#6b7280"; // Pin colour by day
task._dayColor = DAY_COLORS[g] || "#6b7280";
task._statusColor = STATUS_COLORS[task.status] || "#6b7280";
task._statusLabel = STATUS_LABELS[task.status] || task.status || "";
task._statusIcon = STATUS_ICONS[task.status] || "fa-circle";
@@ -228,7 +246,6 @@ function groupTasks(tasksData, localInstanceId) {
groups[g].count++;
}
// Return only non-empty groups in order
return order.map((k) => groups[k]).filter((g) => g.count > 0);
}
@@ -259,12 +276,10 @@ export class FusionTaskMapController extends Component {
showRoute: true,
taskCount: 0,
techCount: 0,
// Sidebar
sidebarOpen: true,
groups: [], // [{key, label, tasks[], count}]
collapsedGroups: {}, // {groupKey: true}
activeTaskId: null, // Highlighted task
// Day filters for map pins (which groups show on map)
groups: [],
collapsedGroups: {},
activeTaskId: null,
visibleGroups: {
[GROUP_YESTERDAY]: false,
[GROUP_TODAY]: true,
@@ -272,6 +287,8 @@ export class FusionTaskMapController extends Component {
[GROUP_THIS_WEEK]: false,
[GROUP_LATER]: false,
},
allTechnicians: [],
visibleTechIds: {},
});
// Yesterday collapsed by default in sidebar list
@@ -339,9 +356,17 @@ export class FusionTaskMapController extends Component {
this.tasksData = result.tasks || [];
this.locationsData = result.locations || [];
this.techStartLocations = result.tech_start_locations || {};
this.state.taskCount = this.tasksData.length;
this.state.allTechnicians = extractTechnicians(this.tasksData);
this._rebuildGroups();
}
_rebuildGroups() {
this.state.groups = groupTasks(
this.tasksData, this.localInstanceId, this.state.visibleTechIds,
);
const filteredCount = this.state.groups.reduce((s, g) => s + g.count, 0);
this.state.taskCount = filteredCount;
this.state.techCount = this.locationsData.length;
this.state.groups = groupTasks(this.tasksData, this.localInstanceId);
}
async _loadAndRender() {
@@ -1008,6 +1033,28 @@ export class FusionTaskMapController extends Component {
this._renderMarkers();
}
// ── Technician filter ─────────────────────────────────────────────
toggleTechFilter(techId) {
if (this.state.visibleTechIds[techId]) {
delete this.state.visibleTechIds[techId];
} else {
this.state.visibleTechIds[techId] = true;
}
this._rebuildGroups();
this._renderMarkers();
}
isTechVisible(techId) {
const hasFilter = Object.keys(this.state.visibleTechIds).length > 0;
return !hasFilter || !!this.state.visibleTechIds[techId];
}
showAllTechs() {
this.state.visibleTechIds = {};
this._rebuildGroups();
this._renderMarkers();
}
// ── Top bar actions ─────────────────────────────────────────────
toggleTraffic() {
this.state.showTraffic = !this.state.showTraffic;