From 8365a64819b1e1b3b9889746030d44d66e47eb2c Mon Sep 17 00:00:00 2001 From: Alyssa Holland <2011hollanda@gmail.com> Date: Wed, 17 Sep 2025 15:52:39 +0100 Subject: [PATCH 1/2] feat: View plan details on hover --- webui/src/views/App.tsx | 71 +++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/webui/src/views/App.tsx b/webui/src/views/App.tsx index ba7d99999..e27b9f52a 100644 --- a/webui/src/views/App.tsx +++ b/webui/src/views/App.tsx @@ -9,8 +9,8 @@ import { LoadingOutlined, } from "@ant-design/icons"; import type { MenuProps } from "antd"; -import { Button, Empty, Layout, Menu, Spin, theme } from "antd"; -import { Config } from "../../gen/ts/v1/config_pb"; +import { Button, Empty, Layout, Menu, Spin, theme, Tooltip } from "antd"; +import { Config, Schedule } from "../../gen/ts/v1/config_pb"; import { useAlertApi } from "../components/Alerts"; import { useShowModal } from "../components/ModalManager"; import { uiBuildVersion } from "../state/buildcfg"; @@ -60,6 +60,35 @@ const RepoView = React.lazy(() => })) ); +// Sets the schedule string to something more readable +const getScheduleString = (schedule: Schedule | undefined) => { + switch (schedule?.schedule?.case) { + case "disabled": + return "Disabled" + + // Just display the cron string + case "cron": + return schedule?.schedule?.value + + // Running once per day, return 'Every day' instead of 'Every 1 days' + case "maxFrequencyDays": + return schedule?.schedule?.value == 1 ? "Every day" : `Every ${schedule?.schedule?.value} days` + + // Running once per hour, return 'Every hour' instead of 'Every 1 hours' + case "maxFrequencyHours": + return schedule?.schedule?.value == 1 ? "Every hour" : `Every ${schedule?.schedule?.value} hours` + } + return "Schedule Unavailable" // Defensive: In case there's an error with the schedule variable +} + +// Generate the text for the tooltip +const generatePlanHoverDetails = (repo: string, paths: any[], schedule: Schedule | undefined) => { + return `Repository: ${repo} + Schedule: ${getScheduleString(schedule)} + Paths: \n${paths.map(p => ` - ${p}`).join("\n")}`; // List paths on their own new line + }; + + const RepoViewContainer = () => { const { repoId } = useParams(); const [config, setConfig] = useConfig(); @@ -306,24 +335,26 @@ const getSidenavItems = (config: Config | null): MenuProps["items"] => { key: "p-" + plan.id, icon: , label: ( -
- {plan.id}{" "} -
+ {generatePlanHoverDetails(plan.repo, plan.paths, plan.schedule)}}> +
+ {plan.id}{" "} +
+
), onClick: async () => { navigate(`/plan/${plan.id}`); From b554e3a6c715f5d2cab45c949c1cdf85d2aa08a1 Mon Sep 17 00:00:00 2001 From: Alyssa Holland <2011hollanda@gmail.com> Date: Tue, 7 Oct 2025 10:33:09 +0100 Subject: [PATCH 2/2] feat: Limit number of paths shown on hover --- webui/src/views/App.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webui/src/views/App.tsx b/webui/src/views/App.tsx index e27b9f52a..163231d2b 100644 --- a/webui/src/views/App.tsx +++ b/webui/src/views/App.tsx @@ -83,9 +83,10 @@ const getScheduleString = (schedule: Schedule | undefined) => { // Generate the text for the tooltip const generatePlanHoverDetails = (repo: string, paths: any[], schedule: Schedule | undefined) => { + const maxPaths = 6; return `Repository: ${repo} Schedule: ${getScheduleString(schedule)} - Paths: \n${paths.map(p => ` - ${p}`).join("\n")}`; // List paths on their own new line + Paths: \n${paths.slice(0, maxPaths).map(p => ` - ${p}`).join("\n") + (paths.length > maxPaths ? `\n + ${paths.length - 6} more` : '')}`; };