feat: polish workflow studio and workspace assets
This commit is contained in:
+44
-14
@@ -1,34 +1,51 @@
|
||||
import React from 'react';
|
||||
|
||||
type WorkflowRuntime = {
|
||||
mode?: string;
|
||||
};
|
||||
|
||||
const LOCAL_WORKFLOW_URL = '/workflow-ui/';
|
||||
const DOCKER_WORKFLOW_URL = '/api/comfyui/proxy/';
|
||||
|
||||
export default function Workflows() {
|
||||
const [ready, setReady] = React.useState(false);
|
||||
const [message, setMessage] = React.useState('正在加载工作流前端...');
|
||||
const [workflowUrl, setWorkflowUrl] = React.useState(LOCAL_WORKFLOW_URL);
|
||||
const [isCloud, setIsCloud] = React.useState(false);
|
||||
const iframeRef = React.useRef<HTMLIFrameElement | null>(null);
|
||||
|
||||
const openFullscreen = () => {
|
||||
window.open('/workflow-ui/', '_blank', 'noopener,noreferrer');
|
||||
window.open(workflowUrl, '_blank', 'noopener,noreferrer');
|
||||
};
|
||||
|
||||
const reloadFrame = () => {
|
||||
if (iframeRef.current) {
|
||||
iframeRef.current.src = '/workflow-ui/';
|
||||
iframeRef.current.src = workflowUrl;
|
||||
}
|
||||
};
|
||||
|
||||
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');
|
||||
});
|
||||
const loadRuntime = async () => {
|
||||
const runtimeResponse = await fetch('/api/workflow-ui/runtime', { signal: controller.signal });
|
||||
const runtime = runtimeResponse.ok ? ((await runtimeResponse.json()) as WorkflowRuntime) : {};
|
||||
const cloudMode = runtime.mode === 'cloud';
|
||||
const dockerMode = runtime.mode === 'docker';
|
||||
const targetUrl = dockerMode ? DOCKER_WORKFLOW_URL : LOCAL_WORKFLOW_URL;
|
||||
if (cancelled) return;
|
||||
setIsCloud(cloudMode);
|
||||
setWorkflowUrl(targetUrl);
|
||||
const response = await fetch(targetUrl, { signal: controller.signal });
|
||||
if (cancelled) return;
|
||||
setReady(response.ok);
|
||||
setMessage(response.ok ? '' : 'Workflow Studio 前端未构建,请先执行 workflow-ui:install');
|
||||
};
|
||||
void loadRuntime().catch((error) => {
|
||||
if (cancelled || error?.name === 'AbortError') return;
|
||||
setReady(false);
|
||||
setMessage('工作流入口不可用,请检查服务配置');
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
controller.abort();
|
||||
@@ -39,6 +56,8 @@ export default function Workflows() {
|
||||
<div style={{ width: '100%', height: 'calc(100vh - 56px)', display: 'flex', flexDirection: 'column' }}>
|
||||
<div style={toolbarStyle}>
|
||||
<div style={toolbarTitleStyle}>工作流</div>
|
||||
{!isCloud && workflowUrl === DOCKER_WORKFLOW_URL && <div style={cloudBadgeStyle}>Docker 完整版 ComfyUI</div>}
|
||||
{isCloud && <div style={cloudBadgeStyle}>Comfy Cloud API 后端</div>}
|
||||
<div style={toolbarActionsStyle}>
|
||||
<button type="button" onClick={reloadFrame} disabled={!ready} style={toolbarButtonStyle}>
|
||||
刷新
|
||||
@@ -51,9 +70,10 @@ export default function Workflows() {
|
||||
{ready ? (
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
src="/workflow-ui/"
|
||||
src={workflowUrl}
|
||||
title="Workflow Studio"
|
||||
allow="clipboard-read; clipboard-write"
|
||||
referrerPolicy="no-referrer"
|
||||
style={{ width: '100%', height: '100%', border: 'none', display: 'block' }}
|
||||
/>
|
||||
) : (
|
||||
@@ -79,6 +99,16 @@ const toolbarStyle: React.CSSProperties = {
|
||||
background: 'var(--color-surface)',
|
||||
};
|
||||
|
||||
const cloudBadgeStyle: React.CSSProperties = {
|
||||
marginRight: 'auto',
|
||||
border: '1px solid var(--color-border)',
|
||||
borderRadius: 999,
|
||||
padding: '3px 8px',
|
||||
color: 'var(--color-text-secondary)',
|
||||
fontSize: 12,
|
||||
fontWeight: 700,
|
||||
};
|
||||
|
||||
const toolbarTitleStyle: React.CSSProperties = {
|
||||
fontSize: 14,
|
||||
fontWeight: 800,
|
||||
|
||||
Reference in New Issue
Block a user