mirror of
https://github.com/woodchen-ink/certimate.git
synced 2025-07-18 17:31:55 +08:00
chore: remove unused code
This commit is contained in:
parent
c27818b3b0
commit
0fa6d2980b
161
ui/package-lock.json
generated
161
ui/package-lock.json
generated
@ -15,7 +15,6 @@
|
|||||||
"@radix-ui/react-dialog": "^1.1.2",
|
"@radix-ui/react-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
"@radix-ui/react-label": "^2.1.0",
|
||||||
"@radix-ui/react-popover": "^1.1.2",
|
|
||||||
"@radix-ui/react-radio-group": "^1.2.0",
|
"@radix-ui/react-radio-group": "^1.2.0",
|
||||||
"@radix-ui/react-scroll-area": "^1.1.0",
|
"@radix-ui/react-scroll-area": "^1.1.0",
|
||||||
"@radix-ui/react-select": "^2.1.1",
|
"@radix-ui/react-select": "^2.1.1",
|
||||||
@ -2166,166 +2165,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@radix-ui/react-popover": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-popover/-/react-popover-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==",
|
|
||||||
"dependencies": {
|
|
||||||
"@radix-ui/primitive": "1.1.0",
|
|
||||||
"@radix-ui/react-compose-refs": "1.1.0",
|
|
||||||
"@radix-ui/react-context": "1.1.1",
|
|
||||||
"@radix-ui/react-dismissable-layer": "1.1.1",
|
|
||||||
"@radix-ui/react-focus-guards": "1.1.1",
|
|
||||||
"@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.2",
|
|
||||||
"@radix-ui/react-presence": "1.1.1",
|
|
||||||
"@radix-ui/react-primitive": "2.0.0",
|
|
||||||
"@radix-ui/react-slot": "1.1.0",
|
|
||||||
"@radix-ui/react-use-controllable-state": "1.1.0",
|
|
||||||
"aria-hidden": "^1.1.1",
|
|
||||||
"react-remove-scroll": "2.6.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-popover/node_modules/@radix-ui/react-context": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-context/-/react-context-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/react": "*",
|
|
||||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/react": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@radix-ui/primitive": "1.1.0",
|
|
||||||
"@radix-ui/react-compose-refs": "1.1.0",
|
|
||||||
"@radix-ui/react-primitive": "2.0.0",
|
|
||||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
|
||||||
"@radix-ui/react-use-escape-keydown": "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-popover/node_modules/@radix-ui/react-focus-guards": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/react": "*",
|
|
||||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/react": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-portal/-/react-portal-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@radix-ui/react-primitive": "2.0.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-popover/node_modules/@radix-ui/react-presence": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
|
|
||||||
"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-popover/node_modules/react-remove-scroll": {
|
|
||||||
"version": "2.6.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz",
|
|
||||||
"integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"react-remove-scroll-bar": "^2.3.6",
|
|
||||||
"react-style-singleton": "^2.2.1",
|
|
||||||
"tslib": "^2.1.0",
|
|
||||||
"use-callback-ref": "^1.3.0",
|
|
||||||
"use-sidecar": "^1.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/react": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@radix-ui/react-popper": {
|
"node_modules/@radix-ui/react-popper": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"@radix-ui/react-dialog": "^1.1.2",
|
"@radix-ui/react-dialog": "^1.1.2",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
||||||
"@radix-ui/react-label": "^2.1.0",
|
"@radix-ui/react-label": "^2.1.0",
|
||||||
"@radix-ui/react-popover": "^1.1.2",
|
|
||||||
"@radix-ui/react-radio-group": "^1.2.0",
|
"@radix-ui/react-radio-group": "^1.2.0",
|
||||||
"@radix-ui/react-scroll-area": "^1.1.0",
|
"@radix-ui/react-scroll-area": "^1.1.0",
|
||||||
"@radix-ui/react-select": "^2.1.1",
|
"@radix-ui/react-select": "^2.1.1",
|
||||||
|
@ -1,197 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type AliyunAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessAliyunFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessAliyunForm = ({ data, op, onAfterReq }: AccessAliyunFormProps) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
accessKeyId: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_id.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
accessSecretId: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_secret.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: AliyunAccessConfig = {
|
|
||||||
accessKeyId: "",
|
|
||||||
accessKeySecret: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as AliyunAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "aliyun",
|
|
||||||
accessKeyId: config.accessKeyId,
|
|
||||||
accessSecretId: config.accessKeySecret,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
accessKeyId: data.accessKeyId,
|
|
||||||
accessKeySecret: data.accessSecretId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKeyId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessSecretId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key_secret.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key_secret.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessAliyunForm;
|
|
@ -1,241 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { AccessModel, accessProvidersMap, accessTypeFormSchema, type AWSAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessAwsFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessAwsForm = ({ data, op, onAfterReq }: AccessAwsFormProps) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
region: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.region.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
accessKeyId: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_id.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
secretAccessKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.secret_access_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
hostedZoneId: z
|
|
||||||
.string()
|
|
||||||
.min(0, "access.form.aws_hosted_zone_id.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: AWSAccessConfig = {
|
|
||||||
region: "cn-north-1",
|
|
||||||
accessKeyId: "",
|
|
||||||
secretAccessKey: "",
|
|
||||||
hostedZoneId: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as AWSAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "aws",
|
|
||||||
region: config.region,
|
|
||||||
accessKeyId: config.accessKeyId,
|
|
||||||
secretAccessKey: config.secretAccessKey,
|
|
||||||
hostedZoneId: config.hostedZoneId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
region: data.region,
|
|
||||||
accessKeyId: data.accessKeyId,
|
|
||||||
secretAccessKey: data.secretAccessKey,
|
|
||||||
hostedZoneId: data.hostedZoneId,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="region"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.region.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.region.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKeyId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretAccessKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="hostedZoneId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.aws_hosted_zone_id.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.aws_hosted_zone_id.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessAwsForm;
|
|
@ -1,197 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type BaiduCloudAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessBaiduCloudFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessBaiduCloudForm = ({ data, op, onAfterReq }: AccessBaiduCloudFormProps) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
accessKeyId: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_id.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
secretAccessKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.secret_access_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: BaiduCloudAccessConfig = {
|
|
||||||
accessKeyId: "",
|
|
||||||
secretAccessKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as BaiduCloudAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "baiducloud",
|
|
||||||
accessKeyId: config.accessKeyId,
|
|
||||||
secretAccessKey: config.secretAccessKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
accessKeyId: data.accessKeyId,
|
|
||||||
secretAccessKey: data.secretAccessKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKeyId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretAccessKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessBaiduCloudForm;
|
|
@ -1,194 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type BytePlusAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessByteplusFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessByteplusForm = ({ data, op, onAfterReq }: AccessByteplusFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
accessKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
secretKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.secret_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: BytePlusAccessConfig = {
|
|
||||||
accessKey: "",
|
|
||||||
secretKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as BytePlusAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "byteplus",
|
|
||||||
accessKey: config.accessKey,
|
|
||||||
secretKey: config.secretKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
accessKey: data.accessKey,
|
|
||||||
secretKey: data.secretKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessByteplusForm;
|
|
@ -1,168 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type CloudflareAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessCloudflareFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessCloudflareForm = ({ data, op, onAfterReq }: AccessCloudflareFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
dnsApiToken: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.cloud_dns_api_token.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: CloudflareAccessConfig = {
|
|
||||||
dnsApiToken: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as CloudflareAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "cloudflare",
|
|
||||||
dnsApiToken: config.dnsApiToken,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
dnsApiToken: data.dnsApiToken,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="dnsApiToken"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.cloud_dns_api_token.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.cloud_dns_api_token.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessCloudflareForm;
|
|
@ -1,188 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type DogeCloudAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessDogeCloudFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessDogeCloudForm = ({ data, op, onAfterReq }: AccessDogeCloudFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
accessKey: z.string().min(1, "access.form.access_key.placeholder").max(64),
|
|
||||||
secretKey: z.string().min(1, "access.form.secret_key.placeholder").max(64),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: DogeCloudAccessConfig = {
|
|
||||||
accessKey: "",
|
|
||||||
secretKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as DogeCloudAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "dogecloud",
|
|
||||||
accessKey: config.accessKey,
|
|
||||||
secretKey: config.secretKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
accessKey: data.accessKey,
|
|
||||||
secretKey: data.secretKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessDogeCloudForm;
|
|
@ -1,306 +0,0 @@
|
|||||||
import { useEffect, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
import { cn } from "@/components/ui/utils";
|
|
||||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
|
||||||
import { Label } from "@/components/ui/label";
|
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
|
||||||
import AccessTypeSelect from "@/components/access/AccessTypeSelect";
|
|
||||||
import AccessAliyunForm from "./AccessAliyunForm";
|
|
||||||
import AccessTencentForm from "./AccessTencentForm";
|
|
||||||
import AccessHuaweiCloudForm from "./AccessHuaweicloudForm";
|
|
||||||
import AccessBaiduCloudForm from "./AccessBaiduCloudForm";
|
|
||||||
import AccessQiniuForm from "./AccessQiniuForm";
|
|
||||||
import AccessDogeCloudForm from "./AccessDogeCloudForm";
|
|
||||||
import AccessAwsForm from "./AccessAwsForm";
|
|
||||||
import AccessCloudflareForm from "./AccessCloudflareForm";
|
|
||||||
import AccessNamesiloForm from "./AccessNamesiloForm";
|
|
||||||
import AccessGodaddyForm from "./AccessGodaddyForm";
|
|
||||||
import AccessPdnsForm from "./AccessPdnsForm";
|
|
||||||
import AccessHttpreqForm from "./AccessHttpreqForm";
|
|
||||||
import AccessLocalForm from "./AccessLocalForm";
|
|
||||||
import AccessSSHForm from "./AccessSSHForm";
|
|
||||||
import AccessWebhookForm from "./AccessWebhookForm";
|
|
||||||
import AccessKubernetesForm from "./AccessKubernetesForm";
|
|
||||||
import AccessVolcengineForm from "./AccessVolcengineForm";
|
|
||||||
import AccessByteplusForm from "./AccessByteplusForm";
|
|
||||||
import { AccessModel } from "@/domain/access";
|
|
||||||
|
|
||||||
type AccessEditProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
className?: string;
|
|
||||||
trigger: React.ReactNode;
|
|
||||||
data?: AccessModel;
|
|
||||||
outConfigType?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessEditDialog = ({ trigger, op, data, className, outConfigType }: AccessEditProps) => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
|
|
||||||
const [configType, setConfigType] = useState(data?.configType || "");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (outConfigType) {
|
|
||||||
setConfigType(outConfigType);
|
|
||||||
}
|
|
||||||
}, [outConfigType]);
|
|
||||||
|
|
||||||
let childComponent = <> </>;
|
|
||||||
switch (configType) {
|
|
||||||
case "aliyun":
|
|
||||||
childComponent = (
|
|
||||||
<AccessAliyunForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "tencentcloud":
|
|
||||||
childComponent = (
|
|
||||||
<AccessTencentForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "huaweicloud":
|
|
||||||
childComponent = (
|
|
||||||
<AccessHuaweiCloudForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "baiducloud":
|
|
||||||
childComponent = (
|
|
||||||
<AccessBaiduCloudForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "qiniu":
|
|
||||||
childComponent = (
|
|
||||||
<AccessQiniuForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "dogecloud":
|
|
||||||
childComponent = (
|
|
||||||
<AccessDogeCloudForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "aws":
|
|
||||||
childComponent = (
|
|
||||||
<AccessAwsForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "cloudflare":
|
|
||||||
childComponent = (
|
|
||||||
<AccessCloudflareForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "namesilo":
|
|
||||||
childComponent = (
|
|
||||||
<AccessNamesiloForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "godaddy":
|
|
||||||
childComponent = (
|
|
||||||
<AccessGodaddyForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "powerdns":
|
|
||||||
childComponent = (
|
|
||||||
<AccessPdnsForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "acmehttpreq":
|
|
||||||
childComponent = (
|
|
||||||
<AccessHttpreqForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "local":
|
|
||||||
childComponent = (
|
|
||||||
<AccessLocalForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "ssh":
|
|
||||||
childComponent = (
|
|
||||||
<AccessSSHForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "webhook":
|
|
||||||
childComponent = (
|
|
||||||
<AccessWebhookForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "k8s":
|
|
||||||
childComponent = (
|
|
||||||
<AccessKubernetesForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "volcengine":
|
|
||||||
childComponent = (
|
|
||||||
<AccessVolcengineForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case "byteplus":
|
|
||||||
childComponent = (
|
|
||||||
<AccessByteplusForm
|
|
||||||
data={data}
|
|
||||||
op={op}
|
|
||||||
onAfterReq={() => {
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Dialog
|
|
||||||
onOpenChange={(openState) => {
|
|
||||||
if (openState) {
|
|
||||||
document.body.style.pointerEvents = "auto";
|
|
||||||
}
|
|
||||||
setOpen(openState);
|
|
||||||
}}
|
|
||||||
open={open}
|
|
||||||
modal={false}
|
|
||||||
>
|
|
||||||
<DialogTrigger asChild className={cn(className)}>
|
|
||||||
{trigger}
|
|
||||||
</DialogTrigger>
|
|
||||||
<DialogContent
|
|
||||||
className="sm:max-w-[600px] w-full dark:text-stone-200"
|
|
||||||
onInteractOutside={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
["add"]: t("access.action.add"),
|
|
||||||
["edit"]: t("access.action.edit"),
|
|
||||||
["copy"]: t("access.action.copy"),
|
|
||||||
}[op]
|
|
||||||
}
|
|
||||||
</DialogTitle>
|
|
||||||
</DialogHeader>
|
|
||||||
<ScrollArea className="max-h-[80vh]">
|
|
||||||
<div className="container py-3">
|
|
||||||
<div>
|
|
||||||
<Label>{t("access.form.type.label")}</Label>
|
|
||||||
<AccessTypeSelect
|
|
||||||
className="w-full mt-3"
|
|
||||||
placeholder={t("access.form.type.placeholder")}
|
|
||||||
value={configType}
|
|
||||||
showSearch={true}
|
|
||||||
onChange={(val) => {
|
|
||||||
setConfigType(val);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-8">{childComponent}</div>
|
|
||||||
</div>
|
|
||||||
</ScrollArea>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessEditDialog;
|
|
@ -1,190 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type GoDaddyAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessGodaddyFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessGodaddyForm = ({ data, op, onAfterReq }: AccessGodaddyFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
apiKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.godaddy_api_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
apiSecret: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.godaddy_api_secret.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: GoDaddyAccessConfig = {
|
|
||||||
apiKey: "",
|
|
||||||
apiSecret: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as GoDaddyAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "godaddy",
|
|
||||||
apiKey: config.apiKey,
|
|
||||||
apiSecret: config.apiSecret,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
apiKey: data.apiKey,
|
|
||||||
apiSecret: data.apiSecret,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="apiKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.godaddy_api_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.godaddy_api_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="apiSecret"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.godaddy_api_secret.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.godaddy_api_secret.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessGodaddyForm;
|
|
@ -1,233 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type ACMEHttpReqAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessHttpreqFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessHttpreqForm = ({ data, op, onAfterReq }: AccessHttpreqFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
endpoint: z.string().url("common.errmsg.url_invalid"),
|
|
||||||
mode: z.enum(["RAW", ""]),
|
|
||||||
username: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_secret.placeholder")
|
|
||||||
.max(128, t("common.errmsg.string_max", { max: 128 })),
|
|
||||||
password: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_secret.placeholder")
|
|
||||||
.max(128, t("common.errmsg.string_max", { max: 128 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: ACMEHttpReqAccessConfig = {
|
|
||||||
endpoint: "",
|
|
||||||
mode: "",
|
|
||||||
username: "",
|
|
||||||
password: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as ACMEHttpReqAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "acmehttpreq",
|
|
||||||
endpoint: config.endpoint,
|
|
||||||
mode: config.mode === "RAW" ? "RAW" : "",
|
|
||||||
username: config.username,
|
|
||||||
password: config.password,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
endpoint: data.endpoint,
|
|
||||||
mode: data.mode,
|
|
||||||
username: data.username,
|
|
||||||
password: data.password,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="endpoint"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.httpreq_endpoint.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.httpreq_endpoint.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="mode"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.httpreq_mode.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.httpreq_mode.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="username"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.username.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.username.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="password"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.password.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.password.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessHttpreqForm;
|
|
@ -1,216 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type HuaweiCloudAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessHuaweiCloudFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessHuaweiCloudForm = ({ data, op, onAfterReq }: AccessHuaweiCloudFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
region: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.region.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
accessKeyId: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_id.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
secretAccessKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.secret_access_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: HuaweiCloudAccessConfig = {
|
|
||||||
region: "cn-north-1",
|
|
||||||
accessKeyId: "",
|
|
||||||
secretAccessKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as HuaweiCloudAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "huaweicloud",
|
|
||||||
region: config.region,
|
|
||||||
accessKeyId: config.accessKeyId,
|
|
||||||
secretAccessKey: config.secretAccessKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
region: data.region,
|
|
||||||
accessKeyId: data.accessKeyId,
|
|
||||||
secretAccessKey: data.secretAccessKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="region"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.region.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.region.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKeyId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretAccessKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessHuaweiCloudForm;
|
|
@ -1,193 +0,0 @@
|
|||||||
import { useRef, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { readFileContent } from "@/utils/file";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type KubernetesAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessKubernetesFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessKubernetesForm = ({ data, op, onAfterReq }: AccessKubernetesFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
|
|
||||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
|
||||||
const [fileName, setFileName] = useState("");
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
kubeConfig: z
|
|
||||||
.string()
|
|
||||||
.min(0, "access.form.k8s_kubeconfig.placeholder")
|
|
||||||
.max(20480, t("common.errmsg.string_max", { max: 20480 })),
|
|
||||||
kubeConfigFile: z.any().optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: KubernetesAccessConfig & { kubeConfigFile?: string } = {
|
|
||||||
kubeConfig: "",
|
|
||||||
kubeConfigFile: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as typeof config;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "k8s",
|
|
||||||
kubeConfig: config.kubeConfig,
|
|
||||||
kubeConfigFile: config.kubeConfigFile,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
kubeConfig: data.kubeConfig,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
} else {
|
|
||||||
createAccess(req);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
const file = event.target.files?.[0];
|
|
||||||
if (!file) return;
|
|
||||||
const savedFile = file;
|
|
||||||
setFileName(savedFile.name);
|
|
||||||
const content = await readFileContent(savedFile);
|
|
||||||
form.setValue("kubeConfig", content);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSelectFileClick = () => {
|
|
||||||
fileInputRef.current?.click();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="kubeConfig"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem hidden>
|
|
||||||
<FormLabel>{t("access.form.k8s_kubeconfig.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.k8s_kubeconfig.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="kubeConfigFile"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.k8s_kubeconfig.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<div>
|
|
||||||
<Button type={"button"} variant={"secondary"} size={"sm"} className="w-48" onClick={handleSelectFileClick}>
|
|
||||||
{fileName ? fileName : t("access.form.k8s_kubeconfig_file.placeholder")}
|
|
||||||
</Button>
|
|
||||||
<Input
|
|
||||||
placeholder={t("access.form.k8s_kubeconfig.placeholder")}
|
|
||||||
{...field}
|
|
||||||
ref={fileInputRef}
|
|
||||||
className="hidden"
|
|
||||||
hidden
|
|
||||||
type="file"
|
|
||||||
onChange={handleFileChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessKubernetesForm;
|
|
@ -1,147 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessLocalFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessLocalForm = ({ data, op, onAfterReq }: AccessLocalFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
});
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "local",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
|
|
||||||
config: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
} else {
|
|
||||||
createAccess(req);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessLocalForm;
|
|
@ -1,168 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type NameSiloAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessNameSiloFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessNameSiloForm = ({ data, op, onAfterReq }: AccessNameSiloFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
apiKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.namesilo_api_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: NameSiloAccessConfig = {
|
|
||||||
apiKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as NameSiloAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "namesilo",
|
|
||||||
apiKey: config.apiKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
apiKey: data.apiKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="apiKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.namesilo_api_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.namesilo_api_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessNameSiloForm;
|
|
@ -1,192 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type PowerDNSAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessPdnsFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessPdnsForm = ({ data, op, onAfterReq }: AccessPdnsFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
apiUrl: z.string().url("common.errmsg.url_invalid"),
|
|
||||||
apiKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_secret.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: PowerDNSAccessConfig = {
|
|
||||||
apiUrl: "",
|
|
||||||
apiKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as PowerDNSAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "powerdns",
|
|
||||||
apiUrl: config.apiUrl,
|
|
||||||
apiKey: config.apiKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
apiUrl: data.apiUrl,
|
|
||||||
apiKey: data.apiKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="apiUrl"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.pdns_api_url.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.pdns_api_url.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="apiKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.pdns_api_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.pdns_api_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessPdnsForm;
|
|
@ -1,188 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type QiniuAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessQiniuFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessQiniuForm = ({ data, op, onAfterReq }: AccessQiniuFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
accessKey: z.string().min(1, "access.form.access_key.placeholder").max(64),
|
|
||||||
secretKey: z.string().min(1, "access.form.secret_key.placeholder").max(64),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: QiniuAccessConfig = {
|
|
||||||
accessKey: "",
|
|
||||||
secretKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as QiniuAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "qiniu",
|
|
||||||
accessKey: config.accessKey,
|
|
||||||
secretKey: config.secretKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
accessKey: data.accessKey,
|
|
||||||
secretKey: data.secretKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessQiniuForm;
|
|
@ -1,348 +0,0 @@
|
|||||||
import { useRef, useState } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { readFileContent } from "@/utils/file";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type SSHAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessSSHFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessSSHForm = ({ data, op, onAfterReq }: AccessSSHFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
|
|
||||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
|
||||||
|
|
||||||
const [fileName, setFileName] = useState("");
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const domainReg = /^(?:\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/;
|
|
||||||
const ipReg =
|
|
||||||
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
||||||
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
host: z.string().refine(
|
|
||||||
(str) => {
|
|
||||||
return ipReg.test(str) || domainReg.test(str);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: "common.errmsg.host_invalid",
|
|
||||||
}
|
|
||||||
),
|
|
||||||
group: z.string().optional(),
|
|
||||||
port: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.ssh_port.placeholder")
|
|
||||||
.max(5, t("common.errmsg.string_max", { max: 5 })),
|
|
||||||
username: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.ssh_username.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
password: z
|
|
||||||
.string()
|
|
||||||
.min(0, "access.form.ssh_password.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
key: z
|
|
||||||
.string()
|
|
||||||
.min(0, "access.form.ssh_key.placeholder")
|
|
||||||
.max(20480, t("common.errmsg.string_max", { max: 20480 })),
|
|
||||||
keyFile: z.any().optional(),
|
|
||||||
keyPassphrase: z
|
|
||||||
.string()
|
|
||||||
.min(0, "access.form.ssh_key_passphrase.placeholder")
|
|
||||||
.max(2048, t("common.errmsg.string_max", { max: 2048 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: SSHAccessConfig = {
|
|
||||||
host: "127.0.0.1",
|
|
||||||
port: "22",
|
|
||||||
username: "root",
|
|
||||||
password: "",
|
|
||||||
key: "",
|
|
||||||
keyFile: "",
|
|
||||||
keyPassphrase: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as SSHAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "ssh",
|
|
||||||
group: data?.group,
|
|
||||||
host: config.host,
|
|
||||||
port: config.port,
|
|
||||||
username: config.username,
|
|
||||||
password: config.password,
|
|
||||||
key: config.key,
|
|
||||||
keyFile: config.keyFile,
|
|
||||||
keyPassphrase: config.keyPassphrase,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
let group = data.group;
|
|
||||||
if (group == "emptyId") group = "";
|
|
||||||
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
group: group,
|
|
||||||
config: {
|
|
||||||
host: data.host,
|
|
||||||
port: data.port,
|
|
||||||
username: data.username,
|
|
||||||
password: data.password,
|
|
||||||
key: data.key,
|
|
||||||
keyPassphrase: data.keyPassphrase,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
} else {
|
|
||||||
createAccess(req);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
const file = event.target.files?.[0];
|
|
||||||
if (!file) return;
|
|
||||||
const savedFile = file;
|
|
||||||
setFileName(savedFile.name);
|
|
||||||
const content = await readFileContent(savedFile);
|
|
||||||
form.setValue("key", content);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSelectFileClick = () => {
|
|
||||||
fileInputRef.current?.click();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<div className="flex space-x-2">
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="host"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="grow">
|
|
||||||
<FormLabel>{t("access.form.ssh_host.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.ssh_host.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="port"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.ssh_port.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.ssh_port.placeholder")} {...field} type="number" />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="username"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.ssh_username.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.ssh_username.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="password"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.ssh_password.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.ssh_password.placeholder")} {...field} type="password" />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="key"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem hidden>
|
|
||||||
<FormLabel>{t("access.form.ssh_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.ssh_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="keyFile"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.ssh_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<div>
|
|
||||||
<Button type={"button"} variant={"secondary"} size={"sm"} className="w-48" onClick={handleSelectFileClick}>
|
|
||||||
{fileName ? fileName : t("access.form.ssh_key_file.placeholder")}
|
|
||||||
</Button>
|
|
||||||
<Input
|
|
||||||
placeholder={t("access.form.ssh_key.placeholder")}
|
|
||||||
{...field}
|
|
||||||
ref={fileInputRef}
|
|
||||||
className="hidden"
|
|
||||||
hidden
|
|
||||||
type="file"
|
|
||||||
onChange={handleFileChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="keyPassphrase"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.ssh_key_passphrase.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.ssh_key_passphrase.placeholder")} {...field} type="password" />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessSSHForm;
|
|
@ -1,190 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type TencentCloudAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessTencentFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessTencentForm = ({ data, op, onAfterReq }: AccessTencentFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
secretId: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.secret_id.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
secretKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.secret_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: TencentCloudAccessConfig = {
|
|
||||||
secretId: "",
|
|
||||||
secretKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as TencentCloudAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "tencentcloud",
|
|
||||||
secretId: config.secretId,
|
|
||||||
secretKey: config.secretKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
secretId: data.secretId,
|
|
||||||
secretKey: data.secretKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_id.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_id.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessTencentForm;
|
|
@ -1,194 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { accessProvidersMap, accessTypeFormSchema, type AccessModel, type VolcEngineAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessVolcengineFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessVolcengineForm = ({ data, op, onAfterReq }: AccessVolcengineFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
accessKeyId: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.access_key_id.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
secretAccessKey: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.secret_access_key.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: VolcEngineAccessConfig = {
|
|
||||||
accessKeyId: "",
|
|
||||||
secretAccessKey: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as VolcEngineAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "volcengine",
|
|
||||||
accessKeyId: config.accessKeyId,
|
|
||||||
secretAccessKey: config.secretAccessKey,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
accessKeyId: data.accessKeyId,
|
|
||||||
secretAccessKey: data.secretAccessKey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="accessKeyId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.access_key_id.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.access_key_id.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="secretAccessKey"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.secret_access_key.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.secret_access_key.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessVolcengineForm;
|
|
@ -1,165 +0,0 @@
|
|||||||
import { useForm } from "react-hook-form";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import z from "zod";
|
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
|
||||||
import { ClientResponseError } from "pocketbase";
|
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { PbErrorData } from "@/domain/base";
|
|
||||||
import { AccessModel, accessProvidersMap, accessTypeFormSchema, WebhookAccessConfig } from "@/domain/access";
|
|
||||||
import { save } from "@/repository/access";
|
|
||||||
import { useAccessStore } from "@/stores/access";
|
|
||||||
|
|
||||||
type AccessWebhookFormProps = {
|
|
||||||
op: "add" | "edit" | "copy";
|
|
||||||
data?: AccessModel;
|
|
||||||
onAfterReq: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessWebhookForm = ({ data, op, onAfterReq }: AccessWebhookFormProps) => {
|
|
||||||
const { createAccess, updateAccess } = useAccessStore();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const formSchema = z.object({
|
|
||||||
id: z.string().optional(),
|
|
||||||
name: z
|
|
||||||
.string()
|
|
||||||
.min(1, "access.form.name.placeholder")
|
|
||||||
.max(64, t("common.errmsg.string_max", { max: 64 })),
|
|
||||||
configType: accessTypeFormSchema,
|
|
||||||
url: z.string().url("common.errmsg.url_invalid"),
|
|
||||||
});
|
|
||||||
|
|
||||||
let config: WebhookAccessConfig = {
|
|
||||||
url: "",
|
|
||||||
};
|
|
||||||
if (data) config = data.config as WebhookAccessConfig;
|
|
||||||
|
|
||||||
const form = useForm<z.infer<typeof formSchema>>({
|
|
||||||
resolver: zodResolver(formSchema),
|
|
||||||
defaultValues: {
|
|
||||||
id: data?.id,
|
|
||||||
name: data?.name || "",
|
|
||||||
configType: "webhook",
|
|
||||||
url: config.url,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onSubmit = async (data: z.infer<typeof formSchema>) => {
|
|
||||||
const req: AccessModel = {
|
|
||||||
id: data.id as string,
|
|
||||||
name: data.name,
|
|
||||||
configType: data.configType,
|
|
||||||
usage: accessProvidersMap.get(data.configType)!.usage,
|
|
||||||
config: {
|
|
||||||
url: data.url,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
req.id = op == "copy" ? "" : req.id;
|
|
||||||
const rs = await save(req);
|
|
||||||
|
|
||||||
onAfterReq();
|
|
||||||
|
|
||||||
req.id = rs.id;
|
|
||||||
req.created = rs.created;
|
|
||||||
req.updated = rs.updated;
|
|
||||||
if (data.id && op == "edit") {
|
|
||||||
updateAccess(req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createAccess(req);
|
|
||||||
} catch (e) {
|
|
||||||
const err = e as ClientResponseError;
|
|
||||||
|
|
||||||
Object.entries(err.response.data as PbErrorData).forEach(([key, value]) => {
|
|
||||||
form.setError(key as keyof z.infer<typeof formSchema>, {
|
|
||||||
type: "manual",
|
|
||||||
message: value.message,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Form {...form}>
|
|
||||||
<form
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
form.handleSubmit(onSubmit)(e);
|
|
||||||
}}
|
|
||||||
className="space-y-8"
|
|
||||||
>
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="name"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.name.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.name.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="id"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="configType"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="hidden">
|
|
||||||
<FormLabel>{t("access.form.config.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="url"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>{t("access.form.webhook_url.label")}</FormLabel>
|
|
||||||
<FormControl>
|
|
||||||
<Input placeholder={t("access.form.webhook_url.placeholder")} {...field} />
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div className="flex justify-end">
|
|
||||||
<Button type="submit">{t("common.button.save")}</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AccessWebhookForm;
|
|
@ -1,28 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
||||||
|
|
||||||
import { cn } from "./utils";
|
|
||||||
|
|
||||||
const Popover = PopoverPrimitive.Root;
|
|
||||||
|
|
||||||
const PopoverTrigger = PopoverPrimitive.Trigger;
|
|
||||||
|
|
||||||
const PopoverContent = React.forwardRef<React.ElementRef<typeof PopoverPrimitive.Content>, React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>>(
|
|
||||||
({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
|
||||||
<PopoverPrimitive.Portal>
|
|
||||||
<PopoverPrimitive.Content
|
|
||||||
ref={ref}
|
|
||||||
align={align}
|
|
||||||
sideOffset={sideOffset}
|
|
||||||
className={cn(
|
|
||||||
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
</PopoverPrimitive.Portal>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
||||||
|
|
||||||
export { Popover, PopoverTrigger, PopoverContent };
|
|
@ -13,7 +13,11 @@ type AccessSelectProps = {
|
|||||||
const AccessSelect = ({ value, onValueChange, providerType }: AccessSelectProps) => {
|
const AccessSelect = ({ value, onValueChange, providerType }: AccessSelectProps) => {
|
||||||
const [localValue, setLocalValue] = React.useState<string>("");
|
const [localValue, setLocalValue] = React.useState<string>("");
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { accesses } = useAccessStore();
|
const { accesses, fetchAccesses } = useAccessStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchAccesses();
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLocalValue(value);
|
setLocalValue(value);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { z } from "zod";
|
|
||||||
import { type BaseModel } from "pocketbase";
|
import { type BaseModel } from "pocketbase";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -44,7 +43,7 @@ export const ACCESS_PROVIDER_TYPES = Object.freeze({
|
|||||||
WEBHOOK: ACCESS_PROVIDER_TYPE_WEBHOOK,
|
WEBHOOK: ACCESS_PROVIDER_TYPE_WEBHOOK,
|
||||||
} as const);
|
} as const);
|
||||||
|
|
||||||
export interface AccessModel extends Omit<BaseModel, "created" | "updated"> {
|
export interface AccessModel extends BaseModel {
|
||||||
name: string;
|
name: string;
|
||||||
configType: string;
|
configType: string;
|
||||||
usage: AccessUsages;
|
usage: AccessUsages;
|
||||||
@ -202,27 +201,3 @@ export const accessProvidersMap: Map<AccessProvider["type"], AccessProvider> = n
|
|||||||
[ACCESS_PROVIDER_TYPE_ACMEHTTPREQ, "common.provider.acmehttpreq", "/imgs/providers/acmehttpreq.svg", "apply"],
|
[ACCESS_PROVIDER_TYPE_ACMEHTTPREQ, "common.provider.acmehttpreq", "/imgs/providers/acmehttpreq.svg", "apply"],
|
||||||
].map(([type, name, icon, usage]) => [type, { type, name, icon, usage: usage as AccessUsages }])
|
].map(([type, name, icon, usage]) => [type, { type, name, icon, usage: usage as AccessUsages }])
|
||||||
);
|
);
|
||||||
|
|
||||||
export const accessTypeFormSchema = z.union(
|
|
||||||
[
|
|
||||||
z.literal("aliyun"),
|
|
||||||
z.literal("tencentcloud"),
|
|
||||||
z.literal("huaweicloud"),
|
|
||||||
z.literal("baiducloud"),
|
|
||||||
z.literal("qiniu"),
|
|
||||||
z.literal("dogecloud"),
|
|
||||||
z.literal("aws"),
|
|
||||||
z.literal("cloudflare"),
|
|
||||||
z.literal("namesilo"),
|
|
||||||
z.literal("godaddy"),
|
|
||||||
z.literal("powerdns"),
|
|
||||||
z.literal("acmehttpreq"),
|
|
||||||
z.literal("local"),
|
|
||||||
z.literal("ssh"),
|
|
||||||
z.literal("webhook"),
|
|
||||||
z.literal("k8s"),
|
|
||||||
z.literal("volcengine"),
|
|
||||||
z.literal("byteplus"),
|
|
||||||
],
|
|
||||||
{ message: "access.form.type.placeholder" }
|
|
||||||
);
|
|
||||||
|
@ -135,33 +135,5 @@
|
|||||||
"access.form.ssh_key.tooltip": "Required when using key to connect to SSH.",
|
"access.form.ssh_key.tooltip": "Required when using key to connect to SSH.",
|
||||||
"access.form.ssh_key_passphrase.label": "SSH Key Passphrase",
|
"access.form.ssh_key_passphrase.label": "SSH Key Passphrase",
|
||||||
"access.form.ssh_key_passphrase.placeholder": "Please enter SSH Key passphrase",
|
"access.form.ssh_key_passphrase.placeholder": "Please enter SSH Key passphrase",
|
||||||
"access.form.ssh_key_passphrase.tooltip": "Optional when using key to connect to SSH.",
|
"access.form.ssh_key_passphrase.tooltip": "Optional when using key to connect to SSH."
|
||||||
"access.form.region.label": "Region",
|
|
||||||
"access.form.region.placeholder": "Please enter Region",
|
|
||||||
"access.form.access_key_id.label": "AccessKeyId",
|
|
||||||
"access.form.access_key_id.placeholder": "Please enter AccessKeyId",
|
|
||||||
"access.form.access_key_secret.label": "AccessKeySecret",
|
|
||||||
"access.form.access_key_secret.placeholder": "Please enter AccessKeySecret",
|
|
||||||
"access.form.access_key.label": "AccessKey",
|
|
||||||
"access.form.access_key.placeholder": "Please enter AccessKey",
|
|
||||||
"access.form.secret_id.label": "SecretId",
|
|
||||||
"access.form.secret_id.placeholder": "Please enter SecretId",
|
|
||||||
"access.form.secret_key.label": "SecretKey",
|
|
||||||
"access.form.secret_key.placeholder": "Please enter SecretKey",
|
|
||||||
"access.form.secret_access_key.label": "SecretAccessKey",
|
|
||||||
"access.form.secret_access_key.placeholder": "Please enter SecretAccessKey",
|
|
||||||
"access.form.cloud_dns_api_token.label": "CLOUD_DNS_API_TOKEN",
|
|
||||||
"access.form.cloud_dns_api_token.placeholder": "Please enter CLOUD_DNS_API_TOKEN",
|
|
||||||
"access.form.pdns_api_url.label": "PDNS_API_URL",
|
|
||||||
"access.form.pdns_api_url.placeholder": "Please enter PDNS_API_URL",
|
|
||||||
"access.form.pdns_api_key.label": "PDNS_API_KEY",
|
|
||||||
"access.form.pdns_api_key.placeholder": "Please enter PDNS_API_KEY",
|
|
||||||
"access.form.httpreq_endpoint.label": "HTTPREQ_ENDPOINT",
|
|
||||||
"access.form.httpreq_endpoint.placeholder": "Please enter HTTPREQ_ENDPOINT",
|
|
||||||
"access.form.httpreq_mode.label": "HTTPREQ_MODE",
|
|
||||||
"access.form.httpreq_mode.placeholder": "Please enter HTTPREQ_MODE(RAW or '')",
|
|
||||||
"access.form.username.label": "Username",
|
|
||||||
"access.form.username.placeholder": "Please enter username",
|
|
||||||
"access.form.password.label": "Password",
|
|
||||||
"access.form.password.placeholder": "Please enter password"
|
|
||||||
}
|
}
|
||||||
|
@ -135,33 +135,5 @@
|
|||||||
"access.form.ssh_key.tooltip": "使用 SSH 密钥连接到 SSH 时必填。",
|
"access.form.ssh_key.tooltip": "使用 SSH 密钥连接到 SSH 时必填。",
|
||||||
"access.form.ssh_key_passphrase.label": "SSH 密钥口令",
|
"access.form.ssh_key_passphrase.label": "SSH 密钥口令",
|
||||||
"access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令",
|
"access.form.ssh_key_passphrase.placeholder": "请输入 SSH 密钥口令",
|
||||||
"access.form.ssh_key_passphrase.tooltip": "使用 SSH 密钥连接到 SSH 时选填。",
|
"access.form.ssh_key_passphrase.tooltip": "使用 SSH 密钥连接到 SSH 时选填。"
|
||||||
"access.form.region.label": "Region",
|
|
||||||
"access.form.region.placeholder": "请输入区域",
|
|
||||||
"access.form.access_key_id.label": "AccessKeyId",
|
|
||||||
"access.form.access_key_id.placeholder": "请输入 AccessKeyId",
|
|
||||||
"access.form.access_key_secret.label": "AccessKeySecret",
|
|
||||||
"access.form.access_key_secret.placeholder": "请输入 AccessKeySecret",
|
|
||||||
"access.form.access_key.label": "AccessKey",
|
|
||||||
"access.form.access_key.placeholder": "请输入 AccessKey",
|
|
||||||
"access.form.secret_id.label": "SecretId",
|
|
||||||
"access.form.secret_id.placeholder": "请输入 SecretId",
|
|
||||||
"access.form.secret_key.label": "SecretKey",
|
|
||||||
"access.form.secret_key.placeholder": "请输入 SecretKey",
|
|
||||||
"access.form.secret_access_key.label": "SecretAccessKey",
|
|
||||||
"access.form.secret_access_key.placeholder": "请输入 SecretAccessKey",
|
|
||||||
"access.form.cloud_dns_api_token.label": "CLOUD_DNS_API_TOKEN",
|
|
||||||
"access.form.cloud_dns_api_token.placeholder": "请输入 CLOUD_DNS_API_TOKEN",
|
|
||||||
"access.form.pdns_api_url.label": "PDNS_API_URL",
|
|
||||||
"access.form.pdns_api_url.placeholder": "请输入 PDNS_API_URL",
|
|
||||||
"access.form.pdns_api_key.label": "PDNS_API_KEY",
|
|
||||||
"access.form.pdns_api_key.placeholder": "请输入 PDNS_API_KEY",
|
|
||||||
"access.form.httpreq_endpoint.label": "HTTP 请求端点",
|
|
||||||
"access.form.httpreq_endpoint.placeholder": "请输入 请求端点",
|
|
||||||
"access.form.httpreq_mode.label": "模式",
|
|
||||||
"access.form.httpreq_mode.placeholder": "请输入模式( RAW or '')",
|
|
||||||
"access.form.username.label": "用户名",
|
|
||||||
"access.form.username.placeholder": "请输入用户名",
|
|
||||||
"access.form.password.label": "密码",
|
|
||||||
"access.form.password.placeholder": "请输入密码"
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ export const list = async () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const save = async (record: Partial<AccessModel>) => {
|
export const save = async (record: AccessModel | Omit<AccessModel, "id" | "created" | "updated" | "deleted">) => {
|
||||||
if (record.id) {
|
if (record.id) {
|
||||||
return await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record);
|
return await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record);
|
||||||
}
|
}
|
||||||
@ -20,7 +20,7 @@ export const save = async (record: Partial<AccessModel>) => {
|
|||||||
return await getPocketBase().collection(COLLECTION_NAME).create<AccessModel>(record);
|
return await getPocketBase().collection(COLLECTION_NAME).create<AccessModel>(record);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const remove = async (record: Partial<AccessModel>) => {
|
export const remove = async (record: AccessModel) => {
|
||||||
record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") };
|
record = { ...record, deleted: dayjs.utc().format("YYYY-MM-DD HH:mm:ss") };
|
||||||
await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id, record);
|
await getPocketBase().collection(COLLECTION_NAME).update<AccessModel>(record.id!, record);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user