@consciousclouds/operator-shell 0.1.0
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/CHANGELOG.md +36 -0
- package/LICENSE +194 -0
- package/README.md +319 -0
- package/dist/chief/ChiefDrawer.d.ts +11 -0
- package/dist/chief/ChiefDrawer.d.ts.map +1 -0
- package/dist/chief/ChiefDrawer.js +49 -0
- package/dist/chief/ChiefDrawer.js.map +1 -0
- package/dist/chief/ChiefPanel.d.ts +10 -0
- package/dist/chief/ChiefPanel.d.ts.map +1 -0
- package/dist/chief/ChiefPanel.js +46 -0
- package/dist/chief/ChiefPanel.js.map +1 -0
- package/dist/chief/ChiefRegion.d.ts +9 -0
- package/dist/chief/ChiefRegion.d.ts.map +1 -0
- package/dist/chief/ChiefRegion.js +55 -0
- package/dist/chief/ChiefRegion.js.map +1 -0
- package/dist/chief/ChiefSession.d.ts +21 -0
- package/dist/chief/ChiefSession.d.ts.map +1 -0
- package/dist/chief/ChiefSession.js +9 -0
- package/dist/chief/ChiefSession.js.map +1 -0
- package/dist/chief/directive.d.ts +15 -0
- package/dist/chief/directive.d.ts.map +1 -0
- package/dist/chief/directive.js +20 -0
- package/dist/chief/directive.js.map +1 -0
- package/dist/chief/turn-adapter.d.ts +52 -0
- package/dist/chief/turn-adapter.d.ts.map +1 -0
- package/dist/chief/turn-adapter.js +23 -0
- package/dist/chief/turn-adapter.js.map +1 -0
- package/dist/chief/use-chief-shortcut.d.ts +17 -0
- package/dist/chief/use-chief-shortcut.d.ts.map +1 -0
- package/dist/chief/use-chief-shortcut.js +61 -0
- package/dist/chief/use-chief-shortcut.js.map +1 -0
- package/dist/chief/use-chief-turn.d.ts +50 -0
- package/dist/chief/use-chief-turn.d.ts.map +1 -0
- package/dist/chief/use-chief-turn.js +99 -0
- package/dist/chief/use-chief-turn.js.map +1 -0
- package/dist/flavor/types.d.ts +189 -0
- package/dist/flavor/types.d.ts.map +1 -0
- package/dist/flavor/types.js +13 -0
- package/dist/flavor/types.js.map +1 -0
- package/dist/frame/OperatorShell.d.ts +91 -0
- package/dist/frame/OperatorShell.d.ts.map +1 -0
- package/dist/frame/OperatorShell.js +54 -0
- package/dist/frame/OperatorShell.js.map +1 -0
- package/dist/guard/PermissionProvider.d.ts +49 -0
- package/dist/guard/PermissionProvider.d.ts.map +1 -0
- package/dist/guard/PermissionProvider.js +103 -0
- package/dist/guard/PermissionProvider.js.map +1 -0
- package/dist/guard/RouteGuard.d.ts +45 -0
- package/dist/guard/RouteGuard.d.ts.map +1 -0
- package/dist/guard/RouteGuard.js +59 -0
- package/dist/guard/RouteGuard.js.map +1 -0
- package/dist/guard/permissions.d.ts +88 -0
- package/dist/guard/permissions.d.ts.map +1 -0
- package/dist/guard/permissions.js +105 -0
- package/dist/guard/permissions.js.map +1 -0
- package/dist/header/EnvironmentSwitcher.d.ts +5 -0
- package/dist/header/EnvironmentSwitcher.d.ts.map +1 -0
- package/dist/header/EnvironmentSwitcher.js +51 -0
- package/dist/header/EnvironmentSwitcher.js.map +1 -0
- package/dist/header/OperatorHeader.d.ts +25 -0
- package/dist/header/OperatorHeader.d.ts.map +1 -0
- package/dist/header/OperatorHeader.js +13 -0
- package/dist/header/OperatorHeader.js.map +1 -0
- package/dist/header/OperatorProfileMenu.d.ts +2 -0
- package/dist/header/OperatorProfileMenu.d.ts.map +1 -0
- package/dist/header/OperatorProfileMenu.js +14 -0
- package/dist/header/OperatorProfileMenu.js.map +1 -0
- package/dist/header/ThemeToggle.d.ts +2 -0
- package/dist/header/ThemeToggle.d.ts.map +1 -0
- package/dist/header/ThemeToggle.js +17 -0
- package/dist/header/ThemeToggle.js.map +1 -0
- package/dist/icons/registry.d.ts +57 -0
- package/dist/icons/registry.d.ts.map +1 -0
- package/dist/icons/registry.js +83 -0
- package/dist/icons/registry.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +129 -0
- package/dist/index.js.map +1 -0
- package/dist/inspector/InspectorProvider.d.ts +41 -0
- package/dist/inspector/InspectorProvider.d.ts.map +1 -0
- package/dist/inspector/InspectorProvider.js +63 -0
- package/dist/inspector/InspectorProvider.js.map +1 -0
- package/dist/inspector/types.d.ts +91 -0
- package/dist/inspector/types.d.ts.map +1 -0
- package/dist/inspector/types.js +40 -0
- package/dist/inspector/types.js.map +1 -0
- package/dist/nav/routes.d.ts +39 -0
- package/dist/nav/routes.d.ts.map +1 -0
- package/dist/nav/routes.js +46 -0
- package/dist/nav/routes.js.map +1 -0
- package/dist/palette/CommandPalette.d.ts +40 -0
- package/dist/palette/CommandPalette.d.ts.map +1 -0
- package/dist/palette/CommandPalette.js +108 -0
- package/dist/palette/CommandPalette.js.map +1 -0
- package/dist/palette/commands.d.ts +58 -0
- package/dist/palette/commands.d.ts.map +1 -0
- package/dist/palette/commands.js +81 -0
- package/dist/palette/commands.js.map +1 -0
- package/dist/palette/search-sources.d.ts +126 -0
- package/dist/palette/search-sources.d.ts.map +1 -0
- package/dist/palette/search-sources.js +101 -0
- package/dist/palette/search-sources.js.map +1 -0
- package/dist/palette/use-search-results.d.ts +4 -0
- package/dist/palette/use-search-results.d.ts.map +1 -0
- package/dist/palette/use-search-results.js +51 -0
- package/dist/palette/use-search-results.js.map +1 -0
- package/dist/sidebar/OperatorSidebar.d.ts +44 -0
- package/dist/sidebar/OperatorSidebar.d.ts.map +1 -0
- package/dist/sidebar/OperatorSidebar.js +30 -0
- package/dist/sidebar/OperatorSidebar.js.map +1 -0
- package/dist/workspace/CanvasWorkspace.d.ts +78 -0
- package/dist/workspace/CanvasWorkspace.d.ts.map +1 -0
- package/dist/workspace/CanvasWorkspace.js +44 -0
- package/dist/workspace/CanvasWorkspace.js.map +1 -0
- package/dist/workspace/DashboardWorkspace.d.ts +91 -0
- package/dist/workspace/DashboardWorkspace.d.ts.map +1 -0
- package/dist/workspace/DashboardWorkspace.js +39 -0
- package/dist/workspace/DashboardWorkspace.js.map +1 -0
- package/dist/workspace/FormWorkspace.d.ts +107 -0
- package/dist/workspace/FormWorkspace.d.ts.map +1 -0
- package/dist/workspace/FormWorkspace.js +38 -0
- package/dist/workspace/FormWorkspace.js.map +1 -0
- package/dist/workspace/GraphWorkspace.d.ts +112 -0
- package/dist/workspace/GraphWorkspace.d.ts.map +1 -0
- package/dist/workspace/GraphWorkspace.js +147 -0
- package/dist/workspace/GraphWorkspace.js.map +1 -0
- package/dist/workspace/TableWorkspace.d.ts +74 -0
- package/dist/workspace/TableWorkspace.d.ts.map +1 -0
- package/dist/workspace/TableWorkspace.js +25 -0
- package/dist/workspace/TableWorkspace.js.map +1 -0
- package/dist/workspace/WorkspaceHost.d.ts +26 -0
- package/dist/workspace/WorkspaceHost.d.ts.map +1 -0
- package/dist/workspace/WorkspaceHost.js +21 -0
- package/dist/workspace/WorkspaceHost.js.map +1 -0
- package/dist/workspace/registry.d.ts +30 -0
- package/dist/workspace/registry.d.ts.map +1 -0
- package/dist/workspace/registry.js +33 -0
- package/dist/workspace/registry.js.map +1 -0
- package/dist/workspace/types.d.ts +79 -0
- package/dist/workspace/types.d.ts.map +1 -0
- package/dist/workspace/types.js +48 -0
- package/dist/workspace/types.js.map +1 -0
- package/package.json +64 -0
- package/styles/source.css +16 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { usePathname } from "next/navigation";
|
|
5
|
+
import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarRail, } from "@consciousclouds/ui";
|
|
6
|
+
import { collectPermissionRefs } from "../guard/permissions.js";
|
|
7
|
+
import { usePermissionDecisions } from "../guard/PermissionProvider.js";
|
|
8
|
+
import { resolveIcon } from "../icons/registry.js";
|
|
9
|
+
import { deriveGatedNavGroups, isNavItemActive } from "../nav/routes.js";
|
|
10
|
+
export function OperatorSidebar({ flavor, resolvePermission, icons, iconFamily, workspaceSwitcher, }) {
|
|
11
|
+
const pathname = usePathname();
|
|
12
|
+
const { product } = flavor;
|
|
13
|
+
// One batch resolution for the whole tree — each reference resolved once,
|
|
14
|
+
// sync decisions on the first render, async ones settling from `loading`.
|
|
15
|
+
const permissionRefs = collectPermissionRefs(flavor.nav.flatMap((group) => group.items));
|
|
16
|
+
const decisions = usePermissionDecisions(permissionRefs, resolvePermission);
|
|
17
|
+
// The pure derivation (nav/routes.ts): denied items don't exist, loading
|
|
18
|
+
// items keep a slot, emptied groups vanish.
|
|
19
|
+
const groups = deriveGatedNavGroups(flavor.nav, decisions);
|
|
20
|
+
return (_jsxs(Sidebar, { collapsible: "icon", className: "top-(--header-height) h-[calc(100svh-var(--header-height))]!", children: [_jsxs(SidebarHeader, { className: "border-b border-sidebar-border px-4 py-3 group-data-[collapsible=icon]:hidden", children: [workspaceSwitcher, product.label && (_jsx("div", { className: "text-[10px] font-semibold tracking-wider text-primary uppercase", children: product.label })), _jsx("div", { className: "truncate text-sm font-semibold text-sidebar-foreground", children: product.name }), product.note && (_jsx("div", { className: "text-[11px] leading-snug text-muted-foreground", children: product.note }))] }), _jsx(SidebarContent, { children: groups.map(({ group, items }) => (_jsxs(SidebarGroup, { children: [_jsx(SidebarGroupLabel, { children: group.label }), _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: items.map(({ item, status }) => {
|
|
21
|
+
if (status === "loading") {
|
|
22
|
+
// The decision is in flight: hold the slot, never flash
|
|
23
|
+
// a destination the resolver may take away.
|
|
24
|
+
return (_jsx(SidebarMenuItem, { "data-slot": "nav-permission-loading", children: _jsx(SidebarMenuSkeleton, { showIcon: true }) }, item.id));
|
|
25
|
+
}
|
|
26
|
+
const Icon = resolveIcon(item.icon, icons, iconFamily);
|
|
27
|
+
return (_jsx(SidebarMenuItem, { children: _jsx(SidebarMenuButton, { asChild: true, isActive: isNavItemActive(item.href, pathname), tooltip: item.label, children: _jsxs(Link, { href: item.href, children: [_jsx(Icon, {}), _jsx("span", { children: item.label })] }) }) }, item.id));
|
|
28
|
+
}) }) })] }, group.id))) }), _jsx(SidebarRail, {})] }));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=OperatorSidebar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperatorSidebar.js","sourceRoot":"","sources":["../../src/sidebar/OperatorSidebar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canvas workspace type — the FIRST-CLASS canvas workspace (the mission's
|
|
3
|
+
* AI-native correction made real: a Canvas is a peer workspace in the main
|
|
4
|
+
* region, not a bolt-on page).
|
|
5
|
+
*
|
|
6
|
+
* MECHANISM ONLY. The framework owns the hosting state machine
|
|
7
|
+
* (error → loading → empty → ready) and delegates rendering to the published
|
|
8
|
+
* @consciousclouds/canvas-runtime CanvasRenderer — consumed as-is, never
|
|
9
|
+
* rebuilt (the renderer keeps its own fail-closed behavior: unknown/removed/
|
|
10
|
+
* unmapped node types render placeholders, permission-filtered nodes drop).
|
|
11
|
+
*
|
|
12
|
+
* MEANING stays with the product: the product fetches the CanvasDefinition
|
|
13
|
+
* (it owns routes/BFF — no URL ever enters this package), supplies the
|
|
14
|
+
* ComponentMap for approved node types, and may supply loading/error/empty
|
|
15
|
+
* slot content in its own words. The framework's default slot content is
|
|
16
|
+
* neutral and fail-closed.
|
|
17
|
+
*
|
|
18
|
+
* Frame-free by design (Separation Law): imports only React, the UI
|
|
19
|
+
* primitives, and the canvas SDKs — never the shell frame.
|
|
20
|
+
*/
|
|
21
|
+
import type * as React from "react";
|
|
22
|
+
import { type ActionHandler, type ComponentMap } from "@consciousclouds/canvas-runtime";
|
|
23
|
+
import type { CanvasDefinition } from "@consciousclouds/canvas-sdk";
|
|
24
|
+
import type { WorkspaceComponentProps, WorkspaceType } from "./types.js";
|
|
25
|
+
/**
|
|
26
|
+
* Product-supplied state content. Each slot replaces the framework's neutral
|
|
27
|
+
* default for that state — the product speaks in its own words (fail-closed
|
|
28
|
+
* copy, domain-specific empty states) while the framework decides WHICH
|
|
29
|
+
* state renders.
|
|
30
|
+
*/
|
|
31
|
+
export interface CanvasWorkspaceSlots {
|
|
32
|
+
/** Rendered while `definition` is still null and no error is set. */
|
|
33
|
+
loading?: React.ReactNode;
|
|
34
|
+
/** Rendered when `error` is set; receives the error message. */
|
|
35
|
+
error?: (message: string) => React.ReactNode;
|
|
36
|
+
/** Rendered when the definition resolved but has zero nodes. */
|
|
37
|
+
empty?: React.ReactNode;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The canvas workspace mount input. The product owns the fetch lifecycle and
|
|
41
|
+
* hands the framework its current state; the framework owns the state
|
|
42
|
+
* machine and the renderer mount.
|
|
43
|
+
*
|
|
44
|
+
* Precedence (fail-closed first): `error` → loading (`definition === null`)
|
|
45
|
+
* → empty (zero nodes) → ready (CanvasRenderer).
|
|
46
|
+
*/
|
|
47
|
+
export interface CanvasWorkspaceInput {
|
|
48
|
+
/** The canvas to render; `null` while the product is still loading it. */
|
|
49
|
+
definition: CanvasDefinition | null;
|
|
50
|
+
/**
|
|
51
|
+
* A load-failure message. When set, the workspace renders the error slot
|
|
52
|
+
* and NOTHING else — a failed read fails closed rather than showing a
|
|
53
|
+
* misleading empty surface.
|
|
54
|
+
*/
|
|
55
|
+
error?: string | null;
|
|
56
|
+
/** Product implementations of approved canvas node types (renderer-injected). */
|
|
57
|
+
componentMap: ComponentMap;
|
|
58
|
+
/** Receives dispatched node actions (the renderer never navigates directly). */
|
|
59
|
+
onAction?: ActionHandler;
|
|
60
|
+
/**
|
|
61
|
+
* Caller permissions, forwarded verbatim to CanvasRenderer's node-level
|
|
62
|
+
* permission filtering. Omitted = filtering not engaged (renderer default).
|
|
63
|
+
*/
|
|
64
|
+
permissions?: string[];
|
|
65
|
+
/** Product-supplied state content; neutral defaults otherwise. */
|
|
66
|
+
slots?: CanvasWorkspaceSlots;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The canvas workspace component. State selection is the framework's; state
|
|
70
|
+
* content and canvas meaning are the product's.
|
|
71
|
+
*/
|
|
72
|
+
export declare function CanvasWorkspace({ input, }: WorkspaceComponentProps<CanvasWorkspaceInput>): import("react/jsx-runtime").JSX.Element;
|
|
73
|
+
/**
|
|
74
|
+
* The registered `canvas` workspace type — compose it into the app's
|
|
75
|
+
* registry via `createWorkspaceRegistry([canvasWorkspaceType, ...])`.
|
|
76
|
+
*/
|
|
77
|
+
export declare const canvasWorkspaceType: WorkspaceType<CanvasWorkspaceInput>;
|
|
78
|
+
//# sourceMappingURL=CanvasWorkspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CanvasWorkspace.d.ts","sourceRoot":"","sources":["../../src/workspace/CanvasWorkspace.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC7C,gEAAgE;IAChE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iFAAiF;IACjF,YAAY,EAAE,YAAY,CAAC;IAC3B,gFAAgF;IAChF,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,kEAAkE;IAClE,KAAK,CAAC,EAAE,oBAAoB,CAAC;CAC9B;AAmCD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,GACN,EAAE,uBAAuB,CAAC,oBAAoB,CAAC,2CAqC/C;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,oBAAoB,CAMnE,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { CanvasRenderer, } from "@consciousclouds/canvas-runtime";
|
|
4
|
+
import { Skeleton } from "@consciousclouds/ui";
|
|
5
|
+
/** Neutral default while the product's canvas read is in flight. */
|
|
6
|
+
function DefaultLoading() {
|
|
7
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsx(Skeleton, { className: "h-7 w-44" }), _jsx(Skeleton, { className: "h-16 w-full" }), _jsx(Skeleton, { className: "h-16 w-full" })] }));
|
|
8
|
+
}
|
|
9
|
+
/** Neutral default when the product's canvas read failed — explicit, never blank. */
|
|
10
|
+
function DefaultError({ message }) {
|
|
11
|
+
return (_jsxs("div", { role: "alert", className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: ["Couldn't load this canvas (", message, "). The workspace fails closed rather than render a misleading empty surface."] }));
|
|
12
|
+
}
|
|
13
|
+
/** Neutral default when the canvas resolved with zero nodes. */
|
|
14
|
+
function DefaultEmpty() {
|
|
15
|
+
return (_jsx("div", { className: "rounded-lg border border-border bg-card p-4 text-sm text-muted-foreground", children: "This canvas has no content yet." }));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The canvas workspace component. State selection is the framework's; state
|
|
19
|
+
* content and canvas meaning are the product's.
|
|
20
|
+
*/
|
|
21
|
+
export function CanvasWorkspace({ input, }) {
|
|
22
|
+
const { definition, error, componentMap, onAction, permissions, slots } = input;
|
|
23
|
+
if (error != null) {
|
|
24
|
+
return (_jsx("div", { "data-canvas-workspace-state": "error", children: slots?.error ? slots.error(error) : _jsx(DefaultError, { message: error }) }));
|
|
25
|
+
}
|
|
26
|
+
if (definition === null) {
|
|
27
|
+
return (_jsx("div", { "data-canvas-workspace-state": "loading", children: slots?.loading ?? _jsx(DefaultLoading, {}) }));
|
|
28
|
+
}
|
|
29
|
+
if (definition.nodes.length === 0) {
|
|
30
|
+
return (_jsx("div", { "data-canvas-workspace-state": "empty", children: slots?.empty ?? _jsx(DefaultEmpty, {}) }));
|
|
31
|
+
}
|
|
32
|
+
return (_jsx("div", { "data-canvas-workspace-state": "ready", children: _jsx(CanvasRenderer, { definition: definition, componentMap: componentMap, onAction: onAction, permissions: permissions }) }));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The registered `canvas` workspace type — compose it into the app's
|
|
36
|
+
* registry via `createWorkspaceRegistry([canvasWorkspaceType, ...])`.
|
|
37
|
+
*/
|
|
38
|
+
export const canvasWorkspaceType = {
|
|
39
|
+
id: "canvas",
|
|
40
|
+
displayName: "Canvas",
|
|
41
|
+
description: "Renders a CanvasDefinition through the published canvas-runtime with a product-injected component map.",
|
|
42
|
+
Component: CanvasWorkspace,
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=CanvasWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CanvasWorkspace.js","sourceRoot":"","sources":["../../src/workspace/CanvasWorkspace.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAyBb,OAAO,EACL,cAAc,GAGf,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAiD/C,oEAAoE;AACpE,SAAS,cAAc;IACrB,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,aACxB,KAAC,QAAQ,IAAC,SAAS,EAAC,UAAU,GAAG,EACjC,KAAC,QAAQ,IAAC,SAAS,EAAC,aAAa,GAAG,EACpC,KAAC,QAAQ,IAAC,SAAS,EAAC,aAAa,GAAG,IAChC,CACP,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,SAAS,YAAY,CAAC,EAAE,OAAO,EAAuB;IACpD,OAAO,CACL,eACE,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,uFAAuF,4CAEhE,OAAO,oFAEpC,CACP,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,SAAS,YAAY;IACnB,OAAO,CACL,cAAK,SAAS,EAAC,2EAA2E,gDAEpF,CACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,KAAK,GACyC;IAC9C,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAEhF,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,CACL,6CAAiC,OAAO,YACrC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAC,YAAY,IAAC,OAAO,EAAE,KAAK,GAAI,GACjE,CACP,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,CACL,6CAAiC,SAAS,YACvC,KAAK,EAAE,OAAO,IAAI,KAAC,cAAc,KAAG,GACjC,CACP,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,CACL,6CAAiC,OAAO,YACrC,KAAK,EAAE,KAAK,IAAI,KAAC,YAAY,KAAG,GAC7B,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,6CAAiC,OAAO,YACtC,KAAC,cAAc,IACb,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,GACxB,GACE,CACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAwC;IACtE,EAAE,EAAE,QAAQ;IACZ,WAAW,EAAE,QAAQ;IACrB,WAAW,EACT,wGAAwG;IAC1G,SAAS,EAAE,eAAe;CAC3B,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard workspace type — the built-in stat/overview workspace: a
|
|
3
|
+
* widget-slot composition of the GRADUATED workspace components (StatCard ·
|
|
4
|
+
* SectionHeading · EmptyState · FailClosed from @consciousclouds/ui).
|
|
5
|
+
*
|
|
6
|
+
* MECHANISM ONLY. The framework owns the hosting state machine
|
|
7
|
+
* (error → loading → empty → ready) and the composition order (notice strip →
|
|
8
|
+
* stat grid → titled widget sections); the PRODUCT owns every value: stat
|
|
9
|
+
* labels/values/trends (favorability is the caller's judgment — see
|
|
10
|
+
* StatCardTrend), the notice wording (e.g. data-freshness honesty), and each
|
|
11
|
+
* section's widget content (tables, charts, lists — arbitrary ReactNode
|
|
12
|
+
* slots). No routes, no fetching, no brand: data arrives fully resolved via
|
|
13
|
+
* the mount input.
|
|
14
|
+
*
|
|
15
|
+
* Frame-free by design (Separation Law): imports only React and the UI
|
|
16
|
+
* primitives — never the shell frame.
|
|
17
|
+
*/
|
|
18
|
+
import type * as React from "react";
|
|
19
|
+
import { type StatCardTrend } from "@consciousclouds/ui";
|
|
20
|
+
import type { WorkspaceComponentProps, WorkspaceType } from "./types.js";
|
|
21
|
+
/** One stat tile in the dashboard's stat grid — rendered through StatCard. */
|
|
22
|
+
export interface DashboardWorkspaceStat {
|
|
23
|
+
/** Stable key for the tile. */
|
|
24
|
+
id: string;
|
|
25
|
+
label: React.ReactNode;
|
|
26
|
+
/** Nullish/empty renders as an em dash (StatCard's honest missing state). */
|
|
27
|
+
value?: React.ReactNode;
|
|
28
|
+
/** Previous-period / context line under the label. */
|
|
29
|
+
hint?: React.ReactNode;
|
|
30
|
+
/** Trend delta badge — supply ONLY when the data honestly carries a trend. */
|
|
31
|
+
trend?: StatCardTrend;
|
|
32
|
+
/** Footnote under the value (e.g. "vs last month"). */
|
|
33
|
+
caption?: React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
/** One titled widget section below the stat grid. */
|
|
36
|
+
export interface DashboardWorkspaceSection {
|
|
37
|
+
/** Stable key for the section. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** Optional section heading (rendered through SectionHeading). */
|
|
40
|
+
heading?: React.ReactNode;
|
|
41
|
+
/**
|
|
42
|
+
* The widget slot — product-supplied content (a DataTable, a chart, a
|
|
43
|
+
* list…). The framework places it; the product means it.
|
|
44
|
+
*/
|
|
45
|
+
content: React.ReactNode;
|
|
46
|
+
}
|
|
47
|
+
/** Product-supplied state content; neutral fail-closed defaults otherwise. */
|
|
48
|
+
export interface DashboardWorkspaceSlots {
|
|
49
|
+
/** Rendered while `loading` is true and no error is set. */
|
|
50
|
+
loading?: React.ReactNode;
|
|
51
|
+
/** Rendered when `error` is set; receives the error message. */
|
|
52
|
+
error?: (message: string) => React.ReactNode;
|
|
53
|
+
/** Rendered when a completed read yields zero stats AND zero sections. */
|
|
54
|
+
empty?: React.ReactNode;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The dashboard workspace mount input. Precedence (fail-closed first):
|
|
58
|
+
* `error` → `loading` → empty (no stats, no sections) → ready.
|
|
59
|
+
*/
|
|
60
|
+
export interface DashboardWorkspaceInput {
|
|
61
|
+
/**
|
|
62
|
+
* A load-failure message. When set, the workspace renders the error state
|
|
63
|
+
* and NOTHING else — a failed read fails closed rather than show a
|
|
64
|
+
* misleading empty dashboard.
|
|
65
|
+
*/
|
|
66
|
+
error?: string | null;
|
|
67
|
+
/** The read is still in flight. */
|
|
68
|
+
loading?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* An annotation strip above the stat grid — the product's honesty seam
|
|
71
|
+
* (e.g. "since boot · in-memory" freshness wording). Optional.
|
|
72
|
+
*/
|
|
73
|
+
notice?: React.ReactNode;
|
|
74
|
+
/** The stat grid (2-up, 4-up from `sm`). */
|
|
75
|
+
stats?: DashboardWorkspaceStat[];
|
|
76
|
+
/** Titled widget sections below the stat grid, in order. */
|
|
77
|
+
sections?: DashboardWorkspaceSection[];
|
|
78
|
+
/** Product-supplied state content; neutral defaults otherwise. */
|
|
79
|
+
slots?: DashboardWorkspaceSlots;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The dashboard workspace component. State selection and composition order
|
|
83
|
+
* are the framework's; every value is the product's.
|
|
84
|
+
*/
|
|
85
|
+
export declare function DashboardWorkspace({ input, }: WorkspaceComponentProps<DashboardWorkspaceInput>): import("react/jsx-runtime").JSX.Element;
|
|
86
|
+
/**
|
|
87
|
+
* The registered `dashboard` workspace type — compose it into the app's
|
|
88
|
+
* registry via `createWorkspaceRegistry([..., dashboardWorkspaceType])`.
|
|
89
|
+
*/
|
|
90
|
+
export declare const dashboardWorkspaceType: WorkspaceType<DashboardWorkspaceInput>;
|
|
91
|
+
//# sourceMappingURL=DashboardWorkspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DashboardWorkspace.d.ts","sourceRoot":"","sources":["../../src/workspace/DashboardWorkspace.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzE,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,sDAAsD;IACtD,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,uDAAuD;IACvD,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,qDAAqD;AACrD,MAAM,WAAW,yBAAyB;IACxC,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,kEAAkE;IAClE,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;CAC1B;AAED,8EAA8E;AAC9E,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC7C,0EAA0E;IAC1E,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACjC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACvC,kEAAkE;IAClE,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC;AAiBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,GACN,EAAE,uBAAuB,CAAC,uBAAuB,CAAC,2CAiElD;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAAa,CAAC,uBAAuB,CAMzE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { EmptyState, FailClosed, SectionHeading, Skeleton, StatCard, } from "@consciousclouds/ui";
|
|
4
|
+
/** Neutral default while the product's read is in flight. */
|
|
5
|
+
function DefaultLoading() {
|
|
6
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4", children: [_jsx(Skeleton, { className: "h-20" }), _jsx(Skeleton, { className: "h-20" }), _jsx(Skeleton, { className: "h-20" }), _jsx(Skeleton, { className: "h-20" })] }), _jsx(Skeleton, { className: "h-40 w-full" })] }));
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The dashboard workspace component. State selection and composition order
|
|
10
|
+
* are the framework's; every value is the product's.
|
|
11
|
+
*/
|
|
12
|
+
export function DashboardWorkspace({ input, }) {
|
|
13
|
+
const { error, loading, notice, stats, sections, slots } = input;
|
|
14
|
+
if (error != null) {
|
|
15
|
+
return (_jsx("div", { "data-dashboard-workspace-state": "error", children: slots?.error ? (slots.error(error)) : (_jsx(FailClosed, { what: "this dashboard", detail: error })) }));
|
|
16
|
+
}
|
|
17
|
+
if (loading) {
|
|
18
|
+
return (_jsx("div", { "data-dashboard-workspace-state": "loading", children: slots?.loading ?? _jsx(DefaultLoading, {}) }));
|
|
19
|
+
}
|
|
20
|
+
const hasStats = (stats?.length ?? 0) > 0;
|
|
21
|
+
const hasSections = (sections?.length ?? 0) > 0;
|
|
22
|
+
if (!hasStats && !hasSections) {
|
|
23
|
+
return (_jsx("div", { "data-dashboard-workspace-state": "empty", children: slots?.empty ?? (_jsx(EmptyState, { children: "This dashboard has no data yet." })) }));
|
|
24
|
+
}
|
|
25
|
+
return (_jsxs("div", { "data-dashboard-workspace-state": "ready", className: "space-y-4", children: [notice != null ? _jsx("div", { children: notice }) : null, hasStats ? (_jsx("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4", children: stats.map((s) => (_jsx(StatCard, { label: s.label, value: s.value, hint: s.hint, trend: s.trend, caption: s.caption, size: "lg" }, s.id))) })) : null, hasSections
|
|
26
|
+
? sections.map((section) => (_jsxs("section", { className: "space-y-4", children: [section.heading != null ? (_jsx(SectionHeading, { children: section.heading })) : null, section.content] }, section.id)))
|
|
27
|
+
: null] }));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The registered `dashboard` workspace type — compose it into the app's
|
|
31
|
+
* registry via `createWorkspaceRegistry([..., dashboardWorkspaceType])`.
|
|
32
|
+
*/
|
|
33
|
+
export const dashboardWorkspaceType = {
|
|
34
|
+
id: "dashboard",
|
|
35
|
+
displayName: "Dashboard",
|
|
36
|
+
description: "Stat/overview composition of the graduated workspace components — a stat grid plus titled widget-slot sections.",
|
|
37
|
+
Component: DashboardWorkspace,
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=DashboardWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DashboardWorkspace.js","sourceRoot":"","sources":["../../src/workspace/DashboardWorkspace.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form workspace type — the built-in structured-input workspace: hosts the
|
|
3
|
+
* graduated forms set's PRESENTATIONAL tier (Field / FieldGroup / FieldSet /
|
|
4
|
+
* FieldLegend / FieldLabel / FieldDescription / FieldError from
|
|
5
|
+
* @consciousclouds/ui — no form-state library).
|
|
6
|
+
*
|
|
7
|
+
* MECHANISM ONLY, two deliberate tiers (mirroring the ui forms-set tiers):
|
|
8
|
+
* this workspace composes the Field vocabulary — sections of labelled,
|
|
9
|
+
* described, error-annotated fields around PRODUCT-SUPPLIED controls — and
|
|
10
|
+
* owns the hosting state machine (error → loading → empty → ready) plus the
|
|
11
|
+
* `<form>` element. Controlled validation state stays the PRODUCT's: a
|
|
12
|
+
* product that needs react-hook-form composes ui's `Form`/`FormField`
|
|
13
|
+
* primitives inside its control nodes (or its own workspace type) — the
|
|
14
|
+
* framework never owns form state, schemas, or submission transport
|
|
15
|
+
* (`onSubmit` is a seam; the product owns the wire).
|
|
16
|
+
*
|
|
17
|
+
* Ships as mechanism: CCU currently has no honest write surface (the gateway
|
|
18
|
+
* admin plane is read-only), so no CCU page exercises this type yet — it is
|
|
19
|
+
* registered, fail-closed, and ready for the first real write surface.
|
|
20
|
+
*
|
|
21
|
+
* Frame-free by design (Separation Law): imports only React and the UI
|
|
22
|
+
* primitives — never the shell frame.
|
|
23
|
+
*/
|
|
24
|
+
import type * as React from "react";
|
|
25
|
+
import type { WorkspaceComponentProps, WorkspaceType } from "./types.js";
|
|
26
|
+
/** One field: label + optional description/error chrome around a product control. */
|
|
27
|
+
export interface FormWorkspaceField {
|
|
28
|
+
/** Stable key for the field. */
|
|
29
|
+
id: string;
|
|
30
|
+
label: React.ReactNode;
|
|
31
|
+
/** Connects the label to the control — supply the control's element id. */
|
|
32
|
+
htmlFor?: string;
|
|
33
|
+
/** Helper text under the control. */
|
|
34
|
+
description?: React.ReactNode;
|
|
35
|
+
/**
|
|
36
|
+
* The control slot — a product-supplied control (Input, Select, Textarea,
|
|
37
|
+
* Checkbox, a react-hook-form-wired composition, …). The framework renders
|
|
38
|
+
* chrome around it; it never inspects it.
|
|
39
|
+
*/
|
|
40
|
+
control: React.ReactNode;
|
|
41
|
+
/**
|
|
42
|
+
* A validation message. When set, the field renders FieldError and marks
|
|
43
|
+
* itself invalid — the JUDGMENT (what is invalid) is the product's.
|
|
44
|
+
*/
|
|
45
|
+
error?: React.ReactNode;
|
|
46
|
+
/** Field layout; matches the ui Field orientations. @default "vertical" */
|
|
47
|
+
orientation?: "vertical" | "horizontal" | "responsive";
|
|
48
|
+
}
|
|
49
|
+
/** One fieldset: optional legend/description + its fields, in order. */
|
|
50
|
+
export interface FormWorkspaceSection {
|
|
51
|
+
/** Stable key for the section. */
|
|
52
|
+
id: string;
|
|
53
|
+
/** Optional fieldset legend. */
|
|
54
|
+
legend?: React.ReactNode;
|
|
55
|
+
/** Optional description under the legend. */
|
|
56
|
+
description?: React.ReactNode;
|
|
57
|
+
fields: FormWorkspaceField[];
|
|
58
|
+
}
|
|
59
|
+
/** Product-supplied state content; neutral fail-closed defaults otherwise. */
|
|
60
|
+
export interface FormWorkspaceSlots {
|
|
61
|
+
/** Rendered while `loading` is true and no error is set. */
|
|
62
|
+
loading?: React.ReactNode;
|
|
63
|
+
/** Rendered when `error` is set; receives the error message. */
|
|
64
|
+
error?: (message: string) => React.ReactNode;
|
|
65
|
+
/** Rendered when the input declares zero sections. */
|
|
66
|
+
empty?: React.ReactNode;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The form workspace mount input. Precedence (fail-closed first): `error`
|
|
70
|
+
* (the LOAD failure — distinct from per-field validation errors) → `loading`
|
|
71
|
+
* → empty (zero sections) → ready.
|
|
72
|
+
*/
|
|
73
|
+
export interface FormWorkspaceInput {
|
|
74
|
+
/**
|
|
75
|
+
* A load-failure message (the read that seeds the form failed). When set,
|
|
76
|
+
* the workspace renders the error state and NO form — never a form over
|
|
77
|
+
* data that didn't load.
|
|
78
|
+
*/
|
|
79
|
+
error?: string | null;
|
|
80
|
+
/** The seeding read is still in flight. */
|
|
81
|
+
loading?: boolean;
|
|
82
|
+
/** The fieldsets, in order. */
|
|
83
|
+
sections: FormWorkspaceSection[];
|
|
84
|
+
/**
|
|
85
|
+
* The actions slot (submit/cancel buttons) — product-supplied, rendered
|
|
86
|
+
* after the last section.
|
|
87
|
+
*/
|
|
88
|
+
actions?: React.ReactNode;
|
|
89
|
+
/**
|
|
90
|
+
* Submit seam. The framework calls `preventDefault()` first — submission
|
|
91
|
+
* transport is the product's, never a browser navigation.
|
|
92
|
+
*/
|
|
93
|
+
onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
94
|
+
/** Product-supplied state content; neutral defaults otherwise. */
|
|
95
|
+
slots?: FormWorkspaceSlots;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The form workspace component. The framework owns chrome + state selection;
|
|
99
|
+
* the product owns controls, validation judgment, and submission transport.
|
|
100
|
+
*/
|
|
101
|
+
export declare function FormWorkspace({ input, }: WorkspaceComponentProps<FormWorkspaceInput>): import("react/jsx-runtime").JSX.Element;
|
|
102
|
+
/**
|
|
103
|
+
* The registered `form` workspace type — compose it into the app's registry
|
|
104
|
+
* via `createWorkspaceRegistry([..., formWorkspaceType])`.
|
|
105
|
+
*/
|
|
106
|
+
export declare const formWorkspaceType: WorkspaceType<FormWorkspaceInput>;
|
|
107
|
+
//# sourceMappingURL=FormWorkspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormWorkspace.d.ts","sourceRoot":"","sources":["../../src/workspace/FormWorkspace.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAepC,OAAO,KAAK,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzE,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;;OAIG;IACH,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,YAAY,CAAC;CACxD;AAED,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACnC,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC7C,sDAAsD;IACtD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+BAA+B;IAC/B,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;IAC7D,kEAAkE;IAClE,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAcD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,GACN,EAAE,uBAAuB,CAAC,kBAAkB,CAAC,2CAwE7C;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,kBAAkB,CAM/D,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { EmptyState, FailClosed, Field, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSet, Skeleton, } from "@consciousclouds/ui";
|
|
4
|
+
/** Neutral default while the product's seeding read is in flight. */
|
|
5
|
+
function DefaultLoading() {
|
|
6
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsx(Skeleton, { className: "h-5 w-40" }), _jsx(Skeleton, { className: "h-9 w-full" }), _jsx(Skeleton, { className: "h-9 w-full" }), _jsx(Skeleton, { className: "h-9 w-2/3" })] }));
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The form workspace component. The framework owns chrome + state selection;
|
|
10
|
+
* the product owns controls, validation judgment, and submission transport.
|
|
11
|
+
*/
|
|
12
|
+
export function FormWorkspace({ input, }) {
|
|
13
|
+
const { error, loading, sections, actions, onSubmit, slots } = input;
|
|
14
|
+
if (error != null) {
|
|
15
|
+
return (_jsx("div", { "data-form-workspace-state": "error", children: slots?.error ? (slots.error(error)) : (_jsx(FailClosed, { what: "this form", detail: error })) }));
|
|
16
|
+
}
|
|
17
|
+
if (loading) {
|
|
18
|
+
return (_jsx("div", { "data-form-workspace-state": "loading", children: slots?.loading ?? _jsx(DefaultLoading, {}) }));
|
|
19
|
+
}
|
|
20
|
+
if (sections.length === 0) {
|
|
21
|
+
return (_jsx("div", { "data-form-workspace-state": "empty", children: slots?.empty ?? _jsx(EmptyState, { children: "This form has no fields." }) }));
|
|
22
|
+
}
|
|
23
|
+
return (_jsx("form", { "data-form-workspace-state": "ready", onSubmit: (event) => {
|
|
24
|
+
event.preventDefault();
|
|
25
|
+
onSubmit?.(event);
|
|
26
|
+
}, children: _jsxs(FieldGroup, { children: [sections.map((section) => (_jsxs(FieldSet, { children: [section.legend != null ? (_jsx(FieldLegend, { children: section.legend })) : null, section.description != null ? (_jsx(FieldDescription, { children: section.description })) : null, _jsx(FieldGroup, { children: section.fields.map((field) => (_jsxs(Field, { orientation: field.orientation, "data-invalid": field.error != null ? true : undefined, children: [_jsx(FieldLabel, { htmlFor: field.htmlFor, children: field.label }), field.control, field.description != null ? (_jsx(FieldDescription, { children: field.description })) : null, field.error != null ? (_jsx(FieldError, { children: field.error })) : null] }, field.id))) })] }, section.id))), actions != null ? _jsx(Field, { orientation: "horizontal", children: actions }) : null] }) }));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The registered `form` workspace type — compose it into the app's registry
|
|
30
|
+
* via `createWorkspaceRegistry([..., formWorkspaceType])`.
|
|
31
|
+
*/
|
|
32
|
+
export const formWorkspaceType = {
|
|
33
|
+
id: "form",
|
|
34
|
+
displayName: "Form",
|
|
35
|
+
description: "Structured input over the presentational forms set — sections of labelled fields around product-supplied controls; form state and submission stay product-owned.",
|
|
36
|
+
Component: FormWorkspace,
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=FormWorkspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormWorkspace.js","sourceRoot":"","sources":["../../src/workspace/FormWorkspace.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Graph workspace type — the built-in entity-relationship exploration
|
|
3
|
+
* workspace: a typed nodes/edges contract rendered as ADJACENCY-STYLE
|
|
4
|
+
* exploration (select an entity → see its connections → traverse), composed
|
|
5
|
+
* entirely from registry primitives. No visualization dependency: the
|
|
6
|
+
* license allowlist is the open shadcn registry + Radix/CVA/lucide + the CC
|
|
7
|
+
* SDKs, so force-directed canvases (react-flow/d3) are deliberately outside
|
|
8
|
+
* this workspace's vocabulary — a master-detail adjacency browser is
|
|
9
|
+
* legitimate graph exploration without them.
|
|
10
|
+
*
|
|
11
|
+
* MECHANISM ONLY. The framework owns the hosting state machine
|
|
12
|
+
* (error → loading → empty → ready), the index/detail composition, selection,
|
|
13
|
+
* and traversal; the PRODUCT owns every node, edge, kind, and label — what an
|
|
14
|
+
* entity IS and what a relationship MEANS arrive fully resolved via the
|
|
15
|
+
* mount input. No routes, no fetching, no brand.
|
|
16
|
+
*
|
|
17
|
+
* FAIL-CLOSED details:
|
|
18
|
+
* - `error` renders the error state and NO graph (a failed read never shows
|
|
19
|
+
* a misleading empty graph).
|
|
20
|
+
* - An edge endpoint that names an id not present in `nodes` renders as an
|
|
21
|
+
* explicit UNRESOLVED connection — visible but not traversable. The
|
|
22
|
+
* workspace never fabricates a node for a dangling reference.
|
|
23
|
+
*
|
|
24
|
+
* Frame-free by design (Separation Law): imports only React and the UI
|
|
25
|
+
* primitives — never the shell frame.
|
|
26
|
+
*/
|
|
27
|
+
import * as React from "react";
|
|
28
|
+
import type { WorkspaceComponentProps, WorkspaceType } from "./types.js";
|
|
29
|
+
/** One attribute row on a node's detail panel — the product's resolved fact. */
|
|
30
|
+
export interface GraphWorkspaceNodeAttribute {
|
|
31
|
+
/** Stable key for the row. */
|
|
32
|
+
id: string;
|
|
33
|
+
label: React.ReactNode;
|
|
34
|
+
value: React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
/** One entity in the graph. `kind` is a product-defined vocabulary id. */
|
|
37
|
+
export interface GraphWorkspaceNode {
|
|
38
|
+
/** Globally unique node id (edges reference it). */
|
|
39
|
+
id: string;
|
|
40
|
+
/** Display name. */
|
|
41
|
+
label: string;
|
|
42
|
+
/** Product-defined kind id (grouped in the index; labeled via `kinds`). */
|
|
43
|
+
kind: string;
|
|
44
|
+
/** Resolved facts shown on the detail panel. */
|
|
45
|
+
attributes?: GraphWorkspaceNodeAttribute[];
|
|
46
|
+
}
|
|
47
|
+
/** One directed relationship. `label` is the product's relationship name. */
|
|
48
|
+
export interface GraphWorkspaceEdge {
|
|
49
|
+
/** Stable edge id (dedupe/dedup keys belong to the product). */
|
|
50
|
+
id: string;
|
|
51
|
+
/** Source node id. */
|
|
52
|
+
source: string;
|
|
53
|
+
/** Target node id. */
|
|
54
|
+
target: string;
|
|
55
|
+
/** Relationship name (e.g. `grants`, `uses`); shown on connection rows. */
|
|
56
|
+
label?: string;
|
|
57
|
+
}
|
|
58
|
+
/** Display metadata for a node kind — order here orders the index groups. */
|
|
59
|
+
export interface GraphWorkspaceKind {
|
|
60
|
+
id: string;
|
|
61
|
+
/** Group heading in the index (e.g. `Products`). */
|
|
62
|
+
label: string;
|
|
63
|
+
}
|
|
64
|
+
/** Product-supplied state content; neutral fail-closed defaults otherwise. */
|
|
65
|
+
export interface GraphWorkspaceSlots {
|
|
66
|
+
/** Rendered while `loading` is true and no error is set. */
|
|
67
|
+
loading?: React.ReactNode;
|
|
68
|
+
/** Rendered when `error` is set; receives the error message. */
|
|
69
|
+
error?: (message: string) => React.ReactNode;
|
|
70
|
+
/** Rendered when a completed read yields zero nodes. */
|
|
71
|
+
empty?: React.ReactNode;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The graph workspace mount input. Precedence (fail-closed first): `error` →
|
|
75
|
+
* `loading` → empty (zero nodes) → ready.
|
|
76
|
+
*/
|
|
77
|
+
export interface GraphWorkspaceInput {
|
|
78
|
+
/**
|
|
79
|
+
* A load-failure message. When set, the workspace renders the error state
|
|
80
|
+
* and NO graph — a failed read fails closed rather than show a misleading
|
|
81
|
+
* empty graph.
|
|
82
|
+
*/
|
|
83
|
+
error?: string | null;
|
|
84
|
+
/** The read is still in flight. */
|
|
85
|
+
loading?: boolean;
|
|
86
|
+
/** The entities. */
|
|
87
|
+
nodes?: GraphWorkspaceNode[];
|
|
88
|
+
/** The directed relationships between them. */
|
|
89
|
+
edges?: GraphWorkspaceEdge[];
|
|
90
|
+
/**
|
|
91
|
+
* Kind display metadata; index groups follow this order, then any kinds
|
|
92
|
+
* not listed here in order of first appearance (labeled by their raw id).
|
|
93
|
+
*/
|
|
94
|
+
kinds?: GraphWorkspaceKind[];
|
|
95
|
+
/** The initially selected node; unknown ids fall back to the first node. */
|
|
96
|
+
initialNodeId?: string;
|
|
97
|
+
/** The honest zero state when a completed read has no entities. */
|
|
98
|
+
emptyMessage?: React.ReactNode;
|
|
99
|
+
/** Product-supplied state content; neutral defaults otherwise. */
|
|
100
|
+
slots?: GraphWorkspaceSlots;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The graph workspace component. Selection, traversal, and grouping are the
|
|
104
|
+
* framework's; every entity, relationship, and label is the product's.
|
|
105
|
+
*/
|
|
106
|
+
export declare function GraphWorkspace({ input, }: WorkspaceComponentProps<GraphWorkspaceInput>): import("react/jsx-runtime").JSX.Element;
|
|
107
|
+
/**
|
|
108
|
+
* The registered `graph` workspace type — compose it into the app's registry
|
|
109
|
+
* via `createWorkspaceRegistry([..., graphWorkspaceType])`.
|
|
110
|
+
*/
|
|
111
|
+
export declare const graphWorkspaceType: WorkspaceType<GraphWorkspaceInput>;
|
|
112
|
+
//# sourceMappingURL=GraphWorkspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphWorkspace.d.ts","sourceRoot":"","sources":["../../src/workspace/GraphWorkspace.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAY/B,OAAO,KAAK,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzE,gFAAgF;AAChF,MAAM,WAAW,2BAA2B;IAC1C,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IACjC,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,UAAU,CAAC,EAAE,2BAA2B,EAAE,CAAC;CAC5C;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC7C,wDAAwD;IACxD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oBAAoB;IACpB,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC7B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC7B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,kEAAkE;IAClE,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B;AAkHD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,GACN,EAAE,uBAAuB,CAAC,mBAAmB,CAAC,2CA+L9C;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAAa,CAAC,mBAAmB,CAMjE,CAAC"}
|