feat(editor): add goView sample gallery for import verification

This commit is contained in:
clawdbot 2026-01-29 00:19:12 +08:00
parent 82769ff37b
commit a2c44b9f1b
2 changed files with 178 additions and 1 deletions

View File

@ -8,6 +8,7 @@ import {
Space, Space,
Tabs, Tabs,
Typography, Typography,
message,
} from 'antd'; } from 'antd';
import { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'; import { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';
import { bindEditorHotkeys } from './hotkeys'; import { bindEditorHotkeys } from './hotkeys';
@ -15,6 +16,7 @@ import { Canvas } from './Canvas';
import { ContextMenu, type ContextMenuState } from './ContextMenu'; import { ContextMenu, type ContextMenuState } from './ContextMenu';
import { Inspector } from './Inspector'; import { Inspector } from './Inspector';
import { selectionKeyOf } from './selection'; import { selectionKeyOf } from './selection';
import { goViewSamples } from './samples/goviewSamples';
import { createInitialState, editorReducer, exportScreenJSON } from './store'; import { createInitialState, editorReducer, exportScreenJSON } from './store';
const { Header, Sider, Content } = Layout; const { Header, Sider, Content } = Layout;
@ -335,7 +337,10 @@ export function EditorApp() {
<Button <Button
size="small" size="small"
type="primary" type="primary"
onClick={() => dispatch({ type: 'importJSON', json: importText })} onClick={() => {
dispatch({ type: 'importJSON', json: importText });
message.success('已导入');
}}
disabled={!importText.trim()} disabled={!importText.trim()}
> >
Import Import
@ -346,11 +351,80 @@ export function EditorApp() {
const json = api.exportJSON(); const json = api.exportJSON();
setImportText(json); setImportText(json);
void navigator.clipboard?.writeText(json); void navigator.clipboard?.writeText(json);
message.success('已导出并复制到剪贴板');
}} }}
> >
Export Export
</Button> </Button>
</Space> </Space>
<Divider style={{ borderColor: 'rgba(255,255,255,0.08)' }} />
<PanelTitle title="SamplesgoView" extra={<Typography.Text style={{ color: '#64748b', fontSize: 12 }}>{goViewSamples.length}</Typography.Text>} />
<div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
{goViewSamples.map((s) => (
<div
key={s.id}
style={{
borderRadius: 10,
border: '1px solid rgba(255,255,255,0.08)',
background: 'rgba(255,255,255,0.03)',
padding: 10,
display: 'flex',
gap: 10,
alignItems: 'center',
}}
>
<div
style={{
width: 72,
height: 44,
borderRadius: 8,
background: 'rgba(16,185,129,0.10)',
border: '1px solid rgba(16,185,129,0.25)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#a7f3d0',
fontSize: 12,
letterSpacing: 0.4,
}}
>
goView
</div>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ color: '#e2e8f0', fontSize: 13, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
{s.title}
</div>
<div style={{ color: '#94a3b8', fontSize: 12, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
{s.subtitle ?? s.description ?? ''}
</div>
</div>
<Space size={6}>
<Button
size="small"
type="primary"
onClick={() => {
setImportText(s.json);
dispatch({ type: 'importJSON', json: s.json });
if (s.focusId) dispatch({ type: 'setSelection', ids: [s.focusId] });
message.success('已加载样例');
}}
>
Load
</Button>
<Button
size="small"
onClick={() => {
void navigator.clipboard?.writeText(s.json);
message.success('已复制 JSON');
}}
>
Copy
</Button>
</Space>
</div>
))}
</div>
</Sider> </Sider>
{/* Center */} {/* Center */}

View File

@ -0,0 +1,103 @@
export type GoViewSample = {
id: string;
title: string;
subtitle?: string;
description?: string;
json: string;
focusId?: string;
};
function prettyJson(v: unknown): string {
return JSON.stringify(v, null, 2);
}
export const goViewSamples: GoViewSample[] = [
{
id: 'goview-iframe-url',
title: '网页iframe- 直接 URL',
subtitle: 'Embed / iframe',
description: '典型 goView 网页组件src/url 在 option 中。',
focusId: 'iframe_1',
json: prettyJson({
editCanvasConfig: { projectName: 'Sample: iframe url', width: 1920, height: 1080, background: '#0b1220' },
componentList: [
{
id: 'iframe_1',
chartConfig: { key: 'Iframe' },
attr: { x: 200, y: 140, w: 960, h: 540 },
option: { src: 'https://example.com' },
},
{
id: 'text_1',
chartConfig: { key: 'TextCommon' },
attr: { x: 200, y: 60, w: 600, h: 60 },
option: { text: 'goView Sample: iframe URL' },
},
],
}),
},
{
id: 'goview-video-mp4',
title: '视频video- mp4',
subtitle: 'Media / video',
description: '典型媒体直链mp4/m3u8/rtsp 等。',
focusId: 'video_1',
json: prettyJson({
editCanvasConfig: { projectName: 'Sample: video mp4', width: 1920, height: 1080, background: '#0b1220' },
componentList: [
{
id: 'video_1',
chartConfig: { key: 'Video' },
attr: { x: 240, y: 140, w: 960, h: 540 },
option: { url: 'https://www.w3schools.com/html/mov_bbb.mp4', autoplay: false },
},
{
id: 'text_1',
chartConfig: { key: 'TextCommon' },
attr: { x: 240, y: 60, w: 700, h: 60 },
option: { text: 'goView Sample: video mp4 (w3schools)' },
},
],
}),
},
{
id: 'goview-iframe-embed-html',
title: '网页iframe- embed HTML',
subtitle: 'Embed / <iframe src="…">',
description: '某些低代码导出会把整段 HTML 存进 option。',
focusId: 'iframe_1',
json: prettyJson({
editCanvasConfig: { projectName: 'Sample: iframe embed html', width: 1920, height: 1080, background: '#0b1220' },
componentList: [
{
id: 'iframe_1',
chartConfig: { key: 'IframeCommon' },
attr: { x: 200, y: 140, w: 960, h: 540 },
option: {
embed: '<iframe src="https://example.com" width="960" height="540" frameborder="0"></iframe>',
},
},
],
}),
},
{
id: 'goview-video-embed-html',
title: '视频video- embed HTML',
subtitle: 'Media / <video><source>',
description: '从 <video>/<source> 里提取 src 的场景。',
focusId: 'video_1',
json: prettyJson({
editCanvasConfig: { projectName: 'Sample: video embed html', width: 1920, height: 1080, background: '#0b1220' },
componentList: [
{
id: 'video_1',
chartConfig: { key: 'Video' },
attr: { x: 240, y: 140, w: 960, h: 540 },
option: {
html: '<video controls><source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" /></video>',
},
},
],
}),
},
];