92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
type WorkbookCellValue = boolean | Date | number | string | null | undefined;
|
|
|
|
export type ResourceMonthReportExplainability = {
|
|
entity: "resource_month";
|
|
periodMonth: string | null;
|
|
locationContextColumns: string[];
|
|
holidayMetricColumns: string[];
|
|
absenceMetricColumns: string[];
|
|
capacityMetricColumns: string[];
|
|
chargeabilityMetricColumns: string[];
|
|
missingRecommendedColumns: string[];
|
|
notes: string[];
|
|
};
|
|
|
|
export type ReportExplainability = ResourceMonthReportExplainability;
|
|
|
|
export type ReportExportSheet = {
|
|
name: string;
|
|
rows: WorkbookCellValue[][];
|
|
};
|
|
|
|
type BuildReportWorkbookSheetsInput = {
|
|
columns: string[];
|
|
rows: Record<string, unknown>[];
|
|
groups: Array<{ key: string; label: string; rowCount: number; startIndex: number }>;
|
|
groupBy?: string;
|
|
explainability?: ReportExplainability;
|
|
resolveColumnLabel: (column: string) => string;
|
|
};
|
|
|
|
export function buildResourceMonthExplainabilitySheetRows(
|
|
explainability: ReportExplainability,
|
|
resolveColumnLabel: (column: string) => string,
|
|
): WorkbookCellValue[][] {
|
|
const mapLabels = (columns: string[]) => (
|
|
columns.length > 0 ? columns.map(resolveColumnLabel) : ["none"]
|
|
);
|
|
|
|
return [
|
|
["Resource Month Explainability"],
|
|
["Period Month", explainability.periodMonth ?? "current month"],
|
|
["Location Context Columns", ...mapLabels(explainability.locationContextColumns)],
|
|
["Holiday Metric Columns", ...mapLabels(explainability.holidayMetricColumns)],
|
|
["Absence Metric Columns", ...mapLabels(explainability.absenceMetricColumns)],
|
|
["Capacity Metric Columns", ...mapLabels(explainability.capacityMetricColumns)],
|
|
["Chargeability Metric Columns", ...mapLabels(explainability.chargeabilityMetricColumns)],
|
|
["Missing Recommended Columns", ...mapLabels(explainability.missingRecommendedColumns)],
|
|
[],
|
|
["Notes"],
|
|
...explainability.notes.map((note) => [note]),
|
|
];
|
|
}
|
|
|
|
export function buildReportWorkbookSheets(
|
|
input: BuildReportWorkbookSheetsInput,
|
|
): ReportExportSheet[] {
|
|
const headerRow = input.columns.map(input.resolveColumnLabel);
|
|
const groupStartByIndex = new Map(
|
|
input.groups.map((group) => [group.startIndex, group] as const),
|
|
);
|
|
const groupByLabel = input.groupBy ? input.resolveColumnLabel(input.groupBy) : null;
|
|
|
|
const reportRows: WorkbookCellValue[][] = [headerRow];
|
|
input.rows.forEach((row, index) => {
|
|
const group = groupStartByIndex.get(index);
|
|
if (group && groupByLabel) {
|
|
reportRows.push([
|
|
`${groupByLabel}: ${group.label} (${group.rowCount})`,
|
|
...Array.from({ length: Math.max(0, input.columns.length - 1) }, () => ""),
|
|
]);
|
|
}
|
|
|
|
reportRows.push(input.columns.map((column) => {
|
|
const value = row[column];
|
|
if (value === undefined) {
|
|
return "";
|
|
}
|
|
return value as WorkbookCellValue;
|
|
}));
|
|
});
|
|
|
|
const sheets: ReportExportSheet[] = [{ name: "Report", rows: reportRows }];
|
|
if (input.explainability?.entity === "resource_month") {
|
|
sheets.push({
|
|
name: "Explainability",
|
|
rows: buildResourceMonthExplainabilitySheetRows(input.explainability, input.resolveColumnLabel),
|
|
});
|
|
}
|
|
|
|
return sheets;
|
|
}
|