Files
mnote/wolai-frontend/src/lib/online-table.ts
T
2026-04-13 19:21:42 +08:00

138 lines
3.7 KiB
TypeScript

import { DocumentTable, DocumentTableSnapshot, TableRowData, TableSchema } from "@/types/online-table";
// 默认表格结构:全部为空列,交由用户/全屏自行定义
export const DEFAULT_TABLE_SCHEMA: TableSchema = {
columns: [],
frozenRowCount: 0,
frozenColCount: 0,
};
export const DEFAULT_TABLE_ROWS = 50;
export const DEFAULT_TABLE_COLUMNS = 15;
export const createDefaultTableSnapshot = (schema: TableSchema): DocumentTableSnapshot => {
const frozenRowCount = schema.frozenRowCount ?? 0;
const frozenColCount = schema.frozenColCount ?? 0;
return {
rows: [],
luckysheet: [
{
name: "Sheet1",
index: 0,
status: 1,
order: 0,
hide: 0,
row: DEFAULT_TABLE_ROWS,
column: DEFAULT_TABLE_COLUMNS,
defaultRowHeight: 19,
defaultColWidth: 73,
celldata: [],
config: {
columnlen: {},
rowlen: {},
},
frozen: {
type: frozenRowCount > 0 || frozenColCount > 0 ? "both" : undefined,
row_focus: frozenRowCount,
column_focus: frozenColCount,
},
scrollLeft: 0,
scrollTop: 0,
zoomRatio: 1,
showGridLines: true,
},
],
};
};
/**
* 在 Supabase 中创建一个新的在线表格并返回元数据。
* @param documentId 当前文档的 ID
* @param title 表格的初始标题
* @returns 新创建的 DocumentTable
*/
export async function createOnlineTable(
documentId: string,
title: string = "未命名表格"
): Promise<DocumentTable> {
// 假设 Next.js API 路由 /api/tables/create 负责与 Supabase 交互
const response = await fetch("/api/tables/create", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
documentId,
title,
schema: DEFAULT_TABLE_SCHEMA,
snapshot: createDefaultTableSnapshot(DEFAULT_TABLE_SCHEMA),
}),
});
if (!response.ok) {
throw new Error("Failed to create online table.");
}
const newTable: DocumentTable = await response.json();
return newTable;
}
/**
* 获取表格元数据 (用于紧凑模式渲染)
* 实际实现中,这可能需要一个更复杂的获取逻辑,例如同时获取前 N 行数据
*/
export async function getDocumentTable(tableId: string): Promise<DocumentTable> {
const response = await fetch(`/api/tables/${tableId}`, {
method: "GET",
headers: { "Content-Type": "application/json" },
});
if (!response.ok) {
throw new Error("Failed to fetch document table.");
}
return response.json() as Promise<DocumentTable>;
}
/**
* 将表格的 snapshot/行数据回写 Supabase,保持内联与全屏视图一致。
*/
export async function saveOnlineTable(
tableId: string,
payload: {
title?: string;
schema?: TableSchema;
snapshot?: DocumentTableSnapshot | null;
rows?: TableRowData[];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
viewPreferences?: Record<string, any>;
},
): Promise<DocumentTable> {
const response = await fetch(`/api/tables/${tableId}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
if (!response.ok) {
const message = await response.text().catch(() => "");
throw new Error(message || "Failed to save online table.");
}
return response.json() as Promise<DocumentTable>;
}
/**
* 删除表格及其行数据。
*/
export async function deleteOnlineTable(tableId: string): Promise<void> {
const response = await fetch(`/api/tables/${tableId}`, {
method: "DELETE",
headers: { "Content-Type": "application/json" },
});
if (!response.ok) {
throw new Error("Failed to delete online table.");
}
}