mcpField
F
frappe-impl-workspace

frappe-impl-workspace

github.com/impertio-studio设计与 UI198109 次安装30 周前更新
代码仓库

关于 frappe-impl-workspace

面向 Frappe 应用开发者和管理员的 Workspace 页面创建与定制工作流参考,涵盖区块布局、访问规则、版本差异及随应用打包依赖项。

主要功能

  1. 01通过界面或代码创建工作区
  2. 02在网格中排列仪表板区块
  3. 03配置模块与角色访问权限
  4. 04管理图表、快捷方式和指标卡
  5. 05导出工作区并打包依赖项

适用场景

  1. 01构建带指标的模块仪表板
  2. 02创建受角色限制的工作区视图
  3. 03随 Frappe 应用发布工作区页面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/impertio-studio/frappe_claude_skill_package --skill frappe-impl-workspace

安装后在 Claude Code 中输入/frappe-impl-workspace确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
anti-patterns.md
shipping-with-app.md
workspace-components.md

详细介绍

Frappe 工作区实施工作流

创建和自定义工作区页面的分步工作流。工作区是 Frappe Desk 中基于区块的仪表板/导航页面。

版本:v14/v15/v16(已注明特定版本的功能)


快速参考

概念说明
工作区采用 12 列网格布局的区块式页面
公共工作区对所有获准用户可见;编辑需要 Workspace Manager 角色
私有工作区位于“My Workspaces”下的个人仪表板;任何 Desk User 都可以创建
内容字段存储区块布局的 JSON 数组
子表6 个表:charts、shortcuts、links、quick_lists、number_cards、custom_blocks
模块关联主要访问控制机制

关键决策:你需要什么?

NEED A WORKSPACE?
│
├─► Default DocType landing page?
│   └─► NO workspace needed — Frappe auto-generates list views
│
├─► Custom dashboard for a module?
│   └─► Create PUBLIC Workspace (Workspace Manager role required)
│
├─► Personal dashboard for a user?
│   └─► Create PRIVATE Workspace (appears under "My Workspaces")
│
└─► Navigation link in sidebar?
    └─► type="Link" (internal) or type="URL" (external)

ADDING COMPONENTS?
│
├─► Key metrics (counts, sums) → Number Cards
├─► Trend / time-series data  → Dashboard Charts
├─► Quick navigation links    → Shortcuts
├─► Grouped link categories   → Link Cards (Card Break + Links)
├─► Custom HTML/JS content    → Custom HTML Blocks
└─► Recent record lists       → Quick Lists

Workspace DocType 结构

关键字段
字段类型用途
labelData侧边栏中的显示名称
titleData页面标题(默认为 label)
moduleLink → Module Def将工作区关联到模块以进行访问控制
parent_pageLink → Workspace在侧边栏中嵌套到其他工作区下
iconData侧边栏图标(例如,"chart-line")
typeSelectWorkspace / Link / URL(v15+)
sequence_idInt侧边栏排序
contentJSON以 JSON 数组形式存储的区块布局
for_userData如果已设置,工作区仅对该用户私有
rolesTable → Has Role基于角色的访问限制
appData所属应用标识符(v15+)
indicator_colorColor侧边栏指示点(v15+)
子表(共 6 个)
子表DocType用途
chartsWorkspace ChartDashboard Chart 引用
shortcutsWorkspace ShortcutDocType/Report/Page/URL 快捷方式
linksWorkspace Link分组导航链接
quick_listsWorkspace Quick List最近记录列表
number_cardsWorkspace Number Card指标卡片引用
custom_blocksWorkspace Custom BlockHTML 区块引用

重要:content JSON 和子表必须保持同步。始终使用 Workspace Builder UI 或程序化 API——切勿在未更新子表的情况下手动编辑 content JSON。请参阅 references/anti-patterns.md。


内容 JSON 格式

content 字段是一个 JSON 数组。每个元素代表 12 列网格中的一个区块:

