feat: unify workspace sidebar and create Foundry graph pages

This commit is contained in:
2026-11-05 23:57:45 +08:00
parent 6ca4b00d2c
commit 71bf8b0f5e
15 changed files with 417 additions and 238 deletions
+1
View File
@@ -44,6 +44,7 @@ export const errorText = (error: unknown) => {
workspace_not_loaded: "空间列表尚未加载成功,请刷新页面后重试。",
workspace_required: "请先创建或选择一个工作空间。",
invalid_workspace: "工作空间名称不符合要求,请修改后重试。",
forbidden: "你没有在此工作空间创建或编辑图谱的权限。",
invalid_material: "画布名称或内容不符合要求,请修改后重试。",
invalid_reference: "工作空间不存在或当前账户无权访问,请刷新空间列表。",
upstream_timeout: "连接服务超时,请稍后再试。",
+15
View File
@@ -0,0 +1,15 @@
import type { Board } from "./workspace";
export function readDemoBoards(workspace: string): Board[] {
try {
const stored = JSON.parse(localStorage.getItem("endoleap_demo_boards_" + workspace) || "null");
if (Array.isArray(stored)) return stored.map((board) => ({
...board, workspace_id: workspace, kind: "board", version: board.version || 1,
}));
} catch { /* Fall back to the sample pages when browser storage is invalid. */ }
return [
{ id: "morning", title: "城市清晨" },
{ id: "ideas", title: "灵感收集" },
{ id: "journey", title: "下一站,去哪里" },
].map((board) => ({ ...board, workspace_id: workspace, kind: "board", version: 1 }));
}
+18 -3
View File
@@ -1,6 +1,19 @@
import type { Profile } from "./api";
export type Workspace = { id: string; name: string };
export type Workspace = { id: string; name: string; role?: "admin" | "editor" | "viewer" };
export type Board = {
id: string;
workspace_id: string;
kind: "board";
title: string;
version: number;
content?: { schema_version: number };
};
export const DEFAULT_BOARD_TITLE = "未命名图谱";
export function boardHref(workspace: string, board: string, demo = false) {
return `/dashboard/${encodeURIComponent(workspace)}/${encodeURIComponent(board)}${demo ? "?demo=1" : ""}`;
}
type Request = <T>(path: string, options?: RequestInit) => Promise<T>;
export async function loadWorkspaceHome(
@@ -32,12 +45,14 @@ export async function createBoard(
id = workspace.id;
onWorkspaceCreated(workspace);
}
return request<{ id: string }>("workspaces/" + id + "/materials", {
const name = title.trim() || DEFAULT_BOARD_TITLE;
const result = await request<{ id: string; workspace_id: string; kind: "board"; version: number }>("workspaces/" + id + "/materials", {
method: "POST",
body: JSON.stringify({
kind: "board",
title: title.trim(),
title: name,
content: { schema_version: 1 },
}),
});
return { ...result, workspace_id: result.workspace_id || id, title: name };
}