refactor: antdv5 notfications (#2161)

Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: Nitesh Singh <nitesh.singh@gitstart.dev>
Co-authored-by: gitstart-app[bot] <57568882+gitstart-app[bot]@users.noreply.github.com>
Co-authored-by: Rubens Rafael <70234898+RubensRafael@users.noreply.github.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
Co-authored-by: niteshsingh1357 <niteshsingh1357@gmail.com>
Co-authored-by: gitstart_bot <gitstart_bot@users.noreply.github.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
GitStart 2023-02-02 14:08:32 +08:00 committed by GitHub
parent 17f32e9765
commit 846da08cbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 744 additions and 539 deletions

View File

@ -47,6 +47,8 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
const dispatch = useDispatch<Dispatch<AppActions>>(); const dispatch = useDispatch<Dispatch<AppActions>>();
const [notifications, NotificationElement] = notification.useNotification();
const currentRoute = mapRoutes.get('current'); const currentRoute = mapRoutes.get('current');
const navigateToLoginIfNotLoggedIn = (isLoggedIn = isLoggedInState): void => { const navigateToLoginIfNotLoggedIn = (isLoggedIn = isLoggedInState): void => {
@ -106,7 +108,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
} else { } else {
Logout(); Logout();
notification.error({ notifications.error({
message: response.error || t('something_went_wrong'), message: response.error || t('something_went_wrong'),
}); });
} }
@ -155,7 +157,12 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
// NOTE: disabling this rule as there is no need to have div // NOTE: disabling this rule as there is no need to have div
// eslint-disable-next-line react/jsx-no-useless-fragment // eslint-disable-next-line react/jsx-no-useless-fragment
return <>{children}</>; return (
<>
{NotificationElement}
{children}
</>
);
} }
interface PrivateRouteProps { interface PrivateRouteProps {

View File

@ -7,14 +7,14 @@ function CopyClipboardHOC({
children, children,
}: CopyClipboardHOCProps): JSX.Element { }: CopyClipboardHOCProps): JSX.Element {
const [value, setCopy] = useCopyToClipboard(); const [value, setCopy] = useCopyToClipboard();
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (value.value) { if (value.value) {
notification.success({ notifications.success({
message: 'Copied to clipboard', message: 'Copied to clipboard',
}); });
} }
}, [value]); }, [value, notifications]);
const onClick = useCallback((): void => { const onClick = useCallback((): void => {
setCopy(textToCopy); setCopy(textToCopy);
@ -22,6 +22,7 @@ function CopyClipboardHOC({
return ( return (
<span onClick={onClick} onKeyDown={onClick} role="button" tabIndex={0}> <span onClick={onClick} onKeyDown={onClick} role="button" tabIndex={0}>
{NotificationElement}
<Popover <Popover
placement="top" placement="top"
content={<span style={{ fontSize: '0.9rem' }}>Copy to clipboard</span>} content={<span style={{ fontSize: '0.9rem' }}>Copy to clipboard</span>}

View File

@ -79,6 +79,7 @@ function LogItem({ logData }: LogItemProps): JSX.Element {
const dispatch = useDispatch(); const dispatch = useDispatch();
const flattenLogData = useMemo(() => FlatLogData(logData), [logData]); const flattenLogData = useMemo(() => FlatLogData(logData), [logData]);
const [, setCopy] = useCopyToClipboard(); const [, setCopy] = useCopyToClipboard();
const [notifications, NotificationElement] = notification.useNotification();
const handleDetailedView = useCallback(() => { const handleDetailedView = useCallback(() => {
dispatch({ dispatch({
@ -89,13 +90,14 @@ function LogItem({ logData }: LogItemProps): JSX.Element {
const handleCopyJSON = (): void => { const handleCopyJSON = (): void => {
setCopy(JSON.stringify(logData, null, 2)); setCopy(JSON.stringify(logData, null, 2));
notification.success({ notifications.success({
message: 'Copied to clipboard', message: 'Copied to clipboard',
}); });
}; };
return ( return (
<Container> <Container>
{NotificationElement}
<div> <div>
<div> <div>
{'{'} {'{'}

View File

@ -127,14 +127,15 @@ function AllErrors(): JSX.Element {
enabled: !loading, enabled: !loading,
}, },
]); ]);
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (data?.error) { if (data?.error) {
notification.error({ notifications.error({
message: data.error || t('something_went_wrong'), message: data.error || t('something_went_wrong'),
}); });
} }
}, [data?.error, data?.payload, t]); }, [data?.error, data?.payload, t, notifications]);
const getDateValue = (value: string): JSX.Element => ( const getDateValue = (value: string): JSX.Element => (
<Typography>{dayjs(value).format('DD/MM/YYYY HH:mm:ss A')}</Typography> <Typography>{dayjs(value).format('DD/MM/YYYY HH:mm:ss A')}</Typography>
@ -379,6 +380,8 @@ function AllErrors(): JSX.Element {
); );
return ( return (
<>
{NotificationElement}
<Table <Table
tableLayout="fixed" tableLayout="fixed"
dataSource={data?.payload as Exception[]} dataSource={data?.payload as Exception[]}
@ -394,6 +397,7 @@ function AllErrors(): JSX.Element {
}} }}
onChange={onChangeHandler} onChange={onChangeHandler}
/> />
</>
); );
} }

View File

@ -91,6 +91,8 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
const latestVersionCounter = useRef(0); const latestVersionCounter = useRef(0);
const latestConfigCounter = useRef(0); const latestConfigCounter = useRef(0);
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if ( if (
getUserLatestVersionResponse.isFetched && getUserLatestVersionResponse.isFetched &&
@ -105,7 +107,7 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
isError: true, isError: true,
}, },
}); });
notification.error({ notifications.error({
message: t('oops_something_went_wrong_version'), message: t('oops_something_went_wrong_version'),
}); });
} }
@ -123,7 +125,7 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
isError: true, isError: true,
}, },
}); });
notification.error({ notifications.error({
message: t('oops_something_went_wrong_version'), message: t('oops_something_went_wrong_version'),
}); });
} }
@ -219,12 +221,14 @@ function AppLayout(props: AppLayoutProps): JSX.Element {
getDynamicConfigsResponse.data, getDynamicConfigsResponse.data,
getDynamicConfigsResponse.isFetched, getDynamicConfigsResponse.isFetched,
getDynamicConfigsResponse.isSuccess, getDynamicConfigsResponse.isSuccess,
notifications,
]); ]);
const isToDisplayLayout = isLoggedIn; const isToDisplayLayout = isLoggedIn;
return ( return (
<Layout> <Layout>
{NotificationElement}
{isToDisplayLayout && <Header />} {isToDisplayLayout && <Header />}
<Layout> <Layout>
{isToDisplayLayout && <SideNav />} {isToDisplayLayout && <SideNav />}

View File

@ -77,13 +77,15 @@ function ErrorDetails(props: ErrorDetailsProps): JSX.Element {
[], [],
); );
const [notifications, NotificationElement] = notification.useNotification();
const onClickErrorIdHandler = async ( const onClickErrorIdHandler = async (
id: string, id: string,
timestamp: string, timestamp: string,
): Promise<void> => { ): Promise<void> => {
try { try {
if (id.length === 0) { if (id.length === 0) {
notification.error({ notifications.error({
message: 'Error Id cannot be empty', message: 'Error Id cannot be empty',
}); });
return; return;
@ -95,7 +97,7 @@ function ErrorDetails(props: ErrorDetailsProps): JSX.Element {
}&timestamp=${getNanoSeconds(timestamp)}&errorId=${id}`, }&timestamp=${getNanoSeconds(timestamp)}&errorId=${id}`,
); );
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('something_went_wrong'), message: t('something_went_wrong'),
}); });
} }
@ -116,6 +118,7 @@ function ErrorDetails(props: ErrorDetailsProps): JSX.Element {
return ( return (
<> <>
{NotificationElement}
<Typography>{errorDetail.exceptionType}</Typography> <Typography>{errorDetail.exceptionType}</Typography>
<Typography>{errorDetail.exceptionMessage}</Typography> <Typography>{errorDetail.exceptionMessage}</Typography>
<Divider /> <Divider />

View File

@ -20,12 +20,14 @@ function ChannelSelect({
const { loading, payload, error, errorMessage } = useFetch(getChannels); const { loading, payload, error, errorMessage } = useFetch(getChannels);
const [notifications, NotificationElement] = notification.useNotification();
const handleChange = (value: string[]): void => { const handleChange = (value: string[]): void => {
onSelectChannels(value); onSelectChannels(value);
}; };
if (error && errorMessage !== '') { if (error && errorMessage !== '') {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: errorMessage, description: errorMessage,
}); });
@ -48,6 +50,8 @@ function ChannelSelect({
return children; return children;
}; };
return ( return (
<>
{NotificationElement}
<StyledSelect <StyledSelect
status={error ? 'error' : ''} status={error ? 'error' : ''}
mode="multiple" mode="multiple"
@ -61,6 +65,7 @@ function ChannelSelect({
> >
{renderOptions()} {renderOptions()}
</StyledSelect> </StyledSelect>
</>
); );
} }

View File

@ -163,10 +163,11 @@ function QuerySection({
...allQueries, ...allQueries,
}); });
}; };
const [notifications, NotificationElement] = notification.useNotification();
const addMetricQuery = useCallback(() => { const addMetricQuery = useCallback(() => {
if (Object.keys(metricQueries).length > 5) { if (Object.keys(metricQueries).length > 5) {
notification.error({ notifications.error({
message: t('metric_query_max_limit'), message: t('metric_query_max_limit'),
}); });
return; return;
@ -191,7 +192,7 @@ function QuerySection({
expression: queryLabel, expression: queryLabel,
}; };
setMetricQueries({ ...queries }); setMetricQueries({ ...queries });
}, [t, getNextQueryLabel, metricQueries, setMetricQueries]); }, [t, getNextQueryLabel, metricQueries, setMetricQueries, notifications]);
const addFormula = useCallback(() => { const addFormula = useCallback(() => {
// defaulting to F1 as only one formula is supported // defaulting to F1 as only one formula is supported
@ -350,6 +351,7 @@ function QuerySection({
}; };
return ( return (
<> <>
{NotificationElement}
<StepHeading> {t('alert_form_step1')}</StepHeading> <StepHeading> {t('alert_form_step1')}</StepHeading>
<FormContainer> <FormContainer>
<div style={{ display: 'flex' }}>{renderTabs(alertType)}</div> <div style={{ display: 'flex' }}>{renderTabs(alertType)}</div>

View File

@ -190,12 +190,14 @@ function FormAlertRules({
}); });
} }
}; };
const [notifications, NotificationElement] = notification.useNotification();
const validatePromParams = useCallback((): boolean => { const validatePromParams = useCallback((): boolean => {
let retval = true; let retval = true;
if (queryCategory !== EQueryType.PROM) return retval; if (queryCategory !== EQueryType.PROM) return retval;
if (!promQueries || Object.keys(promQueries).length === 0) { if (!promQueries || Object.keys(promQueries).length === 0) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('promql_required'), description: t('promql_required'),
}); });
@ -204,7 +206,7 @@ function FormAlertRules({
Object.keys(promQueries).forEach((key) => { Object.keys(promQueries).forEach((key) => {
if (promQueries[key].query === '') { if (promQueries[key].query === '') {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('promql_required'), description: t('promql_required'),
}); });
@ -213,14 +215,14 @@ function FormAlertRules({
}); });
return retval; return retval;
}, [t, promQueries, queryCategory]); }, [t, promQueries, queryCategory, notifications]);
const validateChQueryParams = useCallback((): boolean => { const validateChQueryParams = useCallback((): boolean => {
let retval = true; let retval = true;
if (queryCategory !== EQueryType.CLICKHOUSE) return retval; if (queryCategory !== EQueryType.CLICKHOUSE) return retval;
if (!chQueries || Object.keys(chQueries).length === 0) { if (!chQueries || Object.keys(chQueries).length === 0) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('chquery_required'), description: t('chquery_required'),
}); });
@ -229,7 +231,7 @@ function FormAlertRules({
Object.keys(chQueries).forEach((key) => { Object.keys(chQueries).forEach((key) => {
if (chQueries[key].rawQuery === '') { if (chQueries[key].rawQuery === '') {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('chquery_required'), description: t('chquery_required'),
}); });
@ -238,14 +240,14 @@ function FormAlertRules({
}); });
return retval; return retval;
}, [t, chQueries, queryCategory]); }, [t, chQueries, queryCategory, notifications]);
const validateQBParams = useCallback((): boolean => { const validateQBParams = useCallback((): boolean => {
let retval = true; let retval = true;
if (queryCategory !== EQueryType.QUERY_BUILDER) return true; if (queryCategory !== EQueryType.QUERY_BUILDER) return true;
if (!metricQueries || Object.keys(metricQueries).length === 0) { if (!metricQueries || Object.keys(metricQueries).length === 0) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('condition_required'), description: t('condition_required'),
}); });
@ -253,7 +255,7 @@ function FormAlertRules({
} }
if (!alertDef.condition?.target) { if (!alertDef.condition?.target) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('target_missing'), description: t('target_missing'),
}); });
@ -262,7 +264,7 @@ function FormAlertRules({
Object.keys(metricQueries).forEach((key) => { Object.keys(metricQueries).forEach((key) => {
if (metricQueries[key].metricName === '') { if (metricQueries[key].metricName === '') {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('metricname_missing', { where: metricQueries[key].name }), description: t('metricname_missing', { where: metricQueries[key].name }),
}); });
@ -272,7 +274,7 @@ function FormAlertRules({
Object.keys(formulaQueries).forEach((key) => { Object.keys(formulaQueries).forEach((key) => {
if (formulaQueries[key].expression === '') { if (formulaQueries[key].expression === '') {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('expression_missing', formulaQueries[key].name), description: t('expression_missing', formulaQueries[key].name),
}); });
@ -280,11 +282,11 @@ function FormAlertRules({
} }
}); });
return retval; return retval;
}, [t, alertDef, queryCategory, metricQueries, formulaQueries]); }, [t, alertDef, queryCategory, metricQueries, formulaQueries, notifications]);
const isFormValid = useCallback((): boolean => { const isFormValid = useCallback((): boolean => {
if (!alertDef.alert || alertDef.alert === '') { if (!alertDef.alert || alertDef.alert === '') {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('alertname_required'), description: t('alertname_required'),
}); });
@ -300,7 +302,14 @@ function FormAlertRules({
} }
return validateQBParams(); return validateQBParams();
}, [t, validateQBParams, validateChQueryParams, alertDef, validatePromParams]); }, [
t,
validateQBParams,
validateChQueryParams,
alertDef,
validatePromParams,
notifications,
]);
const preparePostData = (): AlertDef => { const preparePostData = (): AlertDef => {
const postableAlert: AlertDef = { const postableAlert: AlertDef = {
@ -348,7 +357,7 @@ function FormAlertRules({
const response = await saveAlertApi(apiReq); const response = await saveAlertApi(apiReq);
if (response.statusCode === 200) { if (response.statusCode === 200) {
notification.success({ notifications.success({
message: 'Success', message: 'Success',
description: description:
!ruleId || ruleId === 0 ? t('rule_created') : t('rule_edited'), !ruleId || ruleId === 0 ? t('rule_created') : t('rule_edited'),
@ -361,19 +370,26 @@ function FormAlertRules({
history.replace(ROUTES.LIST_ALL_ALERT); history.replace(ROUTES.LIST_ALL_ALERT);
}, 2000); }, 2000);
} else { } else {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: response.error || t('unexpected_error'), description: response.error || t('unexpected_error'),
}); });
} }
} catch (e) { } catch (e) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('unexpected_error'), description: t('unexpected_error'),
}); });
} }
setLoading(false); setLoading(false);
}, [t, isFormValid, ruleId, ruleCache, memoizedPreparePostData]); }, [
t,
isFormValid,
ruleId,
ruleCache,
memoizedPreparePostData,
notifications,
]);
const onSaveHandler = useCallback(async () => { const onSaveHandler = useCallback(async () => {
const content = ( const content = (
@ -407,30 +423,30 @@ function FormAlertRules({
if (response.statusCode === 200) { if (response.statusCode === 200) {
const { payload } = response; const { payload } = response;
if (payload?.alertCount === 0) { if (payload?.alertCount === 0) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('no_alerts_found'), description: t('no_alerts_found'),
}); });
} else { } else {
notification.success({ notifications.success({
message: 'Success', message: 'Success',
description: t('rule_test_fired'), description: t('rule_test_fired'),
}); });
} }
} else { } else {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: response.error || t('unexpected_error'), description: response.error || t('unexpected_error'),
}); });
} }
} catch (e) { } catch (e) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('unexpected_error'), description: t('unexpected_error'),
}); });
} }
setLoading(false); setLoading(false);
}, [t, isFormValid, memoizedPreparePostData]); }, [t, isFormValid, memoizedPreparePostData, notifications]);
const renderBasicInfo = (): JSX.Element => ( const renderBasicInfo = (): JSX.Element => (
<BasicInfo alertDef={alertDef} setAlertDef={setAlertDef} /> <BasicInfo alertDef={alertDef} setAlertDef={setAlertDef} />
@ -467,6 +483,7 @@ function FormAlertRules({
); );
return ( return (
<> <>
{NotificationElement}
{Element} {Element}
<PanelContainer> <PanelContainer>
<StyledLeftContainer flex="5 1 600px"> <StyledLeftContainer flex="5 1 600px">

View File

@ -172,6 +172,8 @@ function GeneralSettings({
logsTtlValuesPayload.status === 'pending' ? 1000 : null, logsTtlValuesPayload.status === 'pending' ? 1000 : null,
); );
const [notifications, NotificationElement] = notification.useNotification();
const onModalToggleHandler = (type: TTTLType): void => { const onModalToggleHandler = (type: TTTLType): void => {
if (type === 'metrics') setModalMetrics((modal) => !modal); if (type === 'metrics') setModalMetrics((modal) => !modal);
if (type === 'traces') setModalTraces((modal) => !modal); if (type === 'traces') setModalTraces((modal) => !modal);
@ -186,14 +188,14 @@ function GeneralSettings({
const onClickSaveHandler = useCallback( const onClickSaveHandler = useCallback(
(type: TTTLType) => { (type: TTTLType) => {
if (!setRetentionPermission) { if (!setRetentionPermission) {
notification.error({ notifications.error({
message: `Sorry you don't have permission to make these changes`, message: `Sorry you don't have permission to make these changes`,
}); });
return; return;
} }
onModalToggleHandler(type); onModalToggleHandler(type);
}, },
[setRetentionPermission], [setRetentionPermission, notifications],
); );
const s3Enabled = useMemo( const s3Enabled = useMemo(
@ -352,7 +354,7 @@ function GeneralSettings({
let hasSetTTLFailed = false; let hasSetTTLFailed = false;
if (setTTLResponse.statusCode === 409) { if (setTTLResponse.statusCode === 409) {
hasSetTTLFailed = true; hasSetTTLFailed = true;
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('retention_request_race_condition'), description: t('retention_request_race_condition'),
placement: 'topRight', placement: 'topRight',
@ -390,7 +392,7 @@ function GeneralSettings({
}); });
} }
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('retention_failed_message'), description: t('retention_failed_message'),
placement: 'topRight', placement: 'topRight',
@ -591,6 +593,7 @@ function GeneralSettings({
return ( return (
<> <>
{NotificationElement}
{Element} {Element}
<Col xs={24} md={22} xl={20} xxl={18} style={{ margin: 'auto' }}> <Col xs={24} md={22} xl={20} xxl={18} style={{ margin: 'auto' }}>
<ErrorTextContainer> <ErrorTextContainer>

View File

@ -204,6 +204,8 @@ function GridGraph(props: Props): JSX.Element {
[widgets, onDragSelect], [widgets, onDragSelect],
); );
const [notifications, NotificationElement] = notification.useNotification();
const onEmptyWidgetHandler = useCallback(async () => { const onEmptyWidgetHandler = useCallback(async () => {
try { try {
const id = 'empty'; const id = 'empty';
@ -219,22 +221,25 @@ function GridGraph(props: Props): JSX.Element {
...(data.layout || []), ...(data.layout || []),
]; ];
await UpdateDashboard({ await UpdateDashboard(
{
data, data,
generateWidgetId: id, generateWidgetId: id,
graphType: 'EMPTY_WIDGET', graphType: 'EMPTY_WIDGET',
selectedDashboard, selectedDashboard,
layout, layout,
isRedirected: false, isRedirected: false,
}); },
notifications,
);
setLayoutFunction(layout); setLayoutFunction(layout);
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: error instanceof Error ? error.toString() : 'Something went wrong', message: error instanceof Error ? error.toString() : 'Something went wrong',
}); });
} }
}, [data, selectedDashboard, setLayoutFunction]); }, [data, selectedDashboard, setLayoutFunction, notifications]);
const onLayoutChangeHandler = async (layout: Layout[]): Promise<void> => { const onLayoutChangeHandler = async (layout: Layout[]): Promise<void> => {
setLayoutFunction(layout); setLayoutFunction(layout);
@ -255,7 +260,7 @@ function GridGraph(props: Props): JSX.Element {
toggleAddWidget(true); toggleAddWidget(true);
}) })
.catch(() => { .catch(() => {
notification.error(t('something_went_wrong')); notifications.error(t('something_went_wrong'));
}); });
} else { } else {
toggleAddWidget(true); toggleAddWidget(true);
@ -263,14 +268,16 @@ function GridGraph(props: Props): JSX.Element {
} }
} catch (error) { } catch (error) {
if (typeof error === 'string') { if (typeof error === 'string') {
notification.error({ notifications.error({
message: error || t('something_went_wrong'), message: error || t('something_went_wrong'),
}); });
} }
} }
}, [layouts, onEmptyWidgetHandler, t, toggleAddWidget]); }, [layouts, onEmptyWidgetHandler, t, toggleAddWidget, notifications]);
return ( return (
<>
{NotificationElement}
<GraphLayoutContainer <GraphLayoutContainer
{...{ {...{
addPanelLoading, addPanelLoading,
@ -283,6 +290,7 @@ function GridGraph(props: Props): JSX.Element {
setLayout, setLayout,
}} }}
/> />
</>
); );
} }

