Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(content-manager): delete and unpublish bulk actions migration to v5 #20213

Closed
4 changes: 2 additions & 2 deletions packages/core/admin/admin/src/components/Table.tsx
Expand Up @@ -412,8 +412,8 @@ const CheckboxCell = ({ id, ...props }: Table.CheckboxCellProps) => {
<Cell {...props} onClick={(e) => e.stopPropagation()}>
<BaseCheckbox
aria-label={formatMessage({
id: 'global.select-all-entries',
defaultMessage: 'Select all entries',
id: 'global.select',
defaultMessage: 'Select',
})}
disabled={rows.length === 0}
checked={isChecked}
Expand Down
3 changes: 3 additions & 0 deletions packages/core/admin/admin/src/features/Tracking.tsx
Expand Up @@ -98,6 +98,7 @@ interface EventWithoutProperties {
| 'didAccessAuthenticatedAdministration'
| 'didAddComponentToDynamicZone'
| 'didBulkDeleteEntries'
| 'didNotBulkDeleteEntries'
| 'didChangeDisplayedFields'
| 'didCheckDraftRelations'
| 'didClickGuidedTourHomepageApiTokens'
Expand Down Expand Up @@ -132,6 +133,8 @@ interface EventWithoutProperties {
| 'didPluginLearnMore'
| 'didPublishEntry'
| 'didUnpublishEntry'
| 'didBulkUnpublishEntries'
| 'didNotBulkUnpublishEntries'
| 'didSaveComponent'
| 'didSaveContentType'
| 'didSearch'
Expand Down
110 changes: 108 additions & 2 deletions packages/core/content-manager/admin/src/hooks/useDocumentActions.ts
Expand Up @@ -14,10 +14,12 @@ import {
useCloneDocumentMutation,
useCreateDocumentMutation,
useDeleteDocumentMutation,
useDeleteManyDocumentsMutation,
useDiscardDocumentMutation,
useLazyGetDocumentQuery,
usePublishDocumentMutation,
useUnpublishDocumentMutation,
useUnpublishManyDocumentsMutation,
useUpdateDocumentMutation,
} from '../services/documents';
import { BaseQueryError } from '../utils/api';
Expand All @@ -29,21 +31,24 @@ import type {
Clone,
Create,
Delete,
BulkDelete,
Discard,
FindOne,
Publish,
Update,
Unpublish,
BulkUnpublish,
} from '../../../shared/contracts/collection-types';

const DEFAULT_UNEXPECTED_ERROR_MSG = {
id: 'notification.error',
defaultMessage: 'An error occurred, please try again',
} satisfies MessageDescriptor;

type OperationResponse<TResponse extends { data: any; meta: any; error?: any }> =
type OperationResponse<TResponse extends { data: any; meta?: any; error?: any }> =
| Pick<TResponse, 'data' | 'meta'>
| { error: BaseQueryError | SerializedError };
| { error: BaseQueryError | SerializedError }
| Pick<TResponse, 'data'>;
madhurisandbhor marked this conversation as resolved.
Show resolved Hide resolved

type UseDocumentActions = () => {
/**
Expand Down Expand Up @@ -90,6 +95,11 @@ type UseDocumentActions = () => {
{ name: 'willDeleteEntry' | 'didDeleteEntry' | 'didNotDeleteEntry' }
>['properties']
) => Promise<OperationResponse<Delete.Response>>;
deleteMany: (args: {
model: string;
documentIds: string[];
params?: object;
}) => Promise<OperationResponse<BulkDelete.Response>>;
discard: (args: {
collectionType: string;
model: string;
Expand Down Expand Up @@ -133,6 +143,11 @@ type UseDocumentActions = () => {
},
discardDraft?: boolean
) => Promise<OperationResponse<Unpublish.Response>>;
unpublishMany: (args: {
model: string;
documentIds: string[];
params?: object;
}) => Promise<OperationResponse<BulkUnpublish.Response>>;
};

type IUseDocumentActs = ReturnType<UseDocumentActions>;
Expand Down Expand Up @@ -213,6 +228,53 @@ const useDocumentActions: UseDocumentActions = () => {
[trackUsage, deleteDocument, toggleNotification, formatMessage, formatAPIError]
);

const [deleteManyDocuments] = useDeleteManyDocumentsMutation();

const deleteMany: IUseDocumentActs['deleteMany'] = React.useCallback(
async ({ model, documentIds, params }) => {
try {
trackUsage('willBulkDeleteEntries');

const res = await deleteManyDocuments({
model,
documentIds,
params,
});

if ('error' in res) {
toggleNotification({
type: 'danger',
message: formatAPIError(res.error),
});

return { error: res.error };
}

toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation('success.records.delete'),
defaultMessage: 'Successfully deleted.',
}),
});

trackUsage('didBulkDeleteEntries');

return res.data;
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG),
});

trackUsage('didNotBulkDeleteEntries');

throw err;
}
},
[trackUsage, deleteManyDocuments, toggleNotification, formatMessage, formatAPIError]
);

const [discardDocument] = useDiscardDocumentMutation();
const discard: IUseDocumentActs['discard'] = React.useCallback(
async ({ collectionType, model, documentId }) => {
Expand Down Expand Up @@ -386,6 +448,48 @@ const useDocumentActions: UseDocumentActions = () => {
[trackUsage, unpublishDocument, toggleNotification, formatMessage, formatAPIError]
);

const [unpublishManyDocuments] = useUnpublishManyDocumentsMutation();
const unpublishMany: IUseDocumentActs['unpublishMany'] = React.useCallback(
async ({ model, documentIds }) => {
try {
trackUsage('willBulkUnpublishEntries');

const res = await unpublishManyDocuments({
model,
documentIds,
});

if ('error' in res) {
toggleNotification({ type: 'danger', message: formatAPIError(res.error) });

return { error: res.error };
}

trackUsage('didBulkUnpublishEntries');

toggleNotification({
type: 'success',
message: formatMessage({
id: getTranslation('success.records.unpublish'),
defaultMessage: 'Successfully unpublished.',
}),
});

return res.data;
} catch (err) {
toggleNotification({
type: 'danger',
message: formatMessage(DEFAULT_UNEXPECTED_ERROR_MSG),
});

trackUsage('didNotBulkUnpublishEntries');

throw err;
}
},
[trackUsage, unpublishManyDocuments, toggleNotification, formatMessage, formatAPIError]
);

const [createDocument] = useCreateDocumentMutation();
const create: IUseDocumentActs['create'] = React.useCallback(
async ({ model, params }, data, trackerProperty) => {
Expand Down Expand Up @@ -530,10 +634,12 @@ const useDocumentActions: UseDocumentActions = () => {
clone,
create,
delete: _delete,
deleteMany,
discard,
getDocument,
publish,
unpublish,
unpublishMany,
update,
} satisfies IUseDocumentActs;
};
Expand Down
Expand Up @@ -46,6 +46,7 @@ import { getTranslation } from '../../utils/translations';
import { getDisplayName } from '../../utils/users';
import { DocumentStatus } from '../EditView/components/DocumentStatus';

import { BulkActionsRenderer } from './components/BulkActions/Actions';
import { Filters } from './components/Filters';
import { TableActions } from './components/TableActions';
import { CellContent } from './components/TableCells/CellContent';
Expand Down Expand Up @@ -245,7 +246,9 @@ const ListViewPage = () => {
<ContentLayout>
<Flex gap={4} direction="column" alignItems="stretch">
<Table.Root rows={results} headers={tableHeaders} isLoading={isLoading}>
<Table.ActionBar />
<Table.ActionBar>
<BulkActionsRenderer />
</Table.ActionBar>
<Table.Content>
<Table.Head>
<Table.HeaderCheckboxCell />
Expand Down