diff --git a/src/components/Agents/AgentName.tsx b/src/components/Agents/AgentName.tsx
index bea874e9f..7c4ad069a 100644
--- a/src/components/Agents/AgentName.tsx
+++ b/src/components/Agents/AgentName.tsx
@@ -1,5 +1,6 @@
import { useQuery } from "@tanstack/react-query";
import { getAgentByID } from "../../api/services/topology";
+import { Badge } from "../Badge";
type TopologyCardAgentProps = {
agentId?: string;
@@ -18,5 +19,5 @@ export default function AgentName({ agentId }: TopologyCardAgentProps) {
return null;
}
- return
{agent.name}
;
+ return ;
}
diff --git a/src/components/CustomScroll/index.tsx b/src/components/CustomScroll/index.tsx
index 57c320e53..fec471a94 100644
--- a/src/components/CustomScroll/index.tsx
+++ b/src/components/CustomScroll/index.tsx
@@ -1,9 +1,9 @@
import clsx from "clsx";
-import React, { useEffect, useRef, useState } from "react";
+import React, { useEffect, useState } from "react";
export type CustomScrollProps = {
maxHeight: string;
- children: JSX.Element | JSX.Element[];
+ children: React.ReactNode;
showMoreClass?: string;
minChildCount: number;
} & React.HTMLProps;
diff --git a/src/components/HealthChecksSummary/index.tsx b/src/components/HealthChecksSummary/index.tsx
index 984c014bc..7e6a86503 100644
--- a/src/components/HealthChecksSummary/index.tsx
+++ b/src/components/HealthChecksSummary/index.tsx
@@ -3,7 +3,7 @@ import { AiFillHeart } from "react-icons/ai";
import { StatusLine, StatusLineProps } from "../StatusLine/StatusLine";
type HealthChecksSummaryProps = React.HTMLProps & {
- checks: {
+ checks?: {
health: number;
warning: number;
unhealthy: number;
diff --git a/src/components/HealthSummary/summary.tsx b/src/components/HealthSummary/summary.tsx
index 10179c665..49a92b3f9 100644
--- a/src/components/HealthSummary/summary.tsx
+++ b/src/components/HealthSummary/summary.tsx
@@ -4,22 +4,15 @@ import {
StatusLine,
StatusLineProps
} from "../StatusLine/StatusLine";
-
-type TopologyComponentProp = {
- id: string;
- name: string;
- icon: string;
- summary: { [key: string]: number };
- components?: TopologyComponentProp[];
-} & { [key: string]: any };
+import { Topology } from "../../context/TopologyPageContext";
type HealthSummaryProps = {
- component: TopologyComponentProp;
+ component: Topology;
iconSize?: "2xs" | "2xsi" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
viewType?: "individual_level" | "children_level";
} & React.HTMLProps;
-function getStatuses(summary: { [key: string]: number }, url?: string) {
+function getStatuses(summary?: { [key: string]: number }, url?: string) {
if (!summary) {
return [];
}
@@ -88,7 +81,7 @@ export const HealthSummary = ({
data.label = component.name;
data.url = `/topology/${component.id}`;
data.statuses = getStatuses(
- component.summary,
+ component?.summary,
`/topology/${component.id}`
);
} else {
diff --git a/src/components/TopologyCard/Property.tsx b/src/components/TopologyCard/Property.tsx
index 1b68c2b2d..0f29d6945 100644
--- a/src/components/TopologyCard/Property.tsx
+++ b/src/components/TopologyCard/Property.tsx
@@ -41,12 +41,12 @@ export function FormatProperty({
type PropertyProps = {
property: TopologyProperty;
-} & React.HTMLAttributes;
+} & Omit, "property">;
export const Property = ({
property,
className = "",
- ...rest
+ ...props
}: PropertyProps) => {
const { name, icon, color } = property;
const label =
@@ -65,7 +65,7 @@ export const Property = ({
{ [className]: className },
icon ? "flex-row" : "flex-col"
)}
- {...rest}
+ {...props}
>
{!isEmpty(label) && (
diff --git a/src/components/TopologyCard/TopologyCard.stories.tsx b/src/components/TopologyCard/TopologyCard.stories.tsx
index ef2848041..0d52ca280 100644
--- a/src/components/TopologyCard/TopologyCard.stories.tsx
+++ b/src/components/TopologyCard/TopologyCard.stories.tsx
@@ -3,6 +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";
const defaultQueryClient = new QueryClient();
@@ -21,11 +22,11 @@ export default {
]
} as ComponentMeta;
-const topology = {
+const topology: Topology = {
name: "abp",
id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
text: "ABP Microservices",
- topology_type: "component",
+ type: "component",
namespace: "dev",
labels: {
environment: "dev",
@@ -34,17 +35,18 @@ const topology = {
},
icon: "dotnet",
status: "unknown",
- type: "DotnetApplication",
summary: {},
properties: [
{
icon: "world",
type: "url",
- text: "https://docs.abp.io/en/abp/latest/Samples/Microservice-Demo"
+ text: "https://docs.abp.io/en/abp/latest/Samples/Microservice-Demo",
+ name: "Documentation"
},
{
icon: "aws",
- text: "eu-west-2"
+ text: "eu-west-2",
+ name: "Region"
},
{
name: "Products",
@@ -67,7 +69,7 @@ const topology = {
{
name: "Auth Server",
id: "01821200-3e6c-7cf0-ad2a-7ed31a924c25",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -75,19 +77,16 @@ const topology = {
},
icon: "dotnet",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.124908Z",
updated_at: "2022-07-18T15:49:42.124908Z",
- deleted_at: null,
external_id: "Auth Server"
},
{
name: "Website",
id: "01821200-3e8d-a787-89cc-49c9bc6841ec",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -95,19 +94,16 @@ const topology = {
},
icon: "dotnet",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.157617Z",
updated_at: "2022-07-18T15:49:42.157617Z",
- deleted_at: null,
external_id: "Website"
},
{
name: "Redis",
id: "01821200-3e93-0df7-f6ce-703a52423827",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -115,19 +111,16 @@ const topology = {
},
icon: "redis",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.163406Z",
updated_at: "2022-07-18T15:49:42.163406Z",
- deleted_at: null,
external_id: "Redis"
},
{
name: "RabbitMQ",
id: "01821200-3e98-cdd5-f081-bc3f93476705",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -135,19 +128,16 @@ const topology = {
},
icon: "rabbitmq",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.169415Z",
updated_at: "2022-07-18T15:49:42.169415Z",
- deleted_at: null,
external_id: "RabbitMQ"
},
{
name: "Mongo",
id: "01821200-3e9f-d054-115a-c818bf42168a",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -155,19 +145,16 @@ const topology = {
},
icon: "mongo",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.175625Z",
updated_at: "2022-07-18T15:49:42.175625Z",
- deleted_at: null,
external_id: "Mongo"
},
{
name: "Backend Admin",
id: "01821200-3e73-2612-7bed-623aba12935c",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -175,19 +162,16 @@ const topology = {
},
icon: "dotnet",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.131378Z",
updated_at: "2022-07-18T15:49:42.131378Z",
- deleted_at: null,
external_id: "Backend Admin"
},
{
name: "Blogging Service",
id: "01821200-3e7a-91aa-bd3e-b95147d33c9f",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -195,19 +179,16 @@ const topology = {
},
icon: "dotnet",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.138489Z",
updated_at: "2022-07-18T15:49:42.138489Z",
- deleted_at: null,
external_id: "Blogging Service"
},
{
name: "Identity Service",
id: "01821200-3e80-1713-425c-2cecf97a8f1f",
- topology_type: "component",
+ type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -215,19 +196,15 @@ const topology = {
},
icon: "dotnet",
path: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.14447Z",
updated_at: "2022-07-18T15:49:42.14447Z",
- deleted_at: null,
external_id: "Identity Service"
},
{
name: "Product Service",
id: "01821200-3e87-9569-3b9a-4e501ba092e9",
- topology_type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -238,16 +215,13 @@ const topology = {
type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.151638Z",
updated_at: "2022-07-18T15:49:42.151638Z",
- deleted_at: null,
external_id: "Product Service"
},
{
name: "SQL Server",
id: "01821200-3ea6-5708-843b-d84222a4d42d",
- topology_type: "component",
labels: {
environment: "dev",
"kustomize.toolkit.fluxcd.io/name": "aws-sandbox",
@@ -258,17 +232,13 @@ const topology = {
type: "Application",
summary: {},
parent_id: "01821200-3e60-0dbb-7ef3-58e1635bc8a6",
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.183071Z",
updated_at: "2022-07-18T15:49:42.183071Z",
- deleted_at: null,
external_id: "SQL Server"
}
],
- system_template_id: "01818abb-1d07-e0c6-cbe0-6b3b702039a5",
created_at: "2022-07-18T15:49:42.112918Z",
- updated_at: "2022-07-18T15:49:42.112918Z",
- deleted_at: null
+ updated_at: "2022-07-18T15:49:42.112918Z"
};
const Template: ComponentStory = (arg: any) => {
diff --git a/src/components/TopologyCard/index.tsx b/src/components/TopologyCard/index.tsx
index 2f8d10b09..f22f6d101 100644
--- a/src/components/TopologyCard/index.tsx
+++ b/src/components/TopologyCard/index.tsx
@@ -1,20 +1,21 @@
+import { useQuery } from "@tanstack/react-query";
import clsx from "clsx";
-import { filter } from "lodash";
-import { useEffect, useState, useMemo, MouseEventHandler } from "react";
+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";
+import { HealthChecksSummary } from "../HealthChecksSummary";
import { HealthSummary } from "../HealthSummary";
import { Icon } from "../Icon";
-import { HealthChecksSummary } from "../HealthChecksSummary";
-import { CardMetrics } from "./CardMetrics";
-import { Property } from "./Property";
-import { TopologyDropdownMenu } from "./TopologyDropdownMenu";
import IncidentCardSummary from "../IncidentCardSummary";
import TopologyCardSkeletonLoader from "../SkeletonLoader/TopologyCardSkeletonLoader";
+import { CardMetrics } from "./CardMetrics";
+import { Property } from "./Property";
import { TopologyConfigAnalysisLine } from "./TopologyConfigAnalysisLine";
-import AgentName from "../Agents/AgentName";
+import { TopologyDropdownMenu } from "./TopologyDropdownMenu";
export enum ComponentStatus {
unhealthy = "unhealthy",
@@ -34,9 +35,9 @@ export const StatusStyles: Record = {
};
interface IProps {
- size: Size | string;
+ size?: Size | string;
topologyId?: string;
- topology?: any;
+ topology?: Topology;
selectionMode?: boolean;
selected?: boolean;
onSelectionChange?: MouseEventHandler;
@@ -52,17 +53,18 @@ export function TopologyCard({
onSelectionChange,
isTopologyPage = false
}: IProps) {
- const [topology, setTopology] = useState(topologyData);
const [searchParams] = useSearchParams();
const { id: parentId } = useParams();
- useEffect(() => {
- if (topologyId != null && topologyData == null) {
- getTopology({ id: topologyId }).then(({ components }) =>
- setTopology(components?.[0])
- );
- }
- }, [topologyId, topologyData]);
+ const { data } = useQuery({
+ queryKey: ["topology", topologyId],
+ queryFn: () => getTopology({ id: topologyId }),
+ enabled: !!topologyId && topologyData == null
+ });
+
+ const topology = useMemo(() => {
+ return topologyData || data?.components?.[0];
+ }, [data, topologyData]);
let selectionModeRootProps = null;
@@ -85,7 +87,7 @@ export function TopologyCard({
topology.summary.unhealthy = topology.summary.unhealthy || 0;
topology.summary.warning = topology.summary.warning || 0;
Object.keys(topology.summary).forEach((key) => {
- totalCount += topology.summary[key];
+ totalCount += topology.summary?.[key];
});
}
return (
@@ -94,11 +96,7 @@ export function TopologyCard({
);
};
- const prepareTopologyLink = (topologyItem: {
- id: string;
- parent_id: string;
- path: string;
- }) => {
+ const prepareTopologyLink = (topologyItem: Topology) => {
if (topologyItem.id === parentId && parentId) {
return "";
}
@@ -125,8 +123,8 @@ export function TopologyCard({
}
topology.properties = topology.properties || [];
- const properties = filter(topology.properties, (i) => !i.headline);
- const heading = filter(topology.properties, (i) => i.headline);
+ const properties = topology.properties.filter((i) => !i.headline);
+ const heading = topology.properties.filter((i) => i.headline);
return (
-
-
+
@@ -157,13 +155,18 @@ export function TopologyCard({
)}
{!prepareTopologyLink(topology) &&
(topology.text || topology.name)}
-
-
- {topology.description && (
-
- {topology.description}
-
- )}
+
+
+
+ {topology.status_reason && (
+
+ {topology.status_reason}
+
+ )}
+
@@ -210,7 +213,7 @@ export function TopologyCard({
key={index}
property={property}
className={
- index === topology.properties.length - 1
+ index === topology.properties!.length - 1
? "mb-0"
: "mb-2.5"
}
diff --git a/src/context/TopologyPageContext.tsx b/src/context/TopologyPageContext.tsx
index 513fa3994..e85d6f064 100644
--- a/src/context/TopologyPageContext.tsx
+++ b/src/context/TopologyPageContext.tsx
@@ -32,6 +32,8 @@ export type Topology = {
icon?: string;
text?: string;
status?: string;
+ status_reason?: string;
+ namespace?: string;
hidden?: boolean;
external_id?: string;
agent_id?: string;
@@ -47,9 +49,17 @@ export type Topology = {
>;
[key: string]: any;
};
- logs: {
+ logs?: {
name: string;
}[];
- parents: string[];
- children: string[];
+ parents?: string[];
+ children?: string[];
+ is_leaf?: boolean;
+ description?: string;
+ checks?: {
+ health: number;
+ warning: number;
+ unhealthy: number;
+ };
+ deleted_at?: string;
} & CostsData;