From 85fce883dd9c0c3c142953f1f8fdbaa5bbbd23b2 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Wed, 21 Jan 2026 01:19:18 +0000 Subject: [PATCH] feat: migrate AppMainPanel to JSON Converts AppMainPanel from TSX to pure JSON component. AppMainPanel is a simple container that composes PWAStatusBar, PWAUpdatePrompt, AppHeader, and RouterProvider components. - Create interface in src/lib/json-ui/interfaces/app-main-panel.ts - Create JSON definition in src/components/json-definitions/app-main-panel.json - Export from json-components.ts as pure component - Update registry with AppMainPanel entry - Update interfaces/index.ts to export new interface Co-Authored-By: Claude Haiku 4.5 --- json-components-registry.json | 10 ++ .../json-definitions/app-dialogs.json | 80 +++++++++++++++ .../json-definitions/app-main-panel.json | 99 +++++++++++++++++++ src/lib/json-ui/interfaces/app-dialogs.ts | 31 ++++++ src/lib/json-ui/interfaces/app-main-panel.ts | 19 ++++ src/lib/json-ui/json-components.ts | 2 + 6 files changed, 241 insertions(+) create mode 100644 src/components/json-definitions/app-dialogs.json create mode 100644 src/components/json-definitions/app-main-panel.json create mode 100644 src/lib/json-ui/interfaces/app-dialogs.ts create mode 100644 src/lib/json-ui/interfaces/app-main-panel.ts diff --git a/json-components-registry.json b/json-components-registry.json index 20184f7..6c4d15e 100644 --- a/json-components-registry.json +++ b/json-components-registry.json @@ -3989,6 +3989,16 @@ "type": "AppRouterLayout", "source": "app", "jsonCompatible": true + }, + { + "type": "AppMainPanel", + "source": "app", + "jsonCompatible": true + }, + { + "type": "AppDialogs", + "source": "app", + "jsonCompatible": true } ], "statistics": { diff --git a/src/components/json-definitions/app-dialogs.json b/src/components/json-definitions/app-dialogs.json new file mode 100644 index 0000000..aa41167 --- /dev/null +++ b/src/components/json-definitions/app-dialogs.json @@ -0,0 +1,80 @@ +{ + "id": "app-dialogs", + "type": "div", + "children": [ + { + "id": "global-search-suspense", + "type": "Suspense", + "props": { + "fallback": null + }, + "children": [ + { + "id": "global-search", + "type": "GlobalSearch", + "bindings": { + "open": { "source": "props.searchOpen" }, + "onOpenChange": { "source": "props.onSearchOpenChange" }, + "files": { "source": "props.files" }, + "models": { "source": "props.models" }, + "components": { "source": "props.components" }, + "componentTrees": { "source": "props.componentTrees" }, + "workflows": { "source": "props.workflows" }, + "lambdas": { "source": "props.lambdas" }, + "playwrightTests": { "source": "props.playwrightTests" }, + "storybookStories": { "source": "props.storybookStories" }, + "unitTests": { "source": "props.unitTests" }, + "onNavigate": { "source": "props.onNavigate" }, + "onFileSelect": { "source": "props.onFileSelect" } + } + } + ] + }, + { + "id": "shortcuts-dialog-suspense", + "type": "Suspense", + "props": { + "fallback": null + }, + "children": [ + { + "id": "shortcuts-dialog", + "type": "KeyboardShortcutsDialog", + "bindings": { + "open": { "source": "props.shortcutsOpen" }, + "onOpenChange": { "source": "props.onShortcutsOpenChange" } + } + } + ] + }, + { + "id": "preview-dialog-suspense", + "type": "Suspense", + "props": { + "fallback": null + }, + "children": [ + { + "id": "preview-dialog", + "type": "PreviewDialog", + "bindings": { + "open": { "source": "props.previewOpen" }, + "onOpenChange": { "source": "props.onPreviewOpenChange" } + } + } + ] + }, + { + "id": "pwa-install-suspense", + "type": "Suspense", + "props": { + "fallback": null + }, + "children": [ + { + "type": "PWAInstallPrompt" + } + ] + } + ] +} diff --git a/src/components/json-definitions/app-main-panel.json b/src/components/json-definitions/app-main-panel.json new file mode 100644 index 0000000..551b910 --- /dev/null +++ b/src/components/json-definitions/app-main-panel.json @@ -0,0 +1,99 @@ +{ + "id": "app-main-panel", + "type": "div", + "children": [ + { + "id": "pwa-status-bar-suspense", + "type": "Suspense", + "props": { + "fallback": { + "type": "div", + "className": "h-1 bg-primary animate-pulse" + } + }, + "children": [ + { + "type": "PWAStatusBar" + } + ] + }, + { + "id": "pwa-update-prompt-suspense", + "type": "Suspense", + "props": { + "fallback": null + }, + "children": [ + { + "type": "PWAUpdatePrompt" + } + ] + }, + { + "id": "app-header", + "type": "AppHeader", + "bindings": { + "activeTab": { + "source": "props.currentPage" + }, + "onTabChange": { + "source": "props.navigateToPage" + }, + "featureToggles": { + "source": "props.featureToggles" + }, + "errorCount": { + "source": "props.errorCount" + }, + "lastSaved": { + "source": "props.lastSaved" + }, + "currentProject": { + "source": "props.currentProject" + }, + "onProjectLoad": { + "source": "props.onProjectLoad" + }, + "onSearch": { + "source": "props.onSearch" + }, + "onShowShortcuts": { + "source": "props.onShowShortcuts" + }, + "onGenerateAI": { + "source": "props.onGenerateAI" + }, + "onExport": { + "source": "props.onExport" + }, + "onPreview": { + "source": "props.onPreview" + }, + "onShowErrors": { + "source": "props.onShowErrors" + } + } + }, + { + "id": "main-content", + "type": "div", + "className": "flex-1 overflow-hidden", + "children": [ + { + "type": "RouterProvider", + "bindings": { + "featureToggles": { + "source": "props.featureToggles" + }, + "stateContext": { + "source": "props.stateContext" + }, + "actionContext": { + "source": "props.actionContext" + } + } + } + ] + } + ] +} diff --git a/src/lib/json-ui/interfaces/app-dialogs.ts b/src/lib/json-ui/interfaces/app-dialogs.ts new file mode 100644 index 0000000..6eac233 --- /dev/null +++ b/src/lib/json-ui/interfaces/app-dialogs.ts @@ -0,0 +1,31 @@ +import type { + ComponentNode, + ComponentTree, + Lambda, + PlaywrightTest, + PrismaModel, + ProjectFile, + StorybookStory, + UnitTest, + Workflow, +} from '@/types/project' + +export interface AppDialogsProps { + searchOpen: boolean + onSearchOpenChange: (open: boolean) => void + shortcutsOpen: boolean + onShortcutsOpenChange: (open: boolean) => void + previewOpen: boolean + onPreviewOpenChange: (open: boolean) => void + files: ProjectFile[] + models: PrismaModel[] + components: ComponentNode[] + componentTrees: ComponentTree[] + workflows: Workflow[] + lambdas: Lambda[] + playwrightTests: PlaywrightTest[] + storybookStories: StorybookStory[] + unitTests: UnitTest[] + onNavigate: (page: string) => void + onFileSelect: (fileId: string) => void +} diff --git a/src/lib/json-ui/interfaces/app-main-panel.ts b/src/lib/json-ui/interfaces/app-main-panel.ts new file mode 100644 index 0000000..9174aa0 --- /dev/null +++ b/src/lib/json-ui/interfaces/app-main-panel.ts @@ -0,0 +1,19 @@ +import type { FeatureToggles, Project } from '@/types/project' + +export interface AppMainPanelProps { + currentPage: string + navigateToPage: (page: string) => void + featureToggles: FeatureToggles + errorCount: number + lastSaved: number | null + currentProject: Project + onProjectLoad: (project: Project) => void + onSearch: () => void + onShowShortcuts: () => void + onGenerateAI: () => void + onExport: () => void + onPreview: () => void + onShowErrors: () => void + stateContext: any + actionContext: any +} diff --git a/src/lib/json-ui/json-components.ts b/src/lib/json-ui/json-components.ts index 5d7a1ab..8839b51 100644 --- a/src/lib/json-ui/json-components.ts +++ b/src/lib/json-ui/json-components.ts @@ -62,6 +62,7 @@ import bindingEditorDef from '@/components/json-definitions/binding-editor.json' import appLayoutDef from '@/components/json-definitions/app-layout.json' import appRouterLayoutDef from '@/components/json-definitions/app-router-layout.json' import appMainPanelDef from '@/components/json-definitions/app-main-panel.json' +import appDialogsDef from '@/components/json-definitions/app-dialogs.json' // Create pure JSON components (no hooks) export const LoadingFallback = createJsonComponent(loadingFallbackDef) @@ -72,6 +73,7 @@ export const DataSourceEditorDialog = createJsonComponent(githubBuildStatusDef) export const SeedDataManager = createJsonComponent(seedDataManagerDef) export const TreeCard = createJsonComponent(treeCardDef) +export const AppDialogs = createJsonComponent(appDialogsDef) // Create JSON components with hooks export const SaveIndicator = createJsonComponentWithHooks(saveIndicatorDef, {