Skip to content

Commit

Permalink
feat: add embedded topology page
Browse files Browse the repository at this point in the history
  • Loading branch information
moshloop committed Oct 29, 2023
1 parent b0857f7 commit 2916426
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 26 deletions.
16 changes: 15 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { features } from "./services/permissions/features";
import { stringSortHelper } from "./utils/common";
import { MdOutlineSupportAgent } from "react-icons/md";
import AgentsPage from "./components/Agents/AgentPage";
import { TopologyCardPage } from "./pages/TopologyCard";

export type NavigationItems = {
name: string;
Expand Down Expand Up @@ -223,14 +224,27 @@ export function HealthRoutes({ sidebar }: { sidebar: ReactNode }) {
export function IncidentManagerRoutes({ sidebar }: { sidebar: ReactNode }) {
const { featureFlagsLoaded } = useFeatureFlagsContext();

if (!featureFlagsLoaded) {
console.log(window.location.pathname);
if (
!featureFlagsLoaded &&
!window.location.pathname.startsWith("/view/topology")
) {
return <FullPageSkeletonLoader />;
}

return (
<Routes>
<Route path="" element={<Navigate to="/topology" />} />

<Route
path="/view/topology/:id"
element={withAccessCheck(
<TopologyCardPage />,
tables.topologies,
"read"
)}
/>

<Route path="topology" element={sidebar}>
<Route
path=":id"
Expand Down
10 changes: 7 additions & 3 deletions src/components/Head/Head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import NextHead from "next/head";

interface Props {
prefix: string;
suffix?: string;
}

export function Head({ prefix }: Props) {
export function Head({ prefix, suffix = " | Mission Control" }: Props) {
return (
<NextHead>
<title>{prefix} | Mission Control</title>
<meta name="description" content={`${prefix} | Mission Control`} />
<title>
{prefix}
{suffix}
</title>
<meta name="description" content={`${prefix}${suffix}`} />
</NextHead>
);
}
4 changes: 3 additions & 1 deletion src/components/HealthChecksSummary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AiFillHeart } from "react-icons/ai";
import { StatusLine, StatusLineProps } from "../StatusLine/StatusLine";

type HealthChecksSummaryProps = React.HTMLProps<HTMLDivElement> & {
target?: string;
checks?: {
health: number;
warning: number;
Expand All @@ -12,6 +13,7 @@ type HealthChecksSummaryProps = React.HTMLProps<HTMLDivElement> & {

export function HealthChecksSummary({
checks,
target = "",
...rest
}: HealthChecksSummaryProps) {
const statusLineInfo = useMemo(() => {
Expand Down Expand Up @@ -53,5 +55,5 @@ export function HealthChecksSummary({
return null;
}

return <StatusLine {...statusLineInfo} {...rest} />;
return <StatusLine {...statusLineInfo} {...rest} target={target} />;
}
13 changes: 11 additions & 2 deletions src/components/IncidentCardSummary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ const chipColorFromSeverity = (
type IncidentSummaryTypes = keyof typeof typeItems;

type IncidentCardSummaryProps = {
target?: string;
topology: Pick<Topology, "summary" | "id">;
};

export default function IncidentCardSummary({
topology
topology,
target = ""
}: IncidentCardSummaryProps) {
const statusLines: StatusLineProps[] = useMemo(() => {
const incidentSummary = Object.entries(topology?.summary?.incidents || {});
Expand Down Expand Up @@ -75,7 +77,14 @@ export default function IncidentCardSummary({
return (
<>
{statusLines.map((statusLine, index) => {
return <StatusLine key={index} {...statusLine} className="" />;
return (
<StatusLine
key={index}
{...statusLine}
className=""
target={target}
/>
);
})}
</>
);
Expand Down
11 changes: 10 additions & 1 deletion src/components/StatusLine/StatusLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,20 @@ const renderIcon = (icon: string | React.ReactNode) => {
}
};

const StatusInfoEntry = ({ statusInfo }: { statusInfo: StatusInfo }) => {
const StatusInfoEntry = ({
statusInfo,
target
}: {
statusInfo: StatusInfo;
target?: string;
}) => {
if (statusInfo.url) {
return (
<Link
className="inline-flex space-x-1 cursor-pointer"
key={statusInfo.url}
to={statusInfo.url}
target={target || ""}
>
{statusInfo.icon && renderIcon(statusInfo.icon)}
<Chip text={statusInfo.label} color={statusInfo.color} />
Expand All @@ -55,6 +62,7 @@ const StatusInfoEntry = ({ statusInfo }: { statusInfo: StatusInfo }) => {

export function StatusLine({
icon,
target = "",
label,
url,
statuses,
Expand All @@ -70,6 +78,7 @@ export function StatusLine({
{url && (
<Link
title={label}
target={target || ""}
className="text-xs cursor-pointer h-4 overflow-hidden truncate"
to={url}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/TopologyCard/TopologyCard.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MemoryRouter } from "react-router-dom";
import { Size } from "../../types";
import { TopologyCard } from "./index";
import { Topology } from "../../context/TopologyPageContext";
import { Topology } from "../../api/types/topology";

const defaultQueryClient = new QueryClient();

Expand Down
6 changes: 4 additions & 2 deletions src/components/TopologyCard/TopologyConfigAnalysisLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ const severityToColorMap = (severity: string) => {
};

type TopologyConfigAnalysisLineProps = {
target?: string;
topology: Pick<Topology, "summary" | "id">;
};

export function TopologyConfigAnalysisLine({
topology
topology,
target = ""
}: TopologyConfigAnalysisLineProps) {
const insights = topology?.summary?.insights;

Expand Down Expand Up @@ -86,5 +88,5 @@ export function TopologyConfigAnalysisLine({
return null;
}

return <StatusLine {...analysis} className="" />;
return <StatusLine {...analysis} className="" target={target} />;
}
10 changes: 5 additions & 5 deletions src/components/TopologyCard/TopologyDropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ function TopologyMenuItem({
interface IProps {
topology: Topology;
onRefresh?: () => void;
isTopologyPage?: boolean;
position?: "fixed" | "absolute";
}

export const TopologyDropdownMenu = ({
topology,
onRefresh,
isTopologyPage = false
position = "fixed"
}: IProps) => {
const [dropDownMenuStyles, setDropDownMenuStyles] = useState<CSSProperties>();

Expand All @@ -62,13 +62,13 @@ export const TopologyDropdownMenu = ({
const top = node.getBoundingClientRect().bottom;

if (left && top) {
if (isTopologyPage) {
if (position === "absolute") {
setDropDownMenuStyles({
right: 0,
top: "1.5rem",
position: "absolute"
});
} else {
} else if (position === "fixed") {
setDropDownMenuStyles({
left: left - 200,
top: top,
Expand All @@ -77,7 +77,7 @@ export const TopologyDropdownMenu = ({
}
}
},
[isTopologyPage]
[position]
);

const [
Expand Down
24 changes: 15 additions & 9 deletions src/components/TopologyCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import clsx from "clsx";
import { MouseEventHandler, useMemo } from "react";
import { Link, useParams, useSearchParams } from "react-router-dom";
import { getTopology } from "../../api/services/topology";
import { Topology } from "../../context/TopologyPageContext";
import { Size } from "../../types";
import AgentName from "../Agents/AgentName";
import { CustomScroll } from "../CustomScroll";
Expand All @@ -16,6 +15,7 @@ import { CardMetrics } from "./CardMetrics";
import { Property } from "./Property";
import { TopologyConfigAnalysisLine } from "./TopologyConfigAnalysisLine";
import { TopologyDropdownMenu } from "./TopologyDropdownMenu";
import { Topology } from "../../api/types/topology";

export enum ComponentStatus {
unhealthy = "unhealthy",
Expand All @@ -39,19 +39,24 @@ interface IProps {
topologyId?: string;
topology?: Topology;
selectionMode?: boolean;
hideMenu?: boolean;
// where to open new links
target?: string;
selected?: boolean;
onSelectionChange?: MouseEventHandler<HTMLDivElement>;
isTopologyPage?: boolean;
menuPosition?: "fixed" | "absolute";
}

export function TopologyCard({
size,
topology: topologyData,
topologyId,
selectionMode,
target = "",
hideMenu,
selected,
onSelectionChange,
isTopologyPage = false
menuPosition = "fixed"
}: IProps) {
const [searchParams] = useSearchParams();
const { id: parentId } = useParams();
Expand Down Expand Up @@ -177,7 +182,7 @@ export function TopologyCard({
)}

<div className="flex ml-auto pl-1 pr-1.5 pb-3.5 pt-3">
{selectionMode ? (
{selectionMode && (
<div className="pr-1.5 pt-1 flex min-w-7 justify-end items-start">
<input
type="checkbox"
Expand All @@ -186,11 +191,10 @@ export function TopologyCard({
readOnly
/>
</div>
) : (
<TopologyDropdownMenu
topology={topology}
isTopologyPage={isTopologyPage}
/>
)}

{!selectionMode && !hideMenu && (
<TopologyDropdownMenu topology={topology} position={menuPosition} />
)}
</div>
</div>
Expand Down Expand Up @@ -231,6 +235,7 @@ export function TopologyCard({
{canShowChildHealth() && (
<HealthSummary
className=""
target={target}
key={topology.id}
component={topology}
/>
Expand All @@ -240,6 +245,7 @@ export function TopologyCard({
{topology?.components?.map((component: any) => (
<HealthSummary
className=""
target={target}
key={component.id}
component={component}
/>
Expand Down
35 changes: 35 additions & 0 deletions src/pages/TopologyCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useQuery } from "@tanstack/react-query";
import { useParams } from "react-router-dom";
import { getTopology } from "../api/services/topology";
import { TopologyCard } from "../components/TopologyCard";
import { Head } from "../components/Head/Head";
import { InfoMessage } from "../components/InfoMessage";

export function TopologyCardPage() {
const { id, size } = useParams();

const { data } = useQuery({
queryKey: ["topology", id],
queryFn: () => getTopology({ id: id })
});

if (!data || !data.components || data.components?.length === 0) {
return <InfoMessage message="Component not found" />;
}

const topology = data.components[0];
return (
<>
<Head prefix={topology.name || ""} suffix=""></Head>

<div className="m-2">
<TopologyCard
topology={topology}
size={size || "large"}
target="_blank"
hideMenu
/>
</div>
</>
);
}
3 changes: 2 additions & 1 deletion src/pages/TopologyPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export function TopologyPage() {
const refererId = searchParams.get("refererId") ?? undefined;
const sortBy = searchParams.get("sortBy") ?? undefined;
const sortOrder = searchParams.get("sortOrder") ?? undefined;
const hideFilters = searchParams.get("hideFilters") ?? undefined;
const showHiddenComponents =
searchParams.get("showHiddenComponents") ?? undefined;

Expand Down Expand Up @@ -230,7 +231,7 @@ export function TopologyPage() {
key={item.id}
topology={item}
size={topologyCardSize}
isTopologyPage
menuPosition="absolute"
/>
))}
{!topology?.length && !isLoading && (
Expand Down

0 comments on commit 2916426

Please sign in to comment.