Skip to content

Commit e322b38

Browse files
committed
Enhance Observability components with empty state handling
- Introduce an empty state display for the Observability Dashboard and Overview components when no data is available. - Update AreaChart properties to improve visual representation, including color adjustments and conditional rendering based on data availability. - Refactor chart data handling to ensure proper fallback when no data is present.
1 parent 127398f commit e322b38

File tree

2 files changed

+124
-64
lines changed

2 files changed

+124
-64
lines changed

web/ee/src/components/pages/app-management/components/ObservabilityDashboardSection.tsx

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import {useMemo, type ComponentProps} from "react"
22

3+
import {ChartLine} from "@phosphor-icons/react"
34
import {AreaChart} from "@tremor/react"
45
import {Spin} from "antd"
56
import {createUseStyles} from "react-jss"
67

7-
import {
8-
formatCompactNumber,
9-
formatCurrency,
10-
formatLatency,
11-
formatNumber,
12-
} from "@/oss/lib/helpers/formatters"
8+
import {formatCompactNumber, formatCurrency, formatNumber} from "@/oss/lib/helpers/formatters"
139
import {JSSTheme} from "@/oss/lib/Types"
1410

1511
import {useObservabilityDashboard} from "../../../../state/observability"
@@ -23,6 +19,16 @@ const useStyles = createUseStyles((theme: JSSTheme) => ({
2319
width: "100%",
2420
},
2521
},
22+
emptyState: {
23+
display: "flex",
24+
alignItems: "center",
25+
justifyContent: "center",
26+
gap: 8,
27+
height: 140,
28+
29+
color: theme.colorTextTertiary,
30+
fontSize: 13,
31+
},
2632
statText: {
2733
display: "flex",
2834
alignItems: "center",
@@ -57,12 +63,13 @@ const ObservabilityDashboardSection = () => {
5763
const classes = useStyles()
5864
const {data, loading, isFetching} = useObservabilityDashboard()
5965

60-
const chartData = useMemo(() => (data?.data?.length ? data.data : [{}]), [data])
66+
const chartData = useMemo(() => (data?.data?.length ? data.data : []), [data])
67+
const hasData = (data?.total_count ?? 0) > 0
6168

6269
const defaultGraphProps = useMemo<ComponentProps<typeof AreaChart>>(
6370
() => ({
6471
className: "h-[140px]",
65-
colors: ["slate", "rose"],
72+
colors: ["cyan-600", "red"],
6673
connectNulls: true,
6774
tickGap: 20,
6875
curveType: "monotone",
@@ -79,6 +86,13 @@ const ObservabilityDashboardSection = () => {
7986
[chartData],
8087
)
8188

89+
const EmptyChart = () => (
90+
<div className={classes.emptyState}>
91+
<ChartLine size={18} />
92+
<span>No data</span>
93+
</div>
94+
)
95+
8296
return (
8397
<div className={classes.container}>
8498
<Spin spinning={loading || isFetching}>
@@ -107,14 +121,18 @@ const ObservabilityDashboardSection = () => {
107121
)
108122
}
109123
>
110-
<AreaChart
111-
{...defaultGraphProps}
112-
categories={
113-
(data?.failure_rate ?? 0) > 0
114-
? ["success_count", "failure_count"]
115-
: ["success_count"]
116-
}
117-
/>
124+
{hasData ? (
125+
<AreaChart
126+
{...defaultGraphProps}
127+
categories={
128+
(data?.failure_rate ?? 0) > 0
129+
? ["success_count", "failure_count"]
130+
: ["success_count"]
131+
}
132+
/>
133+
) : (
134+
<EmptyChart />
135+
)}
118136
</WidgetCard>
119137
</div>
120138
<div className="flex-1">
@@ -131,11 +149,15 @@ const ObservabilityDashboardSection = () => {
131149
</div>
132150
}
133151
>
134-
<AreaChart
135-
{...defaultGraphProps}
136-
categories={["latency"]}
137-
valueFormatter={(value) => `${formatCompactNumber(value)}ms`}
138-
/>
152+
{hasData ? (
153+
<AreaChart
154+
{...defaultGraphProps}
155+
categories={["latency"]}
156+
valueFormatter={(value) => `${formatCompactNumber(value)}ms`}
157+
/>
158+
) : (
159+
<EmptyChart />
160+
)}
139161
</WidgetCard>
140162
</div>
141163
<div className="flex-1">
@@ -158,12 +180,16 @@ const ObservabilityDashboardSection = () => {
158180
</div>
159181
}
160182
>
161-
<AreaChart
162-
{...defaultGraphProps}
163-
categories={["cost"]}
164-
colors={["emerald"]}
165-
valueFormatter={(value) => formatCurrency(value)}
166-
/>
183+
{hasData ? (
184+
<AreaChart
185+
{...defaultGraphProps}
186+
categories={["cost"]}
187+
colors={["cyan-600"]}
188+
valueFormatter={(value) => formatCurrency(value)}
189+
/>
190+
) : (
191+
<EmptyChart />
192+
)}
167193
</WidgetCard>
168194
</div>
169195
<div className="flex-1">
@@ -188,11 +214,15 @@ const ObservabilityDashboardSection = () => {
188214
</div>
189215
}
190216
>
191-
<AreaChart
192-
{...defaultGraphProps}
193-
categories={["total_tokens"]}
194-
colors={["emerald"]}
195-
/>
217+
{hasData ? (
218+
<AreaChart
219+
{...defaultGraphProps}
220+
categories={["total_tokens"]}
221+
colors={["cyan-600"]}
222+
/>
223+
) : (
224+
<EmptyChart />
225+
)}
196226
</WidgetCard>
197227
</div>
198228
</div>

web/ee/src/components/pages/overview/observability/ObservabilityOverview.tsx

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import {useMemo} from "react"
22

3+
import {ChartLine} from "@phosphor-icons/react"
34
import {AreaChart} from "@tremor/react"
45
import {Col, Row, Spin} from "antd"
56
import {createUseStyles} from "react-jss"
67

7-
import {
8-
formatCompactNumber,
9-
formatCurrency,
10-
formatLatency,
11-
formatNumber,
12-
} from "@/oss/lib/helpers/formatters"
8+
import {formatCompactNumber, formatCurrency, formatNumber} from "@/oss/lib/helpers/formatters"
139
import {JSSTheme} from "@/oss/lib/Types"
1410

1511
import {useObservabilityDashboard} from "../../../../state/observability"
@@ -21,6 +17,16 @@ const useStyles = createUseStyles((theme: JSSTheme) => ({
2117
rowGap: "20px !important",
2218
},
2319
},
20+
emptyState: {
21+
display: "flex",
22+
alignItems: "center",
23+
justifyContent: "center",
24+
gap: 8,
25+
height: 140,
26+
27+
color: theme.colorTextTertiary,
28+
fontSize: 13,
29+
},
2430
statText: {
2531
display: "flex",
2632
alignItems: "center",
@@ -44,12 +50,13 @@ const ObservabilityOverview = () => {
4450
const classes = useStyles()
4551
const {data, loading, isFetching} = useObservabilityDashboard()
4652

47-
const chartData = useMemo(() => (data?.data?.length ? data.data : [{}]), [data])
53+
const chartData = useMemo(() => (data?.data?.length ? data.data : []), [data])
54+
const hasData = (data?.total_count ?? 0) > 0
4855

4956
const defaultGraphProps = useMemo<React.ComponentProps<typeof AreaChart>>(
5057
() => ({
5158
className: "h-[140px]",
52-
colors: ["slate", "rose"],
59+
colors: ["cyan-600", "rose"],
5360
connectNulls: true,
5461
tickGap: 20,
5562
curveType: "monotone",
@@ -66,6 +73,13 @@ const ObservabilityOverview = () => {
6673
[chartData],
6774
)
6875

76+
const EmptyChart = () => (
77+
<div className={classes.emptyState}>
78+
<ChartLine size={18} />
79+
<span>No data</span>
80+
</div>
81+
)
82+
6983
return (
7084
<div className={classes.container}>
7185
<Spin spinning={loading || isFetching}>
@@ -94,14 +108,18 @@ const ObservabilityOverview = () => {
94108
)
95109
}
96110
>
97-
<AreaChart
98-
{...defaultGraphProps}
99-
categories={
100-
(data?.failure_rate ?? 0) > 0
101-
? ["success_count", "failure_count"]
102-
: ["success_count"]
103-
}
104-
/>
111+
{hasData ? (
112+
<AreaChart
113+
{...defaultGraphProps}
114+
categories={
115+
(data?.failure_rate ?? 0) > 0
116+
? ["success_count", "failure_count"]
117+
: ["success_count"]
118+
}
119+
/>
120+
) : (
121+
<EmptyChart />
122+
)}
105123
</WidgetCard>
106124
</Col>
107125
<Col span={12}>
@@ -118,11 +136,15 @@ const ObservabilityOverview = () => {
118136
</div>
119137
}
120138
>
121-
<AreaChart
122-
{...defaultGraphProps}
123-
categories={["latency"]}
124-
valueFormatter={(value) => `${formatCompactNumber(value)}ms`}
125-
/>
139+
{hasData ? (
140+
<AreaChart
141+
{...defaultGraphProps}
142+
categories={["latency"]}
143+
valueFormatter={(value) => `${formatCompactNumber(value)}ms`}
144+
/>
145+
) : (
146+
<EmptyChart />
147+
)}
126148
</WidgetCard>
127149
</Col>
128150
<Col span={12}>
@@ -145,12 +167,16 @@ const ObservabilityOverview = () => {
145167
</div>
146168
}
147169
>
148-
<AreaChart
149-
{...defaultGraphProps}
150-
categories={["cost"]}
151-
colors={["emerald"]}
152-
valueFormatter={(value) => formatCurrency(value)}
153-
/>
170+
{hasData ? (
171+
<AreaChart
172+
{...defaultGraphProps}
173+
categories={["cost"]}
174+
colors={["cyan-600"]}
175+
valueFormatter={(value) => formatCurrency(value)}
176+
/>
177+
) : (
178+
<EmptyChart />
179+
)}
154180
</WidgetCard>
155181
</Col>
156182
<Col span={12}>
@@ -175,11 +201,15 @@ const ObservabilityOverview = () => {
175201
</div>
176202
}
177203
>
178-
<AreaChart
179-
{...defaultGraphProps}
180-
categories={["total_tokens"]}
181-
colors={["emerald"]}
182-
/>
204+
{hasData ? (
205+
<AreaChart
206+
{...defaultGraphProps}
207+
categories={["total_tokens"]}
208+
colors={["cyan-600"]}
209+
/>
210+
) : (
211+
<EmptyChart />
212+
)}
183213
</WidgetCard>
184214
</Col>
185215
</Row>

0 commit comments

Comments
 (0)