improvement: tasks feature UX fully overhauled.
This commit is contained in:
89
frontend/src/components/lab/taskListGrouping.ts
Normal file
89
frontend/src/components/lab/taskListGrouping.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import type { LabTaskListItem, TaskSortField } from '@/types/cases';
|
||||
|
||||
export type ProsthesisTaskGroup = {
|
||||
key: string;
|
||||
treatmentDetailId: string;
|
||||
prosthesisTypeCode: string;
|
||||
prosthesisTypeLabel: string;
|
||||
teeth: string[];
|
||||
tasks: LabTaskListItem[];
|
||||
};
|
||||
|
||||
export type CaseTaskGroup = {
|
||||
labCaseId: string;
|
||||
clinic: LabTaskListItem['clinic'];
|
||||
patient: LabTaskListItem['patient'];
|
||||
caseSentAt: string | null;
|
||||
isImportant: boolean;
|
||||
prosthesisGroups: ProsthesisTaskGroup[];
|
||||
};
|
||||
|
||||
export type TaskDisplayModel =
|
||||
| { mode: 'grouped'; cases: CaseTaskGroup[] }
|
||||
| { mode: 'flat'; tasks: LabTaskListItem[] };
|
||||
|
||||
function prosthesisGroupKey(task: LabTaskListItem): string {
|
||||
return `${task.treatmentDetailId}:${task.prosthesisTypeCode}`;
|
||||
}
|
||||
|
||||
export function groupTasksForDisplay(
|
||||
tasks: LabTaskListItem[],
|
||||
sortBy: TaskSortField,
|
||||
): TaskDisplayModel {
|
||||
if (sortBy !== 'date') {
|
||||
return { mode: 'flat', tasks };
|
||||
}
|
||||
|
||||
const cases: CaseTaskGroup[] = [];
|
||||
const caseIndex = new Map<string, number>();
|
||||
|
||||
for (const task of tasks) {
|
||||
let caseIdx = caseIndex.get(task.labCaseId);
|
||||
if (caseIdx === undefined) {
|
||||
caseIdx = cases.length;
|
||||
caseIndex.set(task.labCaseId, caseIdx);
|
||||
cases.push({
|
||||
labCaseId: task.labCaseId,
|
||||
clinic: task.clinic,
|
||||
patient: task.patient,
|
||||
caseSentAt: task.caseSentAt ?? null,
|
||||
isImportant: task.isImportant,
|
||||
prosthesisGroups: [],
|
||||
});
|
||||
}
|
||||
|
||||
const caseGroup = cases[caseIdx];
|
||||
const pgKey = prosthesisGroupKey(task);
|
||||
let prosthesisGroup = caseGroup.prosthesisGroups.find((g) => g.key === pgKey);
|
||||
if (!prosthesisGroup) {
|
||||
prosthesisGroup = {
|
||||
key: pgKey,
|
||||
treatmentDetailId: task.treatmentDetailId,
|
||||
prosthesisTypeCode: task.prosthesisTypeCode,
|
||||
prosthesisTypeLabel: task.prosthesisTypeLabel,
|
||||
teeth: task.teeth,
|
||||
tasks: [],
|
||||
};
|
||||
caseGroup.prosthesisGroups.push(prosthesisGroup);
|
||||
}
|
||||
|
||||
prosthesisGroup.tasks.push(task);
|
||||
}
|
||||
|
||||
return { mode: 'grouped', cases };
|
||||
}
|
||||
|
||||
export function countCaseTaskProgress(caseGroup: CaseTaskGroup): {
|
||||
completed: number;
|
||||
total: number;
|
||||
} {
|
||||
let completed = 0;
|
||||
let total = 0;
|
||||
for (const group of caseGroup.prosthesisGroups) {
|
||||
for (const task of group.tasks) {
|
||||
total += 1;
|
||||
if (task.status === 'COMPLETED') completed += 1;
|
||||
}
|
||||
}
|
||||
return { completed, total };
|
||||
}
|
||||
Reference in New Issue
Block a user