feat : update
CI / Verify (push) Successful in 1m6s
CI / Build immutable images and deploy (push) Successful in 2m49s

This commit is contained in:
2026-09-05 18:39:03 +07:00 Unverified
parent 5aa0ae80c1
commit 2429b9d319
9 changed files with 129 additions and 21 deletions
+38 -3
View File
@@ -12,6 +12,7 @@ export const extraSheetSchema = z.strictObject({
rows: z.array(z.strictObject({
id: extraSheetId,
cells: z.record(z.string(), z.string().max(10_000)),
backgrounds: z.record(z.string(), z.string().regex(/^#[0-9A-Fa-f]{6}$/)).default({}),
})).min(1),
}).superRefine((sheet, context) => {
const columnIds = new Set(sheet.columns.map((column) => column.id));
@@ -27,7 +28,7 @@ export const extraSheetSchema = z.strictObject({
context.addIssue({ code: "custom", path: ["rows"], message: "รหัสแถวต้องไม่ซ้ำกัน" });
}
sheet.rows.forEach((row, rowIndex) => {
Object.keys(row.cells).forEach((columnId) => {
[...Object.keys(row.cells), ...Object.keys(row.backgrounds)].forEach((columnId) => {
if (!columnIds.has(columnId)) {
context.addIssue({
code: "custom",
@@ -41,8 +42,9 @@ export const extraSheetSchema = z.strictObject({
export type ExtraSheet = z.output<typeof extraSheetSchema>;
export type ExtraSheetCell = { value: string };
export type ExtraSheetCell = { value: string; backgroundColor?: string };
export type ExtraSheetMatrix = Array<Array<ExtraSheetCell | undefined>>;
type SheetPoint = { row: number; column: number };
export function nextExtraSheetColumnLabel(columns: ExtraSheet["columns"]): string {
const labels = new Set(columns.map((column) => column.label.toLocaleLowerCase()));
@@ -61,13 +63,17 @@ export function createExtraSheet(createId: (prefix: string) => string): ExtraShe
rows: [1, 2].map(() => ({
id: createId("extra-sheet-row"),
cells: Object.fromEntries(columns.map((column) => [column.id, ""])),
backgrounds: {},
})),
};
}
export function extraSheetToMatrix(sheet: ExtraSheet): ExtraSheetMatrix {
return sheet.rows.map((row) =>
sheet.columns.map((column) => ({ value: row.cells[column.id] ?? "" })),
sheet.columns.map((column) => ({
value: row.cells[column.id] ?? "",
backgroundColor: row.backgrounds[column.id],
})),
);
}
@@ -94,6 +100,11 @@ export function matrixToExtraSheet(
column.id,
String(matrix[rowIndex]?.[columnIndex]?.value ?? ""),
])),
backgrounds: Object.fromEntries(columns.flatMap((column, columnIndex) => {
const backgroundColor = matrix[rowIndex]?.[columnIndex]?.backgroundColor
?? sheet.rows[rowIndex]?.backgrounds[column.id];
return backgroundColor ? [[column.id, backgroundColor]] : [];
})),
}));
return { columns, rows };
}
@@ -115,6 +126,7 @@ export function addExtraSheetRow(sheet: ExtraSheet, id: string): ExtraSheet {
rows: [...sheet.rows, {
id,
cells: Object.fromEntries(sheet.columns.map((column) => [column.id, ""])),
backgrounds: {},
}],
};
}
@@ -152,6 +164,7 @@ export function deleteExtraSheetColumn(sheet: ExtraSheet, index: number): ExtraS
rows: sheet.rows.map((row) => ({
...row,
cells: Object.fromEntries(Object.entries(row.cells).filter(([key]) => key !== columnId)),
backgrounds: Object.fromEntries(Object.entries(row.backgrounds).filter(([key]) => key !== columnId)),
})),
};
}
@@ -178,6 +191,28 @@ export function updateExtraSheetCell(
};
}
export function updateExtraSheetCells(
sheet: ExtraSheet,
points: Iterable<SheetPoint>,
update: { value?: string; backgroundColor?: string | null },
): ExtraSheet {
const selected = new Set(Array.from(points, ({ row, column }) => `${row}:${column}`));
return {
...sheet,
rows: sheet.rows.map((row, rowIndex) => {
const cells = { ...row.cells };
const backgrounds = { ...row.backgrounds };
sheet.columns.forEach((column, columnIndex) => {
if (!selected.has(`${rowIndex}:${columnIndex}`)) return;
if (update.value !== undefined) cells[column.id] = update.value;
if (update.backgroundColor === null) delete backgrounds[column.id];
else if (update.backgroundColor !== undefined) backgrounds[column.id] = update.backgroundColor;
});
return { ...row, cells, backgrounds };
}),
};
}
export function normalizeExtraSheetRichText(sheet: ExtraSheet): ExtraSheet {
return {
...sheet,