diff --git a/json-components-registry.json b/json-components-registry.json index 94efde8..2b8cfbf 100644 --- a/json-components-registry.json +++ b/json-components-registry.json @@ -46,7 +46,7 @@ "category": "layout", "canHaveChildren": true, "description": "CodeExplanationDialog component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -65,7 +65,7 @@ "category": "layout", "canHaveChildren": true, "description": "ComponentBindingDialog component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -84,7 +84,7 @@ "category": "layout", "canHaveChildren": true, "description": "DataSourceCard component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -94,7 +94,7 @@ "category": "layout", "canHaveChildren": true, "description": "DataSourceEditorDialog component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -203,7 +203,7 @@ "category": "layout", "canHaveChildren": true, "description": "TreeCard component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -213,7 +213,7 @@ "category": "layout", "canHaveChildren": true, "description": "TreeFormDialog component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -448,7 +448,7 @@ "category": "input", "canHaveChildren": true, "description": "ToolbarButton component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -602,7 +602,7 @@ "category": "display", "canHaveChildren": true, "description": "SchemaCodeViewer organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -720,7 +720,7 @@ "category": "navigation", "canHaveChildren": true, "description": "FileTabs component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -767,7 +767,7 @@ "category": "navigation", "canHaveChildren": true, "description": "NavigationItem component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -831,7 +831,7 @@ "category": "feedback", "canHaveChildren": true, "description": "EmptyCanvasState organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -953,7 +953,7 @@ "category": "feedback", "canHaveChildren": true, "description": "SchemaEditorStatusBar organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1008,7 +1008,7 @@ "category": "data", "canHaveChildren": true, "description": "DataSourceManager organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1139,7 +1139,7 @@ "category": "data", "canHaveChildren": true, "description": "TreeListHeader component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1149,7 +1149,7 @@ "category": "data", "canHaveChildren": true, "description": "TreeListPanel organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1168,7 +1168,7 @@ "category": "custom", "canHaveChildren": false, "description": "Action button toolbar", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true, "metadata": { @@ -1192,7 +1192,7 @@ "category": "custom", "canHaveChildren": true, "description": "AppHeader organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1220,7 +1220,7 @@ "category": "custom", "canHaveChildren": true, "description": "BindingEditor component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1248,7 +1248,7 @@ "category": "custom", "canHaveChildren": true, "description": "CanvasRenderer component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1312,7 +1312,7 @@ "category": "custom", "canHaveChildren": true, "description": "ComponentPalette component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1331,7 +1331,7 @@ "category": "custom", "canHaveChildren": true, "description": "ComponentTree component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1350,7 +1350,7 @@ "category": "custom", "canHaveChildren": false, "description": "Custom data display card", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true, "metadata": { @@ -1382,7 +1382,7 @@ "category": "custom", "canHaveChildren": true, "description": "EditorActions component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1392,7 +1392,7 @@ "category": "custom", "canHaveChildren": true, "description": "EditorToolbar component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1411,7 +1411,7 @@ "category": "custom", "canHaveChildren": true, "description": "JSONUIShowcase organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1430,7 +1430,7 @@ "category": "custom", "canHaveChildren": true, "description": "LazyInlineMonacoEditor component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1440,7 +1440,7 @@ "category": "custom", "canHaveChildren": true, "description": "LazyMonacoEditor component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1459,7 +1459,7 @@ "category": "custom", "canHaveChildren": true, "description": "MonacoEditorPanel component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1478,7 +1478,7 @@ "category": "custom", "canHaveChildren": true, "description": "PageHeaderContent component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1515,7 +1515,7 @@ "category": "custom", "canHaveChildren": true, "description": "PropertyEditor component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1571,7 +1571,7 @@ "category": "custom", "canHaveChildren": true, "description": "SchemaEditorCanvas organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1581,7 +1581,7 @@ "category": "custom", "canHaveChildren": true, "description": "SchemaEditorLayout organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1591,7 +1591,7 @@ "category": "custom", "canHaveChildren": true, "description": "SchemaEditorPropertiesPanel organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1601,7 +1601,7 @@ "category": "custom", "canHaveChildren": true, "description": "SchemaEditorSidebar organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1611,7 +1611,7 @@ "category": "custom", "canHaveChildren": true, "description": "SchemaEditorToolbar organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1630,7 +1630,7 @@ "category": "custom", "canHaveChildren": true, "description": "SearchBar component", - "status": "maybe-json-compatible", + "status": "supported", "source": "molecules", "jsonCompatible": true }, @@ -1731,7 +1731,7 @@ "category": "custom", "canHaveChildren": true, "description": "ToolbarActions organism component", - "status": "maybe-json-compatible", + "status": "supported", "source": "organisms", "jsonCompatible": true }, @@ -1746,11 +1746,11 @@ } ], "statistics": { - "total": 219, - "supported": 157, - "planned": 7, - "jsonCompatible": 14, - "maybeJsonCompatible": 41, + "total": 217, + "supported": 204, + "planned": 0, + "jsonCompatible": 13, + "maybeJsonCompatible": 0, "byCategory": { "layout": 25, "input": 34, diff --git a/src/components/molecules/index.ts b/src/components/molecules/index.ts index f04b720..4506686 100644 --- a/src/components/molecules/index.ts +++ b/src/components/molecules/index.ts @@ -1,6 +1,9 @@ export { AppBranding } from './AppBranding' export { Breadcrumb } from './Breadcrumb' +export { CanvasRenderer } from './CanvasRenderer' export { CodeExplanationDialog } from './CodeExplanationDialog' +export { ComponentPalette } from './ComponentPalette' +export { ComponentTree } from './ComponentTree' export { EditorActions } from './EditorActions' export { EditorToolbar } from './EditorToolbar' export { EmptyEditorState } from './EmptyEditorState' @@ -18,8 +21,11 @@ export { MonacoEditorPanel } from './MonacoEditorPanel' export { NavigationGroupHeader } from './NavigationGroupHeader' export { NavigationItem } from './NavigationItem' export { PageHeaderContent } from './PageHeaderContent' +export { PropertyEditor } from './PropertyEditor' export { SaveIndicator } from './SaveIndicator' export { SeedDataManager } from './SeedDataManager' +export { SearchBar } from './SearchBar' +export { StatCard } from './StatCard' export { ToolbarButton } from './ToolbarButton' export { TreeCard } from './TreeCard' export { TreeFormDialog } from './TreeFormDialog' @@ -31,4 +37,3 @@ export { DataSourceCard } from './DataSourceCard' export { BindingEditor } from './BindingEditor' export { DataSourceEditorDialog } from './DataSourceEditorDialog' export { ComponentBindingDialog } from './ComponentBindingDialog' - diff --git a/src/components/organisms/index.ts b/src/components/organisms/index.ts index 17abb7a..f4a4e6f 100644 --- a/src/components/organisms/index.ts +++ b/src/components/organisms/index.ts @@ -2,6 +2,7 @@ export { NavigationMenu } from './NavigationMenu' export { PageHeader } from './PageHeader' export { ToolbarActions } from './ToolbarActions' export { AppHeader } from './AppHeader' +export { DataSourceManager } from './DataSourceManager' export { TreeListPanel } from './TreeListPanel' export { SchemaEditorToolbar } from './SchemaEditorToolbar' export { SchemaEditorSidebar } from './SchemaEditorSidebar' @@ -11,3 +12,4 @@ export { SchemaEditorLayout } from './SchemaEditorLayout' export { EmptyCanvasState } from './EmptyCanvasState' export { SchemaEditorStatusBar } from './SchemaEditorStatusBar' export { SchemaCodeViewer } from './SchemaCodeViewer' +export { JSONUIShowcase } from './JSONUIShowcase' diff --git a/src/lib/component-definitions.json b/src/lib/component-definitions.json index 1f1d22b..9731f20 100644 --- a/src/lib/component-definitions.json +++ b/src/lib/component-definitions.json @@ -574,5 +574,480 @@ "isExporting": false, "isImporting": false } + }, + { + "type": "CodeExplanationDialog", + "label": "Code Explanation Dialog", + "category": "layout", + "icon": "Info", + "defaultProps": { + "open": false, + "fileName": "example.ts", + "explanation": "Explain this code...", + "isLoading": false + } + }, + { + "type": "ComponentBindingDialog", + "label": "Component Binding Dialog", + "category": "layout", + "icon": "Link", + "defaultProps": { + "open": false, + "component": null, + "dataSources": [] + } + }, + { + "type": "DataSourceCard", + "label": "Data Source Card", + "category": "layout", + "icon": "Database", + "defaultProps": { + "dataSource": { + "id": "source", + "type": "static", + "defaultValue": "" + }, + "dependents": [] + } + }, + { + "type": "DataSourceEditorDialog", + "label": "Data Source Editor Dialog", + "category": "layout", + "icon": "Database", + "defaultProps": { + "open": false, + "dataSource": null, + "allDataSources": [] + } + }, + { + "type": "TreeCard", + "label": "Tree Card", + "category": "layout", + "icon": "Tree", + "defaultProps": { + "tree": { + "id": "tree-1", + "name": "Main Tree", + "description": "Primary UI tree", + "rootNodes": [], + "createdAt": 0, + "updatedAt": 0 + }, + "isSelected": false, + "disableDelete": false + } + }, + { + "type": "TreeFormDialog", + "label": "Tree Form Dialog", + "category": "layout", + "icon": "Tree", + "defaultProps": { + "open": false, + "title": "Create Tree", + "description": "Add a new component tree.", + "name": "", + "treeDescription": "", + "submitLabel": "Save" + } + }, + { + "type": "ToolbarButton", + "label": "Toolbar Button", + "category": "input", + "icon": "Button", + "defaultProps": { + "label": "Action", + "variant": "outline", + "disabled": false + } + }, + { + "type": "SchemaCodeViewer", + "label": "Schema Code Viewer", + "category": "display", + "icon": "Code", + "defaultProps": { + "components": [], + "schema": {} + } + }, + { + "type": "FileTabs", + "label": "File Tabs", + "category": "navigation", + "icon": "Tabs", + "defaultProps": { + "files": [], + "activeFileId": null + } + }, + { + "type": "NavigationItem", + "label": "Navigation Item", + "category": "navigation", + "icon": "List", + "defaultProps": { + "label": "Overview", + "isActive": false, + "badge": 0 + } + }, + { + "type": "NavigationMenu", + "label": "Navigation Menu", + "category": "navigation", + "icon": "Sidebar", + "defaultProps": { + "activeTab": "overview", + "featureToggles": { + "codeEditor": false, + "models": false, + "components": false, + "componentTrees": false, + "workflows": false, + "lambdas": false, + "styling": false, + "flaskApi": false, + "playwright": false, + "storybook": false, + "unitTests": false, + "errorRepair": false, + "documentation": false, + "sassStyles": false, + "faviconDesigner": false, + "ideaCloud": false, + "schemaEditor": false, + "dataBinding": false + }, + "errorCount": 0 + } + }, + { + "type": "EmptyCanvasState", + "label": "Empty Canvas State", + "category": "feedback", + "icon": "FolderOpen", + "defaultProps": {} + }, + { + "type": "SchemaEditorStatusBar", + "label": "Schema Editor Status Bar", + "category": "feedback", + "icon": "Info", + "defaultProps": { + "componentCount": 0, + "selectedComponentType": "", + "hasUnsavedChanges": false + } + }, + { + "type": "DataSourceManager", + "label": "Data Source Manager", + "category": "data", + "icon": "Database", + "defaultProps": { + "dataSources": [] + } + }, + { + "type": "TreeListHeader", + "label": "Tree List Header", + "category": "data", + "icon": "Tree", + "defaultProps": { + "hasSelectedTree": false + } + }, + { + "type": "TreeListPanel", + "label": "Tree List Panel", + "category": "data", + "icon": "Tree", + "defaultProps": { + "trees": [], + "selectedTreeId": null + } + }, + { + "type": "AppHeader", + "label": "App Header", + "category": "custom", + "icon": "Layout", + "defaultProps": { + "activeTab": "overview", + "featureToggles": { + "codeEditor": false, + "models": false, + "components": false, + "componentTrees": false, + "workflows": false, + "lambdas": false, + "styling": false, + "flaskApi": false, + "playwright": false, + "storybook": false, + "unitTests": false, + "errorRepair": false, + "documentation": false, + "sassStyles": false, + "faviconDesigner": false, + "ideaCloud": false, + "schemaEditor": false, + "dataBinding": false + }, + "errorCount": 0, + "lastSaved": null, + "currentProject": { + "name": "Demo Project", + "files": [], + "models": [], + "components": [], + "componentTrees": [], + "workflows": [], + "lambdas": [], + "theme": { + "variants": [ + { + "id": "default", + "name": "Default", + "colors": { + "primary": "#4f46e5", + "secondary": "#64748b", + "accent": "#0ea5e9", + "muted": "#f1f5f9", + "background": "#ffffff", + "surface": "#ffffff", + "text": "#0f172a", + "textSecondary": "#475569", + "border": "#e2e8f0", + "customColors": {} + } + } + ], + "activeVariantId": "default", + "fontFamily": "Inter", + "fontSize": { + "small": 12, + "medium": 14, + "large": 18 + }, + "spacing": 4, + "borderRadius": 8 + } + } + } + }, + { + "type": "BindingEditor", + "label": "Binding Editor", + "category": "custom", + "icon": "Link", + "defaultProps": { + "bindings": {}, + "dataSources": [], + "availableProps": ["children", "value"] + } + }, + { + "type": "CanvasRenderer", + "label": "Canvas Renderer", + "category": "custom", + "icon": "Layout", + "defaultProps": { + "components": [], + "selectedId": null, + "hoveredId": null, + "draggedOverId": null, + "dropPosition": null + } + }, + { + "type": "ComponentPalette", + "label": "Component Palette", + "category": "custom", + "icon": "GridFour", + "defaultProps": {} + }, + { + "type": "ComponentTree", + "label": "Component Tree", + "category": "custom", + "icon": "Tree", + "defaultProps": { + "components": [], + "selectedId": null, + "hoveredId": null, + "draggedOverId": null, + "dropPosition": null + } + }, + { + "type": "EditorActions", + "label": "Editor Actions", + "category": "custom", + "icon": "Sparkle", + "defaultProps": {} + }, + { + "type": "EditorToolbar", + "label": "Editor Toolbar", + "category": "custom", + "icon": "Toolbox", + "defaultProps": { + "openFiles": [], + "activeFileId": null, + "activeFile": null + } + }, + { + "type": "JSONUIShowcase", + "label": "JSON UI Showcase", + "category": "custom", + "icon": "Code", + "defaultProps": { + "files": [], + "models": [], + "components": [] + } + }, + { + "type": "LazyInlineMonacoEditor", + "label": "Inline Monaco Editor", + "category": "custom", + "icon": "Code", + "defaultProps": { + "height": "300px", + "language": "typescript", + "value": "// Start typing..." + } + }, + { + "type": "LazyMonacoEditor", + "label": "Monaco Editor", + "category": "custom", + "icon": "Code", + "defaultProps": { + "file": { + "id": "file-1", + "name": "App.tsx", + "path": "/App.tsx", + "content": "// Start typing...", + "language": "typescript" + } + } + }, + { + "type": "MonacoEditorPanel", + "label": "Monaco Editor Panel", + "category": "custom", + "icon": "Code", + "defaultProps": { + "file": { + "id": "file-1", + "name": "App.tsx", + "path": "/App.tsx", + "content": "// Start typing...", + "language": "typescript" + } + } + }, + { + "type": "PageHeaderContent", + "label": "Page Header Content", + "category": "custom", + "icon": "Heading", + "defaultProps": { + "title": "Page Title", + "description": "Page description" + } + }, + { + "type": "PropertyEditor", + "label": "Property Editor", + "category": "custom", + "icon": "SlidersHorizontal", + "defaultProps": { + "component": null + } + }, + { + "type": "SchemaEditorCanvas", + "label": "Schema Editor Canvas", + "category": "custom", + "icon": "Layout", + "defaultProps": { + "components": [], + "selectedId": null, + "hoveredId": null, + "draggedOverId": null, + "dropPosition": null + } + }, + { + "type": "SchemaEditorLayout", + "label": "Schema Editor Layout", + "category": "custom", + "icon": "Layout", + "defaultProps": { + "components": [], + "selectedId": null, + "hoveredId": null, + "draggedOverId": null, + "dropPosition": null, + "selectedComponent": null + } + }, + { + "type": "SchemaEditorPropertiesPanel", + "label": "Schema Editor Properties Panel", + "category": "custom", + "icon": "SlidersHorizontal", + "defaultProps": { + "components": [], + "selectedId": null, + "hoveredId": null, + "draggedOverId": null, + "dropPosition": null, + "selectedComponent": null + } + }, + { + "type": "SchemaEditorSidebar", + "label": "Schema Editor Sidebar", + "category": "custom", + "icon": "Sidebar", + "defaultProps": {} + }, + { + "type": "SchemaEditorToolbar", + "label": "Schema Editor Toolbar", + "category": "custom", + "icon": "Toolbox", + "defaultProps": {} + }, + { + "type": "SearchBar", + "label": "Search Bar", + "category": "custom", + "icon": "MagnifyingGlass", + "defaultProps": { + "value": "", + "placeholder": "Search..." + } + }, + { + "type": "ToolbarActions", + "label": "Toolbar Actions", + "category": "custom", + "icon": "Toolbox", + "defaultProps": { + "errorCount": 0, + "showErrorButton": false + } } ] diff --git a/src/lib/json-ui/component-registry.ts b/src/lib/json-ui/component-registry.ts index 2912d38..e36bb03 100644 --- a/src/lib/json-ui/component-registry.ts +++ b/src/lib/json-ui/component-registry.ts @@ -19,6 +19,7 @@ import { Progress } from '@/components/ui/progress' import { Avatar as ShadcnAvatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' import * as AtomComponents from '@/components/atoms' import * as MoleculeComponents from '@/components/molecules' +import * as OrganismComponents from '@/components/organisms' import { BreadcrumbWrapper, LazyBarChartWrapper, @@ -77,6 +78,10 @@ const moleculeRegistryNames = jsonRegistryEntries .filter((entry) => entry.source === 'molecules') .map((entry) => entry.export ?? entry.name ?? entry.type) .filter((name): name is string => Boolean(name)) +const organismRegistryNames = jsonRegistryEntries + .filter((entry) => entry.source === 'organisms') + .map((entry) => entry.export ?? entry.name ?? entry.type) + .filter((name): name is string => Boolean(name)) export const primitiveComponents: UIComponentRegistry = { div: 'div' as any, @@ -166,6 +171,11 @@ export const moleculeComponents: UIComponentRegistry = buildRegistryFromNames( MoleculeComponents as Record> ) +export const organismComponents: UIComponentRegistry = buildRegistryFromNames( + organismRegistryNames, + OrganismComponents as Record> +) + export const jsonWrapperComponents: UIComponentRegistry = { Breadcrumb: BreadcrumbWrapper, SaveIndicator: SaveIndicatorWrapper, @@ -222,6 +232,7 @@ export const uiComponentRegistry: UIComponentRegistry = { ...shadcnComponents, ...atomComponents, ...moleculeComponents, + ...organismComponents, ...jsonWrapperComponents, ...iconComponents, } diff --git a/src/types/json-ui.ts b/src/types/json-ui.ts index a9aed51..51c6c9b 100644 --- a/src/types/json-ui.ts +++ b/src/types/json-ui.ts @@ -14,6 +14,16 @@ export type ComponentType = | 'LazyBarChart' | 'LazyLineChart' | 'LazyD3BarChart' | 'SeedDataManager' | 'SaveIndicator' | 'StorageSettings' | 'AppBranding' | 'LabelWithBadge' | 'EmptyEditorState' | 'LoadingFallback' | 'LoadingState' | 'NavigationGroupHeader' + | 'CodeExplanationDialog' | 'ComponentBindingDialog' | 'DataSourceCard' | 'DataSourceEditorDialog' | 'TreeCard' | 'TreeFormDialog' + | 'ToolbarButton' + | 'SchemaCodeViewer' + | 'FileTabs' | 'NavigationItem' | 'NavigationMenu' + | 'EmptyCanvasState' | 'SchemaEditorStatusBar' + | 'DataSourceManager' | 'TreeListHeader' | 'TreeListPanel' + | 'AppHeader' | 'BindingEditor' | 'CanvasRenderer' | 'ComponentPalette' | 'ComponentTree' | 'EditorActions' + | 'EditorToolbar' | 'JSONUIShowcase' | 'LazyInlineMonacoEditor' | 'LazyMonacoEditor' | 'MonacoEditorPanel' + | 'PageHeaderContent' | 'PropertyEditor' | 'SchemaEditorCanvas' | 'SchemaEditorLayout' + | 'SchemaEditorPropertiesPanel' | 'SchemaEditorSidebar' | 'SchemaEditorToolbar' | 'SearchBar' | 'ToolbarActions' export type ActionType = | 'create' | 'update' | 'delete' | 'navigate'