View File

@ -1,4 +1,4 @@
import { notification } from 'antd'; import { NotificationInstance } from 'antd/es/notification/interface';
import updateDashboardApi from 'api/dashboard/update'; import updateDashboardApi from 'api/dashboard/update';
import { import {
ClickHouseQueryTemplate, ClickHouseQueryTemplate,
@ -12,14 +12,17 @@ import store from 'store';
import { Dashboard } from 'types/api/dashboard/getAll'; import { Dashboard } from 'types/api/dashboard/getAll';
import { EQueryType } from 'types/common/dashboard'; import { EQueryType } from 'types/common/dashboard';
export const UpdateDashboard = async ({ export const UpdateDashboard = async (
{
data, data,
graphType, graphType,
generateWidgetId, generateWidgetId,
layout, layout,
selectedDashboard, selectedDashboard,
isRedirected, isRedirected,
}: UpdateDashboardProps): Promise<Dashboard | undefined> => { }: UpdateDashboardProps,
notify: NotificationInstance,
): Promise<Dashboard | undefined> => {
const updatedSelectedDashboard: Dashboard = { const updatedSelectedDashboard: Dashboard = {
...selectedDashboard, ...selectedDashboard,
data: { data: {
@ -89,7 +92,7 @@ export const UpdateDashboard = async ({
if (response.statusCode === 200) { if (response.statusCode === 200) {
return response.payload; return response.payload;
} }
notification.error({ notify.error({
message: response.error || 'Something went wrong', message: response.error || 'Something went wrong',
}); });
return undefined; return undefined;

View File

@ -26,10 +26,12 @@ function ApplyLicenseForm({
enabled: false, enabled: false,
}); });
const [notifications, NotificationElement] = notification.useNotification();
const onFinish = async (values: unknown | { key: string }): Promise<void> => { const onFinish = async (values: unknown | { key: string }): Promise<void> => {
const params = values as { key: string }; const params = values as { key: string };
if (params.key === '' || !params.key) { if (params.key === '' || !params.key) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('enter_license_key'), description: t('enter_license_key'),
}); });
@ -53,18 +55,18 @@ function ApplyLicenseForm({
payload: featureFlagsResponse.data.payload, payload: featureFlagsResponse.data.payload,
}); });
} }
notification.success({ notifications.success({
message: 'Success', message: 'Success',
description: t('license_applied'), description: t('license_applied'),
}); });
} else { } else {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: response.error || t('unexpected_error'), description: response.error || t('unexpected_error'),
}); });
} }
} catch (e) { } catch (e) {
notification.error({ notifications.error({
message: 'Error', message: 'Error',
description: t('unexpected_error'), description: t('unexpected_error'),
}); });
@ -74,6 +76,7 @@ function ApplyLicenseForm({
return ( return (
<ApplyFormContainer> <ApplyFormContainer>
{NotificationElement}
<ApplyForm layout="inline" onFinish={onFinish}> <ApplyForm layout="inline" onFinish={onFinish}>
<LicenseInput labelAlign="left" name="key"> <LicenseInput labelAlign="left" name="key">
<Input <Input

View File

@ -30,6 +30,8 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
role, role,
); );
const [notificationsApi, NotificationElement] = notification.useNotification();
useInterval(() => { useInterval(() => {
(async (): Promise<void> => { (async (): Promise<void> => {
const { data: refetchData, status } = await refetch(); const { data: refetchData, status } = await refetch();
@ -37,7 +39,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
setData(refetchData?.payload || []); setData(refetchData?.payload || []);
} }
if (status === 'error') { if (status === 'error') {
notification.error({ notificationsApi.error({
message: t('something_went_wrong'), message: t('something_went_wrong'),
}); });
} }
@ -145,6 +147,7 @@ function ListAlert({ allAlertRules, refetch }: ListAlertProps): JSX.Element {
return ( return (
<> <>
{NotificationElement}
{Element} {Element}
<ButtonContainer> <ButtonContainer>

View File

@ -20,6 +20,8 @@ function ToggleAlertState({
payload: undefined, payload: undefined,
}); });
const [notifications, NotificationElement] = notification.useNotification();
const defaultErrorMessage = 'Something went wrong'; const defaultErrorMessage = 'Something went wrong';
const onToggleHandler = async ( const onToggleHandler = async (
@ -58,7 +60,7 @@ function ToggleAlertState({
loading: false, loading: false,
payload: response.payload, payload: response.payload,
})); }));
notification.success({ notifications.success({
message: 'Success', message: 'Success',
}); });
} else { } else {
@ -69,7 +71,7 @@ function ToggleAlertState({
errorMessage: response.error || defaultErrorMessage, errorMessage: response.error || defaultErrorMessage,
})); }));
notification.error({ notifications.error({
message: response.error || defaultErrorMessage, message: response.error || defaultErrorMessage,
}); });
} }
@ -81,13 +83,15 @@ function ToggleAlertState({
errorMessage: defaultErrorMessage, errorMessage: defaultErrorMessage,
})); }));
notification.error({ notifications.error({
message: defaultErrorMessage, message: defaultErrorMessage,
}); });
} }
}; };
return ( return (
<>
{NotificationElement}
<ColumnButton <ColumnButton
disabled={apiStatus.loading || false} disabled={apiStatus.loading || false}
loading={apiStatus.loading || false} loading={apiStatus.loading || false}
@ -96,6 +100,7 @@ function ToggleAlertState({
> >
{disabled ? 'Enable' : 'Disable'} {disabled ? 'Enable' : 'Disable'}
</ColumnButton> </ColumnButton>
</>
); );
} }

