@james_sww/metaform-asset-distribution 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/codebase/codebase.json +13 -11
- package/codebase/template/.env.example +11 -1
- package/codebase/template/.metaform/template-overrides.json +24 -0
- package/codebase/template/index.html +1 -1
- package/codebase/template/src/components/common/empty-state.tsx +52 -0
- package/codebase/template/src/components/common/error-boundary.tsx +2 -2
- package/codebase/template/src/components/ui/alert.tsx +48 -50
- package/codebase/template/src/hooks/index.ts +2 -2
- package/codebase/template/src/integrations/platform.ts +65 -1
- package/codebase/template/src/layouts/role-workspace-shell.tsx +136 -48
- package/codebase/template/src/lib/http-client.ts +1 -1
- package/codebase/template/src/main.tsx +11 -1
- package/codebase/template/src/workspace/default-workspace.tsx +1 -1
- package/dist/application-source.d.ts +5 -3
- package/dist/application-source.js +43 -32
- package/dist/cli.js +1 -1
- package/dist/contracts.d.ts +6 -1
- package/dist/contracts.js +1 -1
- package/dist/export-source.js +3 -3
- package/dist/prepare.d.ts +1 -1
- package/dist/prepare.js +41 -25
- package/dist/source-map.d.ts +2 -1
- package/dist/source-map.js +10 -8
- package/dist/template.d.ts +1 -1
- package/dist/template.js +1 -1
- package/package.json +2 -2
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/catalog.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/common-semantic-region-scaffold.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-icons.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-business-role-tasks-types.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/components-common-semantic-region-contract.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-account.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-icons.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-routes.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/layouts-role-workspace-types.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/lib-utils.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/quality-role-task-groups.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/quality-role-task-overview.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/role-workspace-shell.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-styles.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/styles-theme-tokens.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-avatar.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-badge.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-button.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-collapsible.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-dropdown-menu.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-empty.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-sheet.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-skeleton.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/r/ui-tooltip.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/registry.json +1 -0
- package/registry/47e2405d581daf6aa5433b033351b639e11f9730d174a0563b88e36bc06402f9/release.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/catalog.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/common-semantic-region-scaffold.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/components-business-role-tasks-icons.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/components-business-role-tasks-types.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/components-common-semantic-region-contract.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-account.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-icons.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-routes.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/layouts-role-workspace-types.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/lib-utils.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/quality-role-task-groups.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/quality-role-task-overview.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/role-workspace-shell.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/styles-styles.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/styles-theme-tokens.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-avatar.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-badge.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-button.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-collapsible.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-dropdown-menu.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-empty.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-sheet.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-skeleton.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/r/ui-tooltip.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/registry.json +1 -0
- package/registry/5bce235170d2de6e2c3b0cfe10d0596dd53189c83acb8d3e4256b11606d95a22/release.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/catalog.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/common-semantic-region-scaffold.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/components-business-role-tasks-icons.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/components-business-role-tasks-types.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/components-common-semantic-region-contract.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/lib-utils.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/quality-role-task-groups.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/quality-role-task-overview.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/styles-styles.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/styles-theme-tokens.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-badge.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-button.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-collapsible.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/r/ui-empty.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/registry.json +1 -0
- package/registry/ac851c907cc97669042b64a5d30d9bec2017d07e43c8cd933db399f446c5bb86/release.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/catalog.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/common-semantic-region-scaffold.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/components-business-role-tasks-icons.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/components-business-role-tasks-types.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/components-common-semantic-region-contract.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/lib-utils.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/quality-role-task-groups.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/quality-role-task-overview.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/styles-styles.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/styles-theme-tokens.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-badge.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-button.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-collapsible.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/r/ui-empty.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/registry.json +1 -0
- package/registry/f5db0c88ee95ccef50d6ced1f08e935c8c56006e337b978e332f0974b18d79b2/release.json +1 -0
- package/registry/release.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# Metaform 源码资产分发(P1)
|
|
2
2
|
|
|
3
|
-
这个包提供源码资产 CLI,并携带独立 `@james_sww/metaform-codebase-template`
|
|
3
|
+
这个包提供源码资产 CLI,并携带独立 `@james_sww/metaform-codebase-template` 的版本快照。基础模板工程与外壳维护源是独立 `metaform-codebase/`;其中基础 UI、主题和语义骨架按明确来源派生,不建立第二份人工维护源。业务组件按需复制,源码归应用维护;生成工程不依赖 Metaform workspace 或该 CLI 才能运行。
|
|
4
|
+
|
|
5
|
+
本版为 `0.1.2`,包含独立资产库迁移与模板侧栏、间距和 cobalt 默认主题更新。资产源码及 CLI 已独立迁入 `metaform-asset-library`;本轮仅分发两个岗位任务组件、语义骨架及真实依赖,外壳随模板交付。
|
|
4
6
|
|
|
5
7
|
## npm 使用与沙箱接入
|
|
6
8
|
|
|
7
9
|
发布版本使用 Node 24.18.0、pnpm 10.18.2。CLI 自带固定版本模板与源码 Registry,无需平台仓库或本机桌面目录。私有包需有下载权限;沙箱凭据由运行环境注入,不写入应用源码。
|
|
8
10
|
|
|
9
11
|
```sh
|
|
10
|
-
npm install -g @james_sww/metaform-asset-distribution@0.1.
|
|
12
|
+
npm install -g @james_sww/metaform-asset-distribution@0.1.2
|
|
11
13
|
metaform-assets init --project ./my-app
|
|
12
14
|
cd my-app
|
|
13
15
|
corepack pnpm install --frozen-lockfile
|
|
@@ -16,7 +18,7 @@ corepack pnpm install --frozen-lockfile
|
|
|
16
18
|
不安装全局工具也可运行:
|
|
17
19
|
|
|
18
20
|
```sh
|
|
19
|
-
npm exec --yes --package=@james_sww/metaform-asset-distribution@0.1.
|
|
21
|
+
npm exec --yes --package=@james_sww/metaform-asset-distribution@0.1.2 -- metaform-assets init --project ./my-app
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
Agent 根据应用本体和 skill 形成 `ApplicationDesign` JSON 后,在已初始化的应用目录执行:
|
|
@@ -31,11 +33,11 @@ corepack pnpm dev
|
|
|
31
33
|
|
|
32
34
|
CLI 负责按底稿确定性装配;读取线上本体并作语义转译由 Agent 完成。匹配组件安装为应用内源码,未匹配区域保留语义骨架。模板初始化、安装成功不代表真实业务数据已绑定或平台 S7 已自动接通。
|
|
33
35
|
|
|
34
|
-
基础模板也单独按 `@james_sww/metaform-codebase-template@0.1.
|
|
36
|
+
基础模板也单独按 `@james_sww/metaform-codebase-template@0.1.2` 分发,可安装到工具目录后用 `--codebase /path/to/node_modules/@james_sww/metaform-codebase-template` 指定。初始化底稿的完整类型随 CLI 发布在 `dist/application-design.d.ts`,语义区域类型在 `dist/generated/semantic-region-contract.d.ts`。固定 CLI、模板和 Registry 版本用于沙箱重放;初始化后的源码和基线存入项目快照。
|
|
35
37
|
|
|
36
38
|
## 维护仓库
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
在独立 `metaform-asset-library` 根目录使用 pnpm 10.18.2:
|
|
39
41
|
|
|
40
42
|
```sh
|
|
41
43
|
corepack pnpm --filter @james_sww/metaform-asset-distribution test
|
|
@@ -45,7 +47,7 @@ corepack pnpm --filter @james_sww/metaform-asset-distribution pack --pack-destin
|
|
|
45
47
|
corepack pnpm --filter @james_sww/metaform-asset-distribution test:standalone
|
|
46
48
|
```
|
|
47
49
|
|
|
48
|
-
pack 前从独立基础模板包生成 `codebase/` 快照,再生成 CLI 和资产发布快照。`codebase-source.json`
|
|
50
|
+
pack 前从独立基础模板包生成 `codebase/` 快照,再生成 CLI 和资产发布快照。`codebase-source.json` 固定模板名称、版本、清单摘要及库内快照来源。更新上游时按根目录 README 显式刷新固定来源;可用 `METAFORM_CODEBASE_SOURCE` 指向其他包目录(包括已安装或解压的 npm 包)。修改模板后先在模板包运行 `npm run seal`。CLI 发行包不依赖桌面路径。`prepare:release` 只写本地 registry 目录,不发布在线服务。默认 Registry URL 是本机验收地址;正式托管前显式设置 `METAFORM_REGISTRY_BASE=https://...`。每个 release 目录以完整内容摘要命名;同摘要的条目、依赖 URL 和 Catalog 不可改写。更换部署 URL 时使用新的输出目录,不能覆盖已发布版本。
|
|
49
51
|
|
|
50
52
|
`registry/<digest>/registry.json`、`r/*.json` 遵守 shadcn Registry schema;`release.json` 是 Metaform 的原始字节和来源 sidecar。schema 校验 fixture 来自 [官方 registry-item schema](https://ui.shadcn.com/schema/registry-item.json),2026-10-17 固定入库。Catalog 分开保留 component 与 asset 两种粒度,候选不会自动变成推荐。可发现但不在首批源码范围内的条目显示 `installable: false`。
|
|
51
53
|
|
package/codebase/codebase.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"name": "@james_sww/metaform-codebase-template",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"files": {
|
|
6
6
|
"_gitignore": "184ad45835c68a6d3fd5100366678797c5fe4d2a2aa6548749039912376faf54",
|
|
7
|
-
".env.example": "
|
|
7
|
+
".env.example": "602ae0c89a09593ef560b5d1f7010439e228c7fb0dd7bbc69c9655cf82a8944f",
|
|
8
8
|
".metaform/asset-baselines/0551d7ee067550cd2757cf693414c5e180adbb5efe3af4f5f9b1242aa9cd788e": "0551d7ee067550cd2757cf693414c5e180adbb5efe3af4f5f9b1242aa9cd788e",
|
|
9
9
|
".metaform/asset-baselines/0e7bb494140c2c4118b919496a4246b26935367453282bd654fedecd2b16f1a5": "0e7bb494140c2c4118b919496a4246b26935367453282bd654fedecd2b16f1a5",
|
|
10
10
|
".metaform/asset-baselines/3d1a9a8a1f7ed83eaf3422d1497cac02b643fe1c470b5c5f357f3bd26c585a0f": "3d1a9a8a1f7ed83eaf3422d1497cac02b643fe1c470b5c5f357f3bd26c585a0f",
|
|
@@ -23,20 +23,22 @@
|
|
|
23
23
|
".metaform/asset-baselines/e9d4784c2ad5bceccdc4f2f19f367fdc37537a10e3f99f510e42c0226adfbf8f": "e9d4784c2ad5bceccdc4f2f19f367fdc37537a10e3f99f510e42c0226adfbf8f",
|
|
24
24
|
".metaform/asset-baselines/f3ce568d1ede383d9cb0d11dcc2acb6ce7984cbef8e2db0feec310df76303ccd": "f3ce568d1ede383d9cb0d11dcc2acb6ce7984cbef8e2db0feec310df76303ccd",
|
|
25
25
|
".metaform/asset-baselines/fc763d53079b51a789c1cfff23d40e00f844a9a093a2ad112f0ac68ab46fe080": "fc763d53079b51a789c1cfff23d40e00f844a9a093a2ad112f0ac68ab46fe080",
|
|
26
|
+
".metaform/template-overrides.json": "4c9c16d05caf34c4ee4c76fd296c3cc94a07a1fa1db2b8c8ec1ff9af28115722",
|
|
26
27
|
"application.json": "832c19243f16e38c7a6e100e995675d995537ea0d53da7df9cc1b239782b3ca0",
|
|
27
28
|
"assets.lock.json": "cad385719b1d3b2ccbb56343ca5305d862b813a1e0013d2c12c827423ca47db4",
|
|
28
29
|
"components.json": "bf8e563e20f684aad29b2b7671b3327effd62dc2cb3bd944fcd1ccb7d581217e",
|
|
29
30
|
"eslint.config.js": "05a1c2fbaca8ec2c04985ca14e7da9ecf7b6722a5d9e27313e814de4b0393ccd",
|
|
30
|
-
"index.html": "
|
|
31
|
+
"index.html": "b0615e4fc6fdf82a768f44c818b3bf280897882ffc72c949c8a3ab5cd78ca37b",
|
|
31
32
|
"LICENSES/NOTICE.md": "dc2bd63b6bcdf6007dcc823ae145828ae0fc3ff2768950a2899e752c1016e0b2",
|
|
32
33
|
"package.json": "7b256b3982d5683f6279e75ee86280498b7ef444a4262158f8d622f77361f64f",
|
|
33
34
|
"pnpm-lock.yaml": "46912c695ef4a2f351a7469aa26ab1312ccf6347b4d0aa2b075bf3a96632782b",
|
|
34
35
|
"README.md": "d738a1bfbe9e9221f15e2bdcb46af9fae112afd0c1354bd9d45bdf3ae5205e38",
|
|
35
36
|
"role-targets.json": "37517e5f3dc66819f61f5a7bb8ace1921282415f10551d2defa5c3eb0985b570",
|
|
36
|
-
"src/components/common/
|
|
37
|
+
"src/components/common/empty-state.tsx": "6008a3193b715c5453eee3dba6ee20608fca3e6cf8bba9af774ba898a1890fea",
|
|
38
|
+
"src/components/common/error-boundary.tsx": "1fef1c92e27d8206448cb0e1840bfe81826a95fc58b1ec4c1e2f14462293bf5b",
|
|
37
39
|
"src/components/common/semantic-region/contract.ts": "92cd18a919b549b4827f611c3a4157652c4a6ae034850da1254ca422693c759d",
|
|
38
40
|
"src/components/common/semantic-region/semantic-region-scaffold.tsx": "567f039384fb23a20a4cd5e1d4fda56255abda6fc04d80b36c4bb6f6c040691b",
|
|
39
|
-
"src/components/ui/alert.tsx": "
|
|
41
|
+
"src/components/ui/alert.tsx": "9c380bb1703ba96fe873d5b3094153fa3402d305719e60aa733e4ab202ffddaa",
|
|
40
42
|
"src/components/ui/avatar.tsx": "e9d4784c2ad5bceccdc4f2f19f367fdc37537a10e3f99f510e42c0226adfbf8f",
|
|
41
43
|
"src/components/ui/badge.tsx": "bf9e1bbb252c1fa5da20a17eeee1ac163c7d3a0b6deff817d30ba04b766fb8a1",
|
|
42
44
|
"src/components/ui/breadcrumb.tsx": "c75fcd3d9e8470188bc0dd4b27a2b26fff3ad42b9c9c534a953dc090ae2cba33",
|
|
@@ -59,20 +61,20 @@
|
|
|
59
61
|
"src/components/ui/tabs.tsx": "e1df6e2f95ece373ca909c1d54b8ba8cf4c47dd425c1784bbb9a01c38dd0936b",
|
|
60
62
|
"src/components/ui/tooltip.tsx": "5f56cd15afc07567f7b80b8b4d9e89da405e070a562583bbbc2414fd981af324",
|
|
61
63
|
"src/contexts/toast-context.tsx": "a3af91f8915d7753ef15888997ba941d07459d4df3e3e6d58e25365143bf336f",
|
|
62
|
-
"src/hooks/index.ts": "
|
|
63
|
-
"src/integrations/platform.ts": "
|
|
64
|
+
"src/hooks/index.ts": "ddfe80f0fc8b0b49c0b31f27d9aadc4a54715b5ccee40996a205ecec36958b79",
|
|
65
|
+
"src/integrations/platform.ts": "6edb9755c91f6bf1f16815911739f64c4f45405948eaf0d7bbd5cd2fa939dbe9",
|
|
64
66
|
"src/layouts/role-workspace-account.tsx": "3d1a9a8a1f7ed83eaf3422d1497cac02b643fe1c470b5c5f357f3bd26c585a0f",
|
|
65
67
|
"src/layouts/role-workspace-icons.tsx": "4b8ea69ef28a9699c0c3b28e12590a7521f91aa1a4a3d618fc0778455d39cbcc",
|
|
66
68
|
"src/layouts/role-workspace-routes.ts": "0551d7ee067550cd2757cf693414c5e180adbb5efe3af4f5f9b1242aa9cd788e",
|
|
67
|
-
"src/layouts/role-workspace-shell.tsx": "
|
|
69
|
+
"src/layouts/role-workspace-shell.tsx": "ab0c50c655d759643c77f634337b070807a601580f554796f50284f87c8fd100",
|
|
68
70
|
"src/layouts/role-workspace-types.ts": "b9e31158082ce71a2b3bdb904d9462619e3690735e73e138b1ce57f8f036347f",
|
|
69
|
-
"src/lib/http-client.ts": "
|
|
71
|
+
"src/lib/http-client.ts": "a284532dd0bcc18aaf444b92e883ec77750515c1ba01626d8fa96c3e540d2e37",
|
|
70
72
|
"src/lib/utils.ts": "4acbc7165a8d54738ff62b51414e772c08fe78434e524e6d8770180d3ba2925f",
|
|
71
|
-
"src/main.tsx": "
|
|
73
|
+
"src/main.tsx": "6fa2b2eb510ef94ca04b894c573a041419191f6896043f227eb160ab49bd6efa",
|
|
72
74
|
"src/styles/index.css": "72f8f255c56d117bab6f2aaa53ce5a37aa9b2d5d085b321b9fcb4b4b983e15eb",
|
|
73
75
|
"src/styles/styles.css": "b48c73f51ff3e148f20ad2c9dbd2847235e4fdf1cdb304d5e2feec9c2febd65e",
|
|
74
76
|
"src/styles/theme-tokens.css": "0e7bb494140c2c4118b919496a4246b26935367453282bd654fedecd2b16f1a5",
|
|
75
|
-
"src/workspace/default-workspace.tsx": "
|
|
77
|
+
"src/workspace/default-workspace.tsx": "083313a2e0d61e5eb7f2ee1c2d4dda3243bfdce6204249df85fef7acd751f19d",
|
|
76
78
|
"src/workspace/routes.ts": "94275cc4d44abcfa672e7d56ac1abc7ecd9f5caf656aa54d3e3ef68eaa7e2085",
|
|
77
79
|
"tests/workspace.test.mjs": "daf930b4db33de45eeecf8431663540ecd54aa90c3ba3dd1e683b539cbb8bf5d",
|
|
78
80
|
"tooling/contracts.d.ts": "9ce9d9ac8e59c11c89aa41881b6e8d6edfc84fb4da115970b9f4a2c1e7486ba8",
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"previousTemplateVersion": "0.1.1",
|
|
4
|
+
"files": {
|
|
5
|
+
"index.html": {
|
|
6
|
+
"previousTemplateSha256": "0c8ce9649128d2ebbe282b1eee040524b78896b9df13f3ca1481c3965f66b823",
|
|
7
|
+
"currentSha256": "b0615e4fc6fdf82a768f44c818b3bf280897882ffc72c949c8a3ab5cd78ca37b",
|
|
8
|
+
"owner": "codebase-template",
|
|
9
|
+
"reason": "保留用户现有侧栏、间距及 cobalt 默认主题修改;不是原资产版本的未修改副本"
|
|
10
|
+
},
|
|
11
|
+
"src/layouts/role-workspace-shell.tsx": {
|
|
12
|
+
"previousTemplateSha256": "a9f11ecd7a83647859085f75b6d2ba98760240d474aeb38b9c9c2c8174bff31a",
|
|
13
|
+
"currentSha256": "ab0c50c655d759643c77f634337b070807a601580f554796f50284f87c8fd100",
|
|
14
|
+
"owner": "codebase-template",
|
|
15
|
+
"reason": "保留用户现有侧栏、间距及 cobalt 默认主题修改;不是原资产版本的未修改副本"
|
|
16
|
+
},
|
|
17
|
+
"src/workspace/default-workspace.tsx": {
|
|
18
|
+
"previousTemplateSha256": "0239a9926ab2bc6aa6a0c4923a1af03d618bc245483b114c74b017a4a2051737",
|
|
19
|
+
"currentSha256": "083313a2e0d61e5eb7f2ee1c2d4dda3243bfdce6204249df85fef7acd751f19d",
|
|
20
|
+
"owner": "codebase-template",
|
|
21
|
+
"reason": "保留用户现有侧栏、间距及 cobalt 默认主题修改;不是原资产版本的未修改副本"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { InboxIcon } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
import { cn } from '../../lib/utils';
|
|
5
|
+
import { Button } from '../ui/button';
|
|
6
|
+
|
|
7
|
+
export interface EmptyStateProps {
|
|
8
|
+
icon?: ReactNode;
|
|
9
|
+
title: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
action?: {
|
|
12
|
+
label: string;
|
|
13
|
+
onClick: () => void;
|
|
14
|
+
};
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 空状态组件
|
|
20
|
+
* 当列表、表格或其他数据容器没有内容时显示
|
|
21
|
+
*/
|
|
22
|
+
export function EmptyState({
|
|
23
|
+
icon,
|
|
24
|
+
title,
|
|
25
|
+
description,
|
|
26
|
+
action,
|
|
27
|
+
className,
|
|
28
|
+
}: EmptyStateProps) {
|
|
29
|
+
return (
|
|
30
|
+
<div
|
|
31
|
+
className={cn(
|
|
32
|
+
'flex min-h-[400px] flex-col items-center justify-center gap-4 rounded-lg border border-dashed border-border bg-muted/30 p-8 text-center',
|
|
33
|
+
className,
|
|
34
|
+
)}
|
|
35
|
+
>
|
|
36
|
+
<div className="flex size-20 items-center justify-center rounded-full bg-muted text-muted-foreground">
|
|
37
|
+
{icon || <InboxIcon className="size-10" />}
|
|
38
|
+
</div>
|
|
39
|
+
<div className="space-y-2">
|
|
40
|
+
<h3 className="text-lg font-semibold text-foreground">{title}</h3>
|
|
41
|
+
{description && (
|
|
42
|
+
<p className="max-w-md text-sm text-muted-foreground">{description}</p>
|
|
43
|
+
)}
|
|
44
|
+
</div>
|
|
45
|
+
{action && (
|
|
46
|
+
<Button onClick={action.onClick} className="mt-2">
|
|
47
|
+
{action.label}
|
|
48
|
+
</Button>
|
|
49
|
+
)}
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Button } from '../
|
|
4
|
-
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '../
|
|
3
|
+
import { Button } from '../ui/button';
|
|
4
|
+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '../ui/card';
|
|
5
5
|
|
|
6
6
|
interface ErrorBoundaryProps {
|
|
7
7
|
children: ReactNode;
|
|
@@ -1,65 +1,63 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
|
-
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils";
|
|
4
5
|
|
|
5
6
|
const alertVariants = cva(
|
|
6
|
-
"relative
|
|
7
|
+
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
|
7
8
|
{
|
|
8
9
|
variants: {
|
|
9
10
|
variant: {
|
|
10
|
-
default: "bg-
|
|
11
|
+
default: "bg-background text-foreground",
|
|
12
|
+
success:
|
|
13
|
+
"border-semantic-success/50 bg-semantic-success-soft text-semantic-success-foreground [&>svg]:text-semantic-success",
|
|
14
|
+
warning:
|
|
15
|
+
"border-semantic-warning/50 bg-semantic-warning-soft text-semantic-warning-foreground [&>svg]:text-semantic-warning",
|
|
11
16
|
destructive:
|
|
12
|
-
"bg-
|
|
17
|
+
"border-semantic-danger/50 bg-semantic-danger-soft text-semantic-danger-foreground [&>svg]:text-semantic-danger",
|
|
13
18
|
},
|
|
14
19
|
},
|
|
15
20
|
defaultVariants: {
|
|
16
21
|
variant: "default",
|
|
17
22
|
},
|
|
18
|
-
}
|
|
19
|
-
)
|
|
23
|
+
},
|
|
24
|
+
);
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
)
|
|
34
|
-
}
|
|
26
|
+
const Alert = React.forwardRef<
|
|
27
|
+
HTMLDivElement,
|
|
28
|
+
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
|
|
29
|
+
>(({ className, variant, ...props }, ref) => (
|
|
30
|
+
<div
|
|
31
|
+
ref={ref}
|
|
32
|
+
role="alert"
|
|
33
|
+
className={cn(alertVariants({ variant }), className)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
));
|
|
37
|
+
Alert.displayName = "Alert";
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
39
|
+
const AlertTitle = React.forwardRef<
|
|
40
|
+
HTMLParagraphElement,
|
|
41
|
+
React.HTMLAttributes<HTMLHeadingElement>
|
|
42
|
+
>(({ className, ...props }, ref) => (
|
|
43
|
+
<h5
|
|
44
|
+
ref={ref}
|
|
45
|
+
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
|
|
46
|
+
{...props}
|
|
47
|
+
/>
|
|
48
|
+
));
|
|
49
|
+
AlertTitle.displayName = "AlertTitle";
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{...props}
|
|
61
|
-
/>
|
|
62
|
-
)
|
|
63
|
-
}
|
|
51
|
+
const AlertDescription = React.forwardRef<
|
|
52
|
+
HTMLParagraphElement,
|
|
53
|
+
React.HTMLAttributes<HTMLParagraphElement>
|
|
54
|
+
>(({ className, ...props }, ref) => (
|
|
55
|
+
<div
|
|
56
|
+
ref={ref}
|
|
57
|
+
className={cn("text-sm [&_p]:leading-relaxed", className)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
));
|
|
61
|
+
AlertDescription.displayName = "AlertDescription";
|
|
64
62
|
|
|
65
|
-
export { Alert, AlertTitle, AlertDescription }
|
|
63
|
+
export { Alert, AlertTitle, AlertDescription };
|
|
@@ -166,8 +166,8 @@ export function useMediaQuery(query: string): boolean {
|
|
|
166
166
|
*/
|
|
167
167
|
export function useClickOutside<T extends HTMLElement = HTMLElement>(
|
|
168
168
|
handler: () => void,
|
|
169
|
-
): React.RefObject<T> {
|
|
170
|
-
const ref = useRef<T>(null);
|
|
169
|
+
): React.RefObject<T | null> {
|
|
170
|
+
const ref = useRef<T | null>(null);
|
|
171
171
|
|
|
172
172
|
useEffect(() => {
|
|
173
173
|
const listener = (event: MouseEvent | TouchEvent) => {
|
|
@@ -1,6 +1,70 @@
|
|
|
1
|
-
|
|
1
|
+
import { httpClient } from '../lib/http-client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 平台集成接口
|
|
5
|
+
* 提供统一的认证、查询和操作能力
|
|
6
|
+
*/
|
|
2
7
|
export interface PlatformIntegration {
|
|
3
8
|
getSession(): Promise<{ actorId: string } | null>;
|
|
4
9
|
query<T>(operation: string, input: unknown): Promise<T>;
|
|
5
10
|
execute<T>(operation: string, input: unknown): Promise<T>;
|
|
6
11
|
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 默认平台集成实现
|
|
15
|
+
* 使用 HTTP 客户端与后端通信
|
|
16
|
+
*/
|
|
17
|
+
class DefaultPlatformIntegration implements PlatformIntegration {
|
|
18
|
+
async getSession(): Promise<{ actorId: string } | null> {
|
|
19
|
+
try {
|
|
20
|
+
const response = await httpClient.get<{ actorId: string }>('/auth/session');
|
|
21
|
+
return response.data;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.warn('Failed to get session:', error);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async query<T>(operation: string, input: unknown): Promise<T> {
|
|
29
|
+
const response = await httpClient.post<T>('/query', {
|
|
30
|
+
operation,
|
|
31
|
+
input,
|
|
32
|
+
});
|
|
33
|
+
return response.data;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async execute<T>(operation: string, input: unknown): Promise<T> {
|
|
37
|
+
const response = await httpClient.post<T>('/execute', {
|
|
38
|
+
operation,
|
|
39
|
+
input,
|
|
40
|
+
});
|
|
41
|
+
return response.data;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Mock 平台集成(用于开发和测试)
|
|
47
|
+
*/
|
|
48
|
+
class MockPlatformIntegration implements PlatformIntegration {
|
|
49
|
+
async getSession(): Promise<{ actorId: string } | null> {
|
|
50
|
+
// 模拟已登录用户
|
|
51
|
+
return { actorId: 'mock-user-001' };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async query<T>(operation: string, input: unknown): Promise<T> {
|
|
55
|
+
console.log('[Mock Query]', operation, input);
|
|
56
|
+
// 返回模拟数据
|
|
57
|
+
return {} as T;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async execute<T>(operation: string, input: unknown): Promise<T> {
|
|
61
|
+
console.log('[Mock Execute]', operation, input);
|
|
62
|
+
return {} as T;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 根据环境变量选择实现
|
|
67
|
+
const useMock = (import.meta as { env?: { VITE_USE_MOCK_API?: string } }).env?.VITE_USE_MOCK_API === 'true';
|
|
68
|
+
export const platform: PlatformIntegration = useMock
|
|
69
|
+
? new MockPlatformIntegration()
|
|
70
|
+
: new DefaultPlatformIntegration();
|
|
@@ -67,10 +67,33 @@ function NavigationItem({
|
|
|
67
67
|
variant="ghost-neutral"
|
|
68
68
|
data-route-id={theme.id}
|
|
69
69
|
className={cn(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
// 基础样式
|
|
71
|
+
'group relative h-auto w-full justify-start gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200',
|
|
72
|
+
|
|
73
|
+
// 激活状态
|
|
74
|
+
active && [
|
|
75
|
+
'bg-gradient-to-r from-[var(--theme-accent-soft)] via-[var(--theme-accent-soft)]/50 to-transparent',
|
|
76
|
+
'shadow-sm',
|
|
77
|
+
'border-l-2 border-[var(--theme-accent)]',
|
|
78
|
+
'font-semibold text-[var(--theme-accent)]',
|
|
79
|
+
'hover:from-[var(--theme-accent-soft)] hover:via-[var(--theme-accent-soft)]/60',
|
|
80
|
+
],
|
|
81
|
+
|
|
82
|
+
// 非激活状态
|
|
83
|
+
!active && [
|
|
84
|
+
'text-foreground/80',
|
|
85
|
+
'hover:bg-accent/50 hover:text-foreground',
|
|
86
|
+
'hover:translate-x-0.5 hover:shadow-sm',
|
|
87
|
+
],
|
|
88
|
+
|
|
89
|
+
// 计划中状态
|
|
90
|
+
theme.availability === 'planned' && [
|
|
91
|
+
'cursor-not-allowed opacity-50',
|
|
92
|
+
'hover:translate-x-0 hover:bg-transparent',
|
|
93
|
+
],
|
|
94
|
+
|
|
95
|
+
// 折叠状态
|
|
96
|
+
collapsed && 'justify-center px-2 border-l-0',
|
|
74
97
|
)}
|
|
75
98
|
aria-label={collapsed ? theme.label : undefined}
|
|
76
99
|
aria-current={active ? 'page' : undefined}
|
|
@@ -80,25 +103,33 @@ function NavigationItem({
|
|
|
80
103
|
<span
|
|
81
104
|
aria-hidden="true"
|
|
82
105
|
className={cn(
|
|
83
|
-
'flex
|
|
84
|
-
active ? 'text-
|
|
106
|
+
'relative flex size-5 shrink-0 items-center justify-center transition-transform duration-200',
|
|
107
|
+
active ? 'scale-110 text-[var(--theme-accent)]' : 'text-muted-foreground group-hover:scale-105 group-hover:text-foreground',
|
|
85
108
|
)}
|
|
86
109
|
>
|
|
87
110
|
{theme.icon ?? <Layers3 className="size-4" />}
|
|
111
|
+
{/* 激活状态的微妙发光效果 */}
|
|
112
|
+
{active && (
|
|
113
|
+
<span className="absolute inset-0 animate-pulse rounded-full bg-[var(--theme-accent-soft)] blur-sm" />
|
|
114
|
+
)}
|
|
88
115
|
</span>
|
|
89
|
-
{!collapsed ? <span className="truncate">{theme.label}</span> : null}
|
|
90
|
-
{!collapsed && theme.count !== undefined ? (
|
|
116
|
+
{!collapsed ? <span className="flex-1 truncate text-left">{theme.label}</span> : null}
|
|
117
|
+
{!collapsed && theme.count !== undefined && theme.count > 0 ? (
|
|
91
118
|
<span
|
|
92
119
|
className={cn(
|
|
93
|
-
'rounded-
|
|
94
|
-
active
|
|
120
|
+
'flex h-5 min-w-[20px] items-center justify-center rounded-full px-1.5 text-[11px] font-semibold shadow-sm transition-all duration-200',
|
|
121
|
+
active
|
|
122
|
+
? 'bg-primary text-primary-foreground ring-1 ring-primary/20'
|
|
123
|
+
: 'bg-muted text-muted-foreground group-hover:bg-primary/10 group-hover:text-primary'
|
|
95
124
|
)}
|
|
96
125
|
>
|
|
97
|
-
{theme.count}
|
|
126
|
+
{theme.count > 99 ? '99+' : theme.count}
|
|
98
127
|
</span>
|
|
99
128
|
) : null}
|
|
100
129
|
{!collapsed && theme.availability === 'planned' ? (
|
|
101
|
-
<span className="ml-auto text-
|
|
130
|
+
<span className="ml-auto text-[10px] font-medium uppercase tracking-wide text-muted-foreground/60">
|
|
131
|
+
即将推出
|
|
132
|
+
</span>
|
|
102
133
|
) : null}
|
|
103
134
|
</Button>
|
|
104
135
|
);
|
|
@@ -140,42 +171,99 @@ function ThemeNavigation({
|
|
|
140
171
|
const extensions = themes.filter((theme) => !isWorkspaceRouteId(theme.id));
|
|
141
172
|
return (
|
|
142
173
|
<TooltipProvider delayDuration={200}>
|
|
143
|
-
<nav aria-label="角色工作主题" className="px-3">
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
174
|
+
<nav aria-label="角色工作主题" className="space-y-1 px-3">
|
|
175
|
+
{/* 核心视图组 */}
|
|
176
|
+
<div className="space-y-1">
|
|
177
|
+
{!collapsed && (
|
|
178
|
+
<p className="mb-2 px-3 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70">
|
|
179
|
+
核心视图
|
|
180
|
+
</p>
|
|
181
|
+
)}
|
|
182
|
+
{DEFAULT_WORKSPACE_ROUTES.filter((route) => route.group === 'value').map((route) => (
|
|
183
|
+
<NavigationItem
|
|
184
|
+
key={route.id}
|
|
185
|
+
theme={{
|
|
186
|
+
...route,
|
|
187
|
+
availability: 'implemented',
|
|
188
|
+
icon: <WorkspaceRouteIcon id={route.id} />,
|
|
189
|
+
}}
|
|
190
|
+
activeThemeId={activeThemeId}
|
|
191
|
+
onSelect={onSelect}
|
|
192
|
+
collapsed={collapsed}
|
|
193
|
+
/>
|
|
194
|
+
))}
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
{/* 渐变分隔线 */}
|
|
198
|
+
<div className="my-3 h-px bg-gradient-to-r from-transparent via-border to-transparent" />
|
|
199
|
+
|
|
200
|
+
{/* 待办事项组 */}
|
|
201
|
+
<div className="space-y-1">
|
|
202
|
+
{!collapsed && (
|
|
203
|
+
<p className="mb-2 px-3 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70">
|
|
204
|
+
工作台
|
|
205
|
+
</p>
|
|
206
|
+
)}
|
|
207
|
+
{DEFAULT_WORKSPACE_ROUTES.filter((route) => route.group === 'inbox').map((route) => (
|
|
208
|
+
<NavigationItem
|
|
209
|
+
key={route.id}
|
|
210
|
+
theme={{
|
|
211
|
+
...route,
|
|
212
|
+
availability: 'implemented',
|
|
213
|
+
icon: <WorkspaceRouteIcon id={route.id} />,
|
|
214
|
+
count: route.id === 'inbox' ? count : undefined,
|
|
215
|
+
}}
|
|
216
|
+
activeThemeId={activeThemeId}
|
|
217
|
+
onSelect={onSelect}
|
|
218
|
+
collapsed={collapsed}
|
|
219
|
+
/>
|
|
220
|
+
))}
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
{/* 企业协作组 */}
|
|
224
|
+
{DEFAULT_WORKSPACE_ROUTES.some((route) => route.group === 'enterprise') && (
|
|
225
|
+
<>
|
|
226
|
+
<div className="my-3 h-px bg-gradient-to-r from-transparent via-border to-transparent" />
|
|
227
|
+
<div className="space-y-1">
|
|
228
|
+
{!collapsed && (
|
|
229
|
+
<p className="mb-2 px-3 text-[11px] font-medium uppercase tracking-wider text-muted-foreground/70">
|
|
230
|
+
协作空间
|
|
231
|
+
</p>
|
|
232
|
+
)}
|
|
233
|
+
{DEFAULT_WORKSPACE_ROUTES.filter((route) => route.group === 'enterprise').map((route) => (
|
|
234
|
+
<NavigationItem
|
|
235
|
+
key={route.id}
|
|
236
|
+
theme={{
|
|
237
|
+
...route,
|
|
238
|
+
availability: 'implemented',
|
|
239
|
+
icon: <WorkspaceRouteIcon id={route.id} />,
|
|
240
|
+
}}
|
|
241
|
+
activeThemeId={activeThemeId}
|
|
242
|
+
onSelect={onSelect}
|
|
243
|
+
collapsed={collapsed}
|
|
244
|
+
/>
|
|
245
|
+
))}
|
|
246
|
+
</div>
|
|
247
|
+
</>
|
|
248
|
+
)}
|
|
249
|
+
|
|
250
|
+
{/* 扩展功能 */}
|
|
251
|
+
{extensions.length > 0 && (
|
|
252
|
+
<>
|
|
253
|
+
<div className="my-3 h-px bg-gradient-to-r from-transparent via-border to-transparent" />
|
|
254
|
+
<div className="space-y-1">
|
|
255
|
+
{extensions.map((theme) => (
|
|
256
|
+
<NavigationItem
|
|
257
|
+
key={theme.id}
|
|
258
|
+
theme={theme}
|
|
259
|
+
activeThemeId={activeThemeId}
|
|
260
|
+
onSelect={onSelect}
|
|
261
|
+
collapsed={collapsed}
|
|
262
|
+
/>
|
|
263
|
+
))}
|
|
264
|
+
</div>
|
|
265
|
+
</>
|
|
266
|
+
)}
|
|
179
267
|
</nav>
|
|
180
268
|
</TooltipProvider>
|
|
181
269
|
);
|