Skip to content

Commit a22d4b9

Browse files
committed
Improve UI and layout for pipeline overview loading states
- Center loading indicators in Average Duration, Status, and Number of Runs charts. - Isolate Victory Chart wrappers from flex utilities to maintain correct SVG scaling. - Conditionally render search and toggle controls in the list page so they only appear after data is loaded. Signed-off-by: Aditya Shinde <adishind@redhat.com> fix(ui): [SRVKP-11379] align loader and add dynamic chart heights * Added dynamic height and width calculations using useRef and ResizeObserver to make SVG charts fully responsive. * Solved the mobile layout bug where the loader was collapsing and not aligning properly within the container. * Ensured the loading spinner is now perfectly centered and aligned in every view (mobile, tablet, and desktop) by applying a dynamic minHeight matching the chart. * Dynamically scaled X-axis tick labels (font size, rotation angle, and padding) to prevent text overlap on smaller screens without dropping data points. Signed-off-by: Aditya Shinde <adishind@redhat.com> test: mock ResizeObserver to fix failing CI tests fix: centering loaders using useRef * Removed ResizeObserver completely. * Locked container heights dynamically to prevent the UI from collapsing or expanding when transitioning from the loading spinner to the chart. ref: remove inline css
1 parent 9da4653 commit a22d4b9

4 files changed

Lines changed: 60 additions & 24 deletions

File tree

src/components/pipelines-metrics/PipelinesAverageDuration.tsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { FC } from 'react';
2-
import { useState, useRef, useEffect } from 'react';
2+
import { useState, useRef, useEffect, useCallback } from 'react';
33
import _ from 'lodash';
44
import classNames from 'classnames';
55
import { useTranslation } from 'react-i18next';
@@ -38,7 +38,6 @@ interface PipelinesAverageDurationProps {
3838
parentName?: string;
3939
kind?: string;
4040
namespace?: string;
41-
width?: number;
4241
}
4342
type DomainType = { x?: DomainTuple; y?: DomainTuple };
4443

@@ -75,8 +74,7 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
7574
interval,
7675
parentName,
7776
namespace,
78-
kind,
79-
width = 530
77+
kind
8078
}) => {
8179
const { t } = useTranslation('plugin__pipelines-console-plugin');
8280
const isDevConsoleProxyAvailable = useFlag(FLAGS.DEVCONSOLE_PROXY);
@@ -93,6 +91,12 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
9391
x: domainX || [startDate, endDate],
9492
y: domainY || undefined,
9593
};
94+
const [chartWidth, setChartWidth] = useState(0);
95+
const chartContainerRef = useCallback((node: HTMLDivElement | null) => {
96+
if (node) {
97+
setChartWidth(node.clientWidth);
98+
}
99+
}, []);
96100

97101
if (namespace == ALL_NAMESPACES_KEY) {
98102
namespace = '-';
@@ -224,6 +228,7 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
224228
fontSize: 12,
225229
},
226230
};
231+
let bottomPad: number;
227232
if (tickValues.length > 7) {
228233
xAxisStyle = {
229234
tickLabels: {
@@ -234,7 +239,13 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
234239
verticalAnchor: 'end',
235240
},
236241
};
242+
bottomPad = 55;
243+
} else {
244+
bottomPad = 35;
237245
}
246+
if (showLabel) bottomPad += 15;
247+
// Calculating height using this formula with the help of width and bottom padding
248+
const chartHeight = 10 + Math.max(50, Math.min(100, Math.round(chartWidth / 5))) + bottomPad;
238249

