mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-17 18:09:52 +00:00
feat(ui): show more details in CertificateDetail
This commit is contained in:
parent
419b6eb626
commit
220d98a668
@ -2,6 +2,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { Button, Dropdown, Form, Input, message, Space, Tooltip } from "antd";
|
import { Button, Dropdown, Form, Input, message, Space, Tooltip } from "antd";
|
||||||
import { CopyToClipboard } from "react-copy-to-clipboard";
|
import { CopyToClipboard } from "react-copy-to-clipboard";
|
||||||
import { ChevronDown as ChevronDownIcon, Clipboard as ClipboardIcon, ThumbsUp as ThumbsUpIcon } from "lucide-react";
|
import { ChevronDown as ChevronDownIcon, Clipboard as ClipboardIcon, ThumbsUp as ThumbsUpIcon } from "lucide-react";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
import { type CertificateModel } from "@/domain/certificate";
|
import { type CertificateModel } from "@/domain/certificate";
|
||||||
import { saveFiles2Zip } from "@/utils/file";
|
import { saveFiles2Zip } from "@/utils/file";
|
||||||
@ -36,6 +37,10 @@ const CertificateDetail = ({ data }: CertificateDetailProps) => {
|
|||||||
{MessageContextHolder}
|
{MessageContextHolder}
|
||||||
|
|
||||||
<Form layout="vertical">
|
<Form layout="vertical">
|
||||||
|
<Form.Item label={t("certificate.props.san")}>{data.san}</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item label={t("certificate.props.expiry")}>{dayjs(data.expireAt).format("YYYY-MM-DD HH:mm:ss")}</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<div className="flex items-center justify-between w-full mb-2">
|
<div className="flex items-center justify-between w-full mb-2">
|
||||||
<label className="font-medium">{t("certificate.props.certificate_chain")}</label>
|
<label className="font-medium">{t("certificate.props.certificate_chain")}</label>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"certificate.action.view": "View Certificate",
|
"certificate.action.view": "View Certificate",
|
||||||
"certificate.action.download": "Download Certificate",
|
"certificate.action.download": "Download Certificate",
|
||||||
|
|
||||||
"certificate.props.domain": "Name",
|
"certificate.props.san": "Name",
|
||||||
"certificate.props.expiry": "Expiry",
|
"certificate.props.expiry": "Expiry",
|
||||||
"certificate.props.expiry.left_days": "{{left}} / {{total}} days left",
|
"certificate.props.expiry.left_days": "{{left}} / {{total}} days left",
|
||||||
"certificate.props.expiry.expired": "Expired",
|
"certificate.props.expiry.expired": "Expired",
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"certificate.action.view": "查看证书",
|
"certificate.action.view": "查看证书",
|
||||||
"certificate.action.download": "下载证书",
|
"certificate.action.download": "下载证书",
|
||||||
|
|
||||||
"certificate.props.domain": "名称",
|
"certificate.props.san": "名称",
|
||||||
"certificate.props.expiry": "有效期限",
|
"certificate.props.expiry": "有效期限",
|
||||||
"certificate.props.expiry.left_days": "{{left}} / {{total}} 天",
|
"certificate.props.expiry.left_days": "{{left}} / {{total}} 天",
|
||||||
"certificate.props.expiry.expired": "已到期",
|
"certificate.props.expiry.expired": "已到期",
|
||||||
|
@ -120,43 +120,21 @@ const SiderMenu = React.memo(({ onSelect }: { onSelect?: (key: string) => void }
|
|||||||
const MENU_KEY_CERTIFICATES = "/certificates";
|
const MENU_KEY_CERTIFICATES = "/certificates";
|
||||||
const MENU_KEY_ACCESSES = "/accesses";
|
const MENU_KEY_ACCESSES = "/accesses";
|
||||||
const menuItems: Required<MenuProps>["items"] = [
|
const menuItems: Required<MenuProps>["items"] = [
|
||||||
{
|
[MENU_KEY_HOME, <HomeIcon size={16} />, t("dashboard.page.title")],
|
||||||
key: MENU_KEY_HOME,
|
[MENU_KEY_WORKFLOWS, <WorkflowIcon size={16} />, t("workflow.page.title")],
|
||||||
icon: <HomeIcon size={16} />,
|
[MENU_KEY_CERTIFICATES, <ShieldCheckIcon size={16} />, t("certificate.page.title")],
|
||||||
label: t("dashboard.page.title"),
|
[MENU_KEY_ACCESSES, <ServerIcon size={16} />, t("access.page.title")],
|
||||||
|
].map(([key, icon, label]) => {
|
||||||
|
return {
|
||||||
|
key: key as string,
|
||||||
|
icon: icon,
|
||||||
|
label: label,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
navigate(MENU_KEY_HOME);
|
navigate(key as string);
|
||||||
onSelect?.(MENU_KEY_HOME);
|
onSelect?.(key as string);
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
{
|
});
|
||||||
key: MENU_KEY_WORKFLOWS,
|
|
||||||
icon: <WorkflowIcon size={16} />,
|
|
||||||
label: t("workflow.page.title"),
|
|
||||||
onClick: () => {
|
|
||||||
navigate(MENU_KEY_WORKFLOWS);
|
|
||||||
onSelect?.(MENU_KEY_WORKFLOWS);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: MENU_KEY_CERTIFICATES,
|
|
||||||
icon: <ShieldCheckIcon size={16} />,
|
|
||||||
label: t("certificate.page.title"),
|
|
||||||
onClick: () => {
|
|
||||||
navigate(MENU_KEY_CERTIFICATES);
|
|
||||||
onSelect?.(MENU_KEY_CERTIFICATES);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: MENU_KEY_ACCESSES,
|
|
||||||
icon: <ServerIcon size={16} />,
|
|
||||||
label: t("access.page.title"),
|
|
||||||
onClick: () => {
|
|
||||||
navigate(MENU_KEY_ACCESSES);
|
|
||||||
onSelect?.(MENU_KEY_ACCESSES);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const [menuSelectedKey, setMenuSelectedKey] = useState<string>();
|
const [menuSelectedKey, setMenuSelectedKey] = useState<string>();
|
||||||
|
|
||||||
const getActiveMenuItem = () => {
|
const getActiveMenuItem = () => {
|
||||||
@ -207,22 +185,19 @@ const ThemeToggleButton = React.memo(({ size }: { size?: ButtonProps["size"] })
|
|||||||
const { theme, setThemeMode } = useTheme();
|
const { theme, setThemeMode } = useTheme();
|
||||||
|
|
||||||
const items: Required<MenuProps>["items"] = [
|
const items: Required<MenuProps>["items"] = [
|
||||||
{
|
["light", t("common.theme.light")],
|
||||||
key: "light",
|
["dark", t("common.theme.dark")],
|
||||||
label: <>{t("common.theme.light")}</>,
|
["system", t("common.theme.system")],
|
||||||
onClick: () => setThemeMode("light"),
|
].map(([key, label]) => {
|
||||||
|
return {
|
||||||
|
key: key as string,
|
||||||
|
label: label,
|
||||||
|
onClick: () => {
|
||||||
|
setThemeMode(key as Parameters<typeof setThemeMode>[0]);
|
||||||
|
window.location.reload();
|
||||||
},
|
},
|
||||||
{
|
};
|
||||||
key: "dark",
|
});
|
||||||
label: <>{t("common.theme.dark")}</>,
|
|
||||||
onClick: () => setThemeMode("dark"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "system",
|
|
||||||
label: <>{t("common.theme.system")}</>,
|
|
||||||
onClick: () => setThemeMode("system"),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown menu={{ items }} trigger={["click"]}>
|
<Dropdown menu={{ items }} trigger={["click"]}>
|
||||||
|
@ -33,7 +33,7 @@ const CertificateList = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "name",
|
key: "name",
|
||||||
title: t("certificate.props.domain"),
|
title: t("certificate.props.san"),
|
||||||
render: (_, record) => <Typography.Text>{record.san}</Typography.Text>,
|
render: (_, record) => <Typography.Text>{record.san}</Typography.Text>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user