Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"ag-charts-community": "^7.3.0",
"ag-charts-react": "^7.3.0",
"antd": "~4.10.3",
"axios": "^0.30.0",
"axios": "~1.9.0",
"classnames": "^2.3.2",
"echarts": "^5.5.0",
"filesize": "^6.4.0",
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class NavBar extends React.Component<INavBarProps> {
this.setState({
isLoading: false
});
showDataFetchError(error.toString());
showDataFetchError(error);
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import moment from 'moment';
import { notification } from 'antd';
import { CanceledError } from 'axios';
import axios, { CanceledError, AxiosError } from 'axios';

export const getCapacityPercent = (used: number, total: number) => Math.round((used / total) * 100);

Expand All @@ -43,16 +43,42 @@ export const showInfoNotification = (title: string, description: string) => {
notification.warn(args);
};

export const showDataFetchError = (error: string) => {
export const showDataFetchError = (error: string | AxiosError | unknown) => {
let title = 'Error while fetching data';
let errorMessage = '';

if (error.includes('CanceledError')) return;
if (error.includes('metadata')) {
title = 'Metadata Initialization:';
showInfoNotification(title, error);
return;
// Handle AxiosError instances
if (axios.isAxiosError(error)) {
// Don't show notifications for canceled requests
if (error.code === 'ERR_CANCELED' || error.name === 'CanceledError') {
return;
}

if (error.response) {
// Server responded with error status
errorMessage = `Server Error (${error.response.status}): ${error.response.statusText}`;
if (error.response.data && typeof error.response.data === 'string') {
errorMessage += ` - ${error.response.data}`;
}
} else if (error.request) {
// Request was made but no response received
errorMessage = 'Network Error: No response received from server';
} else {
// Something else happened
errorMessage = error.message || 'Unknown error occurred';
}
} else {
errorMessage = error as string;

if (errorMessage.includes('CanceledError')) return;
if (errorMessage.includes('metadata')) {
title = 'Metadata Initialization:';
showInfoNotification(title, errorMessage);
return;
}
}
showErrorNotification(title, error);

showErrorNotification(title, errorMessage);
};

export const byteToSize = (bytes: number, decimals: number) => {
Expand Down Expand Up @@ -106,12 +132,12 @@ export const checkResponseError = (responses: Awaited<Promise<any>>[]) => {

if (responseError.length !== 0) {
responseError.forEach((err) => {
if (err.reason.toString().includes("CanceledError")) {
if (err.reason instanceof CanceledError || err.reason.code === 'ERR_CANCELED') {
throw new CanceledError('canceled', "ERR_CANCELED");
}
else {
const reqMethod = err.reason.config.method;
const reqURL = err.reason.config.url
const reqMethod = err.reason.config?.method || 'unknown';
const reqURL = err.reason.config?.url || 'unknown URL';
showDataFetchError(
`Failed to ${reqMethod} URL ${reqURL}\n${err.reason.toString()}`
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,17 @@
* limitations under the License.
*/

import React, { useEffect } from 'react';
import { AxiosError } from 'axios';
import React from 'react';
import { Descriptions, Popover, Result } from 'antd';
import { SummaryData } from '@/v2/types/datanode.types';
import { AxiosGetHelper, cancelRequests } from '@/utils/axiosRequestHelper';
import { showDataFetchError } from '@/utils/common';
import { useApiData } from '@/v2/hooks/useAPIData.hook';
import Spin from 'antd/es/spin';

type DecommisioningSummaryProps = {
uuid: string;
}

type DecommisioningSummaryState = {
loading: boolean;
summaryData: SummaryData | Record<string, unknown>;
};

function getDescriptions(summaryData: SummaryData): React.ReactElement {
const {
Expand Down Expand Up @@ -67,59 +62,34 @@ function getDescriptions(summaryData: SummaryData): React.ReactElement {
const DecommissionSummary: React.FC<DecommisioningSummaryProps> = ({
uuid = ''
}) => {
const [state, setState] = React.useState<DecommisioningSummaryState>({
summaryData: {},
loading: false
});
const cancelSignal = React.useRef<AbortController>();
const {
data: decommissionResponse,
loading,
error
} = useApiData<{DatanodesDecommissionInfo: SummaryData[]}>(
`/api/v1/datanodes/decommission/info/datanode?uuid=${uuid}`,
{ DatanodesDecommissionInfo: [] },
{
onError: (error) => showDataFetchError(error)
}
);

const summaryData = decommissionResponse.DatanodesDecommissionInfo[0] || {};

let content = (
<Spin
size='large'
style={{ margin: '15px 15px 10px 15px' }} />
);

async function fetchDecommissionSummary(selectedUuid: string) {
setState({
...state,
loading: true
});
try {
const { request, controller } = AxiosGetHelper(
`/api/v1/datanodes/decommission/info/datanode?uuid=${selectedUuid}`,
cancelSignal.current
);
cancelSignal.current = controller;
const datanodesInfoResponse = await request;
setState({
...state,
loading: false,
summaryData: datanodesInfoResponse?.data?.DatanodesDecommissionInfo[0] ?? {}
});
} catch (error) {
setState({
...state,
loading: false,
summaryData: {}
});
showDataFetchError((error as AxiosError).toString());
content = (
<Result
status='error'
title='Unable to fetch Decommission Summary data'
className='decommission-summary-result' />
)
}
}

useEffect(() => {
fetchDecommissionSummary(uuid);
return (() => {
cancelRequests([cancelSignal.current!]);
})
}, []);

const { summaryData } = state;
if (summaryData?.datanodeDetails
if (error) {
content = (
<Result
status='error'
title='Unable to fetch Decommission Summary data'
className='decommission-summary-result' />
);
} else if (summaryData?.datanodeDetails
&& summaryData?.metrics
&& summaryData?.containers
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
* limitations under the License.
*/

import React, {useEffect, useRef, useState} from 'react';
import {AxiosResponse} from 'axios';
import React, {useEffect} from 'react';
import {Layout, Menu} from 'antd';
import {
BarChartOutlined,
Expand All @@ -36,7 +35,7 @@ import {Link, useLocation} from 'react-router-dom';

import logo from '@/logo.png';
import {showDataFetchError} from '@/utils/common';
import {AxiosGetHelper, cancelRequests} from '@/utils/axiosRequestHelper';
import {useApiData} from '@/v2/hooks/useAPIData.hook';

import './navBar.less';

Expand All @@ -51,34 +50,17 @@ const NavBar: React.FC<NavBarProps> = ({
collapsed = false,
onCollapse = () => { }
}) => {
const [isHeatmapEnabled, setIsHeatmapEnabled] = useState<boolean>(false);
const cancelDisabledFeatureSignal = useRef<AbortController>();
const location = useLocation();

const fetchDisabledFeatures = async () => {
const disabledfeaturesEndpoint = `/api/v1/features/disabledFeatures`;
const { request, controller } = AxiosGetHelper(
disabledfeaturesEndpoint,
cancelDisabledFeatureSignal.current
)
cancelDisabledFeatureSignal.current = controller;
try {
const response: AxiosResponse<string[]> = await request;
const heatmapDisabled = response?.data?.includes('HEATMAP')
setIsHeatmapEnabled(!heatmapDisabled);
} catch (error: unknown) {
showDataFetchError((error as Error).toString())

const { data: disabledFeatures, error } = useApiData<string[]>(
'/api/v1/features/disabledFeatures',
[],
{
onError: (error) => showDataFetchError(error)
}
}

);

useEffect(() => {
fetchDisabledFeatures();
// Component will unmount
return (() => {
cancelRequests([cancelDisabledFeatureSignal.current!])
})
}, [])
const isHeatmapEnabled = !disabledFeatures.includes('HEATMAP');

const menuItems = [(
<Menu.Item key='/Overview'
Expand Down
Loading