mirror of
https://github.com/woodchen-ink/certimate.git
synced 2025-07-18 09:21:56 +08:00
chore: remove unused code
This commit is contained in:
parent
4008c2bfd5
commit
a980904e38
176
ui/package-lock.json
generated
176
ui/package-lock.json
generated
@ -11,7 +11,6 @@
|
||||
"@ant-design/pro-components": "^2.8.2",
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
"@radix-ui/react-select": "^2.1.1",
|
||||
"@radix-ui/react-slot": "^1.1.0",
|
||||
@ -23,7 +22,6 @@
|
||||
"cron-parser": "^4.9.0",
|
||||
"i18next": "^24.2.0",
|
||||
"i18next-browser-languagedetector": "^8.0.2",
|
||||
"i18next-http-backend": "^3.0.1",
|
||||
"immer": "^10.1.1",
|
||||
"jszip": "^3.10.1",
|
||||
"lucide-react": "^0.469.0",
|
||||
@ -3051,34 +3049,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dropdown-menu": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz",
|
||||
"integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.0",
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-context": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-menu": "2.1.1",
|
||||
"@radix-ui/react-primitive": "2.0.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-focus-guards": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
|
||||
@ -3156,45 +3126,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-menu": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-menu/-/react-menu-2.1.1.tgz",
|
||||
"integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.0",
|
||||
"@radix-ui/react-collection": "1.1.0",
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-context": "1.1.0",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-dismissable-layer": "1.1.0",
|
||||
"@radix-ui/react-focus-guards": "1.1.0",
|
||||
"@radix-ui/react-focus-scope": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-popper": "1.2.0",
|
||||
"@radix-ui/react-portal": "1.1.1",
|
||||
"@radix-ui/react-presence": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.0",
|
||||
"@radix-ui/react-roving-focus": "1.1.0",
|
||||
"@radix-ui/react-slot": "1.1.0",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"aria-hidden": "^1.1.1",
|
||||
"react-remove-scroll": "2.5.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popper": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
|
||||
@ -3249,29 +3180,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-presence": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
|
||||
"integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-primitive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
|
||||
@ -3294,36 +3202,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-roving-focus": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
|
||||
"integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.0",
|
||||
"@radix-ui/react-collection": "1.1.0",
|
||||
"@radix-ui/react-compose-refs": "1.1.0",
|
||||
"@radix-ui/react-context": "1.1.0",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.0",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-select": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-select/-/react-select-2.1.1.tgz",
|
||||
@ -4837,14 +4715,6 @@
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-fetch": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/cross-fetch/-/cross-fetch-4.0.0.tgz",
|
||||
"integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
|
||||
"dependencies": {
|
||||
"node-fetch": "^2.6.12"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@ -5667,14 +5537,6 @@
|
||||
"@babel/runtime": "^7.23.2"
|
||||
}
|
||||
},
|
||||
"node_modules/i18next-http-backend": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/i18next-http-backend/-/i18next-http-backend-3.0.1.tgz",
|
||||
"integrity": "sha512-XT2lYSkbAtDE55c6m7CtKxxrsfuRQO3rUfHzj8ZyRtY9CkIX3aRGwXGTkUhpGWce+J8n7sfu3J0f2wTzo7Lw0A==",
|
||||
"dependencies": {
|
||||
"cross-fetch": "4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.1.tgz",
|
||||
@ -6187,25 +6049,6 @@
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz",
|
||||
@ -8176,11 +8019,6 @@
|
||||
"resolved": "https://registry.npmmirror.com/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
|
||||
@ -8481,20 +8319,6 @@
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"@ant-design/pro-components": "^2.8.2",
|
||||
"@hookform/resolvers": "^3.9.0",
|
||||
"@radix-ui/react-dialog": "^1.1.2",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
"@radix-ui/react-select": "^2.1.1",
|
||||
"@radix-ui/react-slot": "^1.1.0",
|
||||
@ -25,7 +24,6 @@
|
||||
"cron-parser": "^4.9.0",
|
||||
"i18next": "^24.2.0",
|
||||
"i18next-browser-languagedetector": "^8.0.2",
|
||||
"i18next-http-backend": "^3.0.1",
|
||||
"immer": "^10.1.1",
|
||||
"jszip": "^3.10.1",
|
||||
"lucide-react": "^0.469.0",
|
||||
|
@ -1,30 +1,17 @@
|
||||
import { Plus } from "lucide-react";
|
||||
|
||||
import { BrandNodeProps, NodeProps } from "./types";
|
||||
|
||||
import { newWorkflowNode, workflowNodeDropdownList, WorkflowNodeType } from "@/domain/workflow";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuPortal,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "../ui/dropdown-menu";
|
||||
import { Dropdown } from "antd";
|
||||
import DropdownMenuItemIcon from "./DropdownMenuItemIcon";
|
||||
import Show from "../Show";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const AddNode = ({ data }: NodeProps | BrandNodeProps) => {
|
||||
const { addNode } = useWorkflowStore(useZustandShallowSelector(["addNode"]));
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { addNode } = useWorkflowStore(useZustandShallowSelector(["addNode"]));
|
||||
|
||||
const handleTypeSelected = (type: WorkflowNodeType, provider?: string) => {
|
||||
const node = newWorkflowNode(type, {
|
||||
providerType: provider,
|
||||
@ -35,57 +22,43 @@ const AddNode = ({ data }: NodeProps | BrandNodeProps) => {
|
||||
|
||||
return (
|
||||
<div className="before:content-[''] before:w-[2px] before:bg-stone-200 before:absolute before:h-full before:left-[50%] before:-translate-x-[50%] before:top-0 pt-6 pb-9 relative flex flex-col items-center">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger className="">
|
||||
<div className="bg-stone-400 hover:bg-stone-500 rounded-full z-10 relative outline-none">
|
||||
<Plus size={18} className="text-white" />
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuLabel>{t("workflow.node.selectNodeType.label")}</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
{workflowNodeDropdownList.map((item) => (
|
||||
<Show
|
||||
key={item.type}
|
||||
when={!!item.leaf}
|
||||
fallback={
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger className="flex space-x-2">
|
||||
<DropdownMenuItemIcon type={item.icon.type} name={item.icon.name} /> <div>{item.name}</div>
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuSubContent>
|
||||
{item.children?.map((subItem) => {
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={subItem.providerType}
|
||||
className="flex space-x-2"
|
||||
onClick={() => {
|
||||
handleTypeSelected(item.type, subItem.providerType);
|
||||
}}
|
||||
>
|
||||
<DropdownMenuItemIcon type={subItem.icon.type} name={subItem.icon.name} /> <div>{subItem.name}</div>
|
||||
</DropdownMenuItem>
|
||||
);
|
||||
})}
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuSub>
|
||||
}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
key={item.type}
|
||||
className="flex space-x-2"
|
||||
onClick={() => {
|
||||
handleTypeSelected(item.type, item.providerType);
|
||||
}}
|
||||
>
|
||||
<DropdownMenuItemIcon type={item.icon.type} name={item.icon.name} /> <div>{item.name}</div>
|
||||
</DropdownMenuItem>
|
||||
</Show>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: workflowNodeDropdownList.map((item) => {
|
||||
if (item.leaf) {
|
||||
return {
|
||||
key: item.type,
|
||||
label: <div className="ml-2">{item.name}</div>,
|
||||
icon: <DropdownMenuItemIcon type={item.icon.type} name={item.icon.name} />,
|
||||
onClick: () => {
|
||||
handleTypeSelected(item.type);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
key: item.type,
|
||||
label: <div className="ml-2">{item.name}</div>,
|
||||
icon: <DropdownMenuItemIcon type={item.icon.type} name={item.icon.name} />,
|
||||
children: item.children?.map((subItem) => {
|
||||
return {
|
||||
key: subItem.providerType,
|
||||
label: <div className="ml-2">{subItem.name}</div>,
|
||||
icon: <DropdownMenuItemIcon type={subItem.icon.type} name={subItem.icon.name} />,
|
||||
onClick: () => {
|
||||
handleTypeSelected(item.type, subItem.providerType);
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
}),
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
<div className="bg-stone-400 hover:bg-stone-500 rounded-full z-10 relative outline-none">
|
||||
<Plus size={18} className="text-white" />
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ import { useWorkflowStore } from "@/stores/workflow";
|
||||
import AddNode from "./AddNode";
|
||||
import { NodeProps } from "./types";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
import { Dropdown } from "antd";
|
||||
import { Ellipsis, Trash2 } from "lucide-react";
|
||||
|
||||
const ConditionNode = ({ data, branchId, branchIndex }: NodeProps) => {
|
||||
@ -13,21 +13,26 @@ const ConditionNode = ({ data, branchId, branchIndex }: NodeProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className="rounded-md shadow-md w-[261px] mt-10 relative z-10">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger className="absolute right-2 top-1">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: "delete",
|
||||
label: "删除分支",
|
||||
icon: <Trash2 size={16} />,
|
||||
danger: true,
|
||||
onClick: () => {
|
||||
removeBranch(branchId ?? "", branchIndex ?? 0);
|
||||
},
|
||||
},
|
||||
],
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
<div className="absolute right-2 top-1 cursor-pointer">
|
||||
<Ellipsis size={17} className="text-stone-600" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
className="flex space-x-2 text-red-600"
|
||||
onClick={() => {
|
||||
removeBranch(branchId ?? "", branchIndex ?? 0);
|
||||
}}
|
||||
>
|
||||
<Trash2 size={16} /> <div>删除分支</div>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
<div className="w-[261px] flex flex-col justify-center text-foreground rounded-md bg-white px-5 py-5">
|
||||
<div contentEditable suppressContentEditableWarning onBlur={handleNameBlur} className="text-center outline-slate-200 dark:text-stone-600">
|
||||
|
@ -14,7 +14,7 @@ import { useEffect, useState } from "react";
|
||||
import i18n from "@/i18n";
|
||||
import { WorkflowNode } from "@/domain/workflow";
|
||||
import { Textarea } from "../ui/textarea";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
import { Dropdown } from "antd";
|
||||
import AccessSelect from "./AccessSelect";
|
||||
import AccessEditModal from "../access/AccessEditModal";
|
||||
import { Plus } from "lucide-react";
|
||||
@ -432,22 +432,30 @@ Remove-Item -Path "$pfxPath" -Force
|
||||
<FormItem>
|
||||
<FormLabel className="flex justify-between items-center">
|
||||
<div>{t("domain.deployment.form.shell_command.label")}</div>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<a className="text-xs text-blue-500 cursor-pointer">{t("domain.deployment.form.shell_preset_scripts.trigger")}</a>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem onClick={() => handleUsePresetScript("reload_nginx")}>
|
||||
{t("domain.deployment.form.shell_preset_scripts.option.reload_nginx.label")}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => handleUsePresetScript("binding_iis")}>
|
||||
{t("domain.deployment.form.shell_preset_scripts.option.binding_iis.label")}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => handleUsePresetScript("binding_netsh")}>
|
||||
{t("domain.deployment.form.shell_preset_scripts.option.binding_netsh.label")}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: "reload_nginx",
|
||||
label: t("domain.deployment.form.shell_preset_scripts.option.reload_nginx.label"),
|
||||
onClick: () => handleUsePresetScript("reload_nginx"),
|
||||
},
|
||||
{
|
||||
key: "binding_iis",
|
||||
label: t("domain.deployment.form.shell_preset_scripts.option.binding_iis.label"),
|
||||
onClick: () => handleUsePresetScript("binding_iis"),
|
||||
},
|
||||
{
|
||||
key: "binding_netsh",
|
||||
label: t("domain.deployment.form.shell_preset_scripts.option.binding_netsh.label"),
|
||||
onClick: () => handleUsePresetScript("binding_netsh"),
|
||||
},
|
||||
],
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
<a className="text-xs text-blue-500 cursor-pointer">{t("domain.deployment.form.shell_preset_scripts.trigger")}</a>
|
||||
</Dropdown>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea placeholder={t("domain.deployment.form.shell_command.placeholder")} {...(field as any)} />
|
||||
|
@ -13,7 +13,7 @@ const DropdownMenuItemIcon = ({ type, name }: WorkflowNodeDropdwonItemIcon) => {
|
||||
if (type === WorkflowNodeDropdwonItemIconType.Icon) {
|
||||
return icons.get(name);
|
||||
} else {
|
||||
return <img src={name} className="w-4" />;
|
||||
return <img src={name} className="inline-block size-4" />;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { WorkflowNode, WorkflowNodeType } from "@/domain/workflow";
|
||||
import AddNode from "./AddNode";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
import { Dropdown } from "antd";
|
||||
import { Ellipsis, Trash2 } from "lucide-react";
|
||||
import { usePanel } from "./PanelProvider";
|
||||
import PanelBody from "./PanelBody";
|
||||
@ -84,21 +84,26 @@ const Node = ({ data }: NodeProps) => {
|
||||
<div className="rounded-md shadow-md w-[260px] relative">
|
||||
{data.type != WorkflowNodeType.Start && (
|
||||
<>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger className="absolute right-2 top-1">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: [
|
||||
{
|
||||
key: "delete",
|
||||
label: t(`${i18nPrefix}.delete.label`),
|
||||
icon: <Trash2 size={16} />,
|
||||
danger: true,
|
||||
onClick: () => {
|
||||
removeNode(data.id);
|
||||
},
|
||||
},
|
||||
],
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
<div className="absolute right-2 top-1 cursor-pointer">
|
||||
<Ellipsis className="text-white" size={17} />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
className="flex space-x-2 text-red-600"
|
||||
onClick={() => {
|
||||
removeNode(data.id);
|
||||
}}
|
||||
>
|
||||
<Trash2 size={16} /> <div>{t(`${i18nPrefix}.delete.label`)}</div>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
@ -1,356 +0,0 @@
|
||||
import { memo, useEffect } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Collapse, Divider, Switch, Tooltip, Typography } from "antd";
|
||||
import z from "zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { ChevronsUpDown as ChevronsUpDownIcon, Plus as PlusIcon, CircleHelp as CircleHelpIcon } from "lucide-react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import AccessEditModal from "@/components/access/AccessEditModal";
|
||||
import EmailsEdit from "@/components/certimate/EmailsEdit";
|
||||
import StringList from "@/components/certimate/StringList";
|
||||
import { accessProvidersMap } from "@/domain/access";
|
||||
import { useZustandShallowSelector } from "@/hooks";
|
||||
import { useAccessStore } from "@/stores/access";
|
||||
import { useContactStore } from "@/stores/contact";
|
||||
import { WorkflowNode, WorkflowNodeConfig } from "@/domain/workflow";
|
||||
import { useWorkflowStore } from "@/stores/workflow";
|
||||
import { usePanel } from "../PanelProvider";
|
||||
|
||||
type ApplyFormProps = {
|
||||
data: WorkflowNode;
|
||||
};
|
||||
|
||||
const ApplyForm = ({ data }: ApplyFormProps) => {
|
||||
const { updateNode } = useWorkflowStore(useZustandShallowSelector(["updateNode"]));
|
||||
|
||||
const { accesses } = useAccessStore();
|
||||
const { emails, fetchEmails } = useContactStore();
|
||||
|
||||
useEffect(() => {
|
||||
fetchEmails();
|
||||
}, []);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { hidePanel } = usePanel();
|
||||
|
||||
const formSchema = z.object({
|
||||
domain: z.string().min(1, {
|
||||
message: "common.errmsg.domain_invalid",
|
||||
}),
|
||||
email: z.string().email("common.errmsg.email_invalid").optional(),
|
||||
access: z.string().regex(/^[a-zA-Z0-9]+$/, {
|
||||
message: "domain.application.form.access.placeholder",
|
||||
}),
|
||||
keyAlgorithm: z.string().optional(),
|
||||
nameservers: z.string().optional(),
|
||||
timeout: z.number().optional(),
|
||||
disableFollowCNAME: z.boolean().optional(),
|
||||
});
|
||||
|
||||
let config: WorkflowNodeConfig = {
|
||||
domain: "",
|
||||
email: "",
|
||||
access: "",
|
||||
keyAlgorithm: "RSA2048",
|
||||
nameservers: "",
|
||||
timeout: 60,
|
||||
disableFollowCNAME: true,
|
||||
};
|
||||
if (data) config = data.config ?? config;
|
||||
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
domain: config.domain as string,
|
||||
email: config.email as string,
|
||||
access: config.access as string,
|
||||
keyAlgorithm: config.keyAlgorithm as string,
|
||||
nameservers: config.nameservers as string,
|
||||
timeout: config.timeout as number,
|
||||
disableFollowCNAME: config.disableFollowCNAME as boolean,
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = async (config: z.infer<typeof formSchema>) => {
|
||||
updateNode({ ...data, config, validated: true });
|
||||
hidePanel();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 dark:text-stone-200">
|
||||
{/* 域名 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="domain"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<>
|
||||
<StringList
|
||||
value={field.value}
|
||||
valueType="domain"
|
||||
onValueChange={(domain: string) => {
|
||||
form.setValue("domain", domain);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* 邮箱 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="email"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="flex justify-between w-full">
|
||||
<div>{t("domain.application.form.email.label") + " " + t("domain.application.form.email.tips")}</div>
|
||||
<EmailsEdit
|
||||
trigger={
|
||||
<div className="flex items-center font-normal cursor-pointer text-primary hover:underline">
|
||||
<PlusIcon size={14} />
|
||||
{t("common.button.add")}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Select
|
||||
{...field}
|
||||
value={field.value}
|
||||
onValueChange={(value) => {
|
||||
form.setValue("email", value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("domain.application.form.email.placeholder")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>{t("domain.application.form.email.list")}</SelectLabel>
|
||||
{emails.map((item) => (
|
||||
<SelectItem key={item} value={item}>
|
||||
<div>{item}</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* DNS 服务商授权 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="access"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel className="flex justify-between w-full">
|
||||
<div>{t("domain.application.form.access.label")}</div>
|
||||
<AccessEditModal
|
||||
preset="add"
|
||||
trigger={
|
||||
<div className="flex items-center font-normal cursor-pointer text-primary hover:underline">
|
||||
<PlusIcon size={14} />
|
||||
{t("common.button.add")}
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<Select
|
||||
{...field}
|
||||
value={field.value}
|
||||
onValueChange={(value) => {
|
||||
form.setValue("access", value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("domain.application.form.access.placeholder")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectLabel>{t("domain.application.form.access.list")}</SelectLabel>
|
||||
{accesses
|
||||
.filter((item) => item.usage != "deploy")
|
||||
.map((item) => (
|
||||
<SelectItem key={item.id} value={item.id}>
|
||||
<div className="flex items-center space-x-2">
|
||||
<img className="w-6" src={accessProvidersMap.get(item.configType)?.icon} />
|
||||
<div>{item.name}</div>
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
|
||||
<Collapse
|
||||
bordered={false}
|
||||
ghost={true}
|
||||
items={[
|
||||
{
|
||||
key: "advanced",
|
||||
styles: {
|
||||
header: { paddingLeft: 0, paddingRight: 0 },
|
||||
body: { paddingLeft: 0, paddingRight: 0 },
|
||||
},
|
||||
label: <Typography.Text type="secondary">{t("domain.application.form.advanced_settings.label")}</Typography.Text>,
|
||||
children: (
|
||||
<div className="flex flex-col space-y-8">
|
||||
{/* 证书算法 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="keyAlgorithm"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("domain.application.form.key_algorithm.label")}</FormLabel>
|
||||
<Select
|
||||
{...field}
|
||||
value={field.value}
|
||||
onValueChange={(value) => {
|
||||
form.setValue("keyAlgorithm", value);
|
||||
}}
|
||||
>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("domain.application.form.key_algorithm.placeholder")} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="RSA2048">RSA2048</SelectItem>
|
||||
<SelectItem value="RSA3072">RSA3072</SelectItem>
|
||||
<SelectItem value="RSA4096">RSA4096</SelectItem>
|
||||
<SelectItem value="RSA8192">RSA8192</SelectItem>
|
||||
<SelectItem value="EC256">EC256</SelectItem>
|
||||
<SelectItem value="EC384">EC384</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* DNS */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="nameservers"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<StringList
|
||||
value={field.value ?? ""}
|
||||
onValueChange={(val: string) => {
|
||||
form.setValue("nameservers", val);
|
||||
}}
|
||||
valueType="dns"
|
||||
></StringList>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* DNS 超时时间 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="timeout"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("domain.application.form.timeout.label")}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="number"
|
||||
placeholder={t("domain.application.form.timeout.placeholder")}
|
||||
{...field}
|
||||
value={field.value}
|
||||
onChange={(e) => {
|
||||
form.setValue("timeout", parseInt(e.target.value));
|
||||
}}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* 禁用 CNAME 跟随 */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="disableFollowCNAME"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>
|
||||
<div className="flex">
|
||||
<span className="mr-1">{t("domain.application.form.disable_follow_cname.label")} </span>
|
||||
<Tooltip
|
||||
title={
|
||||
<p>
|
||||
{t("domain.application.form.disable_follow_cname.tips")}
|
||||
<a
|
||||
className="text-primary"
|
||||
target="_blank"
|
||||
href="https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/#the-advantages-of-a-cname"
|
||||
>
|
||||
{t("domain.application.form.disable_follow_cname.tips_link")}
|
||||
</a>
|
||||
</p>
|
||||
}
|
||||
>
|
||||
<CircleHelpIcon size={14} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
</FormLabel>
|
||||
<FormControl>
|
||||
<div>
|
||||
<Switch
|
||||
defaultChecked={field.value}
|
||||
onChange={(value) => {
|
||||
form.setValue(field.name, value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
extra: <ChevronsUpDownIcon size={14} />,
|
||||
forceRender: true,
|
||||
showArrow: false,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button type="submit">{t("common.button.save")}</Button>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(ApplyForm);
|
@ -14,9 +14,6 @@ i18n
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
backend: {
|
||||
loadPath: "/locales/{{lng}}.json",
|
||||
},
|
||||
detection: {
|
||||
lookupLocalStorage: "certimate-ui-lang",
|
||||
},
|
||||
|
@ -143,6 +143,7 @@ const WorkflowDetail = () => {
|
||||
},
|
||||
],
|
||||
}}
|
||||
trigger={["click"]}
|
||||
>
|
||||
<Button icon={<EllipsisIcon size={14} />} />
|
||||
</Dropdown>
|
||||
|
Loading…
x
Reference in New Issue
Block a user