Skip to content

Commit

Permalink
feat: add side panel for components checks list
Browse files Browse the repository at this point in the history
Closes #1332
  • Loading branch information
mainawycliffe committed Oct 12, 2023
1 parent 00534d4 commit 01f2d3d
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 1 deletion.
19 changes: 19 additions & 0 deletions src/api/services/topology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,3 +279,22 @@ export const getTopologySnapshot = async (
});
return res.data;
};

export type ComponentHealthCheckView = {
component_id: string;
id: string;
type: string;
name: string;
severity: string;
status: string;
check_component_relationships: {
check: Pick<HealthCheck, "id" | "name" | "type" | "icon">;
}[];
};

export const getComponentChecks = async (id: string) => {
const res = await IncidentCommander.get<ComponentHealthCheckView[]>(
`/checks_by_component?component_id=eq.${id}&select=*,check_component_relationships(check:checks(id,name,type,icon))`
);
return res.data;
};
1 change: 1 addition & 0 deletions src/components/Canary/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export function Table({
theadStyle = {},
...rest
}: TableProps) {
console.log({ data, columns });
const rowFinder = (row) => {
const rowValues =
row?.pivoted === true ? row[row.valueLookup] ?? null : row;
Expand Down
112 changes: 112 additions & 0 deletions src/components/TopologySidebar/ComponentChecks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useQuery } from "@tanstack/react-query";
import { useAtom } from "jotai";
import { useEffect } from "react";
import { AiFillHeart } from "react-icons/ai";
import { Link } from "react-router-dom";
import {
ComponentHealthCheckView,
getComponentChecks
} from "../../api/services/topology";
import PillBadge from "../Badge/PillBadge";
import CollapsiblePanel from "../CollapsiblePanel";
import EmptyState from "../EmptyState";
import TextSkeletonLoader from "../SkeletonLoader/TextSkeletonLoader";
import { refreshButtonClickedTrigger } from "../SlidingSideBar";
import { Status } from "../Status";
import Title from "../Title/title";
import { Icon } from "../Icon";

type ComponentCheckLinkProps = {
componentCheck: ComponentHealthCheckView;
};

export function ComponentCheckLink({
componentCheck: check
}: ComponentCheckLinkProps) {
return (
<Link
to={{
pathname: `/health`,
search: `?checkId=${check.id}&timeRange=1h`
}}
className={`flex flex-row justify-between w-full items-center space-x-2 p-2 rounded-md hover:bg-gray-100`}
>
<div className="flex flex-row gap-2 w-full items-center">
<div className="flex flex-row space-x-1 items-center flex-1text-sm ">
<Status good={check.status === "healthy"} />
<Icon
name={check.check_component_relationships[0].check.type}
icon={check.check_component_relationships[0].check.icon}
className="w-4 h-auto"
/>
<div className="overflow-hidden text-ellipsis flex-1">
{check.name}
</div>
</div>
</div>
</Link>
);
}

type Props = {
componentId: string;
isCollapsed?: boolean;
onCollapsedStateChange?: (isClosed: boolean) => void;
};

export function ComponentChecks({
componentId,
isCollapsed,
onCollapsedStateChange
}: Props) {
const {
data: componentChecks,
isLoading,
refetch,
isFetching
} = useQuery(
["component", "checks", componentId],
() => getComponentChecks(componentId),
{
enabled: !!componentId
}
);

const [triggerRefresh] = useAtom(refreshButtonClickedTrigger);

useEffect(() => {
if (!isLoading && !isFetching) {
refetch();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [triggerRefresh]);

return (
<CollapsiblePanel
isCollapsed={isCollapsed}
onCollapsedStateChange={onCollapsedStateChange}
Header={
<div className="flex flex-row w-full items-center space-x-2">
<Title title="Checks" icon={<AiFillHeart className="w-6 h-auto" />} />
<PillBadge>{componentChecks?.length ?? 0}</PillBadge>
</div>
}
dataCount={componentChecks?.length}
>
<div className="flex flex-col gap-4 w-full">
{isLoading ? (
<TextSkeletonLoader />
) : componentChecks && componentChecks.length > 0 ? (
componentChecks.map((componentCheck) => (
<ComponentCheckLink
key={componentCheck.id}
componentCheck={componentCheck}
/>
))
) : (
<EmptyState />
)}
</div>
</CollapsiblePanel>
);
}
12 changes: 11 additions & 1 deletion src/components/TopologySidebar/TopologySidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ComponentTeams } from "./ComponentTeams";
import TopologyActionBar from "./TopologyActionBar";
import TopologyCost from "./TopologyCost";
import TopologyInsights from "./TopologyInsights";
import { ComponentChecks } from "./ComponentChecks";

type Props = {
topology?: Topology;
Expand All @@ -26,7 +27,8 @@ type SidePanels =
| "ConfigChanges"
| "Teams"
| "Insights"
| "PlaybookRuns";
| "PlaybookRuns"
| "ComponentChecks";

export default function TopologySidebar({
topology,
Expand Down Expand Up @@ -95,6 +97,14 @@ export default function TopologySidebar({
}
/>

<ComponentChecks
componentId={id}
isCollapsed={openedPanel !== "ComponentChecks"}
onCollapsedStateChange={(status) =>
panelCollapsedStatusChange(status, "ComponentChecks")
}
/>

<PlaybookRunsSidePanel
panelType="topology"
componentId={id}
Expand Down

0 comments on commit 01f2d3d

Please sign in to comment.