239250
return (
240251
<>
@@ -261,7 +272,10 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
261272
className="pf-v6-u-mb-md pf-v6-u-ml-lg pf-v6-u-mt-lg"
262273
/>
263274
) : (
264-
<div className="pf-v6-u-flex-shrink-0">
275+
<div
276+
ref={chartContainerRef}
277+
className={`pf-v6-u-w-100 ${chartWidth > 0 ? 'pf-v6-u-h-100' : ''}`}
278+
>
265279
{loaded ? (
266280
<Chart
267281
containerComponent={
@@ -273,11 +287,11 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
273287
scale={{ x: 'time', y: 'linear' }}
274288
domain={domainValue}
275289
domainPadding={{ x: [30, 25] }}
276-
height={145}
277-
width={width}
290+
height={chartHeight}
291+
width={chartWidth}
278292
padding={{
279293
top: 10,
280-
bottom: 55,
294+
bottom: bottomPad,
281295
left: 50,
282296
right: 50,
283297
}}
@@ -299,7 +313,7 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
299313
</ChartGroup>
300314
</Chart>
301315
) : (
302-
<div className="pipeline-overview__number-of-plr-card__loading pf-v6-u-h-100">
316+
<div className="pf-v6-u-display-flex pf-v6-u-align-items-center pf-v6-u-justify-content-center pf-v6-u-h-100 pf-v6-u-p-md pf-v6-u-p-0-on-md">
303317
<LoadingInline />
304318
</div>
305319
)}
@@ -311,4 +325,4 @@ const PipelinesAverageDuration: FC<PipelinesAverageDurationProps> = ({
311325
);
312326
};
313327

314-
export default PipelinesAverageDuration;
328+
export default PipelinesAverageDuration;

src/components/pipelines-overview/PipelineRunsNumbersChart.tsx

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { FC } from 'react';
2-
import { useState, useRef, useEffect } from 'react';
2+
import { useState, useRef, useEffect, useCallback } from 'react';
33
import * as _ from 'lodash';
44
import classNames from 'classnames';
55
import { useTranslation } from 'react-i18next';
@@ -29,8 +29,6 @@ import { ALL_NAMESPACES_KEY } from '../../consts';
2929
import { getFilter, useInterval } from './utils';
3030
import { LoadingInline } from '../Loading';
3131

32-
import './PipelinesOverview.scss';
33-
3432
interface PipelinesRunsNumbersChartProps {
3533
namespace?: string;
3634
timespan?: number;
@@ -39,7 +37,6 @@ interface PipelinesRunsNumbersChartProps {
3937
parentName?: string;
4038
bordered?: boolean;
4139
kind?: string;
42-
width?: number;
4340
}
4441
type DomainType = { x?: DomainTuple; y?: DomainTuple };
4542

@@ -77,7 +74,6 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
7774
parentName,
7875
bordered,
7976
kind,
80-
width = 530,
8177
}) => {
8278
const { t } = useTranslation('plugin__pipelines-console-plugin');
8379
const isDevConsoleProxyAvailable = useFlag(FLAGS.DEVCONSOLE_PROXY);
@@ -96,6 +92,12 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
9692
string | undefined
9793
>();
9894
const abortControllerRef = useRef<AbortController>();
95+
const [chartWidth, setChartWidth] = useState(0);
96+
const chartContainerRef = useCallback((node: HTMLDivElement | null) => {
97+
if (node) {
98+
setChartWidth(node.clientWidth);
99+
}
100+
}, []);
99101

100102
if (namespace == ALL_NAMESPACES_KEY) {
101103
namespace = '-';
@@ -222,6 +224,7 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
222224
fontSize: 12,
223225
},
224226
};
227+
let bottomPad: number;
225228
if (tickValues.length > 7) {
226229
xAxisStyle = {
227230
tickLabels: {
@@ -232,7 +235,13 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
232235
verticalAnchor: 'end',
233236
},
234237
};
238+
bottomPad = 55;
239+
} else {
240+
bottomPad = 35;
235241
}
242+
if (showLabel) bottomPad += 15;
243+
// Calculating height using this formula with the help of width and bottom padding
244+
const chartHeight = 10 + Math.max(50, Math.min(100, Math.round(chartWidth / 5))) + bottomPad;
236245

237246
return (
238247
<>
@@ -260,7 +269,8 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
260269
/>
261270
) : (
262271
<div
263-
className="pf-v6-u-flex-shrink-0"
272+
ref={chartContainerRef}
273+
className={`pf-v6-u-w-100 ${chartWidth > 0 ? 'pf-v6-u-h-100' : ''}`}
264274
>
265275
{loaded ? (
266276
<Chart
@@ -273,11 +283,11 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
273283
scale={{ x: 'time', y: 'linear' }}
274284
domain={domainValue}
275285
domainPadding={{ x: [30, 25] }}
276-
height={145}
277-
width={width}
286+
height={chartHeight}
287+
width={chartWidth}
278288
padding={{
279289
top: 10,
280-
bottom: 55,
290+
bottom: bottomPad,
281291
left: 40,
282292
right: 50,
283293
}}
@@ -295,7 +305,7 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
295305
</ChartGroup>
296306
</Chart>
297307
) : (
298-
<div className="pipeline-overview__number-of-plr-card__loading pf-v6-u-pl-md pf-v6-u-h-100">
308+
<div className="pf-v6-u-display-flex pf-v6-u-align-items-center pf-v6-u-justify-content-center pf-v6-u-h-100 pf-v6-u-p-md pf-v6-u-p-0-on-md">
299309
<LoadingInline />
300310
</div>
301311
)}
@@ -307,4 +317,4 @@ const PipelinesRunsNumbersChart: FC<PipelinesRunsNumbersChartProps> = ({
307317
);
308318
};
309319

310-
export default PipelinesRunsNumbersChart;
320+
export default PipelinesRunsNumbersChart;

src/components/pipelines-overview/PipelineRunsStatusCard.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -482,12 +482,22 @@ const PipelinesRunsStatusCard: FC<PipelinesRunsStatusCardProps> = ({
482482
width={350}
483483
/>
484484
) : (
485-
<LoadingInline />
485+
<div className="pf-v6-u-display-flex pf-v6-u-align-items-center pf-v6-u-justify-content-center pf-v6-u-w-100">
486+
<LoadingInline />
487+
</div>
486488
)}
487489
</div>
488490
</GridItem>
489491
<GridItem xl2={8} xl={12} lg={12} md={12} sm={12}>
490-
<div className="pf-v6-u-display-flex pf-v6-u-align-items-flex-end pf-v6-u-h-100 pipeline-overview__chart-area">
492+
<div
493+
className={classNames(
494+
'pf-v6-u-display-flex pf-v6-u-h-100 pf-v6-u-w-100 pipeline-overview__chart-area',
495+
{
496+
'pf-v6-u-align-items-flex-end': loaded,
497+
'pf-v6-u-align-items-center pf-v6-u-justify-content-center': !loaded,
498+
}
499+
)}
500+
>
491501
{loaded ? (
492502
<Chart
493503
containerComponent={
@@ -540,4 +550,4 @@ const PipelinesRunsStatusCard: FC<PipelinesRunsStatusCardProps> = ({
540550
);
541551
};
542552

543-
export default PipelinesRunsStatusCard;
553+
export default PipelinesRunsStatusCard;

src/components/pipelines-overview/list-pages/PipelineRunsListPage.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ const PipelineRunsListPage: FC<PipelineRunsListPageProps> = ({
170170
/>
171171
) : (
172172
<>
173+
{loaded && (
173174
<Grid hasGutter className="pipeline-overview__listpage__grid">
174175
<GridItem
175176
span={9}
@@ -200,6 +201,7 @@ const PipelineRunsListPage: FC<PipelineRunsListPageProps> = ({
200201
</ToggleGroup>
201202
</GridItem>
202203
</Grid>
204+
)}
203205
<Grid hasGutter>
204206
<GridItem span={12}>
205207
{pageFlag === 1 ? (

0 commit comments

Comments
 (0)