Skill125 repo starsupdated 2mo ago
frappe-impl-workspace
>
Install in Claude Code
Copygit clone --depth 1 https://github.com/Impertio-Studio/Frappe_Claude_Skill_Package /tmp/frappe-impl-workspace && cp -r /tmp/frappe-impl-workspace/skills/source/impl/frappe-impl-workspace ~/.claude/skills/frappe-impl-workspaceThen start a new Claude Code session; the skill loads automatically.
Definition
SKILL.md
# Frappe Workspace Implementation Workflow
Step-by-step workflows for creating and customizing Workspace pages. Workspaces are the block-based dashboard/navigation pages in Frappe Desk.
**Version**: v14/v15/v16 (version-specific features noted)
---
## Quick Reference
| Concept | Description |
|---------|-------------|
| Workspace | Block-based page with 12-column grid layout |
| Public Workspace | Visible to all permitted users; requires Workspace Manager role to edit |
| Private Workspace | Per-user dashboard under "My Workspaces"; any Desk User can create |
| Content field | JSON array storing the block layout |
| Child tables | 6 tables: charts, shortcuts, links, quick_lists, number_cards, custom_blocks |
| Module association | Primary access control mechanism |
---
## Master Decision: What Do You Need?
```
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 Structure
### Key Fields
| Field | Type | Purpose |
|-------|------|---------|
| `label` | Data | Display name in sidebar |
| `title` | Data | Page title (defaults to label) |
| `module` | Link → Module Def | Associates workspace with a module for access control |
| `parent_page` | Link → Workspace | Nesting under another workspace in sidebar |
| `icon` | Data | Sidebar icon (e.g., `"chart-line"`) |
| `type` | Select | `Workspace` / `Link` / `URL` (v15+) |
| `sequence_id` | Int | Sidebar ordering |
| `content` | JSON | Block layout as JSON array |
| `for_user` | Data | If set, workspace is private to that user |
| `roles` | Table → Has Role | Role-based access restrictions |
| `app` | Data | Owning app identifier (v15+) |
| `indicator_color` | Color | Sidebar indicator dot (v15+) |
### Child Tables (6 total)
| Child Table | DocType | Purpose |
|-------------|---------|---------|
| `charts` | Workspace Chart | Dashboard Chart references |
| `shortcuts` | Workspace Shortcut | DocType/Report/Page/URL shortcuts |
| `links` | Workspace Link | Grouped navigation links |
| `quick_lists` | Workspace Quick List | Recent record lists |
| `number_cards` | Workspace Number Card | Metric card references |
| `custom_blocks` | Workspace Custom Block | HTML block references |
> **CRITICAL**: The `content` JSON and the child tables MUST stay in sync. ALWAYS use the Workspace Builder UI or programmatic API — NEVER manually edit the `content` JSON without updating child tables. See `references/anti-patterns.md`.
---
## Content JSON Format
The `content` field is a JSON array. Each element represents a block in the 12-column grid:
```json
[
{
"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}
}
]
```
### Block Types
| Type | `data` fields | Description |
|------|---------------|-------------|
| `header` | `text`, `level`, `col` | Section heading (h3/h4/h5) |
| `chart` | `chart_name`, `col` | References a Dashboard Chart doc |
| `number_card` | `number_card_name`, `col` | References a Number Card doc |
| `shortcut` | `shortcut_name`, `col` | References a Workspace Shortcut child |
| `card` | `card_name`, `col` | Card break for grouped links |
| `quick_list` | `quick_list_name`, `col` | Recent records for a DocType |
| `custom_block` | `custom_block_name`, `col` | References a Custom HTML Block doc |
| `text` | `body`, `col` | Rich text / Markdown block |
| `spacer` | `col` | Empty vertical space |
| `onboarding` | `onboarding_name`, `col` | Module onboarding widget |
> `col` values MUST be 1-12 and represent grid column width. Blocks in the same row MUST sum to ≤ 12.
---
## Implementation Workflows
### Workflow 1: Create a Public Workspace via UI
1. Navigate to `/app/workspace` → click **+ New Workspace**
2. Set **Label** (appears in sidebar), **Module**, **Icon**
3. Use the Workspace Builder to drag-and-drop blocks
4. Add components: Charts, Number Cards, Shortcuts, Links
5. Click **Save** → workspace appears in sidebar for permitted users
6. In developer mode: JSON auto-exports to your app directory
### Workflow 2: Create a Workspace Programmatically
```python
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}
}