Skip to content

Commit

Permalink
ADM-955: [frontend] change page loading status representation (#1478)
Browse files Browse the repository at this point in the history
* ADM-955: [frontend] feat: use loading flag to represent api loading status

* ADM-955: [frontend] feat: handle when report API is failed

* ADM-955: [frontend] feat: fix test

* ADM-955: [frontend] feat: refactor errors to loading status

* ADM-955: [frontend] feat: fix lint
  • Loading branch information
Mandy-Tang authored Jun 3, 2024
1 parent 930ad4a commit 6a0e387
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 175 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
nextStep,
updateMetricsPageFailedTimeRangeInfos,
updateReportPageFailedTimeRangeInfos,
updateMetricsPageLoadingStatus,
updateReportPageLoadingStatus,
} from '@src/context/stepper/StepperSlice';
import { formatDateToTimestampString, sortDateRanges } from '@src/utils/util';
import DateRangeViewer from '@src/components/Common/DateRangeViewer';
Expand All @@ -13,6 +13,19 @@ import { Provider } from 'react-redux';
import React from 'react';

const changeDateRange = jest.fn();
const loadedSuccess = { isLoading: false, isLoaded: true, isLoadedWithError: false };
const allMetricsPageDataLoadedSuccess = {
boardInfo: loadedSuccess,
pipelineInfo: loadedSuccess,
pipelineStep: loadedSuccess,
};
const allReportPageDataLoadedSuccess = {
gainPollingUrl: loadedSuccess,
polling: loadedSuccess,
boardMetrics: loadedSuccess,
pipelineMetrics: loadedSuccess,
sourceControlMetrics: loadedSuccess,
};

