feat: add workflow studio and postgres support

This commit is contained in:
boos
2026-05-25 16:03:07 +08:00
parent 7cdb02ef1d
commit cb35d5fc6e
96 changed files with 12414 additions and 15548 deletions
+111
View File
@@ -0,0 +1,111 @@
import React from 'react';
export default function Workflows() {
const [ready, setReady] = React.useState(false);
const [message, setMessage] = React.useState('正在加载工作流前端...');
const iframeRef = React.useRef<HTMLIFrameElement | null>(null);
const openFullscreen = () => {
window.open('/workflow-ui/', '_blank', 'noopener,noreferrer');
};
const reloadFrame = () => {
if (iframeRef.current) {
iframeRef.current.src = '/workflow-ui/';
}
};
React.useEffect(() => {
let cancelled = false;
const controller = new AbortController();
void fetch('/workflow-ui/', { signal: controller.signal })
.then((response) => {
if (cancelled) return;
setReady(response.ok);
setMessage(response.ok ? '' : 'Workflow Studio 前端未构建,请先执行 workflow-ui:install');
})
.catch((error) => {
if (cancelled || error?.name === 'AbortError') return;
setReady(false);
setMessage('Workflow Studio 前端未构建,请先执行 workflow-ui:install');
});
return () => {
cancelled = true;
controller.abort();
};
}, []);
return (
<div style={{ width: '100%', height: 'calc(100vh - 56px)', display: 'flex', flexDirection: 'column' }}>
<div style={toolbarStyle}>
<div style={toolbarTitleStyle}>工作流</div>
<div style={toolbarActionsStyle}>
<button type="button" onClick={reloadFrame} disabled={!ready} style={toolbarButtonStyle}>
刷新
</button>
<button type="button" onClick={openFullscreen} style={primaryToolbarButtonStyle}>
新窗口打开
</button>
</div>
</div>
{ready ? (
<iframe
ref={iframeRef}
src="/workflow-ui/"
title="Workflow Studio"
allow="clipboard-read; clipboard-write"
style={{ width: '100%', height: '100%', border: 'none', display: 'block' }}
/>
) : (
<div style={{ flex: 1, display: 'grid', placeItems: 'center', padding: 24, textAlign: 'center' }}>
<div>
<div style={{ fontSize: 18, fontWeight: 700, marginBottom: 8 }}>Workflow Studio</div>
<div style={{ color: 'var(--color-text-secondary)', lineHeight: 1.7 }}>{message}</div>
</div>
</div>
)}
</div>
);
}
const toolbarStyle: React.CSSProperties = {
minHeight: 44,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: 12,
padding: '8px 12px',
borderBottom: '1px solid var(--color-border-light)',
background: 'var(--color-surface)',
};
const toolbarTitleStyle: React.CSSProperties = {
fontSize: 14,
fontWeight: 800,
color: 'var(--color-text-primary)',
};
const toolbarActionsStyle: React.CSSProperties = {
display: 'flex',
alignItems: 'center',
gap: 8,
};
const toolbarButtonStyle: React.CSSProperties = {
minHeight: 30,
border: '1px solid var(--color-border)',
borderRadius: 8,
padding: '5px 10px',
background: 'var(--color-bg)',
color: 'var(--color-text-primary)',
cursor: 'pointer',
fontSize: 12,
};
const primaryToolbarButtonStyle: React.CSSProperties = {
...toolbarButtonStyle,
borderColor: 'var(--color-primary)',
background: 'var(--color-primary)',
color: '#fff',
fontWeight: 700,
};