Label error handling tweaks (#4687)
# What this PR does
These changes make it so that we no longer show an error notification
when you first add an empty pair `key/value` due to the undefined key.
Other than that, the handling remains the same, with some refactorings
as we don't need the try catch clauses.
Would be nice in the future to find a way not to duplicate the usage of
those 2 functions that fetch the key and the value and share them
somehow 🤔
This commit is contained in:
parent
35ddfab0e4
commit
0325e2af02
8 changed files with 27 additions and 62 deletions
|
|
@ -26,6 +26,7 @@ import { ApiSchemas } from 'network/oncall-api/api.types';
|
||||||
import { components } from 'network/oncall-api/autogenerated-api.types';
|
import { components } from 'network/oncall-api/autogenerated-api.types';
|
||||||
import { useStore } from 'state/useStore';
|
import { useStore } from 'state/useStore';
|
||||||
import { UserActions } from 'utils/authorization/authorization';
|
import { UserActions } from 'utils/authorization/authorization';
|
||||||
|
import { PROCESSING_REQUEST_ERROR } from 'utils/consts';
|
||||||
import { WrapWithGlobalNotification } from 'utils/decorators';
|
import { WrapWithGlobalNotification } from 'utils/decorators';
|
||||||
import { useDebouncedCallback, useIsLoading } from 'utils/hooks';
|
import { useDebouncedCallback, useIsLoading } from 'utils/hooks';
|
||||||
import { pluralize } from 'utils/utils';
|
import { pluralize } from 'utils/utils';
|
||||||
|
|
@ -142,7 +143,7 @@ export const ColumnsModal: React.FC<ColumnsModalProps> = observer(
|
||||||
variant="primary"
|
variant="primary"
|
||||||
onClick={WrapWithGlobalNotification(onAddNewColumns, {
|
onClick={WrapWithGlobalNotification(onAddNewColumns, {
|
||||||
success: 'New column has been added to the list.',
|
success: 'New column has been added to the list.',
|
||||||
failure: 'There was an error processing your request. Please try again.',
|
failure: PROCESSING_REQUEST_ERROR,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{isLoading ? <LoadingPlaceholder className={cx('loadingPlaceholder')} text="Loading..." /> : 'Add'}
|
{isLoading ? <LoadingPlaceholder className={cx('loadingPlaceholder')} text="Loading..." /> : 'Add'}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { ActionKey } from 'models/loader/action-keys';
|
||||||
import { ApiSchemas } from 'network/oncall-api/api.types';
|
import { ApiSchemas } from 'network/oncall-api/api.types';
|
||||||
import { useStore } from 'state/useStore';
|
import { useStore } from 'state/useStore';
|
||||||
import { UserActions } from 'utils/authorization/authorization';
|
import { UserActions } from 'utils/authorization/authorization';
|
||||||
|
import { PROCESSING_REQUEST_ERROR } from 'utils/consts';
|
||||||
import { WrapAutoLoadingState, WrapWithGlobalNotification } from 'utils/decorators';
|
import { WrapAutoLoadingState, WrapWithGlobalNotification } from 'utils/decorators';
|
||||||
import { useIsLoading } from 'utils/hooks';
|
import { useIsLoading } from 'utils/hooks';
|
||||||
|
|
||||||
|
|
@ -81,7 +82,7 @@ export const ColumnsSelectorWrapper: React.FC<ColumnsSelectorWrapperProps> = obs
|
||||||
onClick={WrapAutoLoadingState(
|
onClick={WrapAutoLoadingState(
|
||||||
WrapWithGlobalNotification(onColumnRemovalClick, {
|
WrapWithGlobalNotification(onColumnRemovalClick, {
|
||||||
success: 'Column has been removed from the list.',
|
success: 'Column has been removed from the list.',
|
||||||
failure: 'There was an error processing your request. Please try again',
|
failure: PROCESSING_REQUEST_ERROR,
|
||||||
}),
|
}),
|
||||||
ActionKey.REMOVE_COLUMN_FROM_ALERT_GROUP
|
ActionKey.REMOVE_COLUMN_FROM_ALERT_GROUP
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -284,32 +284,16 @@ const CustomLabels = (props: CustomLabelsProps) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLoadKeys = async (search?: string) => {
|
const onLoadKeys = async (search?: string) => {
|
||||||
let result = undefined;
|
const result = await labelsStore.loadKeys(search);
|
||||||
|
return splitToGroups(result);
|
||||||
try {
|
|
||||||
result = await labelsStore.loadKeys(search);
|
|
||||||
} catch (error) {
|
|
||||||
openErrorNotification('There was an error processing your request. Please try again');
|
|
||||||
}
|
|
||||||
|
|
||||||
const groups = splitToGroups(result);
|
|
||||||
|
|
||||||
return groups;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLoadValuesForKey = async (key: string, search?: string) => {
|
const onLoadValuesForKey = async (key: string, search?: string) => {
|
||||||
let result = undefined;
|
if (!key) {
|
||||||
|
return [];
|
||||||
try {
|
|
||||||
const { values } = await labelsStore.loadValuesForKey(key, search);
|
|
||||||
result = values;
|
|
||||||
} catch (error) {
|
|
||||||
openErrorNotification('There was an error processing your request. Please try again');
|
|
||||||
}
|
}
|
||||||
|
const { values } = await labelsStore.loadValuesForKey(key, search);
|
||||||
const groups = splitToGroups(result);
|
return splitToGroups(values);
|
||||||
|
|
||||||
return groups;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -49,30 +49,16 @@ const _Labels = observer(
|
||||||
);
|
);
|
||||||
|
|
||||||
const onLoadKeys = async (search?: string) => {
|
const onLoadKeys = async (search?: string) => {
|
||||||
let result = undefined;
|
const result = await labelsStore.loadKeys(search);
|
||||||
try {
|
return splitToGroups(result);
|
||||||
result = await labelsStore.loadKeys(search);
|
|
||||||
} catch (error) {
|
|
||||||
openErrorNotification('There was an error processing your request. Please try again');
|
|
||||||
}
|
|
||||||
|
|
||||||
const groups = splitToGroups(result);
|
|
||||||
|
|
||||||
return groups;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLoadValuesForKey = async (key: string, search?: string) => {
|
const onLoadValuesForKey = async (key: string, search?: string) => {
|
||||||
let result = undefined;
|
if (!key) {
|
||||||
try {
|
return [];
|
||||||
const { values } = await labelsStore.loadValuesForKey(key, search);
|
|
||||||
result = values;
|
|
||||||
} catch (error) {
|
|
||||||
openErrorNotification('There was an error processing your request. Please try again');
|
|
||||||
}
|
}
|
||||||
|
const { values } = await labelsStore.loadValuesForKey(key, search);
|
||||||
const groups = splitToGroups(result);
|
return splitToGroups(values);
|
||||||
|
|
||||||
return groups;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isValid = () => {
|
const isValid = () => {
|
||||||
|
|
|
||||||
|
|
@ -32,28 +32,17 @@ export const RouteLabelsDisplay: React.FC<RouteLabelsDisplayProps> = ({ labels,
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLoadKeys = async (search?: string) => {
|
const onLoadKeys = async (search?: string) => {
|
||||||
let result = undefined;
|
const result = await labelsStore.loadKeys(search);
|
||||||
|
|
||||||
try {
|
|
||||||
result = await labelsStore.loadKeys(search);
|
|
||||||
} catch (error) {
|
|
||||||
openErrorNotification('There was an error processing your request. Please try again');
|
|
||||||
}
|
|
||||||
|
|
||||||
return splitToGroups(result);
|
return splitToGroups(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLoadValuesForKey = async (key: string, search?: string) => {
|
const onLoadValuesForKey = async (key: string, search?: string) => {
|
||||||
let result = undefined;
|
if (!key) {
|
||||||
|
return [];
|
||||||
try {
|
|
||||||
const { values } = await labelsStore.loadValuesForKey(key, search);
|
|
||||||
result = values;
|
|
||||||
} catch (error) {
|
|
||||||
openErrorNotification('There was an error processing your request. Please try again');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return splitToGroups(result);
|
const { values } = await labelsStore.loadValuesForKey(key, search);
|
||||||
|
return splitToGroups(values);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { onCallApi } from 'network/oncall-api/http-client';
|
||||||
import { RootStore } from 'state/rootStore';
|
import { RootStore } from 'state/rootStore';
|
||||||
import { SelectOption } from 'state/types';
|
import { SelectOption } from 'state/types';
|
||||||
import { LocationHelper } from 'utils/LocationHelper';
|
import { LocationHelper } from 'utils/LocationHelper';
|
||||||
import { GENERIC_ERROR, PAGE } from 'utils/consts';
|
import { GENERIC_ERROR, PAGE, PROCESSING_REQUEST_ERROR } from 'utils/consts';
|
||||||
import { AutoLoadingState, WithGlobalNotification } from 'utils/decorators';
|
import { AutoLoadingState, WithGlobalNotification } from 'utils/decorators';
|
||||||
|
|
||||||
import { AlertGroupHelper } from './alertgroup.helpers';
|
import { AlertGroupHelper } from './alertgroup.helpers';
|
||||||
|
|
@ -136,7 +136,7 @@ export class AlertGroupStore {
|
||||||
@AutoLoadingState(ActionKey.REMOVE_COLUMN_FROM_ALERT_GROUP)
|
@AutoLoadingState(ActionKey.REMOVE_COLUMN_FROM_ALERT_GROUP)
|
||||||
@WithGlobalNotification({
|
@WithGlobalNotification({
|
||||||
success: 'Column has been removed from the list.',
|
success: 'Column has been removed from the list.',
|
||||||
failure: 'There was an error processing your request. Please try again',
|
failure: PROCESSING_REQUEST_ERROR,
|
||||||
})
|
})
|
||||||
async removeTableColumn(
|
async removeTableColumn(
|
||||||
columnToBeRemoved: AlertGroupColumn,
|
columnToBeRemoved: AlertGroupColumn,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { ApiSchemas } from 'network/oncall-api/api.types';
|
||||||
import { components } from 'network/oncall-api/autogenerated-api.types';
|
import { components } from 'network/oncall-api/autogenerated-api.types';
|
||||||
import { onCallApi } from 'network/oncall-api/http-client';
|
import { onCallApi } from 'network/oncall-api/http-client';
|
||||||
import { RootStore } from 'state/rootStore';
|
import { RootStore } from 'state/rootStore';
|
||||||
|
import { PROCESSING_REQUEST_ERROR } from 'utils/consts';
|
||||||
import { WithGlobalNotification } from 'utils/decorators';
|
import { WithGlobalNotification } from 'utils/decorators';
|
||||||
|
|
||||||
export class LabelStore extends BaseStore {
|
export class LabelStore extends BaseStore {
|
||||||
|
|
@ -17,6 +18,7 @@ export class LabelStore extends BaseStore {
|
||||||
this.path = '/labels/';
|
this.path = '/labels/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WithGlobalNotification({ failure: PROCESSING_REQUEST_ERROR })
|
||||||
@action.bound
|
@action.bound
|
||||||
public async loadKeys(search = ''): Promise<Array<components['schemas']['LabelKey']>> {
|
public async loadKeys(search = ''): Promise<Array<components['schemas']['LabelKey']>> {
|
||||||
const { data } = await onCallApi().GET('/labels/keys/', undefined);
|
const { data } = await onCallApi().GET('/labels/keys/', undefined);
|
||||||
|
|
@ -26,6 +28,7 @@ export class LabelStore extends BaseStore {
|
||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WithGlobalNotification({ failure: PROCESSING_REQUEST_ERROR })
|
||||||
@action.bound
|
@action.bound
|
||||||
async loadValuesForKey(
|
async loadValuesForKey(
|
||||||
key: ApiSchemas['LabelKey']['id'],
|
key: ApiSchemas['LabelKey']['id'],
|
||||||
|
|
|
||||||
|
|
@ -97,5 +97,6 @@ export enum OnCallAGStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GENERIC_ERROR = 'An error has occurred. Please try again';
|
export const GENERIC_ERROR = 'An error has occurred. Please try again';
|
||||||
|
export const PROCESSING_REQUEST_ERROR = 'There was an error processing your request. Please try again';
|
||||||
|
|
||||||
export const INTEGRATION_SERVICENOW = 'servicenow';
|
export const INTEGRATION_SERVICENOW = 'servicenow';
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue