feat(export): dimension primitives, date members, status index
This commit is contained in:
@@ -54,6 +54,54 @@ export function listExportableParams(dailyTemplate, statuses) {
|
||||
return params;
|
||||
}
|
||||
|
||||
export const EXPORT_DIMENSIONS = [
|
||||
{ dim: 'date', label: 'Date' },
|
||||
{ dim: 'subject', label: 'Subject' },
|
||||
{ dim: 'parameter', label: 'Parameter' },
|
||||
];
|
||||
|
||||
export function dimLabel(dim) {
|
||||
return EXPORT_DIMENSIONS.find((d) => d.dim === dim)?.label ?? '';
|
||||
}
|
||||
|
||||
export function otherDimension(rowDim, colDim) {
|
||||
return EXPORT_DIMENSIONS.map((d) => d.dim).find((d) => d !== rowDim && d !== colDim) ?? null;
|
||||
}
|
||||
|
||||
// Resolve a subject's group value for a given group field id.
|
||||
// null -> no grouping (field is falsy or '__none__')
|
||||
// '—' -> grouping is on but this subject has no value
|
||||
export function subjectGroupValue(animal, groupField) {
|
||||
if (!groupField || groupField === '__none__') return null;
|
||||
if (groupField === '__name__') return animal?.animal_name ?? '—';
|
||||
if (groupField === '__id__') return animal?.animal_id_string ?? '—';
|
||||
const v = animal?.subject_info?.[groupField];
|
||||
return v === null || v === undefined || v === '' ? '—' : v;
|
||||
}
|
||||
|
||||
export function listDateMembers(statuses) {
|
||||
const keys = new Set();
|
||||
for (const s of statuses ?? []) {
|
||||
if (s?.date) keys.add(dateKey(s.date));
|
||||
}
|
||||
return [...keys].sort().map((k) => ({ id: k, label: k, dateKey: k }));
|
||||
}
|
||||
|
||||
// dateKey -> Map(animalId -> status); first status per (date, animal) wins,
|
||||
// scanning in date order (matches the legacy buildMatrix tie-break).
|
||||
export function buildStatusIndex(statuses) {
|
||||
const index = new Map();
|
||||
const ordered = [...(statuses ?? [])].sort((a, b) => dateKey(a?.date).localeCompare(dateKey(b?.date)));
|
||||
for (const s of ordered) {
|
||||
if (!s?.date || s.animal_id === null || s.animal_id === undefined) continue;
|
||||
const dk = dateKey(s.date);
|
||||
if (!index.has(dk)) index.set(dk, new Map());
|
||||
const byAnimal = index.get(dk);
|
||||
if (!byAnimal.has(s.animal_id)) byAnimal.set(s.animal_id, s);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
// A cell has a value unless it is null, undefined, or the empty string.
|
||||
// (0 and false are real values.)
|
||||
function hasValue(v) {
|
||||
|
||||
Reference in New Issue
Block a user