From a4eff0b408fee1fc36ac5a19aba2d0f6eb28eef7 Mon Sep 17 00:00:00 2001 From: Fu Diwei <fudiwei@sina.com> Date: Mon, 9 Dec 2024 19:42:56 +0800 Subject: [PATCH] feat(ui): enhance certificate downloading --- .../certificate/CertificateDetail.tsx | 46 +++++++++++++++---- ui/src/pages/dashboard/Dashboard.tsx | 4 +- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/ui/src/components/certificate/CertificateDetail.tsx b/ui/src/components/certificate/CertificateDetail.tsx index c877ddd9..45e7ae51 100644 --- a/ui/src/components/certificate/CertificateDetail.tsx +++ b/ui/src/components/certificate/CertificateDetail.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; -import { Button, Form, Input, message, Tooltip } from "antd"; +import { Button, Dropdown, Form, Input, message, Space, Tooltip } from "antd"; import { CopyToClipboard } from "react-copy-to-clipboard"; -import { Clipboard as ClipboardIcon } from "lucide-react"; +import { ChevronDown as ChevronDownIcon, Clipboard as ClipboardIcon, ThumbsUp as ThumbsUpIcon } from "lucide-react"; import { type Certificate } from "@/domain/certificate"; import { saveFiles2Zip } from "@/utils/file"; @@ -15,8 +15,7 @@ const CertificateDetail = ({ data }: CertificateDetailProps) => { const [messageApi, MessageContextHolder] = message.useMessage(); - const handleDownloadClick = async () => { - // TODO: 支持下载多种格式 + const handleDownloadPEMClick = async () => { const zipName = `${data.id}-${data.san}.zip`; const files = [ { @@ -73,14 +72,41 @@ const CertificateDetail = ({ data }: CertificateDetailProps) => { </Form> <div className="flex items-center justify-end"> - <Button - type="primary" - onClick={() => { - handleDownloadClick(); + <Dropdown + menu={{ + items: [ + { + key: "PEM", + label: "PEM", + extra: <ThumbsUpIcon size="14" />, + onClick: () => handleDownloadPEMClick(), + }, + { + key: "PFX", + label: "PFX", + onClick: () => { + // TODO: 下载 PFX 格式证书 + alert("TODO"); + }, + }, + { + key: "JKS", + label: "JKS", + onClick: () => { + // TODO: 下载 JKS 格式证书 + alert("TODO"); + }, + }, + ], }} > - {t("certificate.action.download")} - </Button> + <Button type="primary"> + <Space> + <span>{t("certificate.action.download")}</span> + <ChevronDownIcon size={14} /> + </Space> + </Button> + </Dropdown> </div> </div> ); diff --git a/ui/src/pages/dashboard/Dashboard.tsx b/ui/src/pages/dashboard/Dashboard.tsx index 60340cfc..69c9ff6c 100644 --- a/ui/src/pages/dashboard/Dashboard.tsx +++ b/ui/src/pages/dashboard/Dashboard.tsx @@ -65,7 +65,7 @@ const Dashboard = () => { <PageHeader title={t("dashboard.page.title")} /> - <Row gutter={[16, 16]}> + <Row className="justify-stretch" gutter={[16, 16]}> <Col {...statisticGridSpans}> <StatisticCard icon={<SquareSigmaIcon size={48} strokeWidth={1} color={themeToken.colorInfo} />} @@ -134,7 +134,7 @@ const StatisticCard = ({ onClick?: () => void; }) => { return ( - <Card className="overflow-hidden" bordered={false} hoverable onClick={onClick}> + <Card className="size-full overflow-hidden" bordered={false} hoverable onClick={onClick}> <Space size="middle"> {icon} <Statistic