mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 11:21:18 +00:00
ReportDefinition gets an optional chart {type: line|bar, x, y[]} field —
plots the same rows the table gets, no separate query. Frontend adds a
table/chart toggle (defaults to table) using the existing recharts
dependency, no new package.
Chart view fetches up to 100 rows (the API's page-size ceiling) instead
of the table's current page, so it doesn't silently plot a fraction of
the filtered set; shows a truncation note past that cap.
Wired onto 5 reports as proof: wagon-fleet-status, locomotive-fleet-
status, booking-status-breakdown, revenue-summary (bar), and
global-logistics-wagons (line). Everything else stays table-only —
charting is opt-in per report, not a default.
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { REPORT_KEYS } from '../../seed/freight-permissions.registry';
|
|
import { REPORTS, getReport } from './report.registry';
|
|
|
|
describe('REPORTS', () => {
|
|
it('has exactly one definition per seeded REPORT_KEYS entry', () => {
|
|
const defKeys = REPORTS.map((r) => r.key).sort();
|
|
expect(defKeys).toEqual([...REPORT_KEYS].sort());
|
|
});
|
|
|
|
it('has no duplicate keys', () => {
|
|
const keys = REPORTS.map((r) => r.key);
|
|
expect(new Set(keys).size).toBe(keys.length);
|
|
});
|
|
|
|
it('resolves every key via getReport', () => {
|
|
for (const key of REPORT_KEYS) {
|
|
expect(getReport(key)?.key).toBe(key);
|
|
}
|
|
});
|
|
|
|
it('every sortable column and defaultSort point at a real column key', () => {
|
|
for (const def of REPORTS) {
|
|
const columnKeys = new Set(def.columns.map((c) => c.key));
|
|
if (def.defaultSort) {
|
|
expect(columnKeys.has(def.defaultSort.key)).toBe(true);
|
|
}
|
|
// Every column marked sortable must have a resolvable key (itself, since
|
|
// the runner falls back to `key` when `sortExpr` is absent).
|
|
for (const col of def.columns.filter((c) => c.sortable)) {
|
|
expect(col.key.length).toBeGreaterThan(0);
|
|
}
|
|
}
|
|
});
|
|
|
|
it('idKey, when declared, is not also listed as a user-facing filter', () => {
|
|
for (const def of REPORTS) {
|
|
if (!def.idKey) continue;
|
|
expect(def.filters.some((f) => f.key === def.idKey!.key)).toBe(false);
|
|
}
|
|
});
|
|
|
|
it('chart.x and chart.y, when declared, point at real column keys', () => {
|
|
for (const def of REPORTS) {
|
|
if (!def.chart) continue;
|
|
const columnKeys = new Set(def.columns.map((c) => c.key));
|
|
expect(columnKeys.has(def.chart.x)).toBe(true);
|
|
for (const y of def.chart.y) {
|
|
expect(columnKeys.has(y)).toBe(true);
|
|
}
|
|
}
|
|
});
|
|
});
|