diff --git a/sundynix-desktop/frontend/src/App.tsx b/sundynix-desktop/frontend/src/App.tsx index d74ef7e..d544164 100644 --- a/sundynix-desktop/frontend/src/App.tsx +++ b/sundynix-desktop/frontend/src/App.tsx @@ -263,7 +263,7 @@ export default function App() { {view === "home" ? ( ) : view === "studio" ? ( - + ) : view === "kb" ? ( ) : view === "report" ? ( diff --git a/sundynix-desktop/frontend/src/studio/StudioView.tsx b/sundynix-desktop/frontend/src/studio/StudioView.tsx index 88316c3..37a3e8a 100644 --- a/sundynix-desktop/frontend/src/studio/StudioView.tsx +++ b/sundynix-desktop/frontend/src/studio/StudioView.tsx @@ -49,7 +49,7 @@ function buildExample(): { nodes: Node[]; edges: Edge[] } { } // 编排 Studio:左(节点面板 + 我的编排) · 中画布 · 右检查器 · 顶工具栏。 -export function StudioView({ onRun, phase, identity }: { onRun: (dsl: TaskDsl) => void; phase: RunPhase; identity: Identity }) { +export function StudioView({ onRun, phase, identity, readOnly = false }: { onRun: (dsl: TaskDsl) => void; phase: RunPhase; identity: Identity; readOnly?: boolean }) { const toast = useToast(); const { theme } = useTheme(); const [nodes, setNodes, onNodesChange] = useNodesState([]); @@ -185,10 +185,14 @@ export function StudioView({ onRun, phase, identity }: { onRun: (dsl: TaskDsl) = }, [phase, setNodes]); const run = useCallback(() => { + if (readOnly) { + toast.push("error", "当前身份为只读成员(viewer),无权在此租户运行编排"); + return; + } const found = validate(nodes, edges); setIssues(found); if (!found.some((i) => i.level === "error")) onRun(exportDsl(nodes, edges)); - }, [nodes, edges, onRun]); + }, [nodes, edges, onRun, readOnly, toast]); const selected = useMemo(() => nodes.find((n) => n.id === selId) ?? null, [nodes, selId]); const running = phase === "submitting" || phase === "streaming"; @@ -236,8 +240,8 @@ export function StudioView({ onRun, phase, identity }: { onRun: (dsl: TaskDsl) = {/* 中画布 */}
-