feat : update excel
CI / Verify (push) Successful in 1m11s
CI / Build immutable images and deploy (push) Successful in 2m0s

This commit is contained in:
2026-09-05 19:30:50 +07:00 Unverified
parent 2d651fbe56
commit 66238795bf
6 changed files with 529 additions and 67 deletions
+18
View File
@@ -12,6 +12,7 @@ import {
moveExtraSheetColumn,
moveExtraSheetRow,
normalizeExtraSheetRichText,
styleExtraSheetCells,
updateExtraSheetCell,
updateExtraSheetCells,
type ExtraSheet,
@@ -124,6 +125,23 @@ describe("Extra sheet", () => {
.rows[0].backgrounds).toEqual({});
});
it("styles selected cells without replacing their individual text", () => {
const sheet = createExtraSheet(idFactory());
const firstColumn = sheet.columns[0].id;
const secondColumn = sheet.columns[1].id;
sheet.rows[0].cells[firstColumn] = "<p>Alpha</p>";
sheet.rows[1].cells[secondColumn] = "<p><em>Beta</em></p>";
const styled = styleExtraSheetCells(sheet, [
{ row: 0, column: 0 },
{ row: 1, column: 1 },
], { bold: true });
expect(styled.rows[0].cells[firstColumn]).toBe("<p><strong>Alpha</strong></p>");
expect(styled.rows[1].cells[secondColumn]).toBe("<p><em><strong>Beta</strong></em></p>");
expect(styled.rows[0].cells[secondColumn]).toBe("");
});
it("renders legacy sheets that do not have background metadata yet", () => {
const sheet = createExtraSheet(idFactory());
const legacy = {
+28 -1
View File
@@ -1,6 +1,10 @@
import * as z from "zod";
import { normalizeExtraRichText } from "@/lib/rich-text";
import {
applyRichTextStylePatch,
normalizeExtraRichText,
type RichTextStylePatch,
} from "@/lib/rich-text";
const extraSheetId = z.string().min(1).max(128);
@@ -213,6 +217,29 @@ export function updateExtraSheetCells(
};
}
export function styleExtraSheetCells(
sheet: ExtraSheet,
points: Iterable<SheetPoint>,
patch: RichTextStylePatch,
): ExtraSheet {
const selected = new Set(Array.from(points, ({ row, column }) => `${row}:${column}`));
return {
...sheet,
rows: sheet.rows.map((row, rowIndex) => ({
...row,
cells: Object.fromEntries(Object.entries(row.cells).map(([columnId, value]) => {
const columnIndex = sheet.columns.findIndex((column) => column.id === columnId);
return [
columnId,
selected.has(`${rowIndex}:${columnIndex}`)
? applyRichTextStylePatch(value, patch)
: value,
];
})),
})),
};
}
export function normalizeExtraSheetRichText(sheet: ExtraSheet): ExtraSheet {
return {
...sheet,