mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-15 00:49:51 +00:00
feat(ui): improve responsive ui
This commit is contained in:
parent
e10fb64d6b
commit
831f0ee5d9
@ -13,7 +13,6 @@
|
||||
"dashboard.quick_actions": "快捷操作",
|
||||
"dashboard.quick_actions.create_workflow": "新建工作流",
|
||||
"dashboard.quick_actions.change_login_password": "修改登录密码",
|
||||
"dashboard.quick_actions.notification_settings": "消息推送设置",
|
||||
"dashboard.quick_actions.certificate_authority_configuration": "证书颁发机构配置"
|
||||
"dashboard.quick_actions.cofigure_notification": "消息推送设置",
|
||||
"dashboard.quick_actions.configure_ca": "证书颁发机构配置"
|
||||
}
|
||||
|
||||
|
@ -29,31 +29,54 @@ import { ClientResponseError } from "pocketbase";
|
||||
import { get as getStatistics } from "@/api/statistics";
|
||||
import WorkflowRunDetailDrawer from "@/components/workflow/WorkflowRunDetailDrawer";
|
||||
import { type Statistics } from "@/domain/statistics";
|
||||
import { WORKFLOW_TRIGGERS } from "@/domain/workflow";
|
||||
import { WORKFLOW_RUN_STATUSES, type WorkflowRunModel } from "@/domain/workflowRun";
|
||||
import { list as listWorkflowRuns } from "@/repository/workflowRun";
|
||||
import { getErrMsg } from "@/utils/error";
|
||||
|
||||
const { useBreakpoint } = Grid;
|
||||
|
||||
const Dashboard = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const screens = useBreakpoint();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { token: themeToken } = theme.useToken();
|
||||
const breakpoints = Grid.useBreakpoint();
|
||||
|
||||
const [notificationApi, NotificationContextHolder] = notification.useNotification();
|
||||
|
||||
const statisticsGridSpans = {
|
||||
xs: { flex: "50%" },
|
||||
md: { flex: "50%" },
|
||||
lg: { flex: "33.3333%" },
|
||||
xl: { flex: "33.3333%" },
|
||||
xxl: { flex: "20%" },
|
||||
};
|
||||
const [statistics, setStatistics] = useState<Statistics>();
|
||||
const { loading: statisticsLoading } = useRequest(
|
||||
() => {
|
||||
return getStatistics();
|
||||
},
|
||||
{
|
||||
onSuccess: (res) => {
|
||||
setStatistics(res.data);
|
||||
},
|
||||
onError: (err) => {
|
||||
if (err instanceof ClientResponseError && err.isAbort) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const tableColumns: TableProps<WorkflowRunModel>["columns"] = [
|
||||
{
|
||||
key: "$index",
|
||||
align: "center",
|
||||
fixed: "left",
|
||||
width: 50,
|
||||
render: (_, __, index) => (page - 1) * pageSize + index + 1,
|
||||
render: (_, __, index) => index + 1,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
@ -98,20 +121,6 @@ const Dashboard = () => {
|
||||
return <></>;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "trigger",
|
||||
title: t("workflow_run.props.trigger"),
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
if (record.trigger === WORKFLOW_TRIGGERS.AUTO) {
|
||||
return t("workflow_run.props.trigger.auto");
|
||||
} else if (record.trigger === WORKFLOW_TRIGGERS.MANUAL) {
|
||||
return t("workflow_run.props.trigger.manual");
|
||||
}
|
||||
|
||||
return <></>;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "startedAt",
|
||||
title: t("workflow_run.props.started_at"),
|
||||
@ -139,7 +148,6 @@ const Dashboard = () => {
|
||||
{
|
||||
key: "$action",
|
||||
align: "end",
|
||||
fixed: "right",
|
||||
width: 120,
|
||||
render: (_, record) => (
|
||||
<Button.Group>
|
||||
@ -149,52 +157,17 @@ const Dashboard = () => {
|
||||
},
|
||||
];
|
||||
const [tableData, setTableData] = useState<WorkflowRunModel[]>([]);
|
||||
const [_tableTotal, setTableTotal] = useState<number>(0);
|
||||
|
||||
const [page, _setPage] = useState<number>(1);
|
||||
const [pageSize, _setPageSize] = useState<number>(3);
|
||||
|
||||
const { loading: loadingWorkflowRun } = useRequest(
|
||||
const { loading: tableLoading } = useRequest(
|
||||
() => {
|
||||
return listWorkflowRuns({
|
||||
page: page,
|
||||
perPage: pageSize,
|
||||
page: 1,
|
||||
perPage: 5,
|
||||
expand: true,
|
||||
});
|
||||
},
|
||||
{
|
||||
refreshDeps: [page, pageSize],
|
||||
onSuccess: (res) => {
|
||||
setTableData(res.items);
|
||||
setTableTotal(res.totalItems > 3 ? 3 : res.totalItems);
|
||||
},
|
||||
onError: (err) => {
|
||||
if (err instanceof ClientResponseError && err.isAbort) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
notificationApi.error({ message: t("common.text.request_error"), description: getErrMsg(err) });
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const statisticsGridSpans = {
|
||||
xs: { flex: "50%" },
|
||||
md: { flex: "50%" },
|
||||
lg: { flex: "33.3333%" },
|
||||
xl: { flex: "33.3333%" },
|
||||
xxl: { flex: "20%" },
|
||||
};
|
||||
const [statistics, setStatistics] = useState<Statistics>();
|
||||
|
||||
const { loading } = useRequest(
|
||||
() => {
|
||||
return getStatistics();
|
||||
},
|
||||
{
|
||||
onSuccess: (res) => {
|
||||
setStatistics(res.data);
|
||||
},
|
||||
onError: (err) => {
|
||||
if (err instanceof ClientResponseError && err.isAbort) {
|
||||
@ -218,7 +191,7 @@ const Dashboard = () => {
|
||||
<StatisticCard
|
||||
icon={<SquareSigmaIcon size={48} strokeWidth={1} color={themeToken.colorInfo} />}
|
||||
label={t("dashboard.statistics.all_certificates")}
|
||||
loading={loading}
|
||||
loading={statisticsLoading}
|
||||
value={statistics?.certificateTotal ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/certificates")}
|
||||
@ -228,7 +201,7 @@ const Dashboard = () => {
|
||||
<StatisticCard
|
||||
icon={<CalendarClockIcon size={48} strokeWidth={1} color={themeToken.colorWarning} />}
|
||||
label={t("dashboard.statistics.expire_soon_certificates")}
|
||||
loading={loading}
|
||||
loading={statisticsLoading}
|
||||
value={statistics?.certificateExpireSoon ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/certificates?state=expireSoon")}
|
||||
@ -238,7 +211,7 @@ const Dashboard = () => {
|
||||
<StatisticCard
|
||||
icon={<CalendarX2Icon size={48} strokeWidth={1} color={themeToken.colorError} />}
|
||||
label={t("dashboard.statistics.expired_certificates")}
|
||||
loading={loading}
|
||||
loading={statisticsLoading}
|
||||
value={statistics?.certificateExpired ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/certificates?state=expired")}
|
||||
@ -248,7 +221,7 @@ const Dashboard = () => {
|
||||
<StatisticCard
|
||||
icon={<WorkflowIcon size={48} strokeWidth={1} color={themeToken.colorInfo} />}
|
||||
label={t("dashboard.statistics.all_workflows")}
|
||||
loading={loading}
|
||||
loading={statisticsLoading}
|
||||
value={statistics?.workflowTotal ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/workflows")}
|
||||
@ -258,7 +231,7 @@ const Dashboard = () => {
|
||||
<StatisticCard
|
||||
icon={<FolderCheckIcon size={48} strokeWidth={1} color={themeToken.colorSuccess} />}
|
||||
label={t("dashboard.statistics.enabled_workflows")}
|
||||
loading={loading}
|
||||
loading={statisticsLoading}
|
||||
value={statistics?.workflowEnabled ?? "-"}
|
||||
suffix={t("dashboard.statistics.unit")}
|
||||
onClick={() => navigate("/workflows?state=enabled")}
|
||||
@ -268,34 +241,32 @@ const Dashboard = () => {
|
||||
|
||||
<Divider />
|
||||
|
||||
<Flex vertical={!screens.md} gap={16}>
|
||||
<Card className="sm:h-full sm:w-[500px] sm:pb-32">
|
||||
<div className="text-lg font-semibold">{t("dashboard.quick_actions")}</div>
|
||||
<div className="mt-9">
|
||||
<Button className="w-full" type="primary" size="large" icon={<PlusOutlined />} onClick={() => navigate("/workflows/new")}>
|
||||
<Flex justify="stretch" vertical={!breakpoints.lg} gap={16}>
|
||||
<Card className="max-lg:flex-1 lg:w-[360px]" title={t("dashboard.quick_actions")}>
|
||||
<Space className="w-full" direction="vertical" size="large">
|
||||
<Button block type="primary" size="large" icon={<PlusOutlined />} onClick={() => navigate("/workflows/new")}>
|
||||
{t("dashboard.quick_actions.create_workflow")}
|
||||
</Button>
|
||||
<Button className="mt-5 w-full" size="large" icon={<LockOutlined />} onClick={() => navigate("/settings/password")}>
|
||||
<Button block size="large" icon={<LockOutlined />} onClick={() => navigate("/settings/password")}>
|
||||
{t("dashboard.quick_actions.change_login_password")}
|
||||
</Button>
|
||||
<Button className="mt-5 w-full" size="large" icon={<SendOutlined />} onClick={() => navigate("/settings/notification")}>
|
||||
<Button block size="large" icon={<SendOutlined />} onClick={() => navigate("/settings/notification")}>
|
||||
{t("dashboard.quick_actions.notification_settings")}
|
||||
</Button>
|
||||
<Button className="mt-5 w-full" size="large" icon={<ApiOutlined />} onClick={() => navigate("/settings/ssl-provider")}>
|
||||
<Button block size="large" icon={<ApiOutlined />} onClick={() => navigate("/settings/ssl-provider")}>
|
||||
{t("dashboard.quick_actions.certificate_authority_configuration")}
|
||||
</Button>
|
||||
</div>
|
||||
</Space>
|
||||
</Card>
|
||||
<Card className="size-full">
|
||||
<div className="text-lg font-semibold">{t("dashboard.latest_workflow_run")} </div>
|
||||
<Card className="flex-1" title={t("dashboard.latest_workflow_run")}>
|
||||
<Table<WorkflowRunModel>
|
||||
className="mt-5"
|
||||
columns={tableColumns}
|
||||
dataSource={tableData}
|
||||
loading={loadingWorkflowRun}
|
||||
loading={tableLoading}
|
||||
locale={{
|
||||
emptyText: <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />,
|
||||
}}
|
||||
pagination={false}
|
||||
rowKey={(record: WorkflowRunModel) => record.id}
|
||||
scroll={{ x: "max(100%, 960px)" }}
|
||||
/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user