feat(ui): disable nodes during workflow running

This commit is contained in:
Fu Diwei 2025-01-04 12:58:45 +08:00
parent 52dfa5e8c3
commit 2213399f5e
8 changed files with 38 additions and 26 deletions

View File

@ -44,8 +44,6 @@ var sslProviderUrls = map[string]string{
sslProviderGts: gtsUrl,
}
const defaultEmail = "536464346@qq.com"
type Certificate struct {
CertUrl string `json:"certUrl"`
CertStableUrl string `json:"certStableUrl"`

View File

@ -16,9 +16,10 @@ import AddNode from "./node/AddNode";
export type NodeProps = {
node: WorkflowNode;
disabled?: boolean;
};
const WorkflowElement = ({ node }: NodeProps) => {
const WorkflowElement = ({ node, disabled }: NodeProps) => {
const { t } = useTranslation();
const { updateNode, removeNode } = useWorkflowStore(useZustandShallowSelector(["updateNode", "removeNode"]));
@ -94,6 +95,8 @@ const WorkflowElement = ({ node }: NodeProps) => {
};
const handleNodeClick = () => {
if (disabled) return;
showPanel({
name: node.name,
children: <PanelBody data={node} />,
@ -111,10 +114,13 @@ const WorkflowElement = ({ node }: NodeProps) => {
items: [
{
key: "delete",
disabled: disabled,
label: t("workflow_node.action.delete_node"),
icon: <CloseCircleOutlinedIcon />,
danger: true,
onClick: () => {
if (disabled) return;
removeNode(node.id);
},
},
@ -150,7 +156,7 @@ const WorkflowElement = ({ node }: NodeProps) => {
</Card>
</Popover>
<AddNode node={node} />
<AddNode node={node} disabled={disabled} />
</>
);
};

View File

@ -10,9 +10,10 @@ import { useWorkflowStore } from "@/stores/workflow";
export type WorkflowElementsProps = {
className?: string;
style?: React.CSSProperties;
disabled?: boolean;
};
const WorkflowElements = ({ className, style }: WorkflowElementsProps) => {
const WorkflowElements = ({ className, style, disabled }: WorkflowElementsProps) => {
const { workflow } = useWorkflowStore(useZustandShallowSelector(["workflow"]));
const elements = useMemo(() => {
@ -20,7 +21,7 @@ const WorkflowElements = ({ className, style }: WorkflowElementsProps) => {
let current = workflow.draft as WorkflowNode;
while (current) {
nodes.push(<NodeRender node={current} key={current.id} />);
nodes.push(<NodeRender key={current.id} node={current} disabled={disabled} />);
current = current.next as WorkflowNode;
}

View File

@ -15,9 +15,10 @@ import { useWorkflowStore } from "@/stores/workflow";
export type AddNodeProps = {
node: WorkflowNode;
disabled?: boolean;
};
const AddNode = ({ node }: AddNodeProps) => {
const AddNode = ({ node, disabled }: AddNodeProps) => {
const { t } = useTranslation();
const { addNode } = useWorkflowStore(useZustandShallowSelector(["addNode"]));
@ -31,20 +32,19 @@ const AddNode = ({ node }: AddNodeProps) => {
].map(([type, label, icon]) => {
return {
key: type as string,
disabled: true,
label: t(label as string),
icon: icon,
onClick: () => {
handleNodeTypeSelect(type as WorkflowNodeType);
if (disabled) return;
const nextNode = newNode(type as WorkflowNodeType);
addNode(nextNode, node.id);
},
};
});
}, []);
const handleNodeTypeSelect = (type: WorkflowNodeType) => {
const nextNode = newNode(type);
addNode(nextNode, node.id);
};
return (
<div className="relative py-6 before:absolute before:left-1/2 before:top-0 before:h-full before:w-[2px] before:-translate-x-1/2 before:bg-stone-200 before:content-['']">
<Dropdown menu={{ items: dropdownMenus }} trigger={["click"]}>

View File

@ -11,9 +11,10 @@ import NodeRender from "./NodeRender";
export type BrandNodeProps = {
node: WorkflowNode;
disabled?: boolean;
};
const BranchNode = ({ node }: BrandNodeProps) => {
const BranchNode = ({ node, disabled }: BrandNodeProps) => {
const { t } = useTranslation();
const { addBranch } = useWorkflowStore(useZustandShallowSelector(["addBranch"]));
@ -23,7 +24,7 @@ const BranchNode = ({ node }: BrandNodeProps) => {
let current = node as WorkflowNode | undefined;
while (current) {
elements.push(<NodeRender key={current.id} node={current} branchId={branchNodeId} branchIndex={branchIndex} />);
elements.push(<NodeRender key={current.id} node={current} branchId={branchNodeId} branchIndex={branchIndex} disabled={disabled} />);
current = current.next;
}
@ -35,6 +36,7 @@ const BranchNode = ({ node }: BrandNodeProps) => {
<div className="relative flex gap-x-16 before:absolute before:inset-x-[128px] before:top-0 before:h-[2px] before:bg-stone-200 before:content-[''] after:absolute after:inset-x-[128px] after:bottom-0 after:h-[2px] after:bg-stone-200 after:content-['']">
<Button
className="absolute left-1/2 z-[1] -translate-x-1/2 -translate-y-1/2 text-xs"
disabled={disabled}
size="small"
shape="round"
variant="outlined"
@ -55,7 +57,7 @@ const BranchNode = ({ node }: BrandNodeProps) => {
))}
</div>
<AddNode node={node} />
<AddNode node={node} disabled={disabled} />
</>
);
};

View File

@ -11,11 +11,12 @@ import AddNode from "./AddNode";
export type ConditionNodeProps = {
node: WorkflowNode;
branchId?: string;
branchIndex?: number;
branchId: string;
branchIndex: number;
disabled?: boolean;
};
const ConditionNode = ({ node, branchId, branchIndex }: ConditionNodeProps) => {
const ConditionNode = ({ node, branchId, branchIndex, disabled }: ConditionNodeProps) => {
const { t } = useTranslation();
const { updateNode, removeBranch } = useWorkflowStore(useZustandShallowSelector(["updateNode", "removeBranch"]));
@ -44,11 +45,14 @@ const ConditionNode = ({ node, branchId, branchIndex }: ConditionNodeProps) => {
items: [
{
key: "delete",
disabled: disabled,
label: t("workflow_node.action.delete_branch"),
icon: <CloseCircleOutlinedIcon />,
danger: true,
onClick: () => {
removeBranch(branchId ?? "", branchIndex ?? 0);
if (disabled) return;
removeBranch(branchId!, branchIndex!);
},
},
],
@ -76,7 +80,7 @@ const ConditionNode = ({ node, branchId, branchIndex }: ConditionNodeProps) => {
</Card>
</Popover>
<AddNode node={node} />
<AddNode node={node} disabled={disabled} />
</>
);
};

View File

@ -11,22 +11,23 @@ export type NodeRenderProps = {
node: WorkflowNode;
branchId?: string;
branchIndex?: number;
disabled?: boolean;
};
const NodeRender = ({ node: data, branchId, branchIndex }: NodeRenderProps) => {
const NodeRender = ({ node: data, branchId, branchIndex, disabled }: NodeRenderProps) => {
const render = () => {
switch (data.type) {
case WorkflowNodeType.Start:
case WorkflowNodeType.Apply:
case WorkflowNodeType.Deploy:
case WorkflowNodeType.Notify:
return <WorkflowElement node={data} />;
return <WorkflowElement node={data} disabled={disabled} />;
case WorkflowNodeType.End:
return <EndNode />;
case WorkflowNodeType.Branch:
return <BranchNode node={data} />;
return <BranchNode node={data} disabled={disabled} />;
case WorkflowNodeType.Condition:
return <ConditionNode node={data as WorkflowNode} branchId={branchId} branchIndex={branchIndex} />;
return <ConditionNode node={data as WorkflowNode} branchId={branchId!} branchIndex={branchIndex!} disabled={disabled} />;
}
};

View File

@ -248,7 +248,7 @@ const WorkflowDetail = () => {
<Show when={tabValue === "orchestration"}>
<div className="relative">
<div className="py-12 lg:pr-36 xl:pr-48">
<WorkflowElements />
<WorkflowElements disabled={isRunning} />
</div>
<div className="absolute right-0 top-0 z-[1]">
<Space>