mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-09 05:59:50 +00:00
feat(ui): new AccessSelect component using antd
This commit is contained in:
parent
c40de5d3b2
commit
2712f9a3f4
@ -66,7 +66,8 @@ const AccessEditFormSSHConfig = ({ form, disabled, loading, model, onModelChange
|
|||||||
.string()
|
.string()
|
||||||
.min(0, "access.form.ssh_key_passphrase.placeholder")
|
.min(0, "access.form.ssh_key_passphrase.placeholder")
|
||||||
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
.max(20480, t("common.errmsg.string_max", { max: 20480 }))
|
||||||
.nullish(),
|
.nullish()
|
||||||
|
.refine((v) => !v || form.getFieldValue("key"), { message: t("access.form.ssh_key.placeholder") }),
|
||||||
});
|
});
|
||||||
const formRule = createSchemaFieldRule(formSchema);
|
const formRule = createSchemaFieldRule(formSchema);
|
||||||
|
|
||||||
|
75
ui/src/components/access/AccessSelect.tsx
Normal file
75
ui/src/components/access/AccessSelect.tsx
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { Avatar, Select, Space, Typography, type SelectProps } from "antd";
|
||||||
|
|
||||||
|
import { accessProvidersMap, type AccessModel } from "@/domain/access";
|
||||||
|
import { useAccessStore } from "@/stores/access";
|
||||||
|
|
||||||
|
export type AccessTypeSelectProps = Omit<
|
||||||
|
SelectProps,
|
||||||
|
"filterOption" | "filterSort" | "labelRender" | "options" | "optionFilterProp" | "optionLabelProp" | "optionRender"
|
||||||
|
> & {
|
||||||
|
filter?: (record: AccessModel) => boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const AccessSelect = ({ filter, ...props }: AccessTypeSelectProps) => {
|
||||||
|
const { accesses, fetchAccesses } = useAccessStore();
|
||||||
|
useEffect(() => {
|
||||||
|
fetchAccesses();
|
||||||
|
}, [fetchAccesses]);
|
||||||
|
|
||||||
|
const [options, setOptions] = useState<Array<{ key: string; value: string; label: string; data: AccessModel }>>([]);
|
||||||
|
useEffect(() => {
|
||||||
|
const items = filter != null ? accesses.filter(filter) : accesses;
|
||||||
|
setOptions(
|
||||||
|
items.map((item) => ({
|
||||||
|
key: item.id,
|
||||||
|
value: item.id,
|
||||||
|
label: item.name,
|
||||||
|
data: item,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
}, [accesses, filter]);
|
||||||
|
|
||||||
|
const renderOption = (key: string) => {
|
||||||
|
const access = accesses.find((e) => e.id === key);
|
||||||
|
if (!access) {
|
||||||
|
return (
|
||||||
|
<Space className="flex-grow max-w-full truncate" size={4}>
|
||||||
|
<Avatar size="small" />
|
||||||
|
<Typography.Text className="leading-loose" ellipsis>
|
||||||
|
{key}
|
||||||
|
</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = accessProvidersMap.get(access.configType);
|
||||||
|
return (
|
||||||
|
<Space className="flex-grow max-w-full truncate" size={4}>
|
||||||
|
<Avatar src={provider?.icon} size="small" />
|
||||||
|
<Typography.Text className="leading-loose" ellipsis>
|
||||||
|
{access.name}
|
||||||
|
</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
{...props}
|
||||||
|
labelRender={({ label, value }) => {
|
||||||
|
if (label) {
|
||||||
|
return renderOption(value as string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Typography.Text type="secondary">{props.placeholder}</Typography.Text>;
|
||||||
|
}}
|
||||||
|
options={options}
|
||||||
|
optionFilterProp="label"
|
||||||
|
optionLabelProp={undefined}
|
||||||
|
optionRender={(option) => renderOption(option.data.value)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AccessSelect;
|
@ -4,7 +4,10 @@ import { Avatar, Select, Space, Tag, Typography, type SelectProps } from "antd";
|
|||||||
|
|
||||||
import { accessProvidersMap } from "@/domain/access";
|
import { accessProvidersMap } from "@/domain/access";
|
||||||
|
|
||||||
export type AccessTypeSelectProps = Omit<SelectProps, "labelRender" | "options" | "optionFilterProp" | "optionLabelProp" | "optionRender">;
|
export type AccessTypeSelectProps = Omit<
|
||||||
|
SelectProps,
|
||||||
|
"filterOption" | "filterSort" | "labelRender" | "options" | "optionFilterProp" | "optionLabelProp" | "optionRender"
|
||||||
|
>;
|
||||||
|
|
||||||
const AccessTypeSelect = memo((props: AccessTypeSelectProps) => {
|
const AccessTypeSelect = memo((props: AccessTypeSelectProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"access.form.name.placeholder": "请输入授权名称",
|
"access.form.name.placeholder": "请输入授权名称",
|
||||||
"access.form.type.label": "提供商",
|
"access.form.type.label": "提供商",
|
||||||
"access.form.type.placeholder": "请选择提供商",
|
"access.form.type.placeholder": "请选择提供商",
|
||||||
"access.form.type.tooltip": "提供商分为两种类型:<br>【DNS 提供商】您的域名托管方,用于管理您的域名解析记录。<br>【主机提供商】您的服务器或云服务的托管方,用于部署申请后的证书。<br><br>该字段保存后不可修改。",
|
"access.form.type.tooltip": "提供商分为两种类型:<br>【DNS 提供商】您的域名 DNS 托管方,用于在申请证书时管理您的域名解析记录。<br>【主机提供商】您的服务器或云服务的托管方,用于部署签发的证书。<br><br>该字段保存后不可修改。",
|
||||||
"access.form.acmehttpreq_endpoint.label": "服务端点",
|
"access.form.acmehttpreq_endpoint.label": "服务端点",
|
||||||
"access.form.acmehttpreq_endpoint.placeholder": "请输入服务端点",
|
"access.form.acmehttpreq_endpoint.placeholder": "请输入服务端点",
|
||||||
"access.form.acmehttpreq_endpoint.tooltip": "这是什么?请参阅 <a href=\"https://go-acme.github.io/lego/dns/httpreq/\" target=\"_blank\">https://go-acme.github.io/lego/dns/httpreq/</a>",
|
"access.form.acmehttpreq_endpoint.tooltip": "这是什么?请参阅 <a href=\"https://go-acme.github.io/lego/dns/httpreq/\" target=\"_blank\">https://go-acme.github.io/lego/dns/httpreq/</a>",
|
||||||
|
@ -33,9 +33,9 @@
|
|||||||
"domain.application.form.email.placeholder": "请选择邮箱",
|
"domain.application.form.email.placeholder": "请选择邮箱",
|
||||||
"domain.application.form.email.add": "添加邮箱",
|
"domain.application.form.email.add": "添加邮箱",
|
||||||
"domain.application.form.email.list": "邮箱列表",
|
"domain.application.form.email.list": "邮箱列表",
|
||||||
"domain.application.form.access.label": "DNS 服务商授权配置",
|
"domain.application.form.access.label": "DNS 提供商授权配置",
|
||||||
"domain.application.form.access.placeholder": "请选择 DNS 服务商授权配置",
|
"domain.application.form.access.placeholder": "请选择 DNS 提供商授权配置",
|
||||||
"domain.application.form.access.list": "DNS 服务商授权配置列表",
|
"domain.application.form.access.list": "DNS 提供商授权配置列表",
|
||||||
"domain.application.form.advanced_settings.label": "高级设置",
|
"domain.application.form.advanced_settings.label": "高级设置",
|
||||||
"domain.application.form.key_algorithm.label": "数字证书算法(默认:RSA2048)",
|
"domain.application.form.key_algorithm.label": "数字证书算法(默认:RSA2048)",
|
||||||
"domain.application.form.key_algorithm.placeholder": "请选择数字证书算法",
|
"domain.application.form.key_algorithm.placeholder": "请选择数字证书算法",
|
||||||
@ -53,7 +53,7 @@
|
|||||||
"domain.deployment.form.type.list": "部署方式列表",
|
"domain.deployment.form.type.list": "部署方式列表",
|
||||||
"domain.deployment.form.access.label": "授权配置",
|
"domain.deployment.form.access.label": "授权配置",
|
||||||
"domain.deployment.form.access.placeholder": "请选择授权配置",
|
"domain.deployment.form.access.placeholder": "请选择授权配置",
|
||||||
"domain.deployment.form.access.list": "服务商授权配置列表",
|
"domain.deployment.form.access.list": "提供商授权配置列表",
|
||||||
"domain.deployment.form.domain.label": "部署到域名(仅支持单个域名;不支持泛域名)",
|
"domain.deployment.form.domain.label": "部署到域名(仅支持单个域名;不支持泛域名)",
|
||||||
"domain.deployment.form.domain.label.wildsupported": "部署到域名(支持泛域名)",
|
"domain.deployment.form.domain.label.wildsupported": "部署到域名(支持泛域名)",
|
||||||
"domain.deployment.form.domain.placeholder": "请输入部署到的域名",
|
"domain.deployment.form.domain.placeholder": "请输入部署到的域名",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user