[
  {
    "id": "unique-block-id",
    "type": "header",
    "data": {"text": "Overview", "level": 4, "col": 12}
  },
  {
    "id": "unique-block-id-2",
    "type": "chart",
    "data": {
      "chart_name": "Sales Trends",
      "col": 12
    }
  },
  {
    "id": "unique-block-id-3",
    "type": "number_card",
    "data": {
      "number_card_name": "Open Orders",
      "col": 4
    }
  },
  {
    "id": "unique-block-id-4",
    "type": "shortcut",
    "data": {
      "shortcut_name": "New Sales Order",
      "col": 4
    }
  },
  {
    "id": "unique-block-id-5",
    "type": "spacer",
    "data": {"col": 12}
  }
]
区块类型
类型data 字段说明
headertext、level、col分区标题(h3/h4/h5)
chartchart_name、col引用一个 Dashboard Chart 文档
number_cardnumber_card_name、col引用一个 Number Card 文档
shortcutshortcut_name、col引用一个 Workspace Shortcut 子项
cardcard_name、col分组链接的卡片分隔
quick_listquick_list_name、col某个 DocType 的最近记录
custom_blockcustom_block_name、col引用一个 Custom HTML Block 文档
textbody、col富文本/Markdown 区块
spacercol垂直留白
onboardingonboarding_name、col模块引导小组件

col 的值必须在 1-12 之间,表示网格列宽。同一行中的区块列宽总和必须 ≤ 12。


实施工作流

工作流 1:通过 UI 创建公共工作区
  1. 前往 /app/workspace → 点击 + New Workspace
  2. 设置 Label(显示在侧边栏中)、Module、Icon
  3. 使用 Workspace Builder 拖放区块
  4. 添加组件:图表、数字卡片、快捷方式、链接
  5. 点击 Save → 工作区将显示在获准用户的侧边栏中
  6. 在开发者模式下:JSON 会自动导出到你的应用目录
工作流 2:以编程方式创建工作区
import frappe
import json

workspace = frappe.new_doc("Workspace")
workspace.label = "Project Dashboard"
workspace.module = "Projects"
workspace.icon = "project"
workspace.type = "Workspace"
workspace.sequence_id = 10

# Build content blocks
workspace.content = json.dumps([
    {
        "id": frappe.generate_hash(length=10),
        "type": "header",
        "data": {"text": "Project Overview", "level": 4, "col": 12}
    },
    {
        "id": frappe.generate_hash(length=10),
        "type": "number_card",
        "data": {"number_card_name": "Active Projects", "col": 4}
    },
    {
        "id": frappe.generate_hash(length=10),
        "type": "chart",
        "data": {"chart_name": "Project Status", "col": 12}
    }
])

# Add child table entries (MUST match content JSON)
workspace.append("number_cards", {
    "number_card_name": "Active Projects"
})
workspace.append("charts", {
    "chart_name": "Project Status"
})

# Role restrictions (optional)
workspace.append("roles", {"role": "Projects Manager"})

workspace.insert(ignore_permissions=True)
frappe.db.commit()

务必在以编程方式设置 content JSON 时,添加相应的子表行。

工作流 3:先创建支持文档

向工作区添加组件之前,请先创建所引用的文档:

数字卡片:

card = frappe.new_doc("Number Card")
card.label = "Active Projects"
card.document_type = "Project"
card.function = "Count"
card.filters_json = json.dumps([["Project", "status", "=", "Open"]])
card.is_public = 1
card.insert(ignore_permissions=True)

仪表板图表:

chart = frappe.new_doc("Dashboard Chart")
chart.chart_name = "Project Status"
chart.chart_type = "Group By"
chart.document_type = "Project"
chart.group_by_type = "Count"
chart.group_by_based_on = "status"
chart.type = "Donut"
chart.is_public = 1
chart.insert(ignore_permissions=True)

快捷方式: 快捷方式是 Workspace 上的子表条目,而不是独立文档:

workspace.append("shortcuts", {
    "label": "New Project",
    "type": "DocType",
    "link_to": "Project",
    "color": "Blue",
    "format": "{} Active",
    "stats_filter": json.dumps([["Project", "status", "=", "Open"]])
})

完整的组件参考请参阅 references/workspace-components.md。


权限模型

三层访问控制
Layer 1: Module Access (PRIMARY)
└─► User must have access to the workspace's module
    └─► Controlled via "Module Def" and user's "Block Modules" list

