Skip to content

Commit

Permalink
fix: Refactor notifications (#498)
Browse files Browse the repository at this point in the history
  • Loading branch information
callmevladik authored and MykolaMarusenko committed Nov 21, 2024
1 parent ec015d4 commit 3113089
Show file tree
Hide file tree
Showing 14 changed files with 468 additions and 235 deletions.
8 changes: 3 additions & 5 deletions src/hooks/useResourceCRUDMutation/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,9 @@ describe('testing useResourceCRUDMutation hook', () => {
expect(result.current.data).toEqual(mutationDataMock);
expect(result.current.variables).toEqual(mutationDataMock);
expect(mockShowBeforeRequestMessage).toHaveBeenCalledWith(CRUD_TYPES.CREATE, {
customMessage: undefined,
entityName: `${result.current.variables.kind} ${result.current.variables.metadata.name}`,
});
expect(mockShowRequestSuccessMessage).toHaveBeenCalledWith(CRUD_TYPES.CREATE, {
customMessage: undefined,
entityName: `${result.current.variables.kind} ${result.current.variables.metadata.name}`,
});
expect(mockShowRequestErrorMessage).not.toHaveBeenCalled();
Expand All @@ -90,16 +88,16 @@ describe('testing useResourceCRUDMutation hook', () => {
expect(result.current.isError).toBe(true);
expect(result.current.error).toEqual({ error: 'error' });
expect(result.current.variables).toEqual(mutationDataMock);

expect(mockShowBeforeRequestMessage).toHaveBeenCalledWith(CRUD_TYPES.EDIT, {
customMessage: undefined,
entityName: `${result.current.variables.kind} ${result.current.variables.metadata.name}`,
});

expect(mockShowRequestSuccessMessage).not.toHaveBeenCalled();

expect(mockShowRequestErrorMessage).toHaveBeenCalledWith(CRUD_TYPES.EDIT, {
customMessage: undefined,
entityName: `${result.current.variables.kind} ${result.current.variables.metadata.name}`,
});
expect(mockShowRequestErrorDetailedMessage).toHaveBeenCalledWith(result.current.error);
});
});
});
101 changes: 0 additions & 101 deletions src/hooks/useResourceCRUDMutation/index.ts

This file was deleted.

216 changes: 216 additions & 0 deletions src/hooks/useResourceCRUDMutation/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import { KubeObjectIface } from '@kinvolk/headlamp-plugin/lib/lib/k8s/cluster';
import { OptionsObject } from 'notistack';
import React from 'react';
import { useMutation, UseMutationResult } from 'react-query';
import { Snackbar } from '../../components/Snackbar';
import { CRUD_TYPES } from '../../constants/crudTypes';
import { EDPKubeObjectInterface } from '../../types/k8s';
import { getDefaultNamespace } from '../../utils/getDefaultNamespace';
import { useRequestStatusMessages } from '../useResourceRequestStatusMessages';

type UseResourceCRUDMutationReturnType<
KubeObjectData,
Mode extends CRUD_TYPES
> = Mode extends CRUD_TYPES.DELETE ? void : KubeObjectData;

interface Message {
message: string;
options?: OptionsObject;
}

type CustomMessages = {
onMutate?: Message;
onError?: Message;
onSuccess?: Message;
};

interface Options<KubeObjectData> {
createCustomMessages?: (item: KubeObjectData) => CustomMessages;
showMessages?: boolean;
}

export const useResourceCRUDMutation = <
KubeObjectData extends EDPKubeObjectInterface,
Mode extends CRUD_TYPES
>(
mutationKey: string,
kubeObject: KubeObjectIface<any>,
mode: Mode,
options?: Options<KubeObjectData>
): UseMutationResult<
UseResourceCRUDMutationReturnType<KubeObjectData, Mode>,
Error,
KubeObjectData
> => {
const showMessages = options?.showMessages ?? true;

const {
showBeforeRequestMessage,
showRequestErrorMessage,
showRequestSuccessMessage,
showRequestErrorDetailedMessage,
closeSnackbar,
} = useRequestStatusMessages();

const namespace = getDefaultNamespace();

return useMutation<
UseResourceCRUDMutationReturnType<KubeObjectData, Mode>,
Error,
KubeObjectData
>(
mutationKey,
(data) => {
let dataCopy = { ...data };

if (!data.metadata?.namespace) {
dataCopy = {
...dataCopy,
metadata: {
...dataCopy.metadata,
namespace,
},
};
}

switch (mode) {
case CRUD_TYPES.CREATE:
return kubeObject.apiEndpoint.post(dataCopy);
case CRUD_TYPES.EDIT:
return kubeObject.apiEndpoint.put(dataCopy);
case CRUD_TYPES.DELETE:
return kubeObject.apiEndpoint.delete(dataCopy.metadata.namespace, dataCopy.metadata.name);
}
},
{
onMutate: (variables) => {
if (!showMessages) {
return;
}

if (!options?.createCustomMessages) {
showBeforeRequestMessage(mode, {
entityName: `${variables.kind} ${variables.metadata.name}`,
});
return;
}

const defaultOptions = {
autoHideDuration: 2000,
anchorOrigin: {
vertical: 'bottom',
horizontal: 'left',
},
variant: 'info',
content: (key, message) => (
<Snackbar
text={String(message)}
handleClose={() => closeSnackbar(key)}
variant="info"
/>
),
} as const;

const customMessage = options?.createCustomMessages(variables)?.onMutate;

const mergedOptions: OptionsObject = {
...defaultOptions,
...(customMessage?.options || {}),
};

showBeforeRequestMessage(mode, {
customMessage: {
message: customMessage.message,
options: mergedOptions,
},
});
},
onSuccess: (data, variables) => {
if (!showMessages) {
return;
}

if (!options?.createCustomMessages) {
showRequestSuccessMessage(mode, {
entityName: `${variables.kind} ${variables.metadata.name}`,
});
return;
}

const defaultOptions = {
autoHideDuration: 5000,
anchorOrigin: {
vertical: 'bottom',
horizontal: 'left',
},
variant: 'success',
content: (key, message) => (
<Snackbar
text={String(message)}
handleClose={() => closeSnackbar(key)}
variant="success"
/>
),
} as const;

const customMessage = options?.createCustomMessages(variables)?.onSuccess;

const mergedOptions: OptionsObject = {
...defaultOptions,
...(customMessage?.options || {}),
};

showRequestSuccessMessage(mode, {
customMessage: {
message: customMessage.message,
options: mergedOptions,
},
});
},
onError: (error, variables) => {
if (!showMessages) {
return;
}

if (!options?.createCustomMessages) {
showRequestErrorMessage(mode, {
entityName: `${variables.kind} ${variables.metadata.name}`,
});
return;
}

const defaultOptions = {
autoHideDuration: 5000,
anchorOrigin: {
vertical: 'bottom',
horizontal: 'left',
},
variant: 'error',
content: (key, message) => (
<Snackbar
text={String(message)}
handleClose={() => closeSnackbar(key)}
variant="error"
/>
),
} as const;

const customMessage = options?.createCustomMessages(variables)?.onError;

const mergedOptions: OptionsObject = {
...defaultOptions,
...(customMessage?.options || {}),
};

showRequestErrorMessage(mode, {
customMessage: {
message: customMessage.message,
options: mergedOptions,
},
});
showRequestErrorDetailedMessage(error);
console.error(error);
},
}
);
};
Loading

0 comments on commit 3113089

Please sign in to comment.