- Introduced coding standards for TypeScript and React in SKILL.md. - Added continuous learning skill with configuration and evaluation scripts. - Created detail layout guidelines for read-only pages. - Established form layout rules for data-entry forms. - Documented project guidelines for the frontend monorepo. - Implemented security review checklist for frontend/Electron applications. - Developed a verification loop skill for comprehensive session checks. This commit enhances the skill set available for developers, ensuring adherence to best practices and improving code quality.
15 KiB
name, description
| name | description |
|---|---|
| detail-layout | Use whenever building or editing a read-only detail / show page in the ERP project (entity detail screens, master-data detail, transaction detail, device/asset detail, contract-style detail with tabs). Governs LAYOUT ONLY — page vertical stack, identity/hero placement, section card stacking, key-value grids vs label/value rows, status metric blocks, summary multi-column blocks, workflow steppers, horizontal tabs for many data categories, embedded tables/lists, and action placement. Does not govern colors, fonts, border-radius, shadows, or other visual styling. Trigger this any time a detail page, detail section, FieldValue grid, detail tab, or related-list table on a detail page is added or restructured — including when the user says "build a detail page", "show entity data", or explicitly asks for tabs. |
Detail Layout
Layout rules for read-only detail / show pages, derived from this project's detail references:
- references/web-device-detail.png — desktop stacked section cards + key-value grid
- references/mobile-device-detail.png — narrow stacked cards + label/value rows
- references/web-contract-detail-tabs.png — top summary + stepper + horizontal tabs for many categories
These rules are about structure and position, not visual style (color, weight, radius, shadows belong to the design system / @repo/ui, not this skill).
Every detail page decision should be made by walking the steps below, in order.
Project chrome (do not rebuild)
Detail routes already render inside EnterpriseDetailPageProvider → ModulePageHeader / CorePageContainer. That chrome owns:
- Breadcrumbs
- Page title (+ optional highlight key, e.g. code/id)
- Status badge next to the title
- Global page actions (Edit, Duplicate, Delete, lifecycle actions, Create)
Do not re-implement those in the detail body. This skill governs the children of EnterpriseDetailPageProvider — the detail content below the module header.
Optional identity / hero (§3) is an extra content block when the entity benefits from an avatar/image + display name stack; it is not a second page header.
1. Pick the page body mode
Look at how many distinct data categories the entity has — that decides stacked vs tabbed body:
| Detail type | Body mode |
|---|---|
| Few categories (≤3–4 section cards; e.g. Branch, User, simple master data) | Stacked sections — vertical stack of section cards under the header |
| Many categories (>3–4 distinct groups) or the user explicitly asks for tabs | Tabbed body — keep a slim always-visible top (identity / summary / stepper), then a horizontal tab bar; each tab owns one category's content |
| Narrow / mobile viewport | Same mode as desktop; only the internal key-value and status layouts collapse (§13) |
Once a page picks stacked vs tabbed, stay consistent — don't mix an ad-hoc tab region with an ad-hoc long scroll of the same categories.
Force tabs when:
- The user prompt says to use tab(s), or
- Showing every section at once would produce a long scroll of ≥4–5 independent category cards (e.g. Basic / Attachments / Milestone / Payment / Approvals / History).
2. Vertical structure of the detail page
Top → bottom, never reorder:
- Module chrome — already provided by
EnterpriseDetailPageProvider(breadcrumbs, title, status, global actions). - Identity / hero (optional, §3) — only when an image/avatar + primary display name is part of the entity story.
- Summary block (optional, §7) — high-level at-a-glance metadata / parties / key facts in a multi-column grid. Prefer this on tabbed pages so critical facts stay visible while tabs switch.
- Workflow stepper (optional, §8) — only for entities with a linear lifecycle.
- Body — either:
- Stacked: section cards (§4) in category order, or
- Tabbed: tab bar (§9) then the active tab panel (§10).
Gap between these major bands uses the largest rhythm gap (§12).
3. Identity / hero (optional content block)
Use when the entity has a meaningful visual (device photo, avatar, logo). Skip for plain master-data rows where the module header title is enough.
Desktop / wide
Single horizontal row inside one section surface:
| Left | Middle (flex grow) | Right |
|---|---|---|
| Leading media (fixed square/circle) | Title stack: primary name (+ id if not already in chrome), then one short subtitle/category line | Primary content action if it belongs to this block (usually omit — Edit lives in module chrome) |
- Media left-aligned; title stack left-aligned next to media; any block-level action right-aligned on the same row.
- Do not center the hero on wide layouts.
Narrow / mobile
Vertical centered stack: media → title → subtitle → optional full-width outline action.
- Center alignment is correct on narrow widths only.
- Primary action, if shown here, is full width under the subtitle — not beside the title.
4. Section cards (category containers)
Every logical data group is its own section container (e.g. "Device Details", "Security & OS Details", "Documents"):
- Sections stack vertically with consistent gap (§12) — never side-by-side category cards for independent groups.
- Inside each section, top row is a section header band:
- Left: section title (bold text only — no input).
- Right (optional): section-scoped action (e.g. "Upload a document") — text/link or secondary control, right-aligned on the same baseline as the title.
- Body of the section is one of: key-value grid (§5), key-value list (§5), status metric row/stack (§6), embedded table (§11), or a short summary + table combo (§10).
- One section = one job. Don't dump unrelated fields into the same card.
5. Key-value fields
Use FieldValue (or equivalent) for static metadata. Choose orientation by viewport / density:
A. Label-above grid (default on desktop / wide)
Matches the web device-detail reference and current SimpleGrid + FieldValue usage:
- Multi-column grid, typically 3–5 columns on wide (
md+), 2 onsm, 1 onbase. - Each cell is a vertical stack: label on top, value underneath (this is what
FieldValuealready does). - Fill left → right, top → bottom in reading order.
- Prefer equal column tracks; a short leftover row leaves trailing cells empty — do not stretch the last field full width just to fill space.
- Long free-text (address, notes) may span 2 columns or the full section width when the value would wrap awkwardly in a single track.
B. Label-left / value-right rows (default on narrow / mobile)
Matches the mobile device-detail reference:
- One field per row: label left-aligned, value right-aligned.
- Rows stack vertically inside the section; no multi-column grid on the narrow breakpoint.
- Status-colored values and link values stay in the value slot (right side) — they do not move to a new row.
Do not mix A and B inside the same section at the same breakpoint. Responsive collapse (§13) switches A → B on narrow widths.
6. Status / metric blocks
Use when each item is a named capability or check with its own status (e.g. Antivirus / MDM / Encryption / OS), not a flat field list.
Desktop / wide
Horizontal row of equal sub-blocks inside the section:
Each sub-block, top → bottom:
- Icon + small category label (same row)
- Primary value (software name / version)
- Status badge / tag under the value
Narrow / mobile
Same sub-blocks, stacked vertically. Inside each sub-block:
- Icon + small category label (top row)
- Primary value on the next row, with status badge on the same row to the right of the value
Don't use this pattern for ordinary scalar fields — those stay in §5.
7. Summary multi-column block (optional, top of body)
Use on complex / tabbed details when several at-a-glance groups must stay visible above tabs (e.g. dates/value metadata | Party A | Party B):
- Full-width band under identity (or under module chrome if no identity).
- 2–3 equal columns on wide; each column is a titled group of compact key-value rows (label then value on one line, or icon + label + value).
- Columns are peer groups, not a key-value grid of unrelated fields — if fields aren't grouped into 2–3 stories, use a normal §5 section instead.
- Collapses to a vertical stack of the same groups on narrow widths (§13).
8. Workflow stepper (optional)
Only for entities with a linear lifecycle (Draft → Review → … → Active):
- Full-width band under summary (or under identity / chrome).
- Horizontal sequence left → right; completed → current → upcoming order must match domain order.
- Label the band with a short section title above the stepper (e.g. "Status update").
- On narrow widths, keep sequence order; may scroll horizontally or show a compact current-step focus — never reorder stages.
9. Horizontal tabs (many-data body)
When §1 selects tabbed body:
- Tab bar sits below identity / summary / stepper and above the active panel — never above the module chrome, never below the first content card of a stacked page.
- Tabs are a single horizontal list of category labels (Basic details, Attachments, Milestone, Payment, …).
- One active tab at a time; switching tabs replaces the panel content — do not keep all tab panels mounted as a long scroll underneath.
- Prefer ≤8–9 tabs; if more categories exist, merge related ones or keep rare ones behind a secondary entry inside a tab.
- Tab labels are short nouns/phrases; order tabs by user-task frequency (overview / basics first, history last).
- Use project
Tabsfrom@repo/ui/components(see showcase forms demo for list/panel structure) — layout concern only:Tabs.ListthenTabs.Panels.
What stays outside tabs
Always-visible above the tab bar (when present): identity (§3), summary (§7), stepper (§8). Do not put the only copy of critical status / party / date facts exclusively inside a tab if the user needs them while browsing other tabs.
10. Tab panel content
Each panel is laid out as if it were a small stacked detail of its own:
- Optional panel sub-header — section title left; optional summary metrics split left/right on the same row (e.g. "Total invoice value" left, "Total estimated project value" right).
- Optional visual summary (progress bar / distribution) full width under the sub-header — position only; styling is design-system.
- One or more section cards (§4) and/or an embedded table (§11).
Do not nest a second tab bar inside a panel.
11. Embedded tables / related lists
For collections (documents, payment proofs, line history):
- Table lives inside a section card (§4).
- Section header band: title left, section action(s) right — filters and "Add …" sit on the right of the header, same row as the title (or immediately under the title row if filters + primary action don't fit).
- Column headers above rows; text/id columns left-aligned; numeric columns right-aligned; status as an inline indicator in its cell; row actions in a fixed trailing column (ellipsis / menu) — same width every row.
- Empty state stays inside the table/section body — don't relocate the section action.
12. Vertical rhythm
Define three consistent gap sizes and use them the same way on every detail page:
- Label → value (smallest): binds a field's label to its value (
FieldValuegap). - Field → next field / sub-block → next sub-block (medium): separates peers inside a section.
- Section → section, and major band → next band (largest): separates cards, summary, stepper, and tab bar from each other.
Horizontal gaps inside grids match the medium rhythm. Don't invent a fourth gap tier per page.
13. Responsive collapse
| Wide layout | Narrow collapse |
|---|---|
| Identity hero row (media | title | action) | Centered vertical stack (media → title → subtitle → full-width action) |
| Key-value label-above grid (§5A) | Label-left / value-right rows (§5B) |
| Status metric horizontal row (§6) | Stacked metric sub-blocks; badge beside value |
| Summary 2–3 columns (§7) | Stacked column groups, same order |
| Tab list | Horizontally scrollable tab list; panels still one-at-a-time |
| Table | Horizontal scroll inside the section or stacked label/value per row — pick one strategy per table type and keep it project-wide |
Never re-pair fields into different logical groups on collapse — only column count / orientation changes.
14. Action placement (position only)
| Action scope | Position |
|---|---|
| Global entity actions (Edit, Delete, Activate, …) | Module header actions via EnterpriseDetailPageProvider — top-right of chrome |
| Section-scoped action (Upload, Add record) | Right side of that section's header band (§4 / §11) |
| Section filters | Right side of the table/section header, before or beside the section primary action |
| Row action | Trailing column of that row only |
Do not duplicate Edit in the body if the provider already exposes it, unless a mobile identity block needs a full-width local affordance (§3 narrow).
15. Checklist before finalizing any detail page
- Did you choose stacked vs tabbed from category count / user request, per §1?
- Is module chrome left to
EnterpriseDetailPageProvider(no second breadcrumb/title/action bar)? - If tabbed: do identity / summary / stepper stay above the tab bar, per §9?
- Is every category its own section card with title-left / action-right, per §4?
- Are scalar fields using label-above grid on wide and label/value rows on narrow, per §5 / §13?
- Are status/capability items using metric sub-blocks (§6), not mixed into a flat field grid?
- Do related lists use header actions + table alignment rules, per §11?
- Are global vs section vs row actions in the correct slots, per §14?
- Does collapse preserve grouping and only change orientation/columns, per §13?
Quick mapping to this codebase
// Stacked (few categories) — children of EnterpriseDetailPageProvider
<>
{/* optional identity */}
<Paper>{/* section: SimpleGrid + FieldValue */}</Paper>
<Paper>{/* section: status metrics or table */}</Paper>
</>
// Tabbed (many categories / user asked for tabs)
<>
{/* optional identity + summary + stepper */}
<Tabs defaultValue="basic">
<Tabs.List>{/* category tabs */}</Tabs.List>
<Tabs.Panel value="basic">{/* section cards */}</Tabs.Panel>
<Tabs.Panel value="payments">{/* summary row + table */}</Tabs.Panel>
</Tabs>
</>
Prefer existing primitives: Paper / section surfaces, SimpleGrid, FieldValue, Tabs, StatusBadge, table components from @repo/ui — this skill decides where they sit, not how they are themed.