Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
366 lines
11 KiB
Plaintext
366 lines
11 KiB
Plaintext
'use client';
|
|
|
|
import { c as _c } from "react/compiler-runtime";
|
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
import { useModal } from '@faceless-ui/modal';
|
|
import { getTranslation } from '@payloadcms/translations';
|
|
import { useRouter, useSearchParams } from 'next/navigation.js';
|
|
import { formatAdminURL, mergeListSearchAndWhere } from 'payload/shared';
|
|
import * as qs from 'qs-esm';
|
|
import React from 'react';
|
|
import { toast } from 'sonner';
|
|
import { CheckboxInput } from '../../fields/Checkbox/Input.js';
|
|
import { useAuth } from '../../providers/Auth/index.js';
|
|
import { useConfig } from '../../providers/Config/index.js';
|
|
import { useLocale } from '../../providers/Locale/index.js';
|
|
import { useRouteCache } from '../../providers/RouteCache/index.js';
|
|
import { SelectAllStatus, useSelection } from '../../providers/Selection/index.js';
|
|
import { useTranslation } from '../../providers/Translation/index.js';
|
|
import { requests } from '../../utilities/api.js';
|
|
import { parseSearchParams } from '../../utilities/parseSearchParams.js';
|
|
import { ConfirmationModal } from '../ConfirmationModal/index.js';
|
|
import { ListSelectionButton } from '../ListSelection/index.js';
|
|
import { Translation } from '../Translation/index.js';
|
|
import './index.scss';
|
|
export const DeleteMany = props => {
|
|
const $ = _c(6);
|
|
const {
|
|
viewType
|
|
} = props;
|
|
const {
|
|
collection: t0,
|
|
modalPrefix
|
|
} = props;
|
|
const {
|
|
slug,
|
|
trash
|
|
} = t0 === undefined ? {} : t0;
|
|
const {
|
|
permissions
|
|
} = useAuth();
|
|
const {
|
|
count,
|
|
selectAll,
|
|
selectedIDs,
|
|
toggleAll
|
|
} = useSelection();
|
|
const router = useRouter();
|
|
const searchParams = useSearchParams();
|
|
const {
|
|
clearRouteCache
|
|
} = useRouteCache();
|
|
const collectionPermissions = permissions?.collections?.[slug];
|
|
const hasDeletePermission = collectionPermissions?.delete;
|
|
const selectingAll = selectAll === SelectAllStatus.AllAvailable;
|
|
const ids = selectingAll ? [] : selectedIDs;
|
|
if (selectAll === SelectAllStatus.None || !hasDeletePermission) {
|
|
return null;
|
|
}
|
|
const baseWhere = parseSearchParams(searchParams)?.where;
|
|
const finalWhere = viewType === "trash" ? {
|
|
and: [...(Array.isArray(baseWhere?.and) ? baseWhere.and : baseWhere ? [baseWhere] : []), {
|
|
deletedAt: {
|
|
exists: true
|
|
}
|
|
}]
|
|
} : baseWhere;
|
|
let t1;
|
|
if ($[0] !== clearRouteCache || $[1] !== router || $[2] !== searchParams || $[3] !== selectAll || $[4] !== toggleAll) {
|
|
t1 = () => {
|
|
toggleAll();
|
|
router.replace(qs.stringify({
|
|
...parseSearchParams(searchParams),
|
|
page: selectAll ? "1" : undefined
|
|
}, {
|
|
addQueryPrefix: true
|
|
}));
|
|
clearRouteCache();
|
|
};
|
|
$[0] = clearRouteCache;
|
|
$[1] = router;
|
|
$[2] = searchParams;
|
|
$[3] = selectAll;
|
|
$[4] = toggleAll;
|
|
$[5] = t1;
|
|
} else {
|
|
t1 = $[5];
|
|
}
|
|
return _jsx(React.Fragment, {
|
|
children: _jsx(DeleteMany_v4, {
|
|
afterDelete: t1,
|
|
modalPrefix,
|
|
search: parseSearchParams(searchParams)?.search,
|
|
selections: {
|
|
[slug]: {
|
|
all: selectAll === SelectAllStatus.AllAvailable,
|
|
ids,
|
|
totalCount: selectingAll ? count : ids.length
|
|
}
|
|
},
|
|
trash,
|
|
viewType,
|
|
where: finalWhere
|
|
})
|
|
});
|
|
};
|
|
/**
|
|
* Handles polymorphic document delete operations.
|
|
*
|
|
* If you are deleting monomorphic documents, shape your `selections` to match the polymorphic structure.
|
|
*/
|
|
export function DeleteMany_v4({
|
|
afterDelete,
|
|
modalPrefix,
|
|
search,
|
|
selections,
|
|
trash,
|
|
viewType,
|
|
where
|
|
}) {
|
|
const {
|
|
t
|
|
} = useTranslation();
|
|
const {
|
|
config: {
|
|
collections,
|
|
routes: {
|
|
api
|
|
},
|
|
serverURL
|
|
}
|
|
} = useConfig();
|
|
const {
|
|
code: locale
|
|
} = useLocale();
|
|
const {
|
|
i18n
|
|
} = useTranslation();
|
|
const {
|
|
openModal
|
|
} = useModal();
|
|
const [deletePermanently, setDeletePermanently] = React.useState(false);
|
|
const confirmManyDeleteDrawerSlug = `${modalPrefix ? `${modalPrefix}-` : ''}confirm-delete-many-docs`;
|
|
const handleDelete = React.useCallback(async () => {
|
|
const deletingOneCollection = Object.keys(selections).length === 1;
|
|
const result = {};
|
|
for (const [relationTo, {
|
|
all,
|
|
ids = []
|
|
}] of Object.entries(selections)) {
|
|
const collectionConfig = collections.find(({
|
|
slug
|
|
}) => slug === relationTo);
|
|
if (collectionConfig) {
|
|
let whereConstraint;
|
|
if (all) {
|
|
// selecting all documents with optional where filter
|
|
if (deletingOneCollection && where) {
|
|
whereConstraint = viewType === 'trash' ? {
|
|
and: [...(Array.isArray(where.and) ? where.and : [where]), {
|
|
deletedAt: {
|
|
exists: true
|
|
}
|
|
}]
|
|
} : where;
|
|
} else {
|
|
whereConstraint = viewType === 'trash' ? {
|
|
and: [{
|
|
id: {
|
|
not_equals: ''
|
|
}
|
|
}, {
|
|
deletedAt: {
|
|
exists: true
|
|
}
|
|
}]
|
|
} : {
|
|
id: {
|
|
not_equals: ''
|
|
}
|
|
};
|
|
}
|
|
} else {
|
|
// selecting specific documents
|
|
whereConstraint = {
|
|
and: [{
|
|
id: {
|
|
in: ids
|
|
}
|
|
}, ...(viewType === 'trash' ? [{
|
|
deletedAt: {
|
|
exists: true
|
|
}
|
|
}] : [])]
|
|
};
|
|
}
|
|
const url = formatAdminURL({
|
|
apiRoute: api,
|
|
path: `/${relationTo}${qs.stringify({
|
|
limit: 0,
|
|
locale,
|
|
select: {},
|
|
where: mergeListSearchAndWhere({
|
|
collectionConfig,
|
|
search,
|
|
where: whereConstraint
|
|
}),
|
|
...(viewType === 'trash' ? {
|
|
trash: true
|
|
} : {})
|
|
}, {
|
|
addQueryPrefix: true
|
|
})}`
|
|
});
|
|
const deleteManyResponse = viewType === 'trash' || deletePermanently || !collectionConfig.trash ? await requests.delete(url, {
|
|
headers: {
|
|
'Accept-Language': i18n.language,
|
|
'Content-Type': 'application/json'
|
|
}
|
|
}) : await requests.patch(url, {
|
|
body: JSON.stringify({
|
|
deletedAt: new Date().toISOString()
|
|
}),
|
|
headers: {
|
|
'Accept-Language': i18n.language,
|
|
'Content-Type': 'application/json'
|
|
}
|
|
});
|
|
try {
|
|
const {
|
|
plural,
|
|
singular
|
|
} = collectionConfig.labels;
|
|
const json = await deleteManyResponse.json();
|
|
const deletedDocs = json?.docs.length || 0;
|
|
const successLabel = deletedDocs > 1 ? plural : singular;
|
|
if (deleteManyResponse.status < 400 || deletedDocs > 0) {
|
|
const wasTrashed = collectionConfig.trash && !deletePermanently && viewType !== 'trash';
|
|
let successKey;
|
|
if (wasTrashed) {
|
|
successKey = 'general:trashedCountSuccessfully';
|
|
} else if (viewType === 'trash' || deletePermanently) {
|
|
successKey = 'general:permanentlyDeletedCountSuccessfully';
|
|
} else {
|
|
successKey = 'general:deletedCountSuccessfully';
|
|
}
|
|
toast.success(t(successKey, {
|
|
count: deletedDocs,
|
|
label: getTranslation(successLabel, i18n)
|
|
}));
|
|
}
|
|
if (json?.errors.length > 0) {
|
|
toast.error(json.message, {
|
|
description: json.errors.map(error => error.message).join('\n')
|
|
});
|
|
}
|
|
result[relationTo] = {
|
|
deletedCount: deletedDocs,
|
|
errors: json?.errors || null,
|
|
ids: json?.docs.map(doc => doc.id) || [],
|
|
totalCount: json.totalDocs
|
|
};
|
|
if (deleteManyResponse.status > 400 && json?.errors.length === 0) {
|
|
toast.error(t('error:unknown'));
|
|
result[relationTo].errors = [t('error:unknown')];
|
|
}
|
|
continue;
|
|
} catch (_err) {
|
|
toast.error(t('error:unknown'));
|
|
result[relationTo] = {
|
|
deletedCount: 0,
|
|
errors: [_err],
|
|
ids: [],
|
|
totalCount: 0
|
|
};
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
if (typeof afterDelete === 'function') {
|
|
afterDelete(result);
|
|
}
|
|
}, [selections, afterDelete, collections, deletePermanently, locale, search, serverURL, api, i18n, viewType, where, t]);
|
|
const {
|
|
label: labelString,
|
|
labelCount: labelCount_0
|
|
} = Object.entries(selections).reduce((acc, [key, value], index, array) => {
|
|
const collectionConfig_0 = collections.find(({
|
|
slug: slug_0
|
|
}) => slug_0 === key);
|
|
if (collectionConfig_0) {
|
|
const labelCount = acc.labelCount === undefined ? value.totalCount : acc.labelCount;
|
|
const collectionLabel = `${acc.labelCount !== undefined ? `${value.totalCount} ` : ''}${getTranslation(value.totalCount > 1 ? collectionConfig_0.labels.plural : collectionConfig_0.labels.singular, i18n)}`;
|
|
let newLabel;
|
|
if (index === array.length - 1 && index !== 0) {
|
|
newLabel = `${acc.label} and ${collectionLabel}`;
|
|
} else if (index > 0) {
|
|
newLabel = `${acc.label}, ${collectionLabel}`;
|
|
} else {
|
|
newLabel = collectionLabel;
|
|
}
|
|
return {
|
|
label: newLabel,
|
|
labelCount
|
|
};
|
|
}
|
|
return acc;
|
|
}, {
|
|
label: '',
|
|
labelCount: undefined
|
|
});
|
|
return /*#__PURE__*/_jsxs(React.Fragment, {
|
|
children: [/*#__PURE__*/_jsx(ListSelectionButton, {
|
|
"aria-label": t('general:delete'),
|
|
className: "delete-documents__toggle",
|
|
onClick: () => {
|
|
openModal(confirmManyDeleteDrawerSlug);
|
|
},
|
|
children: t('general:delete')
|
|
}), /*#__PURE__*/_jsx(ConfirmationModal, {
|
|
body: /*#__PURE__*/_jsxs(React.Fragment, {
|
|
children: [/*#__PURE__*/_jsx("p", {
|
|
children: trash ? viewType === 'trash' ? /*#__PURE__*/_jsx(Translation, {
|
|
elements: {
|
|
'0': ({
|
|
children
|
|
}) => /*#__PURE__*/_jsx("strong", {
|
|
children: children
|
|
}),
|
|
'1': ({
|
|
children: children_0
|
|
}) => /*#__PURE__*/_jsx("strong", {
|
|
children: children_0
|
|
})
|
|
},
|
|
i18nKey: "general:aboutToPermanentlyDeleteTrash",
|
|
t: t,
|
|
variables: {
|
|
count: labelCount_0 ?? 0,
|
|
label: labelString
|
|
}
|
|
}) : t('general:aboutToTrashCount', {
|
|
count: labelCount_0,
|
|
label: labelString
|
|
}) : t('general:aboutToDeleteCount', {
|
|
count: labelCount_0,
|
|
label: labelString
|
|
})
|
|
}), trash && viewType !== 'trash' && /*#__PURE__*/_jsx("div", {
|
|
className: "delete-documents__checkbox",
|
|
children: /*#__PURE__*/_jsx(CheckboxInput, {
|
|
checked: deletePermanently,
|
|
id: "delete-forever",
|
|
label: t('general:deletePermanently'),
|
|
name: "delete-forever",
|
|
onToggle: e => setDeletePermanently(e.target.checked)
|
|
})
|
|
})]
|
|
}),
|
|
confirmingLabel: t('general:deleting'),
|
|
heading: t('general:confirmDeletion'),
|
|
modalSlug: confirmManyDeleteDrawerSlug,
|
|
onConfirm: handleDelete
|
|
})]
|
|
});
|
|
}
|
|
//# sourceMappingURL=index.js.map |