describe('DateRangeViewer', () => {
let store = setupStore();
Expand Down Expand Up @@ -77,18 +90,30 @@ describe('DateRangeViewer', () => {
const failedTimeRangeList = [
{
startDate: formatDateToTimestampString('2024-02-01T00:00:00.000+08:00'),
errors: { isBoardInfoError: true, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: {
boardInfo: { isLoading: false, isLoaded: true, isLoadedWithError: true },
pipelineInfo: loadedSuccess,
pipelineStep: loadedSuccess,
},
},
{
startDate: formatDateToTimestampString('2024-03-19T00:00:00.000+08:00'),
errors: { isBoardInfoError: false, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: {
boardInfo: loadedSuccess,
pipelineInfo: loadedSuccess,
pipelineStep: loadedSuccess,
},
},
{
startDate: formatDateToTimestampString('2024-04-01T00:00:00.000+08:00'),
errors: { isBoardInfoError: false, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: {
boardInfo: loadedSuccess,
pipelineInfo: loadedSuccess,
pipelineStep: loadedSuccess,
},
},
];
store.dispatch(updateMetricsPageFailedTimeRangeInfos(failedTimeRangeList));
store.dispatch(updateMetricsPageLoadingStatus(failedTimeRangeList));
const { getByLabelText } = setup(mockDateRanges);
expect(screen.getByTestId('PriorityHighIcon')).toBeInTheDocument();

Expand All @@ -100,18 +125,30 @@ describe('DateRangeViewer', () => {
const failedTimeRangeList = [
{
startDate: formatDateToTimestampString('2024-02-01T00:00:00.000+08:00'),
errors: { isBoardInfoError: undefined, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: {
boardInfo: { isLoading: true, isLoaded: false, isLoadedWithError: false },
pipelineInfo: loadedSuccess,
pipelineStep: loadedSuccess,
},
},
{
startDate: formatDateToTimestampString('2024-03-19T00:00:00.000+08:00'),
errors: { isBoardInfoError: false, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: {
boardInfo: loadedSuccess,
pipelineInfo: loadedSuccess,
pipelineStep: loadedSuccess,
},
},
{
startDate: formatDateToTimestampString('2024-04-01T00:00:00.000+08:00'),
errors: { isBoardInfoError: false, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: {
boardInfo: loadedSuccess,
pipelineInfo: loadedSuccess,
pipelineStep: loadedSuccess,
},
},
];
store.dispatch(updateMetricsPageFailedTimeRangeInfos(failedTimeRangeList));
store.dispatch(updateMetricsPageLoadingStatus(failedTimeRangeList));
const { getByLabelText } = setup(mockDateRanges);

expect(screen.getByLabelText('loading icon in date')).toBeInTheDocument();
Expand All @@ -124,18 +161,18 @@ describe('DateRangeViewer', () => {
const failedTimeRangeList = [
{
startDate: formatDateToTimestampString('2024-02-01T00:00:00.000+08:00'),
errors: { isBoardInfoError: false, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: allMetricsPageDataLoadedSuccess,
},
{
startDate: formatDateToTimestampString('2024-03-19T00:00:00.000+08:00'),
errors: { isBoardInfoError: false, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: allMetricsPageDataLoadedSuccess,
},
{
startDate: formatDateToTimestampString('2024-04-01T00:00:00.000+08:00'),
errors: { isBoardInfoError: false, isPipelineInfoError: false, isPipelineStepError: false },
loadingStatus: allMetricsPageDataLoadedSuccess,
},
];
store.dispatch(updateMetricsPageFailedTimeRangeInfos(failedTimeRangeList));
store.dispatch(updateMetricsPageLoadingStatus(failedTimeRangeList));
const { getByLabelText } = setup(mockDateRanges);

expect(screen.getByTestId('CheckIcon')).toBeInTheDocument();
Expand Down Expand Up @@ -179,15 +216,15 @@ describe('DateRangeViewer', () => {
const failedTimeRangeList = [
{
startDate: formatDateToTimestampString('2024-02-01T00:00:00.000+08:00'),
errors: { isGainPollingUrlError: false },
loadingStatus: allReportPageDataLoadedSuccess,
},
{
startDate: formatDateToTimestampString('2024-03-19T00:00:00.000+08:00'),
errors: { isPollingError: false },
loadingStatus: allReportPageDataLoadedSuccess,
},
];

store.dispatch(updateReportPageFailedTimeRangeInfos(failedTimeRangeList));
store.dispatch(updateReportPageLoadingStatus(failedTimeRangeList));
const { getByLabelText } = setup(mockDateRanges);

await userEvent.click(getByLabelText('expandMore'));
Expand All @@ -214,66 +251,56 @@ describe('DateRangeViewer', () => {
const failedTimeRangeList = [
{
startDate: formatDateToTimestampString('2024-02-01T00:00:00.000+08:00'),
errors: {
isBoardMetricsError: true,
isGainPollingUrlError: false,
isPipelineMetricsError: false,
isPollingError: false,
isSourceControlMetricsError: false,
loadingStatus: {
gainPollingUrl: loadedSuccess,
polling: loadedSuccess,
boardMetrics: { isLoading: false, isLoaded: true, isLoadedWithError: true },
pipelineMetrics: loadedSuccess,
sourceControlMetrics: loadedSuccess,
},
},
{
startDate: formatDateToTimestampString('2024-03-19T00:00:00.000+08:00'),
errors: {
isBoardMetricsError: false,
isGainPollingUrlError: true,
isPipelineMetricsError: false,
isPollingError: false,
isSourceControlMetricsError: false,
loadingStatus: {
gainPollingUrl: { isLoading: false, isLoaded: true, isLoadedWithError: true },
},
},
{
startDate: formatDateToTimestampString('2024-04-01T00:00:00.000+08:00'),
errors: {
isBoardMetricsError: false,
isGainPollingUrlError: false,
isPipelineMetricsError: true,
isPollingError: false,
isSourceControlMetricsError: false,
loadingStatus: {
gainPollingUrl: loadedSuccess,
polling: loadedSuccess,
boardMetrics: loadedSuccess,
pipelineMetrics: { isLoading: false, isLoaded: true, isLoadedWithError: true },
sourceControlMetrics: loadedSuccess,
},
},
{
startDate: formatDateToTimestampString('2023-02-01T00:00:00.000+08:00'),
errors: {
isBoardMetricsError: false,
isGainPollingUrlError: false,
isPipelineMetricsError: false,
isPollingError: true,
isSourceControlMetricsError: false,
loadingStatus: {
gainPollingUrl: loadedSuccess,
polling: { isLoading: false, isLoaded: true, isLoadedWithError: true },
boardMetrics: { isLoading: false, isLoaded: true, isLoadedWithError: true },
pipelineMetrics: { isLoading: false, isLoaded: true, isLoadedWithError: true },
sourceControlMetrics: { isLoading: false, isLoaded: true, isLoadedWithError: true },
},
},
{
startDate: formatDateToTimestampString('2023-03-19T00:00:00.000+08:00'),
errors: {
isBoardMetricsError: false,
isGainPollingUrlError: false,
isPipelineMetricsError: false,
isPollingError: false,
isSourceControlMetricsError: true,
loadingStatus: {
gainPollingUrl: loadedSuccess,
polling: loadedSuccess,
boardMetrics: loadedSuccess,
pipelineMetrics: loadedSuccess,
sourceControlMetrics: { isLoading: false, isLoaded: true, isLoadedWithError: true },
},
},
{
startDate: formatDateToTimestampString('2023-04-01T00:00:00.000+08:00'),
errors: {
isBoardMetricsError: false,
isGainPollingUrlError: false,
isPipelineMetricsError: false,
isPollingError: false,
isSourceControlMetricsError: false,
},
loadingStatus: allReportPageDataLoadedSuccess,
},
];
store.dispatch(updateReportPageFailedTimeRangeInfos(failedTimeRangeList));
store.dispatch(updateReportPageLoadingStatus(failedTimeRangeList));
const { getByLabelText } = setup(dateRangeList);
expect(screen.getByTestId('PriorityHighIcon')).toBeInTheDocument();

Expand Down
16 changes: 8 additions & 8 deletions frontend/__tests__/context/stepperSlice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ describe('stepper reducer', () => {
stepNumber: 0,
timeStamp: 0,
shouldMetricsLoaded: true,
metricsPageFailedTimeRangeInfos: {},
reportPageFailedTimeRangeInfos: {},
metricsPageTimeRangeLoadingStatus: {},
reportPageTimeRangeLoadingStatus: {},
},
nextStep(),
);
Expand All @@ -36,8 +36,8 @@ describe('stepper reducer', () => {
stepNumber: 0,
timeStamp: 0,
shouldMetricsLoaded: true,
metricsPageFailedTimeRangeInfos: {},
reportPageFailedTimeRangeInfos: {},
metricsPageTimeRangeLoadingStatus: {},
reportPageTimeRangeLoadingStatus: {},
},
backStep(),
);
Expand All @@ -51,8 +51,8 @@ describe('stepper reducer', () => {
stepNumber: 2,
timeStamp: 0,
shouldMetricsLoaded: true,
metricsPageFailedTimeRangeInfos: {},
reportPageFailedTimeRangeInfos: {},
metricsPageTimeRangeLoadingStatus: {},
reportPageTimeRangeLoadingStatus: {},
},
backStep(),
);
Expand All @@ -67,8 +67,8 @@ describe('stepper reducer', () => {
stepNumber: 2,
timeStamp: 0,
shouldMetricsLoaded: true,
metricsPageFailedTimeRangeInfos: {},
reportPageFailedTimeRangeInfos: {},
metricsPageTimeRangeLoadingStatus: {},
reportPageTimeRangeLoadingStatus: {},
},
updateTimeStamp(mockTime),
);
Expand Down
39 changes: 13 additions & 26 deletions frontend/src/components/Common/DateRangeViewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
StyledExpandMoreIcon,
} from './style';
import {
IMetricsPageFailedDateRange,
IReportPageFailedDateRange,
IMetricsPageLoadingStatus,
IReportPageLoadingStatus,
selectMetricsPageFailedTimeRangeInfos,
selectReportPageFailedTimeRangeInfos,
selectStepNumber,
Expand Down Expand Up @@ -42,8 +42,8 @@ const DateRangeViewer = ({
}: Props) => {
const [showMoreDateRange, setShowMoreDateRange] = useState(false);
const DateRangeExpandRef = useRef<HTMLDivElement>(null);
const metricsPageFailedTimeRangeInfos = useAppSelector(selectMetricsPageFailedTimeRangeInfos);
const reportPageFailedTimeRangeInfos = useAppSelector(selectReportPageFailedTimeRangeInfos);
const metricsPageTimeRangeLoadingStatus = useAppSelector(selectMetricsPageFailedTimeRangeInfos);
const reportPageTimeRangeLoadingStatus = useAppSelector(selectReportPageFailedTimeRangeInfos);
const stepNumber = useAppSelector(selectStepNumber);
const currentDateRange: DateRange = selectedDateRange || dateRangeList[0];
const isMetricsPage = stepNumber === STEP_NUMBER.METRICS_PAGE;
Expand Down Expand Up @@ -87,31 +87,18 @@ const DateRangeViewer = ({
}, [handleClickOutside]);

function getDateRangeStatus(startDate: string) {
let errorInfo: IMetricsPageFailedDateRange | IReportPageFailedDateRange;
const dateRangeStatus: { isLoading: boolean; isFailed: boolean } = { isLoading: false, isFailed: false };
let errorInfo: IMetricsPageLoadingStatus | IReportPageLoadingStatus;

if (isMetricsPage) {
errorInfo = metricsPageFailedTimeRangeInfos[startDate] || {};
if (
errorInfo.isBoardInfoError === undefined ||
errorInfo.isPipelineInfoError === undefined ||
errorInfo.isPipelineStepError === undefined
) {
dateRangeStatus.isLoading = true;
}
errorInfo = metricsPageTimeRangeLoadingStatus[startDate] || {};
} else {
errorInfo = reportPageFailedTimeRangeInfos[startDate] || {};
if (
errorInfo.isBoardMetricsError === undefined ||
errorInfo.isGainPollingUrlError === undefined ||
errorInfo.isPipelineMetricsError === undefined ||
errorInfo.isPollingError === undefined ||
errorInfo.isSourceControlMetricsError === undefined
) {
dateRangeStatus.isLoading = true;
}
errorInfo = reportPageTimeRangeLoadingStatus[startDate] || {};
}
dateRangeStatus.isFailed = Object.values(errorInfo).some((value) => value);
return dateRangeStatus;

return {
isLoading: Object.values(errorInfo).some(({ isLoading }) => isLoading),
isFailed: Object.values(errorInfo).some(({ isLoaded, isLoadedWithError }) => isLoaded && isLoadedWithError),
};
}

function getTotalDateRangeStatus() {
Expand Down
Loading

0 comments on commit 6a0e387

Please sign in to comment.