Add JSON page routing support

This commit is contained in:
2026-01-18 17:15:39 +00:00
parent 6388880362
commit 7be52ffc1e
4 changed files with 78 additions and 7 deletions

View File

@@ -1,4 +1,5 @@
import pagesConfig from './pages.json'
import { PageSchema } from '@/types/json-ui'
import { FeatureToggles } from '@/types/project'
export interface PropConfig {
@@ -23,7 +24,10 @@ export interface PageConfig {
id: string
title: string
icon: string
component: string
component?: string
type?: 'json' | 'component'
schemaPath?: string
schema?: PageSchema
enabled: boolean
isRoot?: boolean
toggleKey?: string

View File

@@ -57,7 +57,9 @@ export function validatePageConfig(): ValidationError[] {
})
}
if (!page.component) {
const isJsonPage = page.type === 'json' || Boolean(page.schemaPath)
if (!page.component && !isJsonPage) {
errors.push({
page: page.id || 'Unknown',
field: 'component',
@@ -66,6 +68,15 @@ export function validatePageConfig(): ValidationError[] {
})
}
if (isJsonPage && !page.schemaPath && !page.schema) {
errors.push({
page: page.id || 'Unknown',
field: 'schemaPath',
message: 'schemaPath is required for JSON pages',
severity: 'error',
})
}
if (!page.icon) {
errors.push({
page: page.id || 'Unknown',

View File

@@ -1,9 +1,11 @@
import { lazy, Suspense } from 'react'
import { RouteObject, Navigate } from 'react-router-dom'
import { LoadingFallback } from '@/components/molecules'
import { JSONSchemaPageLoader } from '@/components/JSONSchemaPageLoader'
import { NotFoundPage } from '@/components/NotFoundPage'
import { getEnabledPages, resolveProps } from '@/config/page-loader'
import { ComponentRegistry } from '@/lib/component-registry'
import { PageRenderer } from '@/lib/json-ui/page-renderer'
import { FeatureToggles } from '@/types/project'
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@/components/ui/resizable'
@@ -87,6 +89,21 @@ export function createRoutes(
const rootPage = enabledPages.find(p => p.isRoot)
console.log('[ROUTES] 🏠 Root page search result:', rootPage ? `Found: ${rootPage.id} (${rootPage.component})` : 'NOT FOUND - will redirect to /dashboard')
const renderJsonPage = (page: typeof enabledPages[number]) => {
if (page.schema) {
console.log('[ROUTES] 🧾 Rendering preloaded JSON schema for page:', page.id)
return <PageRenderer schema={page.schema} />
}
if (page.schemaPath) {
console.log('[ROUTES] 🧾 Rendering JSON schema loader for page:', page.id)
return <JSONSchemaPageLoader schemaPath={page.schemaPath} />
}
console.error('[ROUTES] ❌ JSON page missing schemaPath:', page.id)
return <LoadingFallback message={`Schema path missing for JSON page: ${page.id}`} />
}
const routes: RouteObject[] = enabledPages
.filter(p => !p.isRoot)
.map(page => {
@@ -96,11 +113,26 @@ export function createRoutes(
? resolveProps(page.props, stateContext, actionContext)
: {}
if (page.type === 'json' || page.schemaPath) {
return {
path: `/${page.id}`,
element: renderJsonPage(page)
}
}
if (page.requiresResizable && page.resizableConfig) {
console.log('[ROUTES] 🔀 Page requires resizable layout:', page.id)
const config = page.resizableConfig
const leftProps = resolveProps(config.leftProps, stateContext, actionContext)
if (!page.component) {
console.error('[ROUTES] ❌ Resizable page missing component:', page.id)
return {
path: `/${page.id}`,
element: <LoadingFallback message={`Component missing for page: ${page.id}`} />
}
}
return {
path: `/${page.id}`,
element: (
@@ -115,6 +147,14 @@ export function createRoutes(
}
}
if (!page.component) {
console.error('[ROUTES] ❌ Page missing component:', page.id)
return {
path: `/${page.id}`,
element: <LoadingFallback message={`Component missing for page: ${page.id}`} />
}
}
return {
path: `/${page.id}`,
element: <LazyComponent componentName={page.component} props={props} />
@@ -127,10 +167,23 @@ export function createRoutes(
? resolveProps(rootPage.props, stateContext, actionContext)
: {}
routes.push({
path: '/',
element: <LazyComponent componentName={rootPage.component} props={props} />
})
if (rootPage.type === 'json' || rootPage.schemaPath) {
routes.push({
path: '/',
element: renderJsonPage(rootPage)
})
} else if (!rootPage.component) {
console.error('[ROUTES] ❌ Root page missing component:', rootPage.id)
routes.push({
path: '/',
element: <LoadingFallback message="Root page component missing" />
})
} else {
routes.push({
path: '/',
element: <LazyComponent componentName={rootPage.component} props={props} />
})
}
} else {
console.log('[ROUTES] ⚠️ No root page in config, redirecting to /dashboard')
routes.push({

View File

@@ -1,3 +1,4 @@
import { PageSchema } from './json-ui'
import { PropConfig } from './prop-config'
import { ResizableConfig } from './resizable-config'
@@ -6,7 +7,9 @@ export interface PageConfig {
title: string
icon: string
component?: string
schema?: string
type?: 'json' | 'component'
schemaPath?: string
schema?: PageSchema
enabled: boolean
isRoot?: boolean
toggleKey?: string