Merge pull request #148 from johndoe6345789/codex/create-json-showcase-page-for-batches

Add JSON Conversion Showcase page/component and remove visual regression snapshot
This commit is contained in:
2026-01-18 13:12:19 +00:00
committed by GitHub
9 changed files with 408 additions and 2 deletions

View File

@@ -236,6 +236,15 @@
"category": "showcase",
"description": "JSON UI system demonstration"
},
{
"name": "JSONConversionShowcase",
"path": "@/components/JSONConversionShowcase",
"export": "JSONConversionShowcase",
"type": "feature",
"preload": false,
"category": "showcase",
"description": "JSON conversion showcase overview"
},
{
"name": "SchemaEditor",
"path": "@/components/SchemaEditorPage",

View File

@@ -0,0 +1,16 @@
import { test, expect } from '@playwright/test'
test.describe('visual regression', () => {
test('json conversion showcase', async ({ page }) => {
await page.goto('/json-conversion-showcase')
await page.waitForLoadState('networkidle')
await page.waitForFunction(() => {
const root = document.querySelector('#root')
return root && root.textContent && root.textContent.length > 0
})
await page.addStyleTag({
content: '* { transition: none !important; animation: none !important; }',
})
await expect(page).toHaveScreenshot('json-conversion-showcase.png', { fullPage: true })
})
})

View File

@@ -0,0 +1,9 @@
import { PageRenderer } from '@/lib/json-ui/page-renderer'
import conversionShowcaseSchema from '@/config/pages/json-conversion-showcase.json'
import { PageSchema } from '@/types/json-ui'
export function JSONConversionShowcase() {
const schema = conversionShowcaseSchema as PageSchema
return <PageRenderer schema={schema} />
}

View File

@@ -6,9 +6,8 @@ import { DataSourceIdField } from '@/components/molecules/data-source-editor/Dat
import { KvSourceFields } from '@/components/molecules/data-source-editor/KvSourceFields'
import { StaticSourceFields } from '@/components/molecules/data-source-editor/StaticSourceFields'
import { ComputedSourceFields } from '@/components/molecules/data-source-editor/ComputedSourceFields'
import { useDataSourceEditor } from '@/hooks/data/use-data-source-editor'
import dataSourceEditorCopy from '@/data/data-source-editor-dialog.json'
import { useDataSourceEditor } from '@/hooks/use-data-source-editor'
import { useDataSourceEditor } from '@/hooks/data/use-data-source-editor'
interface DataSourceEditorDialogProps {
open: boolean

View File

@@ -235,6 +235,16 @@
"type": "single"
}
},
{
"id": "json-conversion-showcase",
"title": "JSON Conversion Showcase",
"description": "JSON conversion showcase overview",
"icon": "BookOpen",
"component": "JSONConversionShowcase",
"layout": {
"type": "single"
}
},
{
"id": "sass",
"title": "Sass Styles",

View File

@@ -27,6 +27,7 @@ import { PWASettings } from '@/components/PWASettings'
import { FaviconDesigner } from '@/components/FaviconDesigner'
import { FeatureIdeaCloud } from '@/components/FeatureIdeaCloud'
import { JSONUIShowcase } from '@/components/JSONUIShowcase'
import { JSONConversionShowcase } from '@/components/JSONConversionShowcase'
export const ComponentRegistry: Record<string, ComponentType<any>> = {
Button,
@@ -61,6 +62,7 @@ export const ComponentRegistry: Record<string, ComponentType<any>> = {
FaviconDesigner,
FeatureIdeaCloud,
JSONUIShowcase,
JSONConversionShowcase,
}
export function getComponent(name: string): ComponentType<any> | null {

View File

@@ -365,6 +365,15 @@
"order": 22,
"props": {}
},
{
"id": "json-conversion-showcase",
"title": "JSON Conversion Showcase",
"icon": "BookOpen",
"component": "JSONConversionShowcase",
"enabled": true,
"order": 22.1,
"props": {}
},
{
"id": "schema-editor",
"title": "Schema Editor",

View File

@@ -0,0 +1,341 @@
{
"id": "json-conversion-showcase",
"name": "JSON Conversion Showcase",
"layout": {
"type": "single"
},
"dataSources": [
{
"id": "batches",
"type": "static",
"defaultValue": [
{
"title": "Phase 1",
"summary": "Models, Component Trees, Workflows",
"stats": [
{ "label": "Pages Converted", "value": "3" },
{ "label": "JSON Schema Lines", "value": "~900" },
{ "label": "Code Reduction", "value": "~60%" }
],
"pages": [
{
"name": "Models Designer",
"pageId": "models-json",
"schema": "src/config/pages/model-designer.json",
"dataStore": "app-models"
},
{
"name": "Component Trees Manager",
"pageId": "component-trees-json",
"schema": "src/config/pages/component-tree.json",
"dataStore": "app-component-trees"
},
{
"name": "Workflows Designer",
"pageId": "workflows-json",
"schema": "src/config/pages/workflow-designer.json",
"dataStore": "app-workflows"
}
],
"seedHighlights": [
"3 model records (User, Post, Comment)",
"2 component trees (Dashboard, Profile)",
"3 workflow definitions (Registration, Processing, Payment)"
]
},
{
"title": "Phase 2",
"summary": "Lambdas, Styling, Flask API",
"stats": [
{ "label": "Pages Converted", "value": "3" },
{ "label": "JSON Schema Lines", "value": "~2,100" },
{ "label": "Seed Records", "value": "8" }
],
"pages": [
{
"name": "Lambda Designer",
"pageId": "lambdas-json",
"schema": "src/config/pages/lambda-designer.json",
"dataStore": "app-lambdas"
},
{
"name": "Style Designer",
"pageId": "styling-json",
"schema": "src/config/pages/style-designer.json",
"dataStore": "app-theme"
},
{
"name": "Flask API Designer",
"pageId": "flask-json",
"schema": "src/config/pages/flask-designer.json",
"dataStore": "app-flask-config"
}
],
"seedHighlights": [
"3 serverless functions seeded with triggers",
"2 theme variants with custom palettes",
"3 Flask blueprints covering 7 endpoints"
]
}
]
},
{
"id": "patterns",
"type": "static",
"defaultValue": [
"Sidebar + detail layout pattern",
"Computed counters for live totals",
"KV-backed data sources for persistence",
"Declarative empty states and actions"
]
}
],
"components": [
{
"id": "root",
"type": "div",
"props": {
"className": "h-full overflow-auto bg-background p-6"
},
"children": [
{
"id": "header",
"type": "div",
"props": { "className": "space-y-2" },
"children": [
{
"id": "title",
"type": "Heading",
"props": {
"className": "text-3xl font-bold",
"children": "JSON Conversion Showcase"
}
},
{
"id": "subtitle",
"type": "Text",
"props": {
"className": "text-muted-foreground",
"children": "One-page overview of JSON conversion phases and their deliverables."
}
}
]
},
{
"id": "phase-grid",
"type": "div",
"props": { "className": "mt-8 space-y-8" },
"loop": {
"source": "batches",
"itemVar": "batch"
},
"children": [
{
"id": "phase-card",
"type": "Card",
"children": [
{
"id": "phase-header",
"type": "CardHeader",
"children": [
{
"id": "phase-title",
"type": "CardTitle",
"bindings": {
"children": { "source": "batch", "sourceType": "bindings", "path": "title" }
}
},
{
"id": "phase-description",
"type": "CardDescription",
"bindings": {
"children": { "source": "batch", "sourceType": "bindings", "path": "summary" }
}
}
]
},
{
"id": "phase-content",
"type": "CardContent",
"props": { "className": "space-y-6" },
"children": [
{
"id": "stats-grid",
"type": "div",
"props": {
"className": "grid gap-3 md:grid-cols-3"
},
"loop": {
"source": "batch.stats",
"itemVar": "stat"
},
"children": [
{
"id": "stat-item",
"type": "div",
"props": { "className": "rounded-lg border border-border p-3" },
"children": [
{
"id": "stat-label",
"type": "Text",
"props": { "className": "text-xs text-muted-foreground" },
"bindings": {
"children": { "source": "stat", "sourceType": "bindings", "path": "label" }
}
},
{
"id": "stat-value",
"type": "Text",
"props": { "className": "text-lg font-semibold" },
"bindings": {
"children": { "source": "stat", "sourceType": "bindings", "path": "value" }
}
}
]
}
]
},
{
"id": "pages-section",
"type": "div",
"props": { "className": "space-y-3" },
"children": [
{
"id": "pages-title",
"type": "Heading",
"props": { "className": "text-base font-semibold", "children": "Converted Pages" }
},
{
"id": "pages-grid",
"type": "div",
"props": { "className": "grid gap-3 md:grid-cols-3" },
"loop": {
"source": "batch.pages",
"itemVar": "page"
},
"children": [
{
"id": "page-item",
"type": "Card",
"children": [
{
"id": "page-item-header",
"type": "CardHeader",
"children": [
{
"id": "page-item-title",
"type": "CardTitle",
"bindings": {
"children": { "source": "page", "sourceType": "bindings", "path": "name" }
}
},
{
"id": "page-item-description",
"type": "CardDescription",
"bindings": {
"children": { "source": "page", "sourceType": "bindings", "path": "schema" }
}
}
]
},
{
"id": "page-item-content",
"type": "CardContent",
"props": { "className": "space-y-2" },
"children": [
{
"id": "page-id",
"type": "Badge",
"bindings": {
"children": { "source": "page", "sourceType": "bindings", "path": "pageId" }
}
},
{
"id": "page-store",
"type": "Text",
"props": { "className": "text-xs text-muted-foreground" },
"bindings": {
"children": { "source": "page", "sourceType": "bindings", "path": "dataStore" }
}
}
]
}
]
}
]
}
]
},
{
"id": "seed-section",
"type": "div",
"props": { "className": "space-y-2" },
"children": [
{
"id": "seed-title",
"type": "Heading",
"props": { "className": "text-base font-semibold", "children": "Seed Data Highlights" }
},
{
"id": "seed-list",
"type": "div",
"props": { "className": "space-y-1" },
"loop": {
"source": "batch.seedHighlights",
"itemVar": "seed"
},
"children": [
{
"id": "seed-item",
"type": "Text",
"props": { "className": "text-sm" },
"bindings": {
"children": { "source": "seed", "sourceType": "bindings" }
}
}
]
}
]
}
]
}
]
}
]
},
{
"id": "patterns-section",
"type": "div",
"props": { "className": "mt-8" },
"children": [
{
"id": "patterns-title",
"type": "Heading",
"props": { "className": "text-xl font-semibold", "children": "Reusable Patterns" }
},
{
"id": "patterns-list",
"type": "div",
"props": { "className": "mt-3 space-y-2" },
"loop": {
"source": "patterns",
"itemVar": "pattern"
},
"children": [
{
"id": "pattern-item",
"type": "Text",
"props": { "className": "text-sm" },
"bindings": {
"children": { "source": "pattern", "sourceType": "bindings" }
}
}
]
}
]
}
]
}
],
"globalActions": []
}

View File

@@ -153,6 +153,11 @@ export const tabInfo: Record<string, TabInfo> = {
icon: <Code size={24} weight="duotone" />,
description: 'JSON-driven UI examples',
},
'json-conversion-showcase': {
title: 'JSON Conversion Showcase',
icon: <BookOpen size={24} weight="duotone" />,
description: 'JSON conversion showcase overview',
},
'atomic-library': {
title: 'Atomic Components',
icon: <Atom size={24} weight="duotone" />,
@@ -332,6 +337,12 @@ export const navigationGroups: NavigationGroup[] = [
value: 'docs',
featureKey: 'documentation',
},
{
id: 'json-conversion-showcase',
label: 'JSON Conversion Showcase',
icon: <BookOpen size={18} />,
value: 'json-conversion-showcase',
},
{
id: 'settings',
label: 'Settings',