View File

@ -17,28 +17,38 @@ function ListAlertRules(): JSX.Element {
cacheTime: 0, cacheTime: 0,
}); });
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (status === 'error' || (status === 'success' && data.statusCode >= 400)) { if (status === 'error' || (status === 'success' && data.statusCode >= 400)) {
notification.error({ notifications.error({
message: data?.error || t('something_went_wrong'), message: data?.error || t('something_went_wrong'),
}); });
} }
}, [data?.error, data?.statusCode, status, t]); }, [data?.error, data?.statusCode, status, t, notifications]);
// api failed to load the data // api failed to load the data
if (isError) { if (isError) {
return <div>{data?.error || t('something_went_wrong')}</div>; return (
<div>
{NotificationElement}
{data?.error || t('something_went_wrong')}
</div>
);
} }
// api is successful but error is present // api is successful but error is present
if (status === 'success' && data.statusCode >= 400) { if (status === 'success' && data.statusCode >= 400) {
return ( return (
<>
{NotificationElement}
<ListAlert <ListAlert
{...{ {...{
allAlertRules: [], allAlertRules: [],
refetch, refetch,
}} }}
/> />
</>
); );
} }
@ -49,6 +59,7 @@ function ListAlertRules(): JSX.Element {
return ( return (
<Space direction="vertical" size="large" style={{ width: '100%' }}> <Space direction="vertical" size="large" style={{ width: '100%' }}>
{NotificationElement}
<ReleaseNote path={location.pathname} /> <ReleaseNote path={location.pathname} />
<ListAlert <ListAlert
{...{ {...{

View File

@ -41,6 +41,8 @@ function ImportJSON({
const [editorValue, setEditorValue] = useState<string>(''); const [editorValue, setEditorValue] = useState<string>('');
const [notifications, NotificationElement] = notification.useNotification();
const onChangeHandler: UploadProps['onChange'] = (info) => { const onChangeHandler: UploadProps['onChange'] = (info) => {
const { fileList } = info; const { fileList } = info;
const reader = new FileReader(); const reader = new FileReader();
@ -106,7 +108,7 @@ function ImportJSON({
}, 10); }, 10);
} else { } else {
setIsCreateDashboardError(true); setIsCreateDashboardError(true);
notification.error({ notifications.error({
message: message:
response.error || response.error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -130,6 +132,8 @@ function ImportJSON({
); );
return ( return (
<>
{NotificationElement}
<Modal <Modal
open={isImportJSONModalVisible} open={isImportJSONModalVisible}
centered centered
@ -182,6 +186,7 @@ function ImportJSON({
</EditorContainer> </EditorContainer>
</div> </div>
</Modal> </Modal>
</>
); );
} }

View File

@ -42,6 +42,8 @@ function Login({
const [precheckInProcess, setPrecheckInProcess] = useState(false); const [precheckInProcess, setPrecheckInProcess] = useState(false);
const [precheckComplete, setPrecheckComplete] = useState(false); const [precheckComplete, setPrecheckComplete] = useState(false);
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (withPassword === 'Y') { if (withPassword === 'Y') {
setPrecheckComplete(true); setPrecheckComplete(true);
@ -62,15 +64,15 @@ function Login({
useEffect(() => { useEffect(() => {
if (ssoerror !== '') { if (ssoerror !== '') {
notification.error({ notifications.error({
message: t('failed_to_login'), message: t('failed_to_login'),
}); });
} }
}, [ssoerror, t]); }, [ssoerror, t, notifications]);
const onNextHandler = async (): Promise<void> => { const onNextHandler = async (): Promise<void> => {
if (!email) { if (!email) {
notification.error({ notifications.error({
message: t('invalid_email'), message: t('invalid_email'),
}); });
return; return;
@ -88,18 +90,18 @@ function Login({
if (isUser) { if (isUser) {
setPrecheckComplete(true); setPrecheckComplete(true);
} else { } else {
notification.error({ notifications.error({
message: t('invalid_account'), message: t('invalid_account'),
}); });
} }
} else { } else {
notification.error({ notifications.error({
message: t('invalid_config'), message: t('invalid_config'),
}); });
} }
} catch (e) { } catch (e) {
console.log('failed to call precheck Api', e); console.log('failed to call precheck Api', e);
notification.error({ message: t('unexpected_error') }); notifications.error({ message: t('unexpected_error') });
} }
setPrecheckInProcess(false); setPrecheckInProcess(false);
}; };
@ -144,14 +146,14 @@ function Login({
); );
history.push(ROUTES.APPLICATION); history.push(ROUTES.APPLICATION);
} else { } else {
notification.error({ notifications.error({
message: response.error || t('unexpected_error'), message: response.error || t('unexpected_error'),
}); });
} }
setIsLoading(false); setIsLoading(false);
} catch (error) { } catch (error) {
setIsLoading(false); setIsLoading(false);
notification.error({ notifications.error({
message: t('unexpected_error'), message: t('unexpected_error'),
}); });
} }
@ -183,6 +185,7 @@ function Login({
return ( return (
<FormWrapper> <FormWrapper>
{NotificationElement}
<FormContainer onSubmit={onSubmitHandler}> <FormContainer onSubmit={onSubmitHandler}>
<Title level={4}>{t('login_page_title')}</Title> <Title level={4}>{t('login_page_title')}</Title>
<ParentContainer> <ParentContainer>

View File

@ -36,6 +36,8 @@ function SearchFields({
const keyPrefixRef = useRef(hashCode(JSON.stringify(fieldsQuery))); const keyPrefixRef = useRef(hashCode(JSON.stringify(fieldsQuery)));
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
const updatedFieldsQuery = createParsedQueryStructure([ const updatedFieldsQuery = createParsedQueryStructure([
...parsedQuery, ...parsedQuery,
@ -81,7 +83,7 @@ function SearchFields({
const flatParsedQuery = flatten(fieldsQuery); const flatParsedQuery = flatten(fieldsQuery);
if (!fieldsQueryIsvalid(flatParsedQuery)) { if (!fieldsQueryIsvalid(flatParsedQuery)) {
notification.error({ notifications.error({
message: 'Please enter a valid criteria for each of the selected fields', message: 'Please enter a valid criteria for each of the selected fields',
}); });
return; return;
@ -90,7 +92,7 @@ function SearchFields({
keyPrefixRef.current = hashCode(JSON.stringify(flatParsedQuery)); keyPrefixRef.current = hashCode(JSON.stringify(flatParsedQuery));
updateParsedQuery(flatParsedQuery); updateParsedQuery(flatParsedQuery);
onDropDownToggleHandler(false)(); onDropDownToggleHandler(false)();
}, [onDropDownToggleHandler, fieldsQuery, updateParsedQuery]); }, [onDropDownToggleHandler, fieldsQuery, updateParsedQuery, notifications]);
const clearFilters = useCallback((): void => { const clearFilters = useCallback((): void => {
keyPrefixRef.current = hashCode(JSON.stringify([])); keyPrefixRef.current = hashCode(JSON.stringify([]));
@ -100,6 +102,7 @@ function SearchFields({
return ( return (
<> <>
{NotificationElement}
<QueryBuilder <QueryBuilder
key={keyPrefixRef.current} key={keyPrefixRef.current}
keyPrefix={keyPrefixRef.current} keyPrefix={keyPrefixRef.current}

View File

@ -23,6 +23,8 @@ function PasswordContainer(): JSX.Element {
ns: 'settings', ns: 'settings',
}); });
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (currentPassword && !isPasswordValid(currentPassword)) { if (currentPassword && !isPasswordValid(currentPassword)) {
setIsPasswordPolicyError(true); setIsPasswordPolicyError(true);
@ -52,13 +54,13 @@ function PasswordContainer(): JSX.Element {
}); });
if (statusCode === 200) { if (statusCode === 200) {
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
}); });
} else { } else {
notification.error({ notifications.error({
message: message:
error || error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -70,7 +72,7 @@ function PasswordContainer(): JSX.Element {
} catch (error) { } catch (error) {
setIsLoading(false); setIsLoading(false);
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -80,6 +82,7 @@ function PasswordContainer(): JSX.Element {
return ( return (
<Space direction="vertical" size="large"> <Space direction="vertical" size="large">
{NotificationElement}
<Typography.Title level={3}> <Typography.Title level={3}>
{t('change_password', { {t('change_password', {
ns: 'settings', ns: 'settings',

View File

@ -21,6 +21,8 @@ function UpdateName(): JSX.Element {
const [changedName, setChangedName] = useState<string>(user?.name || ''); const [changedName, setChangedName] = useState<string>(user?.name || '');
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const [notifications, NotificationElement] = notification.useNotification();
if (!user || !org) { if (!user || !org) {
return <div />; return <div />;
} }
@ -34,7 +36,7 @@ function UpdateName(): JSX.Element {
}); });
if (statusCode === 200) { if (statusCode === 200) {
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
@ -51,7 +53,7 @@ function UpdateName(): JSX.Element {
}, },
}); });
} else { } else {
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -59,7 +61,7 @@ function UpdateName(): JSX.Element {
} }
setLoading(false); setLoading(false);
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -70,6 +72,7 @@ function UpdateName(): JSX.Element {
return ( return (
<div> <div>
{NotificationElement}
<Space direction="vertical" size="middle"> <Space direction="vertical" size="middle">
<Typography>Name</Typography> <Typography>Name</Typography>
<NameInput <NameInput

View File

@ -22,6 +22,8 @@ function DashboardGraphSlider({ toggleAddWidget }: Props): JSX.Element {
(state) => state.dashboards, (state) => state.dashboards,
); );
const [notifications, NotificationElement] = notification.useNotification();
const [selectedDashboard] = dashboards; const [selectedDashboard] = dashboards;
const { data } = selectedDashboard; const { data } = selectedDashboard;
@ -31,7 +33,7 @@ function DashboardGraphSlider({ toggleAddWidget }: Props): JSX.Element {
const emptyLayout = data.layout?.find((e) => e.i === 'empty'); const emptyLayout = data.layout?.find((e) => e.i === 'empty');
if (emptyLayout === undefined) { if (emptyLayout === undefined) {
notification.error({ notifications.error({
message: 'Please click on Add Panel Button', message: 'Please click on Add Panel Button',
}); });
return; return;
@ -43,18 +45,19 @@ function DashboardGraphSlider({ toggleAddWidget }: Props): JSX.Element {
`${history.location.pathname}/new?graphType=${name}&widgetId=${emptyLayout.i}`, `${history.location.pathname}/new?graphType=${name}&widgetId=${emptyLayout.i}`,
); );
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: 'Something went wrong', message: 'Something went wrong',
}); });
} }
}, },
[data, toggleAddWidget], [data, toggleAddWidget, notifications],
); );
const isDarkMode = useIsDarkMode(); const isDarkMode = useIsDarkMode();
const fillColor: React.CSSProperties['color'] = isDarkMode ? 'white' : 'black'; const fillColor: React.CSSProperties['color'] = isDarkMode ? 'white' : 'black';
return ( return (
<Container> <Container>
{NotificationElement}
{menuItems.map(({ name, Icon, display }) => ( {menuItems.map(({ name, Icon, display }) => (
<Card <Card
onClick={(event): void => { onClick={(event): void => {

View File

@ -1,6 +1,7 @@
import { blue, red } from '@ant-design/colors'; import { blue, red } from '@ant-design/colors';
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import { Button, Modal, Row, Space, Table, Tag } from 'antd'; import { Button, Modal, notification, Row, Space, Table, Tag } from 'antd';
import { NotificationInstance } from 'antd/es/notification/interface';
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import { connect, useSelector } from 'react-redux'; import { connect, useSelector } from 'react-redux';
import { bindActionCreators, Dispatch } from 'redux'; import { bindActionCreators, Dispatch } from 'redux';
@ -24,6 +25,8 @@ function VariablesSetting({
(state) => state.dashboards, (state) => state.dashboards,
); );
const [notifications, NotificationElement] = notification.useNotification();
const [selectedDashboard] = dashboards; const [selectedDashboard] = dashboards;
const { const {
@ -74,8 +77,7 @@ function VariablesSetting({
if (oldName) { if (oldName) {
delete newVariables[oldName]; delete newVariables[oldName];
} }
updateDashboardVariables(newVariables, notifications);
updateDashboardVariables(newVariables);
onDoneVariableViewMode(); onDoneVariableViewMode();
}; };
@ -87,7 +89,7 @@ function VariablesSetting({
const handleDeleteConfirm = (): void => { const handleDeleteConfirm = (): void => {
const newVariables = { ...variables }; const newVariables = { ...variables };
if (variableToDelete?.current) delete newVariables[variableToDelete?.current]; if (variableToDelete?.current) delete newVariables[variableToDelete?.current];
updateDashboardVariables(newVariables); updateDashboardVariables(newVariables, notifications);
variableToDelete.current = null; variableToDelete.current = null;
setDeleteVariableModal(false); setDeleteVariableModal(false);
}; };
@ -137,6 +139,7 @@ function VariablesSetting({
return ( return (
<> <>
{NotificationElement}
{variableViewMode ? ( {variableViewMode ? (
<VariableItem <VariableItem
variableData={{ ...variableEditData } as IDashboardVariable} variableData={{ ...variableEditData } as IDashboardVariable}
@ -178,6 +181,7 @@ function VariablesSetting({
interface DispatchProps { interface DispatchProps {
updateDashboardVariables: ( updateDashboardVariables: (
props: Record<string, IDashboardVariable>, props: Record<string, IDashboardVariable>,
notify: NotificationInstance,
) => (dispatch: Dispatch<AppActions>) => void; ) => (dispatch: Dispatch<AppActions>) => void;
} }

View File

@ -1,4 +1,5 @@
import { Row } from 'antd'; import { notification, Row } from 'antd';
import { NotificationInstance } from 'antd/es/notification/interface';
import { map, sortBy } from 'lodash-es'; import { map, sortBy } from 'lodash-es';
import React, { useState } from 'react'; import React, { useState } from 'react';
import { connect, useSelector } from 'react-redux'; import { connect, useSelector } from 'react-redux';
@ -25,6 +26,7 @@ function DashboardVariableSelection({
const [update, setUpdate] = useState<boolean>(false); const [update, setUpdate] = useState<boolean>(false);
const [lastUpdatedVar, setLastUpdatedVar] = useState<string>(''); const [lastUpdatedVar, setLastUpdatedVar] = useState<string>('');
const [notifications, NotificationElement] = notification.useNotification();
const onVarChanged = (name: string): void => { const onVarChanged = (name: string): void => {
setLastUpdatedVar(name); setLastUpdatedVar(name);
@ -45,7 +47,7 @@ function DashboardVariableSelection({
): void => { ): void => {
const updatedVariablesData = { ...variables }; const updatedVariablesData = { ...variables };
updatedVariablesData[name].selectedValue = value; updatedVariablesData[name].selectedValue = value;
updateDashboardVariables(updatedVariablesData); updateDashboardVariables(updatedVariablesData, notifications);
onVarChanged(name); onVarChanged(name);
}; };
const onAllSelectedUpdate = ( const onAllSelectedUpdate = (
@ -54,12 +56,13 @@ function DashboardVariableSelection({
): void => { ): void => {
const updatedVariablesData = { ...variables }; const updatedVariablesData = { ...variables };
updatedVariablesData[name].allSelected = value; updatedVariablesData[name].allSelected = value;
updateDashboardVariables(updatedVariablesData); updateDashboardVariables(updatedVariablesData, notifications);
onVarChanged(name); onVarChanged(name);
}; };
return ( return (
<Row style={{ gap: '1rem' }}> <Row style={{ gap: '1rem' }}>
{NotificationElement}
{map(sortBy(Object.keys(variables)), (variableName) => ( {map(sortBy(Object.keys(variables)), (variableName) => (
<VariableItem <VariableItem
key={`${variableName}${variables[variableName].modificationUUID}`} key={`${variableName}${variables[variableName].modificationUUID}`}
@ -81,6 +84,7 @@ function DashboardVariableSelection({
interface DispatchProps { interface DispatchProps {
updateDashboardVariables: ( updateDashboardVariables: (
props: Parameters<typeof UpdateDashboardVariables>[0], props: Parameters<typeof UpdateDashboardVariables>[0],
notify: NotificationInstance,
) => (dispatch: Dispatch<AppActions>) => void; ) => (dispatch: Dispatch<AppActions>) => void;
} }

View File

@ -32,10 +32,11 @@ function ShareModal({
const [isViewJSON, setIsViewJSON] = useState<boolean>(false); const [isViewJSON, setIsViewJSON] = useState<boolean>(false);
const { t } = useTranslation(['dashboard', 'common']); const { t } = useTranslation(['dashboard', 'common']);
const [state, setCopy] = useCopyToClipboard(); const [state, setCopy] = useCopyToClipboard();
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (state.error) { if (state.error) {
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -43,13 +44,13 @@ function ShareModal({
} }
if (state.value) { if (state.value) {
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
}); });
} }
}, [state.error, state.value, t]); }, [state.error, state.value, t, notifications]);
const selectedDataCleaned = cleardQueryData(selectedData); const selectedDataCleaned = cleardQueryData(selectedData);
const GetFooterComponent = useMemo(() => { const GetFooterComponent = useMemo(() => {
@ -83,6 +84,8 @@ function ShareModal({
}, [isViewJSON, jsonValue, selectedData, selectedDataCleaned, setCopy, t]); }, [isViewJSON, jsonValue, selectedData, selectedDataCleaned, setCopy, t]);
return ( return (
<>
{NotificationElement}
<Modal <Modal
open={isJSONModalVisible} open={isJSONModalVisible}
onCancel={(): void => { onCancel={(): void => {
@ -102,9 +105,13 @@ function ShareModal({
{!isViewJSON ? ( {!isViewJSON ? (
<Typography>{t('export_dashboard')}</Typography> <Typography>{t('export_dashboard')}</Typography>
) : ( ) : (
<Editor onChange={(value): void => setJSONValue(value)} value={jsonValue} /> <Editor
onChange={(value): void => setJSONValue(value)}
value={jsonValue}
/>
)} )}
</Modal> </Modal>
</>
); );
} }

View File

@ -37,6 +37,7 @@ function QueryBuilderQueryContainer({
metricsBuilderQueries, metricsBuilderQueries,
selectedGraph, selectedGraph,
}: IQueryBuilderQueryContainerProps): JSX.Element | null { }: IQueryBuilderQueryContainerProps): JSX.Element | null {
const [notifications, NotificationElement] = notification.useNotification();
const handleQueryBuilderQueryChange = ({ const handleQueryBuilderQueryChange = ({
queryIndex, queryIndex,
aggregateFunction, aggregateFunction,
@ -113,7 +114,7 @@ function QueryBuilderQueryContainer({
}; };
const addQueryHandler = (): void => { const addQueryHandler = (): void => {
if (!canCreateQueryAndFormula(queryData)) { if (!canCreateQueryAndFormula(queryData)) {
notification.error({ notifications.error({
message: message:
'Unable to create query. You can create at max 10 queries and formulae.', 'Unable to create query. You can create at max 10 queries and formulae.',
}); });
@ -130,7 +131,7 @@ function QueryBuilderQueryContainer({
const addFormulaHandler = (): void => { const addFormulaHandler = (): void => {
if (!canCreateQueryAndFormula(queryData)) { if (!canCreateQueryAndFormula(queryData)) {
notification.error({ notifications.error({
message: message:
'Unable to create formula. You can create at max 10 queries and formulae.', 'Unable to create formula. You can create at max 10 queries and formulae.',
}); });
@ -155,6 +156,7 @@ function QueryBuilderQueryContainer({
} }
return ( return (
<> <>
{NotificationElement}
{metricsBuilderQueries.queryBuilder.map((q, idx) => ( {metricsBuilderQueries.queryBuilder.map((q, idx) => (
<MetricsBuilder <MetricsBuilder
key={q.name} key={q.name}

View File

@ -21,6 +21,8 @@ function AddDomain({ refetch }: Props): JSX.Element {
const { org } = useSelector<AppState, AppReducer>((state) => state.app); const { org } = useSelector<AppState, AppReducer>((state) => state.app);
const [notifications, NotificationElement] = notification.useNotification();
const onCreateHandler = async (): Promise<void> => { const onCreateHandler = async (): Promise<void> => {
try { try {
const response = await createDomainApi({ const response = await createDomainApi({
@ -29,19 +31,19 @@ function AddDomain({ refetch }: Props): JSX.Element {
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
notification.success({ notifications.success({
message: 'Your domain has been added successfully.', message: 'Your domain has been added successfully.',
duration: 15, duration: 15,
}); });
setIsDomain(false); setIsDomain(false);
refetch(); refetch();
} else { } else {
notification.error({ notifications.error({
message: t('common:something_went_wrong'), message: t('common:something_went_wrong'),
}); });
} }
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('common:something_went_wrong'), message: t('common:something_went_wrong'),
}); });
} }
@ -49,6 +51,7 @@ function AddDomain({ refetch }: Props): JSX.Element {
return ( return (
<> <>
{NotificationElement}
<Container> <Container>
<Typography.Title level={3}> <Typography.Title level={3}>
{t('authenticated_domains', { {t('authenticated_domains', {

View File

@ -31,6 +31,8 @@ function EditSSO({
const { t } = useTranslation(['common']); const { t } = useTranslation(['common']);
const [notifications, NotificationElement] = notification.useNotification();
const onFinishHandler = useCallback(() => { const onFinishHandler = useCallback(() => {
form form
.validateFields() .validateFields()
@ -44,11 +46,11 @@ function EditSSO({
}); });
}) })
.catch(() => { .catch(() => {
notification.error({ notifications.error({
message: t('something_went_wrong', { ns: 'common' }), message: t('something_went_wrong', { ns: 'common' }),
}); });
}); });
}, [form, onRecordUpdateHandler, record, t]); }, [form, onRecordUpdateHandler, record, t, notifications]);
const onResetHandler = useCallback(() => { const onResetHandler = useCallback(() => {
form.resetFields(); form.resetFields();
@ -61,7 +63,7 @@ function EditSSO({
initialValues={record} initialValues={record}
onFinishFailed={(error): void => { onFinishFailed={(error): void => {
error.errorFields.forEach(({ errors }) => { error.errorFields.forEach(({ errors }) => {
notification.error({ notifications.error({
message: message:
errors[0].toString() || t('something_went_wrong', { ns: 'common' }), errors[0].toString() || t('something_went_wrong', { ns: 'common' }),
}); });
@ -73,6 +75,7 @@ function EditSSO({
autoComplete="off" autoComplete="off"
form={form} form={form}
> >
{NotificationElement}
{renderFormInputs(record)} {renderFormInputs(record)}
<Space <Space
style={{ width: '100%', justifyContent: 'flex-end' }} style={{ width: '100%', justifyContent: 'flex-end' }}

View File

@ -56,6 +56,8 @@ function AuthDomains(): JSX.Element {
enabled: org !== null, enabled: org !== null,
}); });
const [notifications, NotificationElement] = notification.useNotification();
const assignSsoMethod = useCallback( const assignSsoMethod = useCallback(
(typ: AuthDomain['ssoType']): void => { (typ: AuthDomain['ssoType']): void => {
setCurrentDomain({ ...currentDomain, ssoType: typ } as AuthDomain); setCurrentDomain({ ...currentDomain, ssoType: typ } as AuthDomain);
@ -76,7 +78,7 @@ function AuthDomains(): JSX.Element {
const response = await updateDomain(record); const response = await updateDomain(record);
if (response.statusCode === 200) { if (response.statusCode === 200) {
notification.success({ notifications.success({
message: t('saml_settings', { message: t('saml_settings', {
ns: 'organizationsettings', ns: 'organizationsettings',
}), }),
@ -87,7 +89,7 @@ function AuthDomains(): JSX.Element {
return true; return true;
} }
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -95,7 +97,7 @@ function AuthDomains(): JSX.Element {
return false; return false;
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -103,7 +105,7 @@ function AuthDomains(): JSX.Element {
return false; return false;
} }
}, },
[refetch, t, onCloseHandler], [refetch, t, onCloseHandler, notifications],
); );
const onOpenHandler = useCallback( const onOpenHandler = useCallback(
@ -142,19 +144,19 @@ function AuthDomains(): JSX.Element {
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
notification.success({ notifications.success({
message: t('common:success'), message: t('common:success'),
}); });
refetch(); refetch();
} else { } else {
notification.error({ notifications.error({
message: t('common:something_went_wrong'), message: t('common:something_went_wrong'),
}); });
} }
}, },
}); });
}, },
[refetch, t], [refetch, t, notifications],
); );
const onClickLicenseHandler = useCallback(() => { const onClickLicenseHandler = useCallback(() => {
@ -247,6 +249,7 @@ function AuthDomains(): JSX.Element {
if (!isLoading && data?.payload?.length === 0) { if (!isLoading && data?.payload?.length === 0) {
return ( return (
<Space direction="vertical" size="middle"> <Space direction="vertical" size="middle">
{NotificationElement}
<AddDomain refetch={refetch} /> <AddDomain refetch={refetch} />
<Modal <Modal
@ -278,6 +281,7 @@ function AuthDomains(): JSX.Element {
return ( return (
<> <>
{NotificationElement}
<Modal <Modal
centered centered
title="Configure Authentication Method" title="Configure Authentication Method"

View File

@ -21,6 +21,7 @@ function DisplayName({
const { name } = (org || [])[index]; const { name } = (org || [])[index];
const [isLoading, setIsLoading] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false);
const dispatch = useDispatch<Dispatch<AppActions>>(); const dispatch = useDispatch<Dispatch<AppActions>>();
const [notifications, NotificationElement] = notification.useNotification();
const onSubmit = async ({ name: orgName }: OnSubmitProps): Promise<void> => { const onSubmit = async ({ name: orgName }: OnSubmitProps): Promise<void> => {
try { try {
@ -31,7 +32,7 @@ function DisplayName({
orgId, orgId,
}); });
if (statusCode === 200) { if (statusCode === 200) {
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
@ -44,7 +45,7 @@ function DisplayName({
}, },
}); });
} else { } else {
notification.error({ notifications.error({
message: message:
error || error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -55,7 +56,7 @@ function DisplayName({
setIsLoading(false); setIsLoading(false);
} catch (error) { } catch (error) {
setIsLoading(false); setIsLoading(false);
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -75,6 +76,7 @@ function DisplayName({
onFinish={onSubmit} onFinish={onSubmit}
autoComplete="off" autoComplete="off"
> >
{NotificationElement}
<Form.Item name="name" label="Display name" rules={[{ required: true }]}> <Form.Item name="name" label="Display name" rules={[{ required: true }]}>
<Input size="large" placeholder={t('signoz')} disabled={isLoading} /> <Input size="large" placeholder={t('signoz')} disabled={isLoading} />
</Form.Item> </Form.Item>

View File

@ -36,19 +36,21 @@ function EditMembersDetails({
[], [],
); );
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (state.error) { if (state.error) {
notification.error({ notifications.error({
message: t('something_went_wrong'), message: t('something_went_wrong'),
}); });
} }
if (state.value) { if (state.value) {
notification.success({ notifications.success({
message: t('success'), message: t('success'),
}); });
} }
}, [state.error, state.value, t]); }, [state.error, state.value, t, notifications]);
const onPasswordChangeHandler: React.ChangeEventHandler<HTMLInputElement> = useCallback( const onPasswordChangeHandler: React.ChangeEventHandler<HTMLInputElement> = useCallback(
(event) => { (event) => {
@ -67,7 +69,7 @@ function EditMembersDetails({
if (response.statusCode === 200) { if (response.statusCode === 200) {
setPasswordLink(getPasswordLink(response.payload.token)); setPasswordLink(getPasswordLink(response.payload.token));
} else { } else {
notification.error({ notifications.error({
message: message:
response.error || response.error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -79,7 +81,7 @@ function EditMembersDetails({
} catch (error) { } catch (error) {
setIsLoading(false); setIsLoading(false);
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -89,6 +91,7 @@ function EditMembersDetails({
return ( return (
<Space direction="vertical" size="large"> <Space direction="vertical" size="large">
{NotificationElement}
<Space direction="horizontal"> <Space direction="horizontal">
<Title>Email address</Title> <Title>Email address</Title>
<Input <Input

View File

@ -39,6 +39,7 @@ function UserFunction({
const { t } = useTranslation(['common']); const { t } = useTranslation(['common']);
const [isDeleteLoading, setIsDeleteLoading] = useState<boolean>(false); const [isDeleteLoading, setIsDeleteLoading] = useState<boolean>(false);
const [isUpdateLoading, setIsUpdateLoading] = useState<boolean>(false); const [isUpdateLoading, setIsUpdateLoading] = useState<boolean>(false);
const [notifications, NotificationElement] = notification.useNotification();
const onUpdateDetailsHandler = (): void => { const onUpdateDetailsHandler = (): void => {
setDataSource((data) => { setDataSource((data) => {
@ -88,14 +89,14 @@ function UserFunction({
if (response.statusCode === 200) { if (response.statusCode === 200) {
onDelete(); onDelete();
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
}); });
setIsDeleteModalVisible(false); setIsDeleteModalVisible(false);
} else { } else {
notification.error({ notifications.error({
message: message:
response.error || response.error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -107,7 +108,7 @@ function UserFunction({
} catch (error) { } catch (error) {
setIsDeleteLoading(false); setIsDeleteLoading(false);
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -134,13 +135,13 @@ function UserFunction({
updateRoleResponse.statusCode === 200 updateRoleResponse.statusCode === 200
) { ) {
onUpdateDetailsHandler(); onUpdateDetailsHandler();
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
}); });
} else { } else {
notification.error({ notifications.error({
message: message:
editUserResponse.error || editUserResponse.error ||
updateRoleResponse.error || updateRoleResponse.error ||
@ -151,7 +152,7 @@ function UserFunction({
} }
setIsUpdateLoading(false); setIsUpdateLoading(false);
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -162,6 +163,7 @@ function UserFunction({
return ( return (
<> <>
{NotificationElement}
<Space direction="horizontal"> <Space direction="horizontal">
<Typography.Link <Typography.Link
onClick={(): void => onModalToggleHandler(setIsModalVisible, true)} onClick={(): void => onModalToggleHandler(setIsModalVisible, true)}

View File

@ -25,22 +25,23 @@ function PendingInvitesContainer(): JSX.Element {
const [isInvitingMembers, setIsInvitingMembers] = useState<boolean>(false); const [isInvitingMembers, setIsInvitingMembers] = useState<boolean>(false);
const { t } = useTranslation(['organizationsettings', 'common']); const { t } = useTranslation(['organizationsettings', 'common']);
const [state, setText] = useCopyToClipboard(); const [state, setText] = useCopyToClipboard();
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (state.error) { if (state.error) {
notification.error({ notifications.error({
message: state.error.message, message: state.error.message,
}); });
} }
if (state.value) { if (state.value) {
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
}); });
} }
}, [state.error, state.value, t]); }, [state.error, state.value, t, notifications]);
const getPendingInvitesResponse = useQuery({ const getPendingInvitesResponse = useQuery({
queryFn: () => getPendingInvites(), queryFn: () => getPendingInvites(),
@ -112,13 +113,13 @@ function PendingInvitesContainer(): JSX.Element {
...dataSource.slice(index + 1, dataSource.length), ...dataSource.slice(index + 1, dataSource.length),
]); ]);
} }
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
}); });
} else { } else {
notification.error({ notifications.error({
message: message:
response.error || response.error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -127,7 +128,7 @@ function PendingInvitesContainer(): JSX.Element {
}); });
} }
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -192,7 +193,7 @@ function PendingInvitesContainer(): JSX.Element {
}); });
if (statusCode !== 200) { if (statusCode !== 200) {
notification.error({ notifications.error({
message: message:
error || error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -212,7 +213,7 @@ function PendingInvitesContainer(): JSX.Element {
toggleModal(false); toggleModal(false);
}, 2000); }, 2000);
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -222,6 +223,7 @@ function PendingInvitesContainer(): JSX.Element {
return ( return (
<div> <div>
{NotificationElement}
<Modal <Modal
title={t('invite_team_members')} title={t('invite_team_members')}
open={isInviteTeamMemberModalOpen} open={isInviteTeamMemberModalOpen}

View File

@ -24,6 +24,7 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
const { search } = useLocation(); const { search } = useLocation();
const params = new URLSearchParams(search); const params = new URLSearchParams(search);
const token = params.get('token'); const token = params.get('token');
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (!token) { if (!token) {
@ -53,14 +54,14 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
notification.success({ notifications.success({
message: t('success', { message: t('success', {
ns: 'common', ns: 'common',
}), }),
}); });
history.push(ROUTES.LOGIN); history.push(ROUTES.LOGIN);
} else { } else {
notification.error({ notifications.error({
message: message:
response.error || response.error ||
t('something_went_wrong', { t('something_went_wrong', {
@ -72,7 +73,7 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
setLoading(false); setLoading(false);
} catch (error) { } catch (error) {
setLoading(false); setLoading(false);
notification.error({ notifications.error({
message: t('something_went_wrong', { message: t('something_went_wrong', {
ns: 'common', ns: 'common',
}), }),
@ -82,6 +83,8 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
return ( return (
<WelcomeLeftContainer version={version}> <WelcomeLeftContainer version={version}>
<>
{NotificationElement}
<FormWrapper> <FormWrapper>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<Title level={4}>Reset Your Password</Title> <Title level={4}>Reset Your Password</Title>
@ -146,6 +149,7 @@ function ResetPassword({ version }: ResetPasswordProps): JSX.Element {
</ButtonContainer> </ButtonContainer>
</form> </form>
</FormWrapper> </FormWrapper>
</>
</WelcomeLeftContainer> </WelcomeLeftContainer>
); );
} }

View File

@ -38,6 +38,8 @@ function CheckBoxComponent(props: CheckBoxProps): JSX.Element {
(userSelectedFilter.get(name) || []).find((e) => e === keyValue) !== (userSelectedFilter.get(name) || []).find((e) => e === keyValue) !==
undefined; undefined;
const [notifications, NotificationElement] = notification.useNotification();
// eslint-disable-next-line sonarjs/cognitive-complexity // eslint-disable-next-line sonarjs/cognitive-complexity
const onCheckHandler = async (): Promise<void> => { const onCheckHandler = async (): Promise<void> => {
try { try {
@ -141,12 +143,12 @@ function CheckBoxComponent(props: CheckBoxProps): JSX.Element {
} else { } else {
setIsLoading(false); setIsLoading(false);
notification.error({ notifications.error({
message: response.error || 'Something went wrong', message: response.error || 'Something went wrong',
}); });
} }
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: (error as AxiosError).toString() || 'Something went wrong', message: (error as AxiosError).toString() || 'Something went wrong',
}); });
setIsLoading(false); setIsLoading(false);
@ -161,6 +163,7 @@ function CheckBoxComponent(props: CheckBoxProps): JSX.Element {
return ( return (
<CheckBoxContainer> <CheckBoxContainer>
{NotificationElement}
<Checkbox <Checkbox
disabled={isLoading || filterLoading} disabled={isLoading || filterLoading}
onClick={onCheckHandler} onClick={onCheckHandler}

View File

@ -28,6 +28,7 @@ function TraceID(): JSX.Element {
); );
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [userEnteredValue, setUserEnteredValue] = useState<string>(''); const [userEnteredValue, setUserEnteredValue] = useState<string>('');
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
setUserEnteredValue(selectedFilter.get('traceID')?.[0] || ''); setUserEnteredValue(selectedFilter.get('traceID')?.[0] || '');
}, [selectedFilter]); }, [selectedFilter]);
@ -91,7 +92,7 @@ function TraceID(): JSX.Element {
); );
} }
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: (error as AxiosError).toString() || 'Something went wrong', message: (error as AxiosError).toString() || 'Something went wrong',
}); });
} finally { } finally {
@ -108,6 +109,7 @@ function TraceID(): JSX.Element {
}; };
return ( return (
<div> <div>
{NotificationElement}
<Search <Search
placeholder="Filter by Trace ID" placeholder="Filter by Trace ID"
onSearch={onSearch} onSearch={onSearch}

View File

@ -53,6 +53,8 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
const defaultErrorMessage = 'Something went wrong'; const defaultErrorMessage = 'Something went wrong';
const [notifications, NotificationElement] = notification.useNotification();
// eslint-disable-next-line sonarjs/cognitive-complexity // eslint-disable-next-line sonarjs/cognitive-complexity
const onExpandHandler: React.MouseEventHandler<HTMLDivElement> = async (e) => { const onExpandHandler: React.MouseEventHandler<HTMLDivElement> = async (e) => {
try { try {
@ -119,14 +121,14 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
spansAggregate.orderParam, spansAggregate.orderParam,
); );
} else { } else {
notification.error({ notifications.error({
message: response.error || defaultErrorMessage, message: response.error || defaultErrorMessage,
}); });
} }
setIsLoading(false); setIsLoading(false);
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: (error as AxiosError).toString() || defaultErrorMessage, message: (error as AxiosError).toString() || defaultErrorMessage,
}); });
} }
@ -225,13 +227,13 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
spansAggregate.orderParam, spansAggregate.orderParam,
); );
} else { } else {
notification.error({ notifications.error({
message: response.error || 'Something went wrong', message: response.error || 'Something went wrong',
}); });
} }
setIsLoading(false); setIsLoading(false);
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: (error as AxiosError).toString(), message: (error as AxiosError).toString(),
}); });
setIsLoading(false); setIsLoading(false);
@ -295,6 +297,7 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
return ( return (
<> <>
{NotificationElement}
{PanelName !== 'duration' && <Divider plain style={{ margin: 0 }} />} {PanelName !== 'duration' && <Divider plain style={{ margin: 0 }} />}
<Card bordered={false}> <Card bordered={false}>

View File

@ -17,6 +17,7 @@ function TriggeredAlerts(): JSX.Element {
payload: [], payload: [],
}); });
const { t } = useTranslation(['common']); const { t } = useTranslation(['common']);
const [notifications, NotificationElement] = notification.useNotification();
const fetchData = useCallback(async () => { const fetchData = useCallback(async () => {
try { try {
@ -61,18 +62,28 @@ function TriggeredAlerts(): JSX.Element {
useEffect(() => { useEffect(() => {
if (groupState.error) { if (groupState.error) {
notification.error({ notifications.error({
message: groupState.errorMessage || t('something_went_wrong'), message: groupState.errorMessage || t('something_went_wrong'),
}); });
} }
}, [groupState.error, groupState.errorMessage, t]); }, [groupState.error, groupState.errorMessage, t, notifications]);
if (groupState.error) { if (groupState.error) {
return <TriggerComponent allAlerts={[]} />; return (
<>
{NotificationElement}
<TriggerComponent allAlerts={[]} />
</>
);
} }
if (groupState.loading || groupState.payload === undefined) { if (groupState.loading || groupState.payload === undefined) {
return <Spinner height="75vh" tip="Loading Alerts..." />; return (
<>
{NotificationElement}
<Spinner height="75vh" tip="Loading Alerts..." />
</>
);
} }
// commented the reduce() call as we no longer use /alerts/groups // commented the reduce() call as we no longer use /alerts/groups
@ -84,7 +95,12 @@ function TriggeredAlerts(): JSX.Element {
// return [...acc, ...curr.alerts]; // return [...acc, ...curr.alerts];
// }, initialAlerts); // }, initialAlerts);
return <TriggerComponent allAlerts={groupState.payload} />; return (
<>
{NotificationElement}
<TriggerComponent allAlerts={groupState.payload} />
</>
);
} }
export default TriggeredAlerts; export default TriggeredAlerts;

View File

@ -26,21 +26,28 @@ function EditRules(): JSX.Element {
enabled: isValidRuleId, enabled: isValidRuleId,
}); });
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (!isValidRuleId) { if (!isValidRuleId) {
notification.error({ notifications.error({
message: 'Rule Id is required', message: 'Rule Id is required',
}); });
history.replace(ROUTES.LIST_ALL_ALERT); history.replace(ROUTES.LIST_ALL_ALERT);
} }
}, [isValidRuleId, ruleId]); }, [isValidRuleId, ruleId, notifications]);
if ( if (
(isError && !isValidRuleId) || (isError && !isValidRuleId) ||
ruleId == null || ruleId == null ||
(data?.payload?.data === undefined && !isLoading) (data?.payload?.data === undefined && !isLoading)
) { ) {
return <div>{data?.error || t('something_went_wrong')}</div>; return (
<div>
{NotificationElement}
{data?.error || t('something_went_wrong')}
</div>
);
} }
if (isLoading || !data?.payload) { if (isLoading || !data?.payload) {
@ -48,10 +55,13 @@ function EditRules(): JSX.Element {
} }
return ( return (
<>
{NotificationElement}
<EditRulesContainer <EditRulesContainer
ruleId={parseInt(ruleId, 10)} ruleId={parseInt(ruleId, 10)}
initialValue={data.payload.data} initialValue={data.payload.data}
/> />
</>
); );
} }

View File

@ -30,14 +30,15 @@ function Metrics({ getService }: MetricsProps): JSX.Element {
error, error,
errorMessage, errorMessage,
} = useSelector<AppState, MetricReducer>((state) => state.metrics); } = useSelector<AppState, MetricReducer>((state) => state.metrics);
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if (error) { if (error) {
notification.error({ notifications.error({
message: errorMessage, message: errorMessage,
}); });
} }
}, [error, errorMessage]); }, [error, errorMessage, notifications]);
const selectedTags = useMemo( const selectedTags = useMemo(
() => () =>
@ -90,6 +91,7 @@ function Metrics({ getService }: MetricsProps): JSX.Element {
return ( return (
<Space direction="vertical" style={{ width: '100%' }}> <Space direction="vertical" style={{ width: '100%' }}>
{NotificationElement}
<ReleaseNote path={location.pathname} /> <ReleaseNote path={location.pathname} />
<ResourceAttributesFilter /> <ResourceAttributesFilter />

View File

@ -56,6 +56,8 @@ function SignUp({ version }: SignUpProps): JSX.Element {
enabled: token !== null, enabled: token !== null,
}); });
const [notifications, NotificationElement] = notification.useNotification();
useEffect(() => { useEffect(() => {
if ( if (
getInviteDetailsResponse.status === 'success' && getInviteDetailsResponse.status === 'success' &&
@ -73,7 +75,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
getInviteDetailsResponse.data?.error getInviteDetailsResponse.data?.error
) { ) {
const { error } = getInviteDetailsResponse.data; const { error } = getInviteDetailsResponse.data;
notification.error({ notifications.error({
message: error, message: error,
}); });
} }
@ -82,6 +84,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
getInviteDetailsResponse.data?.error, getInviteDetailsResponse.data?.error,
getInviteDetailsResponse.status, getInviteDetailsResponse.status,
getInviteDetailsResponse, getInviteDetailsResponse,
notifications,
]); ]);
const setState = ( const setState = (
@ -122,17 +125,17 @@ function SignUp({ version }: SignUpProps): JSX.Element {
callback(userResponse); callback(userResponse);
} }
} else { } else {
notification.error({ notifications.error({
message: loginResponse.error || t('unexpected_error'), message: loginResponse.error || t('unexpected_error'),
}); });
} }
} else { } else {
notification.error({ notifications.error({
message: response.error || t('unexpected_error'), message: response.error || t('unexpected_error'),
}); });
} }
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('unexpected_error'), message: t('unexpected_error'),
}); });
} }
@ -150,7 +153,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
if (editResponse.statusCode === 200) { if (editResponse.statusCode === 200) {
history.push(ROUTES.APPLICATION); history.push(ROUTES.APPLICATION);
} else { } else {
notification.error({ notifications.error({
message: editResponse.error || t('unexpected_error'), message: editResponse.error || t('unexpected_error'),
}); });
} }
@ -159,7 +162,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
e: React.FormEvent<HTMLFormElement>, e: React.FormEvent<HTMLFormElement>,
): Promise<void> => { ): Promise<void> => {
if (!params.get('token')) { if (!params.get('token')) {
notification.error({ notifications.error({
message: t('token_required'), message: t('token_required'),
}); });
return; return;
@ -182,7 +185,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
if (response.payload?.ssoUrl) { if (response.payload?.ssoUrl) {
window.location.href = response.payload?.ssoUrl; window.location.href = response.payload?.ssoUrl;
} else { } else {
notification.error({ notifications.error({
message: t('failed_to_initiate_login'), message: t('failed_to_initiate_login'),
}); });
// take user to login page as there is nothing to do here // take user to login page as there is nothing to do here
@ -190,12 +193,12 @@ function SignUp({ version }: SignUpProps): JSX.Element {
} }
} }
} else { } else {
notification.error({ notifications.error({
message: response.error || t('unexpected_error'), message: response.error || t('unexpected_error'),
}); });
} }
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('unexpected_error'), message: t('unexpected_error'),
}); });
} }
@ -227,7 +230,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
setLoading(false); setLoading(false);
} catch (error) { } catch (error) {
notification.error({ notifications.error({
message: t('unexpected_error'), message: t('unexpected_error'),
}); });
setLoading(false); setLoading(false);
@ -263,6 +266,8 @@ function SignUp({ version }: SignUpProps): JSX.Element {
return ( return (
<WelcomeLeftContainer version={version}> <WelcomeLeftContainer version={version}>
<>
{NotificationElement}
<FormWrapper> <FormWrapper>
<form onSubmit={!precheck.sso ? handleSubmit : handleSubmitSSO}> <form onSubmit={!precheck.sso ? handleSubmit : handleSubmitSSO}>
<Title level={4}>Create your account</Title> <Title level={4}>Create your account</Title>
@ -368,7 +373,9 @@ function SignUp({ version }: SignUpProps): JSX.Element {
<MarginTop marginTop="2.4375rem"> <MarginTop marginTop="2.4375rem">
<Space> <Space>
<Switch <Switch
onChange={(value): void => onSwitchHandler(value, setHasOptedUpdates)} onChange={(value): void =>
onSwitchHandler(value, setHasOptedUpdates)
}
checked={hasOptedUpdates} checked={hasOptedUpdates}
/> />
<Typography>{t('prompt_keepme_posted')} </Typography> <Typography>{t('prompt_keepme_posted')} </Typography>
@ -421,6 +428,7 @@ function SignUp({ version }: SignUpProps): JSX.Element {
</ButtonContainer> </ButtonContainer>
</form> </form>
</FormWrapper> </FormWrapper>
</>
</WelcomeLeftContainer> </WelcomeLeftContainer>
); );
} }

View File

@ -1,4 +1,5 @@
import { Card } from 'antd'; import { Card, notification } from 'antd';
import { NotificationInstance } from 'antd/es/notification/interface';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import Filters from 'container/Trace/Filters'; import Filters from 'container/Trace/Filters';
import TraceGraph from 'container/Trace/Graph'; import TraceGraph from 'container/Trace/Graph';
@ -52,12 +53,15 @@ function Trace({
isFilterExclude, isFilterExclude,
} = useSelector<AppState, TraceReducer>((state) => state.traces); } = useSelector<AppState, TraceReducer>((state) => state.traces);
useEffect(() => { const [notifications, NotificationElement] = notification.useNotification();
getInitialFilter(minTime, maxTime);
}, [maxTime, minTime, getInitialFilter, isChanged]);
useEffect(() => { useEffect(() => {
getSpansAggregate({ getInitialFilter(minTime, maxTime, notifications);
}, [maxTime, minTime, getInitialFilter, isChanged, notifications]);
useEffect(() => {
getSpansAggregate(
{
maxTime, maxTime,
minTime, minTime,
selectedFilter, selectedFilter,
@ -66,7 +70,9 @@ function Trace({
selectedTags, selectedTags,
order: spansAggregate.order, order: spansAggregate.order,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
}); },
notifications,
);
}, [ }, [
selectedTags, selectedTags,
selectedFilter, selectedFilter,
@ -77,10 +83,12 @@ function Trace({
spansAggregate.pageSize, spansAggregate.pageSize,
spansAggregate.order, spansAggregate.order,
spansAggregate.orderParam, spansAggregate.orderParam,
notifications,
]); ]);
useEffect(() => { useEffect(() => {
getSpans({ getSpans(
{
end: maxTime, end: maxTime,
function: selectedFunction, function: selectedFunction,
groupBy: selectedGroupBy, groupBy: selectedGroupBy,
@ -89,7 +97,9 @@ function Trace({
start: minTime, start: minTime,
step: getStep({ start: minTime, end: maxTime, inputFormat: 'ns' }), step: getStep({ start: minTime, end: maxTime, inputFormat: 'ns' }),
isFilterExclude, isFilterExclude,
}); },
notifications,
);
}, [ }, [
selectedFunction, selectedFunction,
selectedGroupBy, selectedGroupBy,
@ -99,6 +109,7 @@ function Trace({
minTime, minTime,
getSpans, getSpans,
isFilterExclude, isFilterExclude,
notifications,
]); ]);
useEffect( useEffect(
@ -128,6 +139,7 @@ function Trace({
return ( return (
<> <>
{NotificationElement}
<Search /> <Search />
<Container> <Container>
<div> <div>
@ -155,11 +167,15 @@ function Trace({
} }
interface DispatchProps { interface DispatchProps {
getSpansAggregate: (props: GetSpansAggregateProps) => void; getSpansAggregate: (
getSpans: (props: GetSpansProps) => void; props: GetSpansAggregateProps,
notify: NotificationInstance,
) => void;
getSpans: (props: GetSpansProps, notify: NotificationInstance) => void;
getInitialFilter: ( getInitialFilter: (
minTime: GlobalReducer['minTime'], minTime: GlobalReducer['minTime'],
maxTime: GlobalReducer['maxTime'], maxTime: GlobalReducer['maxTime'],
notify: NotificationInstance,
) => void; ) => void;
} }

View File

@ -1,4 +1,4 @@
import { notification } from 'antd'; import { NotificationInstance } from 'antd/es/notification/interface';
import update from 'api/dashboard/update'; import update from 'api/dashboard/update';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import store from 'store/index'; import store from 'store/index';
@ -8,6 +8,7 @@ import { IDashboardVariable } from 'types/api/dashboard/getAll';
export const UpdateDashboardVariables = ( export const UpdateDashboardVariables = (
variables: Record<string, IDashboardVariable>, variables: Record<string, IDashboardVariable>,
notify: NotificationInstance,
): ((dispatch: Dispatch<AppActions>) => void) => async ( ): ((dispatch: Dispatch<AppActions>) => void) => async (
dispatch: Dispatch<AppActions>, dispatch: Dispatch<AppActions>,
): Promise<void> => { ): Promise<void> => {
@ -28,7 +29,7 @@ export const UpdateDashboardVariables = (
}); });
if (response.statusCode !== 200) { if (response.statusCode !== 200) {
notification.error({ notify.error({
message: response.error, message: response.error,
}); });
} }

View File

@ -1,4 +1,4 @@
import { notification } from 'antd'; import { NotificationInstance } from 'antd/es/notification/interface';
import getFiltersApi from 'api/trace/getFilters'; import getFiltersApi from 'api/trace/getFilters';
import xor from 'lodash-es/xor'; import xor from 'lodash-es/xor';
import { Dispatch, Store } from 'redux'; import { Dispatch, Store } from 'redux';
@ -29,6 +29,7 @@ import {
export const GetInitialTraceFilter = ( export const GetInitialTraceFilter = (
minTime: GlobalReducer['minTime'], minTime: GlobalReducer['minTime'],
maxTime: GlobalReducer['maxTime'], maxTime: GlobalReducer['maxTime'],
notify: NotificationInstance,
): (( ): ((
dispatch: Dispatch<AppActions>, dispatch: Dispatch<AppActions>,
getState: Store<AppState>['getState'], getState: Store<AppState>['getState'],
@ -166,7 +167,7 @@ export const GetInitialTraceFilter = (
}, },
}); });
} else { } else {
notification.error({ notify.error({
message: response.error || 'Something went wrong', message: response.error || 'Something went wrong',
}); });
} }

View File

@ -1,4 +1,4 @@
import { notification } from 'antd'; import { NotificationInstance } from 'antd/es/notification/interface';
import getSpansAggregate from 'api/trace/getSpansAggregate'; import getSpansAggregate from 'api/trace/getSpansAggregate';
import { Dispatch, Store } from 'redux'; import { Dispatch, Store } from 'redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
@ -12,6 +12,7 @@ import { updateURL } from './util';
export const GetSpansAggregate = ( export const GetSpansAggregate = (
props: GetSpansAggregateProps, props: GetSpansAggregateProps,
notify: NotificationInstance,
): (( ): ((
dispatch: Dispatch<AppActions>, dispatch: Dispatch<AppActions>,
getState: Store<AppState>['getState'], getState: Store<AppState>['getState'],
@ -91,7 +92,7 @@ export const GetSpansAggregate = (
spansAggregate.orderParam, spansAggregate.orderParam,
); );
} else { } else {
notification.error({ notify.error({
message: response.error || 'Something went wrong', message: response.error || 'Something went wrong',
}); });

View File

@ -1,4 +1,4 @@
import { notification } from 'antd'; import { NotificationInstance } from 'antd/es/notification/interface';
import getSpans from 'api/trace/getSpans'; import getSpans from 'api/trace/getSpans';
import { Dispatch, Store } from 'redux'; import { Dispatch, Store } from 'redux';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
@ -12,6 +12,7 @@ import { Props } from 'types/api/trace/getSpans';
export const GetSpans = ( export const GetSpans = (
props: GetSpansProps, props: GetSpansProps,
notify: NotificationInstance,
): (( ): ((
dispatch: Dispatch<AppActions>, dispatch: Dispatch<AppActions>,
getState: Store<AppState>['getState'], getState: Store<AppState>['getState'],
@ -72,7 +73,7 @@ export const GetSpans = (
}, },
}); });
} else { } else {
notification.error({ notify.error({
message: response.error || defaultMessage, message: response.error || defaultMessage,
}); });
dispatch({ dispatch({