-
{renderBadge()}
+
+
+
{
+ const { token: themeToken } = theme.useToken();
+
+ switch (value) {
+ case WORKFLOW_RUN_STATUSES.PENDING:
+ if (defaultColor == null || !defaultColor) {
+ return themeToken.colorTextSecondary;
+ }
+ break;
+ case WORKFLOW_RUN_STATUSES.RUNNING:
+ if (defaultColor == null || !defaultColor) {
+ return themeToken.colorInfo;
+ }
+ break;
+ case WORKFLOW_RUN_STATUSES.SUCCEEDED:
+ if (defaultColor == null || !defaultColor) {
+ return themeToken.colorSuccess;
+ }
+ break;
+ case WORKFLOW_RUN_STATUSES.FAILED:
+ if (defaultColor == null || !defaultColor) {
+ return themeToken.colorError;
+ }
+ break;
+ case WORKFLOW_RUN_STATUSES.CANCELED:
+ if (defaultColor == null || !defaultColor) {
+ return themeToken.colorWarning;
+ }
+ break;
+ default:
+ if (defaultColor == null || !defaultColor) {
+ return themeToken.colorTextSecondary;
+ }
+ break;
+ }
+
+ return defaultColor;
+};
+
+export interface WorkflowStatusIconProps {
+ className?: string;
+ style?: React.CSSProperties;
+ color?: string | false;
+ size?: number | string;
+ type?: "filled" | "outlined";
+ value: WorkflorRunStatusType | string;
+}
+
+const WorkflowStatusIcon = ({ className, style, size = "1.25em", type = "outlined", value, ...props }: WorkflowStatusIconProps) => {
+ const color = useColor(value, props.color);
+
+ switch (value) {
+ case WORKFLOW_RUN_STATUSES.PENDING:
+ return (
+
+ {type === "filled" ? : }
+
+ );
+ case WORKFLOW_RUN_STATUSES.RUNNING:
+ return (
+
+
+
+ );
+ case WORKFLOW_RUN_STATUSES.SUCCEEDED:
+ return (
+
+ {type === "filled" ? : }
+
+ );
+ case WORKFLOW_RUN_STATUSES.FAILED:
+ return (
+
+ {type === "filled" ? : }
+
+ );
+ case WORKFLOW_RUN_STATUSES.CANCELED:
+ return (
+
+
+
+ );
+ default:
+ return (
+
+
+
+ );
+ }
+};
+
+export interface WorkflowStatusProps {
+ className?: string;
+ style?: React.CSSProperties;
+ children?: React.ReactNode;
+ color?: string | false;
+ showIcon?: boolean;
+ type?: WorkflowStatusIconProps["type"];
+ value: WorkflorRunStatusType | string;
+}
+
+const WorkflowStatus = ({ className, style, children, showIcon = true, type, value, ...props }: WorkflowStatusProps) => {
+ const { t } = useTranslation();
+
+ const color = useColor(value, props.color);
+
+ const renderIcon = () => (showIcon ? : null);
+
+ switch (value) {
+ case WORKFLOW_RUN_STATUSES.PENDING:
+ case WORKFLOW_RUN_STATUSES.RUNNING:
+ case WORKFLOW_RUN_STATUSES.SUCCEEDED:
+ case WORKFLOW_RUN_STATUSES.FAILED:
+ case WORKFLOW_RUN_STATUSES.CANCELED:
+ return (
+
+
+ {renderIcon()}
+ {children != null ? children : {t(`workflow_run.props.status.${value.toLowerCase()}`)}}
+
+
+ );
+ default:
+ return (
+
+ {children != null ? children : <>>}
+
+ );
+ }
+};
+
+const _default = Object.assign(WorkflowStatus, {
+ Icon: WorkflowStatusIcon,
+});
+
+export default _default;
diff --git a/ui/src/components/workflow/WorkflowStatusIcon.tsx b/ui/src/components/workflow/WorkflowStatusIcon.tsx
deleted file mode 100644
index 04d4d2d38..000000000
--- a/ui/src/components/workflow/WorkflowStatusIcon.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import { IconCircleCheck, IconCircleDashed, IconCircleOff, IconCircleX, IconClock, IconLoader3 } from "@tabler/icons-react";
-import { theme } from "antd";
-
-import { WORKFLOW_RUN_STATUSES } from "@/domain/workflowRun";
-import { mergeCls } from "@/utils/css";
-
-export interface WorkflowStatusIconProps {
- className?: string;
- style?: React.CSSProperties;
- color?: string | true;
- size?: number | string;
- status: string;
-}
-
-const WorkflowStatusIcon = ({ className, style, color, status, ...props }: WorkflowStatusIconProps) => {
- const { size = "1em" } = props;
-
- const { token: themeToken } = theme.useToken();
-
- switch (status) {
- case WORKFLOW_RUN_STATUSES.PENDING:
- if (color === true) {
- color = themeToken.colorTextSecondary;
- }
- return (
-
-
-
- );
- case WORKFLOW_RUN_STATUSES.RUNNING:
- if (color === true) {
- color = themeToken.colorInfo;
- }
- return (
-
-
-
- );
- case WORKFLOW_RUN_STATUSES.SUCCEEDED:
- if (color === true) {
- color = themeToken.colorSuccess;
- }
- return (
-
-
-
- );
- case WORKFLOW_RUN_STATUSES.FAILED:
- if (color === true) {
- color = themeToken.colorError;
- }
- return (
-
-
-
- );
- case WORKFLOW_RUN_STATUSES.CANCELED:
- if (color === true) {
- color = themeToken.colorWarning;
- }
- return (
-
-
-
- );
- default:
- if (color === true) {
- color = themeToken.colorTextSecondary;
- }
- return (
-
-
-
- );
- }
-};
-
-export default WorkflowStatusIcon;
diff --git a/ui/src/components/workflow/WorkflowStatusTag.tsx b/ui/src/components/workflow/WorkflowStatusTag.tsx
deleted file mode 100644
index 12a645d9b..000000000
--- a/ui/src/components/workflow/WorkflowStatusTag.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { useTranslation } from "react-i18next";
-import { Tag } from "antd";
-
-import { WORKFLOW_RUN_STATUSES } from "@/domain/workflowRun";
-
-import WorkflowStatusIcon from "./WorkflowStatusIcon";
-
-export interface WorkflowStatusTagProps {
- className?: string;
- style?: React.CSSProperties;
- status: string;
-}
-
-const WorkflowStatusTag = ({ className, style, status }: WorkflowStatusTagProps) => {
- const { t } = useTranslation();
-
- const Icon = ;
-
- switch (status) {
- case WORKFLOW_RUN_STATUSES.PENDING:
- return (
-
- {t("workflow_run.props.status.pending")}
-
- );
- case WORKFLOW_RUN_STATUSES.RUNNING:
- return (
-
- {t("workflow_run.props.status.running")}
-
- );
- case WORKFLOW_RUN_STATUSES.SUCCEEDED:
- return (
-
- {t("workflow_run.props.status.succeeded")}
-
- );
- case WORKFLOW_RUN_STATUSES.FAILED:
- return (
-
- {t("workflow_run.props.status.failed")}
-
- );
- case WORKFLOW_RUN_STATUSES.CANCELED:
- return (
-
- {t("workflow_run.props.status.canceled")}
-
- );
- default:
- return <>>;
- }
-};
-
-export default WorkflowStatusTag;
diff --git a/ui/src/i18n/locales/en/nls.dashboard.json b/ui/src/i18n/locales/en/nls.dashboard.json
index 123ac884d..66345b266 100644
--- a/ui/src/i18n/locales/en/nls.dashboard.json
+++ b/ui/src/i18n/locales/en/nls.dashboard.json
@@ -7,12 +7,12 @@
"dashboard.statistics.all_workflows": "All workflows",
"dashboard.statistics.enabled_workflows": "Active workflows",
+ "dashboard.shortcut": "Shortcuts",
+ "dashboard.shortcut.create_workflow": "Create new workflow",
+ "dashboard.shortcut.change_account": "Change username or password",
+ "dashboard.shortcut.configure_ca": "Configure certificate authorities",
+
"dashboard.latest_workflow_runs": "Latest workflow runs",
"dashboard.latest_workflow_runs.nodata.description": "It looks like you don't have any runs. Get started by running a workflow.",
- "dashboard.latest_workflow_runs.nodata.button": "Go to workflows",
-
- "dashboard.quick_actions": "Quick actions",
- "dashboard.quick_actions.create_workflow": "Create workflow",
- "dashboard.quick_actions.change_password": "Change password",
- "dashboard.quick_actions.configure_ca": "Configure CA"
+ "dashboard.latest_workflow_runs.nodata.button": "Go to workflows"
}
diff --git a/ui/src/i18n/locales/zh/nls.dashboard.json b/ui/src/i18n/locales/zh/nls.dashboard.json
index 21a659c77..afe6e30c1 100644
--- a/ui/src/i18n/locales/zh/nls.dashboard.json
+++ b/ui/src/i18n/locales/zh/nls.dashboard.json
@@ -7,12 +7,12 @@
"dashboard.statistics.all_workflows": "所有工作流",
"dashboard.statistics.enabled_workflows": "已启用工作流",
+ "dashboard.shortcut": "快捷操作",
+ "dashboard.shortcut.create_workflow": "创建新的工作流",
+ "dashboard.shortcut.change_account": "修改登录账号密码",
+ "dashboard.shortcut.configure_ca": "配置证书颁发机构",
+
"dashboard.latest_workflow_runs": "最近运行的工作流",
"dashboard.latest_workflow_runs.nodata.description": "当前未找到任何工作流运行历史。请先运行一个工作流。",
- "dashboard.latest_workflow_runs.nodata.button": "前往工作流",
-
- "dashboard.quick_actions": "快捷操作",
- "dashboard.quick_actions.create_workflow": "新建工作流",
- "dashboard.quick_actions.change_password": "修改登录密码",
- "dashboard.quick_actions.configure_ca": "配置证书颁发机构"
+ "dashboard.latest_workflow_runs.nodata.button": "前往工作流"
}
diff --git a/ui/src/pages/dashboard/Dashboard.tsx b/ui/src/pages/dashboard/Dashboard.tsx
index adde54a69..426fd48a9 100644
--- a/ui/src/pages/dashboard/Dashboard.tsx
+++ b/ui/src/pages/dashboard/Dashboard.tsx
@@ -15,14 +15,14 @@ import {
IconShieldCheckered,
} from "@tabler/icons-react";
import { useRequest } from "ahooks";
-import { App, Button, Card, Col, Divider, Flex, Grid, Row, Skeleton, Table, type TableProps, Typography } from "antd";
+import { App, Button, Card, Col, Row, Skeleton, Table, type TableProps, Typography } from "antd";
import dayjs from "dayjs";
import { ClientResponseError } from "pocketbase";
import { get as getStatistics } from "@/api/statistics";
import Empty from "@/components/Empty";
import WorkflowRunDetailDrawer from "@/components/workflow/WorkflowRunDetailDrawer";
-import WorkflowStatusTag from "@/components/workflow/WorkflowStatusTag";
+import WorkflowStatus from "@/components/workflow/WorkflowStatus";
import { type Statistics } from "@/domain/statistics";
import { type WorkflowRunModel } from "@/domain/workflowRun";
import { useBrowserTheme } from "@/hooks";
@@ -35,8 +35,6 @@ const Dashboard = () => {
const { t } = useTranslation();
- const breakpoints = Grid.useBreakpoint();
-
return (
@@ -48,26 +46,25 @@ const Dashboard = () => {
-
+
+
{t("dashboard.shortcut")}
+
+ } shape="round" size="large" type="primary" onClick={() => navigate("/workflows/new")}>
+ {t("dashboard.shortcut.create_workflow")}
+
+ } shape="round" size="large" onClick={() => navigate("/settings/account")}>
+ {t("dashboard.shortcut.change_account")}
+
+ } shape="round" size="large" onClick={() => navigate("/settings/ssl-provider")}>
+ {t("dashboard.shortcut.configure_ca")}
+
+
+
-
-
-
- } onClick={() => navigate("/workflows/new")}>
- {t("dashboard.quick_actions.create_workflow")}
-
- } onClick={() => navigate("/settings/account")}>
- {t("dashboard.quick_actions.change_password")}
-
- } onClick={() => navigate("/settings/ssl-provider")}>
- {t("dashboard.quick_actions.configure_ca")}
-
-
-
-
-
-
-
+
+
{t("dashboard.latest_workflow_runs")}
+
+
);
@@ -268,7 +265,7 @@ const WorkflowRunHistoryTable = ({ className, style }: { className?: string; sty
key: "status",
title: t("workflow_run.props.status"),
render: (_, record) => {
- return
;
+ return
;
},
},
{
diff --git a/ui/src/pages/workflows/WorkflowDetailRuns.tsx b/ui/src/pages/workflows/WorkflowDetailRuns.tsx
index d8512dc78..b2a2469c6 100644
--- a/ui/src/pages/workflows/WorkflowDetailRuns.tsx
+++ b/ui/src/pages/workflows/WorkflowDetailRuns.tsx
@@ -11,7 +11,7 @@ import Empty from "@/components/Empty";
import Show from "@/components/Show";
import Tips from "@/components/Tips";
import WorkflowRunDetailDrawer from "@/components/workflow/WorkflowRunDetailDrawer";
-import WorkflowStatusTag from "@/components/workflow/WorkflowStatusTag";
+import WorkflowStatus from "@/components/workflow/WorkflowStatus";
import { WORKFLOW_TRIGGERS } from "@/domain/workflow";
import { WORKFLOW_RUN_STATUSES, type WorkflowRunModel } from "@/domain/workflowRun";
import { useAppSettings, useZustandShallowSelector } from "@/hooks";
@@ -52,7 +52,7 @@ const WorkflowDetailRuns = () => {
key: "status",
title: t("workflow_run.props.status"),
render: (_, record) => {
- return
;
+ return
;
},
},
{
diff --git a/ui/src/pages/workflows/WorkflowList.tsx b/ui/src/pages/workflows/WorkflowList.tsx
index 66f597f97..ec1f0be8d 100644
--- a/ui/src/pages/workflows/WorkflowList.tsx
+++ b/ui/src/pages/workflows/WorkflowList.tsx
@@ -10,7 +10,7 @@ import { ClientResponseError } from "pocketbase";
import { startRun as startWorkflowRun } from "@/api/workflows";
import Empty from "@/components/Empty";
import Show from "@/components/Show";
-import WorkflowStatusIcon from "@/components/workflow/WorkflowStatusIcon";
+import WorkflowStatus from "@/components/workflow/WorkflowStatus";
import { WORKFLOW_TRIGGERS, type WorkflowModel, cloneNode, initWorkflow, isAllNodesValidated } from "@/domain/workflow";
import { useAppSettings } from "@/hooks";
import { list as listWorkflows, remove as removeWorkflow, save as saveWorkflow } from "@/repository/workflow";
@@ -108,10 +108,9 @@ const WorkflowList = () => {
return <>>;
} else {
return (
-
-
- {lastRunTime ? dayjs(lastRunTime).format("YYYY-MM-DD HH:mm:ss") : ""}
-
+
+ {lastRunTime ? dayjs(lastRunTime).format("YYYY-MM-DD HH:mm:ss") : ""}
+
);
}
},