Skip to content

Commit

Permalink
feat(explorer): delete linked value action (#711)
Browse files Browse the repository at this point in the history
  • Loading branch information
evoiron authored Jan 17, 2025
1 parent 412fb2f commit 67cd90e
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ const LibraryHome: FunctionComponent<ILibraryHomeProps> = ({library}) => {
type: 'library',
libraryId: library
}}
defaultActionsForItem={['edit', 'deactivate']}
defaultActionsForItem={['edit', 'remove']}
defaultPrimaryActions={['create']}
itemActions={[
{
Expand Down
32 changes: 31 additions & 1 deletion libs/ui/src/components/Explorer/Explorer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,36 @@ describe('Explorer', () => {
expect(mockDeactivateMutation).toHaveBeenCalled();
});

test('Should be able to delete a linked record with default actions', async () => {
const mockDeleteValueMutation = jest.fn().mockReturnValue({
data: {
deleteValue: [
{
id_value: 0,
linkValue: mockRecords[0]
}
]
}
});

jest.spyOn(gqlTypes, 'useDeleteValueMutation').mockImplementation(() => [
mockDeleteValueMutation,
{loading: false, called: false, client: {} as any, reset: jest.fn()}
]);

render(<Explorer entrypoint={linkEntrypoint} />, {
mocks: [ExplorerLinkAttributeQueryMock]
});

const [_columnNameRow, firstRecordRow] = await screen.findAllByRole('row');
await user.click(within(firstRecordRow).getByRole('button', {name: 'explorer.delete-item'}));

expect(screen.getByText('record_edition.delete_link_confirm')).toBeVisible();
await user.click(screen.getByText('global.submit'));

expect(mockDeleteValueMutation).toHaveBeenCalled();
});

test('Should be able to edit a record with default actions', async () => {
render(<Explorer entrypoint={libraryEntrypoint} />);

Expand Down Expand Up @@ -972,7 +1002,7 @@ describe('Explorer', () => {
describe('Entrypoint type link', () => {
test('Should display the list of linked records', async () => {
const actionCallback = jest.fn();
const {container} = render(
render(
<Explorer
entrypoint={linkEntrypoint}
primaryActions={customPrimaryActions}
Expand Down
17 changes: 10 additions & 7 deletions libs/ui/src/components/Explorer/Explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import styled from 'styled-components';
import {DefaultViewSettings, Entrypoint, IItemAction, IPrimaryAction} from './_types';
import {useExplorerData} from './_queries/useExplorerData';
import {DataView} from './DataView';
import {useDeactivateAction} from './useDeactivateAction';
import {useRemoveAction} from './useRemoveAction';
import {useEditAction} from './useEditAction';
import {usePrimaryActionsButton} from './usePrimaryActions';
import {ExplorerTitle} from './ExplorerTitle';
Expand Down Expand Up @@ -52,7 +52,7 @@ interface IExplorerProps {
itemActions?: IItemAction[];
primaryActions?: IPrimaryAction[];
title?: string;
defaultActionsForItem?: Array<'edit' | 'deactivate'>;
defaultActionsForItem?: Array<'edit' | 'remove'>;
defaultPrimaryActions?: Array<'create'>;
defaultViewSettings?: DefaultViewSettings;
}
Expand All @@ -63,7 +63,7 @@ export const Explorer: FunctionComponent<IExplorerProps> = ({
primaryActions,
title,
noPagination,
defaultActionsForItem = ['edit', 'deactivate'],
defaultActionsForItem = ['edit', 'remove'],
defaultPrimaryActions = ['create'],
defaultViewSettings
}) => {
Expand All @@ -90,9 +90,12 @@ export const Explorer: FunctionComponent<IExplorerProps> = ({
skip: viewSettingsLoading
}); // TODO: refresh when go back on page

const {deactivateAction} = useDeactivateAction({
isEnabled: isNotEmpty(defaultActionsForItem) && defaultActionsForItem.includes('deactivate')
});
const {removeAction} = useRemoveAction(
{
isEnabled: isNotEmpty(defaultActionsForItem) && defaultActionsForItem.includes('remove')
},
entrypoint
);

const {editAction, editModal} = useEditAction({
isEnabled: isNotEmpty(defaultActionsForItem) && defaultActionsForItem.includes('edit')
Expand Down Expand Up @@ -151,7 +154,7 @@ export const Explorer: FunctionComponent<IExplorerProps> = ({
}
: undefined
}
itemActions={[editAction, deactivateAction, ...(itemActions ?? emptyArray)].filter(Boolean)}
itemActions={[editAction, removeAction, ...(itemActions ?? emptyArray)].filter(Boolean)}
/>
)}
</ExplorerPageDivStyled>
Expand Down
60 changes: 0 additions & 60 deletions libs/ui/src/components/Explorer/useDeactivateAction.tsx

This file was deleted.

101 changes: 101 additions & 0 deletions libs/ui/src/components/Explorer/useRemoveAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright LEAV Solutions 2017 until 2023/11/05, Copyright Aristid from 2023/11/06
// This file is released under LGPL V3
// License text available at https://www.gnu.org/licenses/lgpl-3.0.txt
import {FaTrash} from 'react-icons/fa';
import {KitModal} from 'aristid-ds';
import {useDeactivateRecordsMutation, useDeleteValueMutation} from '_ui/_gqlTypes';
import {useSharedTranslation} from '_ui/hooks/useSharedTranslation';
import {ActionHook, Entrypoint, IEntrypointLink, IItemAction} from './_types';
import {useMemo} from 'react';
import {useValuesCacheUpdate} from '_ui/hooks';

/**
* Hook used to get the action for `<DataView />` component.
*
* When the mutation for removing is done, the Apollo cache will be clean (`Record` and `RecordIdentity`)
* from removed record.
*
* @param isEnabled - whether the action is present
*/
export const useRemoveAction = (
{isEnabled}: ActionHook,
entrypoint: Entrypoint
): {removeAction: IItemAction | null} => {
const {t} = useSharedTranslation();
const updateValuesCache = useValuesCacheUpdate();

const [deactivateRecordsMutation] = useDeactivateRecordsMutation({
update(cache, deactivatedRecords) {
deactivatedRecords.data?.deactivateRecords.forEach(record => {
cache.evict({
id: cache.identify(record)
});
});
cache.gc();
}
});

const [deleteRecordLinkMutation] = useDeleteValueMutation({
update: (_, deletedRecord) => {
const parentRecord = {
id: (entrypoint as IEntrypointLink).parentRecordId,
library: {
id: (entrypoint as IEntrypointLink).parentLibraryId
}
};
updateValuesCache(parentRecord, deletedRecord.data?.deleteValue ?? []);
}
});

const _removeAction: IItemAction = useMemo(
() => ({
label: entrypoint.type === 'library' ? t('explorer.deactivate-item') : t('explorer.delete-item'),
icon: <FaTrash />,
isDanger: true,
callback: ({itemId, libraryId, id_value}) => {
KitModal.confirm({
type: 'confirm',
dangerConfirm: true,
content:
entrypoint.type === 'library'
? t('records_deactivation.confirm_one')
: t('record_edition.delete_link_confirm'),
okText: t('global.submit') ?? undefined,
cancelText: t('global.cancel') ?? undefined,
onOk: () => {
switch (entrypoint.type) {
case 'library':
deactivateRecordsMutation({
variables: {
libraryId,
recordsIds: [itemId]
}
});
break;
case 'link':
deleteRecordLinkMutation({
variables: {
library: entrypoint.parentLibraryId,
attribute: entrypoint.linkAttributeId,
recordId: entrypoint.parentRecordId,
value: {
payload: itemId,
id_value
}
}
});
break;
default:
return;
}
}
});
}
}),
[t, deactivateRecordsMutation, deleteRecordLinkMutation, entrypoint.type]
);

return {
removeAction: isEnabled ? _removeAction : null
};
};
4 changes: 3 additions & 1 deletion libs/ui/src/locales/en/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@
"add_value_link": "Add link",
"delete_value": "Delete value",
"delete_value_confirm": "Do you really want to delete this value?",
"delete_link_confirm": "Do you really want to delete this link?",
"whoAmI": "Information",
"no_value": "No value",
"value_details": "Value details",
Expand Down Expand Up @@ -626,7 +627,8 @@
"create-one": "Create",
"actions": "Actions",
"more-actions": "Show more",
"deactivate-item": "Deactivate item",
"deactivate-item": "Deactivate",
"delete-item": "Delete",
"edit-item": "Edit item",
"settings": "Settings",
"back": "Back",
Expand Down
4 changes: 3 additions & 1 deletion libs/ui/src/locales/fr/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@
"add_value_link": "Ajouter une liaison",
"delete_value": "Supprimer cette valeur",
"delete_value_confirm": "Êtes-vous sûr de vouloir supprimer cette valeur?",
"delete_link_confirm": "Êtes-vous sûr de vouloir supprimer cette liaison?",
"whoAmI": "Informations",
"no_value": "Pas de valeur",
"value_details": "Infos valeur",
Expand Down Expand Up @@ -626,7 +627,8 @@
"create-one": "Créer",
"actions": "Actions",
"more-actions": "Voir plus",
"deactivate-item": "Désactiver l’élément",
"deactivate-item": "Désactiver",
"delete-item": "Supprimer",
"edit-item": "Éditer l’élément",
"settings": "Paramètres",
"back": "Retour",
Expand Down

0 comments on commit 67cd90e

Please sign in to comment.