31 lines
1.5 KiB
TypeScript
31 lines
1.5 KiB
TypeScript
import type { Spec } from "@json-render/core";
|
|
import { formatDisplayText, withChartDisplayTimes } from "@/shared/utils/date-time-text";
|
|
|
|
const textFields = new Set(["title", "description", "summary", "text", "label", "value", "source", "observed_at"]);
|
|
const utcLabel = /UTC(?:\s*\+?0(?::00)?)?(?![\w+:-])/;
|
|
const timeAxis = (value: string) => formatDisplayText(value).replace(/UTC(?:\s*\+?0(?::00)?)?(?![\w+:-])/g, "UTC+8");
|
|
const bareTime = /^(?:\d{4}-\d{2}-\d{2}[T ])?\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?$/;
|
|
|
|
function displayCell(value: string, heading: string): string {
|
|
return formatDisplayText(utcLabel.test(heading) && bareTime.test(value) ? `${value} UTC` : value);
|
|
}
|
|
|
|
/** Render display fields in UTC8 while keeping the stored spec and identifiers intact. */
|
|
export function withAnswerDisplayTimes(spec: Spec): Spec {
|
|
return { ...spec, elements: Object.fromEntries(Object.entries(spec.elements).map(([id, node]) => {
|
|
const props = { ...node.props };
|
|
for (const key of textFields) {
|
|
if (typeof props[key] === "string") props[key] = formatDisplayText(props[key]);
|
|
}
|
|
if (node.type === "Table") {
|
|
const columns = props.columns as string[];
|
|
props.rows = (props.rows as string[][]).map((row) => row.map((cell, index) => displayCell(cell, columns[index] ?? "")));
|
|
props.columns = columns.map(timeAxis);
|
|
}
|
|
if (node.type === "Chart") {
|
|
Object.assign(props, withChartDisplayTimes(props as Parameters<typeof withChartDisplayTimes>[0]));
|
|
}
|
|
return [id, { ...node, props }];
|
|
})) };
|
|
}
|