Layer 2: Role Restrictions (OPTIONAL)
└─► workspace.roles child table
    └─► If populated: ONLY users with listed roles see the workspace
    └─► If empty: ALL users with module access see it

Layer 3: Workspace Manager Role
└─► Required to create/edit PUBLIC workspaces
└─► NOT required for private workspaces
规则
  • 对公开工作区务必设置 module —— 否则该工作区对所有 Desk 用户可见
  • 对敏感仪表板(财务、人力资源)务必添加角色限制
  • 切勿对随应用发布的工作区设置 for_user —— 这会创建私有工作区

版本差异

功能v14v15v16
Workspace Builder UI基础重新设计(拖放网格)增量修复
type 字段(Workspace/Link/URL)不可用已添加可用
app 字段不可用已添加可用
indicator_color不可用已添加可用
名称冲突保护手动手动自动去重
欢迎页眉配置不可用不可用已添加
Content JSON 格式相同相同相同
迁移说明
  • v14 → v15:Workspace Builder UI 有重大变化;现有 JSON 内容仍兼容
  • v15 → v16:新增少量字段;工作区结构没有不兼容的变更
  • 大版本升级后务必测试工作区渲染效果

使用自定义应用发布工作区

目录结构
myapp/
└── mymodule/
    └── workspace/
        └── my_workspace/
            └── my_workspace.json
导出流程
  1. 启用 Developer Mode(frappe.conf.developer_mode = 1)
  2. 通过 Workspace Builder UI 创建或编辑工作区
  3. 保存时,Frappe 会自动导出到上述应用目录
  4. 将 JSON 文件提交到版本控制系统
重要:同时发布依赖项

仅有工作区 JSON 是不够的。还必须同时发布:

组件发布方式
数字卡片使用 hooks.py 中的 fixtures 或 myapp/fixtures/
仪表板图表使用 hooks.py 中的 fixtures 或 myapp/fixtures/
自定义 HTML 块使用 hooks.py 中的 fixtures 或 myapp/fixtures/
链接的报表已通过报表目录结构发布
链接的页面已通过页面目录结构发布
# hooks.py
fixtures = [
    {"dt": "Number Card", "filters": [["module", "=", "My Module"]]},
    {"dt": "Dashboard Chart", "filters": [["module", "=", "My Module"]]},
    {"dt": "Custom HTML Block", "filters": [["name", "in", ["My Block"]]]},
]

完整的发布指南请参阅 references/shipping-with-app.md。


常见模式

模式 1:包含 KPI 的模块仪表板
[Header: "Key Metrics"]
[Number Card: Open Orders (col=3)] [Number Card: Revenue (col=3)]
[Number Card: Pending (col=3)]     [Number Card: Overdue (col=3)]
[Spacer]
[Header: "Trends"]
[Chart: Monthly Revenue (col=12)]
[Header: "Quick Access"]
[Shortcut: New Order (col=4)] [Shortcut: Reports (col=4)] [Shortcut: Settings (col=4)]
模式 2:基于角色的工作区
# Sales Manager sees full dashboard; Sales User sees limited view
# Option A: Two separate workspaces with different role restrictions
# Option B: One workspace — use Number Card/Chart permissions to filter

# Option A implementation:
ws_manager = frappe.get_doc({"doctype": "Workspace", "label": "Sales Management", ...})
ws_manager.append("roles", {"role": "Sales Manager"})

ws_user = frappe.get_doc({"doctype": "Workspace", "label": "Sales Overview", ...})
ws_user.append("roles", {"role": "Sales User"})
模式 3:侧边栏层级结构
# Parent workspace
parent = frappe.get_doc({"doctype": "Workspace", "label": "CRM", "module": "CRM"})

# Child workspaces (nested in sidebar)
child = frappe.get_doc({
    "doctype": "Workspace",
    "label": "Lead Pipeline",
    "module": "CRM",
    "parent_page": "CRM"  # References parent workspace label
})

参考文件

文件内容
references/workspace-components.md数字卡片、仪表板图表、快捷方式、自定义块——完整 API
references/shipping-with-app.mdJSON 格式、fixtures、模块结构、安装钩子
references/anti-patterns.md常见工作区错误及其规避方法

评论

支持 Markdown