Skip to content

Commit 99a28d8

Browse files
committed
fix: show two columns, when the other one is empty
fix: show two columns when no none headline properties chore: remove console.log chore: update spacing fix: show two property columns when no analytics fix: fix issues with cards styling fix: scroll issues
1 parent 0f8dbd4 commit 99a28d8

File tree

7 files changed

+92
-71
lines changed

7 files changed

+92
-71
lines changed

src/components/Canary/HealthChecksSummary.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function HealthChecksSummary({
2323

2424
const data: StatusLineProps = {
2525
label: "Health Checks",
26-
icon: <AiFillHeart className="mr-1 inline-block h-3.5 w-3.5" />,
26+
icon: <AiFillHeart className="inline-block h-4 w-4" />,
2727
url: "/health",
2828
statuses: [
2929
...(checks.healthy > 0

src/components/StatusLine/StatusLine.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,21 @@ export type StatusLineData = {
2020

2121
export type StatusLineProps = React.HTMLProps<HTMLDivElement> & StatusLineData;
2222

23-
const renderIcon = (icon: string | React.ReactNode) => {
23+
interface RenderIconProps {
24+
icon: string | React.ReactNode;
25+
}
26+
27+
const RenderIcon: React.FC<RenderIconProps> = ({ icon }) => {
2428
if (!icon) {
2529
return null;
2630
}
2731
if (typeof icon === "object") {
28-
return icon;
32+
// eslint-disable-next-line react/jsx-no-useless-fragment
33+
return <>{icon}</>;
2934
} else if (typeof icon === "string") {
30-
return <Icon name={icon} className="h-4 w-4" />;
35+
return <Icon name={icon} className="h-4 w-4 min-w-max" />;
3136
}
37+
return null;
3238
};
3339

3440
const StatusInfoEntry = ({
@@ -46,14 +52,14 @@ const StatusInfoEntry = ({
4652
to={statusInfo.url}
4753
target={target || ""}
4854
>
49-
{statusInfo.icon && renderIcon(statusInfo.icon)}
55+
{statusInfo.icon && <RenderIcon icon={statusInfo.icon} />}
5056
<Chip text={statusInfo.label} color={statusInfo.color} />
5157
</Link>
5258
);
5359
} else {
5460
return (
5561
<span className="inline-flex cursor-pointer space-x-1">
56-
{statusInfo.icon && renderIcon(statusInfo.icon)}
62+
{statusInfo.icon && <RenderIcon icon={statusInfo.icon} />}
5763
<Chip text={statusInfo.label} color={statusInfo.color} />
5864
</span>
5965
);
@@ -74,7 +80,7 @@ export function StatusLine({
7480
className={clsx("flex flex-row items-center space-x-1", className)}
7581
{...rest}
7682
>
77-
{icon && renderIcon(icon)}
83+
{icon && <RenderIcon icon={icon} />}
7884
{url && (
7985
<Link
8086
title={label}

src/components/Topology/TopologyCard/CardMetrics.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ export const CardMetrics = ({
2424
labelClasses = "text-gray-600 font-semibold text-xs mb-0.5",
2525
metricsClasses = "font-bold text-xs leading-1.21rel flex flex-center justify-center"
2626
}: IProps) => {
27+
if (!items || items.length === 0) {
28+
return null;
29+
}
30+
2731
return (
2832
<div className="flex flex-1 items-center justify-between divide-x rounded-b-8px">
2933
{items.map((item) => (

src/components/Topology/TopologyCard/TopologyCard.tsx

Lines changed: 65 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,6 @@ export function TopologyCard({
8585
[size]
8686
);
8787

88-
const canShowChildHealth = () => {
89-
let totalCount = 0;
90-
if (topology?.summary?.checks) {
91-
topology.summary.checks.healthy = topology.summary.checks.healthy || 0;
92-
topology.summary.checks.unhealthy =
93-
topology.summary.checks.unhealthy || 0;
94-
topology.summary.checks.warning = topology.summary.checks.warning || 0;
95-
Object.keys(topology.summary.checks).forEach((key) => {
96-
totalCount +=
97-
topology.summary?.checks?.[key as keyof Topology["summary"]] || 0;
98-
});
99-
}
100-
return (
101-
!topology?.components?.length &&
102-
(!topology?.is_leaf || (topology.is_leaf && totalCount !== 1))
103-
);
104-
};
105-
10688
const prepareTopologyLink = (topologyItem: Topology) => {
10789
if (topologyItem.id === parentId && parentId) {
10890
return "";
@@ -143,22 +125,49 @@ export function TopologyCard({
143125
[topology?.components]
144126
);
145127

128+
const { heading, properties, isPropertiesPanelEmpty } = useMemo(() => {
129+
const allProperties = topology?.properties || [];
130+
const properties = allProperties.filter((i) => !i.headline);
131+
132+
const heading = allProperties.filter(
133+
(i) => i.headline && (!!i.value || !!i.text || !!i.url)
134+
);
135+
136+
const isPropertiesPanelShown =
137+
properties.filter(
138+
(i) => !i.headline && i.type !== "hidden" && (i.text || i.value)
139+
).length > 0;
140+
141+
return {
142+
heading,
143+
properties,
144+
isPropertiesPanelEmpty: !isPropertiesPanelShown
145+
};
146+
}, [topology?.properties]);
147+
148+
const isAnalyticsPanelEmpty = useMemo(() => {
149+
// if there are no insights, checks or components, we don't need to show the
150+
// second panel at all
151+
return (
152+
!topology?.summary?.insights &&
153+
!topology?.summary?.checks &&
154+
(sortedTopologyComponents ?? []).length === 0
155+
);
156+
}, [
157+
sortedTopologyComponents,
158+
topology?.summary?.checks,
159+
topology?.summary?.insights
160+
]);
161+
146162
if (topology == null) {
147163
return <TopologyCardSkeletonLoader />;
148164
}
149165

150-
const allProperties = topology.properties || [];
151-
const properties = allProperties.filter((i) => !i.headline);
152-
153-
const heading = allProperties.filter(
154-
(i) => i.headline && (!!i.value || !!i.text || !!i.url)
155-
);
156-
157166
return (
158167
<div
159168
style={{ width: CardWidth[size as Size] || size }}
160169
className={clsx(
161-
"card relative mb-3 mr-3 rounded-8px border-0 border-t-8 bg-lightest-gray shadow-card",
170+
"card relative mb-3 mr-3 overflow-hidden rounded-8px border-0 border-t-8 bg-lightest-gray shadow-card",
162171
StatusStyles[topology.status as ComponentStatus] || "border-white",
163172
selectionMode ? "cursor-pointer" : ""
164173
)}
@@ -224,42 +233,43 @@ export function TopologyCard({
224233
</div>
225234
</div>
226235
<div className="flex flex-nowrap space-x-4 rounded-b-8px bg-lightest-gray">
227-
{metricsInFooter ? (
236+
{metricsInFooter && heading.length > 0 ? (
228237
<div className="flex flex-1 py-4">
229238
<CardMetrics items={heading} />
230239
</div>
231240
) : (
232241
<>
233-
<TopologyCardPropertiesColumn properties={properties} />
234-
<CustomScroll
235-
className="flex-1 space-y-1.5 py-2 pl-2 pr-2"
236-
showMoreClass="text-xs linear-1.21rel mr-1 cursor-pointer"
237-
maxHeight="200px"
238-
minChildCount={5}
239-
>
240-
<TopologyConfigAnalysisLine topology={topology} />
241-
{canShowChildHealth() && (
242-
<HealthSummary
243-
className=""
244-
target={target}
245-
key={topology.id}
246-
component={topology}
247-
/>
248-
)}
249-
<HealthChecksSummary
250-
checks={topology?.summary?.checks}
251-
className=""
252-
/>
253-
{topology?.id && <IncidentCardSummary topology={topology} />}
254-
{sortedTopologyComponents?.map((component: any) => (
255-
<HealthSummary
242+
<TopologyCardPropertiesColumn
243+
displayTwoColumns={isAnalyticsPanelEmpty}
244+
properties={properties}
245+
/>
246+
{!isAnalyticsPanelEmpty && (
247+
<CustomScroll
248+
className={clsx(
249+
"flex-1 py-2 pl-2 pr-2",
250+
isPropertiesPanelEmpty ? "grid grid-cols-2 gap-1" : ""
251+
)}
252+
showMoreClass="text-xs linear-1.21rel mr-1 cursor-pointer"
253+
maxHeight="200px"
254+
// When we showing two columns, we need to show more items
255+
minChildCount={isPropertiesPanelEmpty ? 5 : 10}
256+
>
257+
<TopologyConfigAnalysisLine topology={topology} />
258+
<HealthChecksSummary
259+
checks={topology?.summary?.checks}
256260
className=""
257-
target={target}
258-
key={component.id}
259-
component={component}
260261
/>
261-
))}
262-
</CustomScroll>
262+
{sortedTopologyComponents?.map((component: any) => (
263+
<HealthSummary
264+
className=""
265+
target={target}
266+
key={component.id}
267+
component={component}
268+
/>
269+
))}
270+
{topology?.id && <IncidentCardSummary topology={topology} />}
271+
</CustomScroll>
272+
)}
263273
</>
264274
)}
265275
</div>

src/components/Topology/TopologyCard/TopologyCardPropertiesColumn.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { Property } from "@flanksource-ui/api/types/topology";
22
import { CustomScroll } from "@flanksource-ui/ui/CustomScroll";
3+
import clsx from "clsx";
34
import { PropertyDisplay } from "./Property";
45

56
type TopologyCardPropertiesColumnProps = {
67
properties: Property[];
8+
displayTwoColumns?: boolean;
79
};
810

911
export default function TopologyCardPropertiesColumn({
10-
properties
12+
properties,
13+
displayTwoColumns = false
1114
}: TopologyCardPropertiesColumnProps) {
1215
// Filter out properties that are hidden, have no text or value, and are not a
1316
// headline property.
@@ -21,7 +24,10 @@ export default function TopologyCardPropertiesColumn({
2124

2225
return (
2326
<CustomScroll
24-
className="flex-1 py-2 pl-2"
27+
className={clsx(
28+
"flex-1 py-2 pl-2",
29+
displayTwoColumns ? "grid grid-cols-2" : ""
30+
)}
2531
showMoreClass="text-xs linear-1.21rel mr-1 cursor-pointer"
2632
maxHeight="200px"
2733
minChildCount={6}

src/components/Topology/TopologyCard/Utils/FormatProperties.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ type FormatPropertyProps = {
1414
};
1515

1616
export function FormatPropertyURL({ property }: FormatPropertyProps) {
17-
console.log("property", property);
1817
if (property == null) {
1918
return null;
2019
}

src/ui/CustomScroll/index.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ export const CustomScroll = ({
3434

3535
return (
3636
<div
37-
className={clsx(
38-
"relative overflow-hidden",
39-
className,
40-
hasScroll && !showMore ? "hover:overflow-y-scroll" : ""
41-
)}
37+
className={clsx("relative overflow-y-auto", className)}
4238
style={{ ...style, maxHeight, height: "min-content" }}
4339
{...rest}
4440
>
@@ -51,7 +47,7 @@ export const CustomScroll = ({
5147
setShowMore(false);
5248
}}
5349
className={clsx(
54-
"bottom-0 m-auto w-full hover:underline",
50+
"bottom-0 col-span-2 m-auto w-full hover:underline",
5551
showMoreClass
5652
)}
5753
>

0 commit comments

Comments
 (0)