ui: Add expandable scrape interval and timeout to targets page
Implements expand/collapse functionality for displaying final scrape configuration (interval + timeout) in the targets page timing column. - Add ScrapeDetails component with expand/collapse chevron - Keep existing "Last Scrape" and "Scrape Duration" badges always visible - Display "Scrape interval: every \<interval\>" and "Scrape timeout: after \<timeout\>" when expanded - Use IconRepeat for interval and IconPlugConnectedX for timeout - Follow TargetLabels.tsx pattern for consistency - Implement performance optimization with conditional DOM rendering - Maintain existing hover tooltip functionality Signed-off-by: ADITYATIWARI342005 <142050150+ADITYATIWARI342005@users.noreply.github.com>
This commit is contained in:
parent
c9e0e36701
commit
8eb8758925
|
@ -0,0 +1,109 @@
|
|||
import { FC } from "react";
|
||||
import { ActionIcon, Badge, Collapse, Group, Stack, Tooltip } from "@mantine/core";
|
||||
import { useDisclosure } from "@mantine/hooks";
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronUp,
|
||||
IconHourglass,
|
||||
IconPlugConnectedX,
|
||||
IconRefresh,
|
||||
IconRepeat,
|
||||
} from "@tabler/icons-react";
|
||||
import { humanizeDuration, humanizeDurationRelative, now } from "../../lib/formatTime";
|
||||
import { Target } from "../../api/responseTypes/targets";
|
||||
import badgeClasses from "../../Badge.module.css";
|
||||
import { actionIconStyle, badgeIconStyle } from "../../styles";
|
||||
|
||||
type ScrapeDetailsProps = {
|
||||
target: Target;
|
||||
};
|
||||
|
||||
const ScrapeDetails: FC<ScrapeDetailsProps> = ({ target }) => {
|
||||
const [showDetails, { toggle: toggleDetails }] = useDisclosure(false);
|
||||
|
||||
return (
|
||||
<Stack gap="xs">
|
||||
<Group wrap="nowrap" align="flex-start">
|
||||
<Group gap="xs" wrap="wrap">
|
||||
<Tooltip label="Last target scrape" withArrow>
|
||||
<Badge
|
||||
variant="light"
|
||||
className={badgeClasses.statsBadge}
|
||||
styles={{
|
||||
label: { textTransform: "none" },
|
||||
}}
|
||||
leftSection={<IconRefresh style={badgeIconStyle} />}
|
||||
>
|
||||
{humanizeDurationRelative(target.lastScrape, now())}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
label={
|
||||
<div style={{ lineHeight: 1.2 }}>
|
||||
<div>Interval: {target.scrapeInterval}</div>
|
||||
<div>Timeout: {target.scrapeTimeout}</div>
|
||||
</div>
|
||||
}
|
||||
withArrow
|
||||
>
|
||||
<Badge
|
||||
variant="light"
|
||||
className={badgeClasses.statsBadge}
|
||||
styles={{
|
||||
label: { textTransform: "none" },
|
||||
}}
|
||||
leftSection={<IconHourglass style={badgeIconStyle} />}
|
||||
>
|
||||
{humanizeDuration(target.lastScrapeDuration * 1000)}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
|
||||
<ActionIcon
|
||||
size="xs"
|
||||
color="gray"
|
||||
variant="light"
|
||||
onClick={toggleDetails}
|
||||
title={`${showDetails ? "Hide" : "Show"} scrape configuration details`}
|
||||
>
|
||||
{showDetails ? (
|
||||
<IconChevronUp style={actionIconStyle} />
|
||||
) : (
|
||||
<IconChevronDown style={actionIconStyle} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
|
||||
<Collapse in={showDetails}>
|
||||
{/* Additionally remove DOM elements when not expanded (helps performance) */}
|
||||
{showDetails && (
|
||||
<Group gap="xs" wrap="wrap">
|
||||
<Tooltip label="Scrape interval" withArrow>
|
||||
<Badge
|
||||
variant="light"
|
||||
className={badgeClasses.statsBadge}
|
||||
styles={{ label: { textTransform: "none" } }}
|
||||
leftSection={<IconRepeat style={badgeIconStyle} />}
|
||||
>
|
||||
every {target.scrapeInterval}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
<Tooltip label="Scrape timeout" withArrow>
|
||||
<Badge
|
||||
variant="light"
|
||||
className={badgeClasses.statsBadge}
|
||||
styles={{ label: { textTransform: "none" } }}
|
||||
leftSection={<IconPlugConnectedX style={badgeIconStyle} />}
|
||||
>
|
||||
after {target.scrapeTimeout}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
)}
|
||||
</Collapse>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default ScrapeDetails;
|
|
@ -8,23 +8,15 @@ import {
|
|||
Stack,
|
||||
Table,
|
||||
Text,
|
||||
Tooltip,
|
||||
} from "@mantine/core";
|
||||
import { KVSearch } from "@nexucis/kvsearch";
|
||||
import {
|
||||
IconAlertTriangle,
|
||||
IconHourglass,
|
||||
IconInfoCircle,
|
||||
IconRefresh,
|
||||
} from "@tabler/icons-react";
|
||||
import { useSuspenseAPIQuery } from "../../api/api";
|
||||
import { Target, TargetsResult } from "../../api/responseTypes/targets";
|
||||
import React, { FC, memo, useMemo } from "react";
|
||||
import {
|
||||
humanizeDurationRelative,
|
||||
humanizeDuration,
|
||||
now,
|
||||
} from "../../lib/formatTime";
|
||||
import { useLocalStorage } from "@mantine/hooks";
|
||||
import { useAppDispatch, useAppSelector } from "../../state/hooks";
|
||||
import {
|
||||
|
@ -37,8 +29,8 @@ import CustomInfiniteScroll from "../../components/CustomInfiniteScroll";
|
|||
import badgeClasses from "../../Badge.module.css";
|
||||
import panelClasses from "../../Panel.module.css";
|
||||
import TargetLabels from "./TargetLabels";
|
||||
import ScrapeDetails from "./ScrapeDetails";
|
||||
import { targetPoolDisplayLimit } from "./TargetsPage";
|
||||
import { badgeIconStyle } from "../../styles";
|
||||
|
||||
type ScrapePool = {
|
||||
targets: Target[];
|
||||
|
@ -332,52 +324,7 @@ const ScrapePoolList: FC<ScrapePoolListProp> = memo(
|
|||
/>
|
||||
</Table.Td>
|
||||
<Table.Td valign="top">
|
||||
<Group gap="xs" wrap="wrap">
|
||||
<Tooltip
|
||||
label="Last target scrape"
|
||||
withArrow
|
||||
>
|
||||
<Badge
|
||||
variant="light"
|
||||
className={badgeClasses.statsBadge}
|
||||
styles={{
|
||||
label: { textTransform: "none" },
|
||||
}}
|
||||
leftSection={
|
||||
<IconRefresh
|
||||
style={badgeIconStyle}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{humanizeDurationRelative(
|
||||
target.lastScrape,
|
||||
now()
|
||||
)}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
label="Duration of last target scrape"
|
||||
withArrow
|
||||
>
|
||||
<Badge
|
||||
variant="light"
|
||||
className={badgeClasses.statsBadge}
|
||||
styles={{
|
||||
label: { textTransform: "none" },
|
||||
}}
|
||||
leftSection={
|
||||
<IconHourglass
|
||||
style={badgeIconStyle}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{humanizeDuration(
|
||||
target.lastScrapeDuration * 1000
|
||||
)}
|
||||
</Badge>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
<ScrapeDetails target={target} />
|
||||
</Table.Td>
|
||||
<Table.Td valign="top">
|
||||
<Badge
|
||||
|
|
Loading…
Reference in New Issue