feat(ui): different provider range of accesses in AccessList

This commit is contained in:
Fu Diwei 2025-03-30 21:04:17 +08:00
parent 4ab6b72e6f
commit a72737fdd5
5 changed files with 65 additions and 15 deletions

View File

@ -292,6 +292,7 @@ const AccessForm = forwardRef<AccessFormInstance, AccessFormProps>(({ className,
}}
disabled={scene !== "add"}
placeholder={providerPlaceholder}
showOptionTags={range == null || range === "both-dns-hosting"}
showSearch={!disabled}
/>
</Form.Item>

View File

@ -40,7 +40,7 @@ const AccessProviderSelect = ({ filter, showOptionTags, ...props }: AccessProvid
{t(provider?.name ?? "")}
</Typography.Text>
</Space>
{!showOptionTags && (
{showOptionTags && (
<div>
{provider?.usages?.includes(ACCESS_USAGES.DNS) && <Tag color="peru">{t("access.props.provider.usage.dns")}</Tag>}
{provider?.usages?.includes(ACCESS_USAGES.HOSTING) && <Tag color="royalblue">{t("access.props.provider.usage.hosting")}</Tag>}

View File

@ -17,8 +17,9 @@
"access.props.provider.usage.hosting": "Hosting provider",
"access.props.provider.usage.ca": "Certificate authority",
"access.props.provider.usage.notification": "Notification channel",
"access.props.ca": "Certificate authority",
"access.props.channel": "Notification channel",
"access.props.range.both_dns_hosting": "Provider",
"access.props.range.ca_only": "Certificate authority",
"access.props.range.notify_only": "Notification channel",
"access.props.created_at": "Created at",
"access.props.updated_at": "Updated at",

View File

@ -17,8 +17,9 @@
"access.props.provider.usage.hosting": "主机提供商",
"access.props.provider.usage.ca": "证书颁发机构",
"access.props.provider.usage.notification": "通知渠道",
"access.props.ca": "证书颁发机构",
"access.props.channel": "通知渠道",
"access.props.range.both_dns_hosting": "提供商",
"access.props.range.ca_only": "证书颁发机构",
"access.props.range.notify_only": "通知渠道",
"access.props.created_at": "创建时间",
"access.props.updated_at": "更新时间",

View File

@ -14,13 +14,15 @@ import { Avatar, Button, Card, Empty, Flex, Input, Modal, Space, Table, type Tab
import dayjs from "dayjs";
import { ClientResponseError } from "pocketbase";
import AccessEditModal from "@/components/access/AccessEditModal";
import AccessEditModal, { type AccessEditModalProps } from "@/components/access/AccessEditModal";
import { type AccessModel } from "@/domain/access";
import { accessProvidersMap } from "@/domain/provider";
import { ACCESS_USAGES, accessProvidersMap } from "@/domain/provider";
import { useZustandShallowSelector } from "@/hooks";
import { useAccessesStore } from "@/stores/access";
import { getErrMsg } from "@/utils/error";
type AccessRanges = AccessEditModalProps["range"];
const AccessList = () => {
const [searchParams] = useSearchParams();
@ -85,6 +87,7 @@ const AccessList = () => {
<Space.Compact>
<AccessEditModal
data={record}
range={filters["range"] as AccessRanges}
scene="edit"
trigger={
<Tooltip title={t("access.action.edit")}>
@ -95,6 +98,7 @@ const AccessList = () => {
<AccessEditModal
data={{ ...record, id: undefined, name: `${record.name}-copy` }}
range={filters["range"] as AccessRanges}
scene="add"
trigger={
<Tooltip title={t("access.action.duplicate")}>
@ -122,6 +126,7 @@ const AccessList = () => {
const [filters, setFilters] = useState<Record<string, unknown>>(() => {
return {
range: "both-dns-hosting" satisfies AccessRanges,
keyword: searchParams.get("keyword"),
};
});
@ -144,14 +149,26 @@ const AccessList = () => {
() => {
const startIndex = (page - 1) * pageSize;
const endIndex = startIndex + pageSize;
const list = accesses.filter((e) => {
const keyword = (filters["keyword"] as string | undefined)?.trim();
if (keyword) {
return e.name.includes(keyword);
}
const list = accesses
.filter((e) => {
const keyword = (filters["keyword"] as string | undefined)?.trim();
if (keyword) {
return e.name.includes(keyword);
}
return true;
});
return true;
})
.filter((e) => {
const provider = accessProvidersMap.get(e.provider);
switch (filters["range"] as AccessRanges) {
case "both-dns-hosting":
return provider?.usages?.includes(ACCESS_USAGES.DNS) || provider?.usages?.includes(ACCESS_USAGES.HOSTING);
case "ca-only":
return provider?.usages?.includes(ACCESS_USAGES.CA);
case "notify-only":
return provider?.usages?.includes(ACCESS_USAGES.NOTIFICATION);
}
});
return Promise.resolve({
items: list.slice(startIndex, endIndex),
totalItems: list.length,
@ -166,6 +183,10 @@ const AccessList = () => {
}
);
const handleTabChange = (key: string) => {
setFilters((prev) => ({ ...prev, range: key }));
};
const handleSearch = (value: string) => {
setFilters((prev) => ({ ...prev, keyword: value }));
};
@ -203,6 +224,7 @@ const AccessList = () => {
extra={[
<AccessEditModal
key="create"
range={filters["range"] as AccessRanges}
scene="add"
trigger={
<Button type="primary" icon={<PlusOutlinedIcon />}>
@ -213,7 +235,32 @@ const AccessList = () => {
]}
/>
<Card size="small">
<Card
className="rounded-b-none"
styles={{
body: {
padding: 0,
},
}}
tabList={[
{
key: "both-dns-hosting",
label: t("access.props.range.both_dns_hosting"),
},
{
key: "ca-only",
label: t("access.props.range.ca_only"),
},
{
key: "notify-only",
label: t("access.props.range.notify_only"),
},
]}
activeTabKey={filters["range"] as string}
onTabChange={(key) => handleTabChange(key)}
/>
<Card className="rounded-t-none " size="small">
<div className="mb-4">
<Flex gap="small">
<div className="flex-1">