mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 07:33:17 +00:00
Add delete behavior
Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
parent
787d4e5a41
commit
81bdbab104
@ -13,12 +13,7 @@ const reducers = {
|
||||
})),
|
||||
'content-manager_listView': jest.fn(() => ({
|
||||
data: [],
|
||||
didDeleteData: false,
|
||||
entriesToDelete: [],
|
||||
isLoading: true,
|
||||
showModalConfirmButtonLoading: false,
|
||||
showWarningDelete: false,
|
||||
showWarningDeleteAll: false,
|
||||
contentType: {},
|
||||
initialDisplayedHeaders: [],
|
||||
displayedHeaders: [],
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Dialog, DialogBody, DialogFooter } from '@strapi/parts/Dialog';
|
||||
import { Stack } from '@strapi/parts/Stack';
|
||||
import { Row } from '@strapi/parts/Row';
|
||||
import { Text } from '@strapi/parts/Text';
|
||||
import { Button } from '@strapi/parts/Button';
|
||||
import AlertWarningIcon from '@strapi/icons/AlertWarningIcon';
|
||||
import DeleteIcon from '@strapi/icons/DeleteIcon';
|
||||
import InjectionZoneList from '../../InjectionZoneList';
|
||||
|
||||
const ConfirmDialogDelete = ({ isConfirmButtonLoading, isOpen, onToggleDialog, onConfirm }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onClose={onToggleDialog}
|
||||
title={formatMessage({
|
||||
id: 'app.components.ConfirmDialog.title',
|
||||
defaultMessage: 'Confirmation',
|
||||
})}
|
||||
labelledBy="confirmation"
|
||||
describedBy="confirm-description"
|
||||
isOpen={isOpen}
|
||||
>
|
||||
<DialogBody icon={<AlertWarningIcon />}>
|
||||
<Stack size={2}>
|
||||
<Row justifyContent="center">
|
||||
<Text id="confirm-description">
|
||||
{formatMessage({
|
||||
id: 'components.popUpWarning.message',
|
||||
defaultMessage: 'Are you sure you want to delete this?',
|
||||
})}
|
||||
</Text>
|
||||
</Row>
|
||||
<Row>
|
||||
<InjectionZoneList area="contentManager.listView.deleteModalAdditionalInfos" />
|
||||
</Row>
|
||||
</Stack>
|
||||
</DialogBody>
|
||||
<DialogFooter
|
||||
startAction={
|
||||
<Button onClick={onToggleDialog} variant="tertiary">
|
||||
{formatMessage({
|
||||
id: 'app.components.Button.cancel',
|
||||
defaultMessage: 'Cancel',
|
||||
})}
|
||||
</Button>
|
||||
}
|
||||
endAction={
|
||||
<Button
|
||||
onClick={onConfirm}
|
||||
variant="danger-light"
|
||||
startIcon={<DeleteIcon />}
|
||||
id="confirm-delete"
|
||||
loading={isConfirmButtonLoading}
|
||||
>
|
||||
{formatMessage({
|
||||
id: 'app.components.Button.confirm',
|
||||
defaultMessage: 'Confirm',
|
||||
})}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
ConfirmDialogDelete.propTypes = {
|
||||
isConfirmButtonLoading: PropTypes.bool.isRequired,
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onToggleDialog: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ConfirmDialogDelete;
|
||||
@ -0,0 +1,78 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Dialog, DialogBody, DialogFooter } from '@strapi/parts/Dialog';
|
||||
import { Stack } from '@strapi/parts/Stack';
|
||||
import { Row } from '@strapi/parts/Row';
|
||||
import { Text } from '@strapi/parts/Text';
|
||||
import { Button } from '@strapi/parts/Button';
|
||||
import AlertWarningIcon from '@strapi/icons/AlertWarningIcon';
|
||||
import DeleteIcon from '@strapi/icons/DeleteIcon';
|
||||
import InjectionZoneList from '../../InjectionZoneList';
|
||||
import { getTrad } from '../../../utils';
|
||||
|
||||
const ConfirmDialogDeleteAll = ({ isConfirmButtonLoading, isOpen, onToggleDialog, onConfirm }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onClose={onToggleDialog}
|
||||
title={formatMessage({
|
||||
id: 'app.components.ConfirmDialog.title',
|
||||
defaultMessage: 'Confirmation',
|
||||
})}
|
||||
labelledBy="confirmation"
|
||||
describedBy="confirm-description"
|
||||
isOpen={isOpen}
|
||||
>
|
||||
<DialogBody icon={<AlertWarningIcon />}>
|
||||
<Stack size={2}>
|
||||
<Row justifyContent="center">
|
||||
<Text id="confirm-description">
|
||||
{formatMessage({
|
||||
id: getTrad('popUpWarning.bodyMessage.contentType.delete.all'),
|
||||
defaultMessage: 'Are you sure you want to delete these entries?',
|
||||
})}
|
||||
</Text>
|
||||
</Row>
|
||||
<Row>
|
||||
<InjectionZoneList area="contentManager.listView.deleteModalAdditionalInfos" />
|
||||
</Row>
|
||||
</Stack>
|
||||
</DialogBody>
|
||||
<DialogFooter
|
||||
startAction={
|
||||
<Button onClick={onToggleDialog} variant="tertiary">
|
||||
{formatMessage({
|
||||
id: 'app.components.Button.cancel',
|
||||
defaultMessage: 'Cancel',
|
||||
})}
|
||||
</Button>
|
||||
}
|
||||
endAction={
|
||||
<Button
|
||||
onClick={onConfirm}
|
||||
variant="danger-light"
|
||||
startIcon={<DeleteIcon />}
|
||||
id="confirm-delete"
|
||||
loading={isConfirmButtonLoading}
|
||||
>
|
||||
{formatMessage({
|
||||
id: 'app.components.Button.confirm',
|
||||
defaultMessage: 'Confirm',
|
||||
})}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
ConfirmDialogDeleteAll.propTypes = {
|
||||
isConfirmButtonLoading: PropTypes.bool.isRequired,
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onToggleDialog: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ConfirmDialogDeleteAll;
|
||||
@ -7,6 +7,8 @@ import { INJECT_COLUMN_IN_TABLE } from '../../../exposedHooks';
|
||||
import { getTrad } from '../../utils';
|
||||
import State from '../State';
|
||||
import TableRows from './TableRows';
|
||||
import ConfirmDialogDeleteAll from './ConfirmDialogDeleteAll';
|
||||
import ConfirmDialogDelete from './ConfirmDialogDelete';
|
||||
|
||||
const DynamicTable = ({
|
||||
canCreate,
|
||||
@ -14,6 +16,8 @@ const DynamicTable = ({
|
||||
contentTypeName,
|
||||
isBulkable,
|
||||
isLoading,
|
||||
onConfirmDelete,
|
||||
onConfirmDeleteAll,
|
||||
layout,
|
||||
rows,
|
||||
}) => {
|
||||
@ -55,9 +59,12 @@ const DynamicTable = ({
|
||||
|
||||
return (
|
||||
<Table
|
||||
components={{ ConfirmDialogDelete, ConfirmDialogDeleteAll }}
|
||||
contentType={contentTypeName}
|
||||
isLoading={isLoading}
|
||||
headers={tableHeaders}
|
||||
onConfirmDelete={onConfirmDelete}
|
||||
onConfirmDeleteAll={onConfirmDeleteAll}
|
||||
rows={rows}
|
||||
withBulkActions
|
||||
withMainAction={canDelete && isBulkable}
|
||||
@ -94,6 +101,8 @@ DynamicTable.propTypes = {
|
||||
settings: PropTypes.object.isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
onConfirmDelete: PropTypes.func.isRequired,
|
||||
onConfirmDeleteAll: PropTypes.func.isRequired,
|
||||
rows: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
|
||||
@ -1,29 +1,8 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'styled-components';
|
||||
import { Box } from '@strapi/parts/Box';
|
||||
import { useInjectionZone } from '../../../shared/hooks';
|
||||
|
||||
const List = styled.ul`
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
`;
|
||||
|
||||
const ListItem = styled.li`
|
||||
font-size: ${p => p.theme.main.sizes.fonts.md};
|
||||
|
||||
&:before {
|
||||
background: ${p => p.theme.main.colors.grey};
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
margin-left: -${p => p.theme.main.sizes.margins.sm};
|
||||
margin-top: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
const InjectionZoneList = ({ area, ...props }) => {
|
||||
const compos = useInjectionZone(area);
|
||||
|
||||
@ -31,22 +10,23 @@ const InjectionZoneList = ({ area, ...props }) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO
|
||||
return (
|
||||
<List>
|
||||
<ul>
|
||||
{compos.map(compo => {
|
||||
const component = compo.Component(props);
|
||||
|
||||
if (component) {
|
||||
return (
|
||||
<ListItem key={compo.name}>
|
||||
<Box key={compo.name} padding={3} style={{ textAlign: 'center' }}>
|
||||
<compo.Component {...props} />
|
||||
</ListItem>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})}
|
||||
</List>
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,18 +1,10 @@
|
||||
import {
|
||||
GET_DATA,
|
||||
GET_DATA_SUCCEEDED,
|
||||
ON_CHANGE_BULK,
|
||||
ON_CHANGE_BULK_SELECT_ALL,
|
||||
ON_CHANGE_LIST_HEADERS,
|
||||
ON_RESET_LIST_HEADERS,
|
||||
ON_DELETE_DATA_ERROR,
|
||||
ON_DELETE_DATA_SUCCEEDED,
|
||||
ON_DELETE_SEVERAL_DATA_SUCCEEDED,
|
||||
RESET_PROPS,
|
||||
SET_LIST_LAYOUT,
|
||||
SET_MODAL_LOADING_STATE,
|
||||
TOGGLE_MODAL_DELETE,
|
||||
TOGGLE_MODAL_DELETE_ALL,
|
||||
} from './constants';
|
||||
|
||||
export const getData = () => ({ type: GET_DATA });
|
||||
@ -23,61 +15,12 @@ export const getDataSucceeded = (pagination, data) => ({
|
||||
data,
|
||||
});
|
||||
|
||||
export function onChangeBulk({ target: { name } }) {
|
||||
return {
|
||||
type: ON_CHANGE_BULK,
|
||||
name,
|
||||
};
|
||||
}
|
||||
|
||||
export function onChangeBulkSelectall() {
|
||||
return {
|
||||
type: ON_CHANGE_BULK_SELECT_ALL,
|
||||
};
|
||||
}
|
||||
|
||||
export function onDeleteDataError() {
|
||||
return {
|
||||
type: ON_DELETE_DATA_ERROR,
|
||||
};
|
||||
}
|
||||
|
||||
export function onDeleteDataSucceeded() {
|
||||
return {
|
||||
type: ON_DELETE_DATA_SUCCEEDED,
|
||||
};
|
||||
}
|
||||
|
||||
export function onDeleteSeveralDataSucceeded() {
|
||||
return {
|
||||
type: ON_DELETE_SEVERAL_DATA_SUCCEEDED,
|
||||
};
|
||||
}
|
||||
|
||||
export const onResetListHeaders = () => ({ type: ON_RESET_LIST_HEADERS });
|
||||
|
||||
export function resetProps() {
|
||||
return { type: RESET_PROPS };
|
||||
}
|
||||
|
||||
export function setModalLoadingState() {
|
||||
return {
|
||||
type: SET_MODAL_LOADING_STATE,
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleModalDeleteAll() {
|
||||
return {
|
||||
type: TOGGLE_MODAL_DELETE_ALL,
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleModalDelete() {
|
||||
return {
|
||||
type: TOGGLE_MODAL_DELETE,
|
||||
};
|
||||
}
|
||||
|
||||
export const setLayout = contentType => {
|
||||
const { layouts } = contentType;
|
||||
|
||||
|
||||
@ -1,16 +1,6 @@
|
||||
export const GET_DATA = 'ContentManager/ListView/GET_DATA';
|
||||
export const GET_DATA_SUCCEEDED = 'ContentManager/ListView/GET_DATA_SUCCEEDED';
|
||||
export const ON_CHANGE_BULK = 'ContentManager/ListView/ON_CHANGE_BULK';
|
||||
export const ON_CHANGE_BULK_SELECT_ALL = 'ContentManager/ListView/ON_CHANGE_BULK_SELECT_ALL';
|
||||
export const ON_DELETE_DATA_SUCCEEDED = 'ContentManager/ListView/ON_DELETE_DATA_SUCCEEDED';
|
||||
export const ON_DELETE_DATA_ERROR = 'ContentManager/ListView/ON_DELETE_DATA_ERROR';
|
||||
export const ON_DELETE_SEVERAL_DATA_SUCCEEDED =
|
||||
'ContentManager/ListView/ON_DELETE_SEVERAL_DATA_SUCCEEDED';
|
||||
export const RESET_PROPS = 'ContentManager/ListView/RESET_PROPS';
|
||||
export const TOGGLE_MODAL_DELETE_ALL = 'ContentManager/ListView/TOGGLE_MODAL_DELETE_ALL';
|
||||
export const TOGGLE_MODAL_DELETE = 'ContentManager/ListView/TOGGLE_MODAL_DELETE';
|
||||
export const SET_MODAL_LOADING_STATE = 'ContentManager/ListView/SET_MODAL_LOADING_STATE';
|
||||
|
||||
export const ON_CHANGE_LIST_HEADERS = 'ContentManager/ListView/ON_CHANGE_LIST_HEADERS ';
|
||||
export const ON_RESET_LIST_HEADERS = 'ContentManager/ListView/ON_RESET_LIST_HEADERS ';
|
||||
export const SET_LIST_LAYOUT = 'ContentManager/ListView/SET_LIST_LAYOUT ';
|
||||
|
||||
@ -2,6 +2,7 @@ import React, { memo, useCallback, useEffect, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { bindActionCreators, compose } from 'redux';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
// import { get, isEmpty } from 'lodash';
|
||||
import get from 'lodash/get';
|
||||
// import isEmpty from 'lodash/isEmpty'
|
||||
@ -42,21 +43,7 @@ import {
|
||||
// import FieldPicker from './FieldPicker';
|
||||
// import Filter from './Filter';
|
||||
import PaginationFooter from './PaginationFooter';
|
||||
import {
|
||||
getData,
|
||||
getDataSucceeded,
|
||||
onChangeBulk,
|
||||
onChangeBulkSelectall,
|
||||
onDeleteDataError,
|
||||
onDeleteDataSucceeded,
|
||||
onDeleteSeveralDataSucceeded,
|
||||
setModalLoadingState,
|
||||
toggleModalDelete,
|
||||
toggleModalDeleteAll,
|
||||
setLayout,
|
||||
onChangeListHeaders,
|
||||
onResetListHeaders,
|
||||
} from './actions';
|
||||
import { getData, getDataSucceeded, onChangeListHeaders, onResetListHeaders } from './actions';
|
||||
import makeSelectListView from './selectors';
|
||||
import {
|
||||
// getAllAllowedHeaders,
|
||||
@ -72,20 +59,8 @@ function ListView({
|
||||
canCreate,
|
||||
canDelete,
|
||||
canRead,
|
||||
// canUpdate,
|
||||
// didDeleteData,
|
||||
// entriesToDelete,
|
||||
// onChangeBulk,
|
||||
// onChangeBulkSelectall,
|
||||
// onDeleteDataError,
|
||||
// onDeleteDataSucceeded,
|
||||
// onDeleteSeveralDataSucceeded,
|
||||
// setModalLoadingState,
|
||||
// showWarningDelete,
|
||||
// showModalConfirmButtonLoading,
|
||||
// showWarningDeleteAll,
|
||||
// toggleModalDelete,
|
||||
// toggleModalDeleteAll,
|
||||
data,
|
||||
getData,
|
||||
getDataSucceeded,
|
||||
@ -114,7 +89,6 @@ function ListView({
|
||||
|
||||
useFocusWhenNavigate();
|
||||
|
||||
// const [{ query }, setQuery] = useQueryParams();
|
||||
const [{ query }] = useQueryParams();
|
||||
const params = buildQueryString(query);
|
||||
|
||||
@ -136,6 +110,7 @@ function ListView({
|
||||
// const sort = query.sort;
|
||||
// const _q = query._q || '';
|
||||
|
||||
// FIXME
|
||||
// Using a ref to avoid requests being fired multiple times on slug on change
|
||||
// We need it because the hook as mulitple dependencies so it may run before the permissions have checked
|
||||
const requestUrlRef = useRef('');
|
||||
@ -169,7 +144,6 @@ function ListView({
|
||||
}
|
||||
|
||||
const resStatus = get(err, 'response.status', null);
|
||||
console.log(err);
|
||||
|
||||
if (resStatus === 403) {
|
||||
await fetchPermissionsRef.current();
|
||||
@ -212,80 +186,67 @@ function ListView({
|
||||
// [displayedHeaders, onChangeListHeaders, toggleNotification]
|
||||
// );
|
||||
|
||||
// const handleConfirmDeleteAllData = useCallback(async () => {
|
||||
// try {
|
||||
// setModalLoadingState();
|
||||
const handleConfirmDeleteAllData = useCallback(
|
||||
async ids => {
|
||||
try {
|
||||
await axiosInstance.post(getRequestUrl(`collection-types/${slug}/actions/bulkDelete`), {
|
||||
ids,
|
||||
});
|
||||
|
||||
// await axiosInstance.post(getRequestUrl(`collection-types/${slug}/actions/bulkDelete`), {
|
||||
// ids: entriesToDelete,
|
||||
// });
|
||||
const requestUrl = getRequestUrl(`collection-types/${slug}${params}`);
|
||||
fetchData(requestUrl);
|
||||
trackUsageRef.current('didBulkDeleteEntries');
|
||||
} catch (err) {
|
||||
toggleNotification({
|
||||
type: 'warning',
|
||||
message: { id: getTrad('error.record.delete') },
|
||||
});
|
||||
}
|
||||
},
|
||||
[fetchData, params, slug, toggleNotification]
|
||||
);
|
||||
|
||||
// onDeleteSeveralDataSucceeded();
|
||||
// trackUsageRef.current('didBulkDeleteEntries');
|
||||
// } catch (err) {
|
||||
// toggleNotification({
|
||||
// type: 'warning',
|
||||
// message: { id: getTrad('error.record.delete') },
|
||||
// });
|
||||
// }
|
||||
// }, [
|
||||
// entriesToDelete,
|
||||
// onDeleteSeveralDataSucceeded,
|
||||
// slug,
|
||||
// setModalLoadingState,
|
||||
// toggleNotification,
|
||||
// ]);
|
||||
const handleConfirmDeleteData = useCallback(
|
||||
async idToDelete => {
|
||||
try {
|
||||
let trackerProperty = {};
|
||||
|
||||
// const handleConfirmDeleteData = useCallback(async () => {
|
||||
// try {
|
||||
// let trackerProperty = {};
|
||||
if (hasDraftAndPublish) {
|
||||
const dataToDelete = data.find(obj => obj.id.toString() === idToDelete.toString());
|
||||
const isDraftEntry = isEmpty(dataToDelete.published_at);
|
||||
const status = isDraftEntry ? 'draft' : 'published';
|
||||
|
||||
// if (hasDraftAndPublish) {
|
||||
// const dataToDelete = data.find(obj => obj.id.toString() === idToDelete.toString());
|
||||
// const isDraftEntry = isEmpty(dataToDelete.published_at);
|
||||
// const status = isDraftEntry ? 'draft' : 'published';
|
||||
trackerProperty = { status };
|
||||
}
|
||||
|
||||
// trackerProperty = { status };
|
||||
// }
|
||||
trackUsageRef.current('willDeleteEntry', trackerProperty);
|
||||
|
||||
// trackUsageRef.current('willDeleteEntry', trackerProperty);
|
||||
// setModalLoadingState();
|
||||
await axiosInstance.delete(getRequestUrl(`collection-types/${slug}/${idToDelete}`));
|
||||
|
||||
// await axiosInstance.delete(getRequestUrl(`collection-types/${slug}/${idToDelete}`));
|
||||
const requestUrl = getRequestUrl(`collection-types/${slug}${params}`);
|
||||
fetchData(requestUrl);
|
||||
|
||||
// toggleNotification({
|
||||
// type: 'success',
|
||||
// message: { id: getTrad('success.record.delete') },
|
||||
// });
|
||||
toggleNotification({
|
||||
type: 'success',
|
||||
message: { id: getTrad('success.record.delete') },
|
||||
});
|
||||
|
||||
// // Close the modal and refetch data
|
||||
// onDeleteDataSucceeded();
|
||||
// trackUsageRef.current('didDeleteEntry', trackerProperty);
|
||||
// } catch (err) {
|
||||
// const errorMessage = get(
|
||||
// err,
|
||||
// 'response.payload.message',
|
||||
// formatMessage({ id: getTrad('error.record.delete') })
|
||||
// );
|
||||
trackUsageRef.current('didDeleteEntry', trackerProperty);
|
||||
} catch (err) {
|
||||
const errorMessage = get(
|
||||
err,
|
||||
'response.payload.message',
|
||||
formatMessage({ id: getTrad('error.record.delete') })
|
||||
);
|
||||
|
||||
// toggleNotification({
|
||||
// type: 'warning',
|
||||
// message: errorMessage,
|
||||
// });
|
||||
// // Close the modal
|
||||
// onDeleteDataError();
|
||||
// }
|
||||
// }, [
|
||||
// toggleNotification,
|
||||
// hasDraftAndPublish,
|
||||
// setModalLoadingState,
|
||||
// slug,
|
||||
// idToDelete,
|
||||
// onDeleteDataSucceeded,
|
||||
// data,
|
||||
// formatMessage,
|
||||
// onDeleteDataError,
|
||||
// ]);
|
||||
toggleNotification({
|
||||
type: 'warning',
|
||||
message: errorMessage,
|
||||
});
|
||||
}
|
||||
},
|
||||
[hasDraftAndPublish, slug, params, fetchData, toggleNotification, data, formatMessage]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const CancelToken = axios.CancelToken;
|
||||
@ -306,19 +267,6 @@ function ListView({
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [canRead, getData, slug, params, getDataSucceeded, fetchData]);
|
||||
|
||||
// const handleClickDelete = id => {
|
||||
// setIdToDelete(id);
|
||||
// toggleModalDelete();
|
||||
// };
|
||||
|
||||
// const handleModalClose = useCallback(() => {
|
||||
// if (didDeleteData) {
|
||||
// const requestUrl = getRequestUrl(`collection-types/${slug}${params}`);
|
||||
|
||||
// fetchData(requestUrl);
|
||||
// }
|
||||
// }, [fetchData, didDeleteData, slug, params]);
|
||||
|
||||
// const toggleFilterPickerState = useCallback(() => {
|
||||
// setFilterPickerState(prevState => {
|
||||
// if (!prevState) {
|
||||
@ -329,11 +277,6 @@ function ListView({
|
||||
// });
|
||||
// }, []);
|
||||
|
||||
// const handleToggleModalDeleteAll = e => {
|
||||
// trackUsageRef.current('willBulkDeleteEntries');
|
||||
// toggleModalDeleteAll(e);
|
||||
// };
|
||||
|
||||
const defaultHeaderLayoutTitle = formatMessage({
|
||||
id: getTrad('header.name'),
|
||||
defaultMessage: 'Content',
|
||||
@ -399,6 +342,8 @@ function ListView({
|
||||
canCreate={canCreate}
|
||||
canDelete={canDelete}
|
||||
contentTypeName={headerLayoutTitle}
|
||||
onConfirmDeleteAll={handleConfirmDeleteAllData}
|
||||
onConfirmDelete={handleConfirmDeleteData}
|
||||
isBulkable={isBulkable}
|
||||
isLoading={isLoading}
|
||||
// FIXME: remove the layout props drilling
|
||||
@ -557,18 +502,11 @@ function ListView({
|
||||
// );
|
||||
}
|
||||
|
||||
// ListView.defaultProps = {
|
||||
// permissions: [],
|
||||
// };
|
||||
|
||||
ListView.propTypes = {
|
||||
canCreate: PropTypes.bool.isRequired,
|
||||
canDelete: PropTypes.bool.isRequired,
|
||||
canRead: PropTypes.bool.isRequired,
|
||||
// canUpdate: PropTypes.bool.isRequired,
|
||||
data: PropTypes.array.isRequired,
|
||||
// didDeleteData: PropTypes.bool.isRequired,
|
||||
// entriesToDelete: PropTypes.array.isRequired,
|
||||
layout: PropTypes.exact({
|
||||
components: PropTypes.object.isRequired,
|
||||
contentType: PropTypes.shape({
|
||||
@ -586,31 +524,12 @@ ListView.propTypes = {
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
getData: PropTypes.func.isRequired,
|
||||
getDataSucceeded: PropTypes.func.isRequired,
|
||||
// onChangeBulk: PropTypes.func.isRequired,
|
||||
// onChangeBulkSelectall: PropTypes.func.isRequired,
|
||||
// onChangeListHeaders: PropTypes.func.isRequired,
|
||||
// onDeleteDataError: PropTypes.func.isRequired,
|
||||
// onDeleteDataSucceeded: PropTypes.func.isRequired,
|
||||
// onDeleteSeveralDataSucceeded: PropTypes.func.isRequired,
|
||||
// onResetListHeaders: PropTypes.func.isRequired,
|
||||
pagination: PropTypes.shape({ total: PropTypes.number.isRequired, pageCount: PropTypes.number })
|
||||
.isRequired,
|
||||
// setModalLoadingState: PropTypes.func.isRequired,
|
||||
// showModalConfirmButtonLoading: PropTypes.bool.isRequired,
|
||||
// showWarningDelete: PropTypes.bool.isRequired,
|
||||
// showWarningDeleteAll: PropTypes.bool.isRequired,
|
||||
slug: PropTypes.string.isRequired,
|
||||
// toggleModalDelete: PropTypes.func.isRequired,
|
||||
// toggleModalDeleteAll: PropTypes.func.isRequired,
|
||||
// setLayout: PropTypes.func.isRequired,
|
||||
// permissions: PropTypes.arrayOf(
|
||||
// PropTypes.shape({
|
||||
// action: PropTypes.string.isRequired,
|
||||
// subject: PropTypes.string.isRequired,
|
||||
// properties: PropTypes.object,
|
||||
// conditions: PropTypes.arrayOf(PropTypes.string),
|
||||
// })
|
||||
// ),
|
||||
};
|
||||
|
||||
const mapStateToProps = makeSelectListView();
|
||||
@ -620,17 +539,8 @@ export function mapDispatchToProps(dispatch) {
|
||||
{
|
||||
getData,
|
||||
getDataSucceeded,
|
||||
onChangeBulk,
|
||||
onChangeBulkSelectall,
|
||||
onChangeListHeaders,
|
||||
onDeleteDataError,
|
||||
onDeleteDataSucceeded,
|
||||
onDeleteSeveralDataSucceeded,
|
||||
onResetListHeaders,
|
||||
setModalLoadingState,
|
||||
toggleModalDelete,
|
||||
toggleModalDeleteAll,
|
||||
setLayout,
|
||||
},
|
||||
dispatch
|
||||
);
|
||||
|
||||
@ -8,27 +8,14 @@ import {
|
||||
GET_DATA,
|
||||
GET_DATA_SUCCEEDED,
|
||||
RESET_PROPS,
|
||||
ON_CHANGE_BULK,
|
||||
ON_CHANGE_BULK_SELECT_ALL,
|
||||
ON_DELETE_DATA_ERROR,
|
||||
ON_DELETE_DATA_SUCCEEDED,
|
||||
ON_DELETE_SEVERAL_DATA_SUCCEEDED,
|
||||
TOGGLE_MODAL_DELETE,
|
||||
TOGGLE_MODAL_DELETE_ALL,
|
||||
ON_CHANGE_LIST_HEADERS,
|
||||
ON_RESET_LIST_HEADERS,
|
||||
SET_LIST_LAYOUT,
|
||||
SET_MODAL_LOADING_STATE,
|
||||
} from './constants';
|
||||
|
||||
export const initialState = {
|
||||
data: [],
|
||||
didDeleteData: false,
|
||||
entriesToDelete: [],
|
||||
isLoading: true,
|
||||
showModalConfirmButtonLoading: false,
|
||||
showWarningDelete: false,
|
||||
showWarningDeleteAll: false,
|
||||
contentType: {},
|
||||
initialDisplayedHeaders: [],
|
||||
displayedHeaders: [],
|
||||
@ -56,30 +43,6 @@ const listViewReducer = (state = initialState, action) =>
|
||||
drafState.isLoading = false;
|
||||
break;
|
||||
}
|
||||
case ON_CHANGE_BULK: {
|
||||
const hasElement = state.entriesToDelete.some(el => el === action.name);
|
||||
|
||||
if (hasElement) {
|
||||
drafState.entriesToDelete = drafState.entriesToDelete.filter(el => el !== action.name);
|
||||
break;
|
||||
}
|
||||
|
||||
drafState.entriesToDelete.push(action.name);
|
||||
break;
|
||||
}
|
||||
case ON_CHANGE_BULK_SELECT_ALL: {
|
||||
if (state.entriesToDelete.length > 0) {
|
||||
drafState.entriesToDelete = [];
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
drafState.data.forEach(value => {
|
||||
drafState.entriesToDelete.push(value.id.toString());
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ON_CHANGE_LIST_HEADERS: {
|
||||
const {
|
||||
@ -115,21 +78,6 @@ const listViewReducer = (state = initialState, action) =>
|
||||
|
||||
break;
|
||||
}
|
||||
case ON_DELETE_DATA_SUCCEEDED: {
|
||||
drafState.didDeleteData = true;
|
||||
drafState.showWarningDelete = false;
|
||||
break;
|
||||
}
|
||||
case ON_DELETE_DATA_ERROR: {
|
||||
drafState.didDeleteData = false;
|
||||
drafState.showWarningDelete = false;
|
||||
break;
|
||||
}
|
||||
case ON_DELETE_SEVERAL_DATA_SUCCEEDED: {
|
||||
drafState.didDeleteData = true;
|
||||
drafState.showWarningDeleteAll = false;
|
||||
break;
|
||||
}
|
||||
case ON_RESET_LIST_HEADERS: {
|
||||
drafState.displayedHeaders = state.initialDisplayedHeaders;
|
||||
break;
|
||||
@ -137,34 +85,6 @@ const listViewReducer = (state = initialState, action) =>
|
||||
case RESET_PROPS: {
|
||||
return initialState;
|
||||
}
|
||||
case SET_MODAL_LOADING_STATE: {
|
||||
drafState.showModalConfirmButtonLoading = true;
|
||||
break;
|
||||
}
|
||||
case TOGGLE_MODAL_DELETE: {
|
||||
drafState.showModalConfirmButtonLoading = false;
|
||||
|
||||
// Only change this value when the modal is opening
|
||||
if (!state.showWarningDelete) {
|
||||
drafState.didDeleteData = false;
|
||||
}
|
||||
|
||||
drafState.entriesToDelete = [];
|
||||
drafState.showWarningDelete = !state.showWarningDelete;
|
||||
|
||||
break;
|
||||
}
|
||||
case TOGGLE_MODAL_DELETE_ALL: {
|
||||
drafState.showModalConfirmButtonLoading = false;
|
||||
|
||||
// Only change this value when the modal is closing
|
||||
if (!state.showWarningDeleteAll) {
|
||||
drafState.didDeleteData = false;
|
||||
}
|
||||
|
||||
drafState.showWarningDeleteAll = !state.showWarningDeleteAll;
|
||||
break;
|
||||
}
|
||||
case SET_LIST_LAYOUT: {
|
||||
const { contentType, displayedHeaders } = action;
|
||||
|
||||
|
||||
@ -1,15 +1,5 @@
|
||||
import produce from 'immer';
|
||||
import {
|
||||
getData,
|
||||
getDataSucceeded,
|
||||
onChangeBulk,
|
||||
onChangeBulkSelectall,
|
||||
onDeleteDataSucceeded,
|
||||
onDeleteSeveralDataSucceeded,
|
||||
setModalLoadingState,
|
||||
toggleModalDelete,
|
||||
toggleModalDeleteAll,
|
||||
} from '../actions';
|
||||
import { getData, getDataSucceeded } from '../actions';
|
||||
|
||||
import reducer from '../reducer';
|
||||
|
||||
@ -19,12 +9,7 @@ describe('CONTENT MANAGER | CONTAINERS | ListView | reducer', () => {
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
data: [],
|
||||
didDeleteData: false,
|
||||
entriesToDelete: [],
|
||||
isLoading: true,
|
||||
showModalConfirmButtonLoading: false,
|
||||
showWarningDelete: false,
|
||||
showWarningDeleteAll: false,
|
||||
contentType: {},
|
||||
initialDisplayedHeaders: [],
|
||||
displayedHeaders: [],
|
||||
@ -50,12 +35,7 @@ describe('CONTENT MANAGER | CONTAINERS | ListView | reducer', () => {
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.data = [];
|
||||
draft.didDeleteData = false;
|
||||
draft.entriesToDelete = [];
|
||||
draft.isLoading = true;
|
||||
draft.showModalConfirmButtonLoading = false;
|
||||
draft.showWarningDelete = false;
|
||||
draft.showWarningDeleteAll = false;
|
||||
draft.contentType = 'test';
|
||||
draft.initialDisplayedHeaders = ['test'];
|
||||
draft.displayedHeaders = ['test'];
|
||||
@ -74,179 +54,4 @@ describe('CONTENT MANAGER | CONTAINERS | ListView | reducer', () => {
|
||||
|
||||
expect(reducer(state, getDataSucceeded({ count: 1 }, ['test']))).toEqual(expected);
|
||||
});
|
||||
|
||||
describe('ON_CHANGE_BULK', () => {
|
||||
it('should add the data to the entriesToDelete if it is not already selected', () => {
|
||||
const target = {
|
||||
name: '13',
|
||||
};
|
||||
state.entriesToDelete = ['1'];
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.entriesToDelete = ['1', '13'];
|
||||
});
|
||||
|
||||
expect(reducer(state, onChangeBulk({ target }))).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should remove the data to the entriesToDelete if it is already selected', () => {
|
||||
const target = {
|
||||
name: '13',
|
||||
};
|
||||
state.entriesToDelete = ['1', '13', '14'];
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.entriesToDelete = ['1', '14'];
|
||||
});
|
||||
|
||||
expect(reducer(state, onChangeBulk({ target }))).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ON_CHANGE_BULK_SELECT_ALL', () => {
|
||||
it('should remove all the selected elements if the entriesToDelete array is not empty', () => {
|
||||
state.entriesToDelete = ['1', '13', '14'];
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.entriesToDelete = [];
|
||||
});
|
||||
|
||||
expect(reducer(state, onChangeBulkSelectall())).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should all all the elements if the entriesToDelete array is empty', () => {
|
||||
state.entriesToDelete = [];
|
||||
state.data = [{ id: 1 }, { id: '2' }, { id: '3' }];
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.entriesToDelete = ['1', '2', '3'];
|
||||
});
|
||||
|
||||
expect(reducer(state, onChangeBulkSelectall())).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ON_DELETE_DATA_SUCCEEDED', () => {
|
||||
it('should toggle the modal and set the didDeleteData to true', () => {
|
||||
state.showWarningDelete = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.showWarningDelete = false;
|
||||
draft.didDeleteData = true;
|
||||
});
|
||||
|
||||
expect(reducer(state, onDeleteDataSucceeded())).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ON_DELETE_DATA_SEVERAL_DATA_SUCCEEDED', () => {
|
||||
it('should toggle the modal and set the didDeleteData to true', () => {
|
||||
state.showWarningDeleteAll = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.showWarningDeleteAll = false;
|
||||
draft.didDeleteData = true;
|
||||
});
|
||||
|
||||
expect(reducer(state, onDeleteSeveralDataSucceeded())).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SET_MODAL_LOADING_STATE', () => {
|
||||
it('should set the showModalConfirmButtonLoading to true', () => {
|
||||
state.showModalConfirmButtonLoading = false;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.showModalConfirmButtonLoading = true;
|
||||
});
|
||||
|
||||
expect(reducer(state, setModalLoadingState())).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('TOGGLE_MODAL_DELETE', () => {
|
||||
it('should set the showModalConfirmButtonLoading to false', () => {
|
||||
state.showModalConfirmButtonLoading = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.showModalConfirmButtonLoading = false;
|
||||
draft.showWarningDelete = true;
|
||||
});
|
||||
|
||||
expect(reducer(state, toggleModalDelete())).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should set the didDeleteData to false if showWarningDelete is false', () => {
|
||||
state.showWarningDelete = false;
|
||||
state.didDeleteData = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.didDeleteData = false;
|
||||
draft.showWarningDelete = true;
|
||||
});
|
||||
|
||||
expect(reducer(state, toggleModalDelete())).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should not change the didDeleteData to false if showWarningDelete is truthy', () => {
|
||||
state.showWarningDelete = true;
|
||||
state.didDeleteData = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.didDeleteData = true;
|
||||
draft.showWarningDelete = false;
|
||||
});
|
||||
|
||||
expect(reducer(state, toggleModalDelete())).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should set the entriesToDelete to an empty array', () => {
|
||||
state.showWarningDelete = false;
|
||||
state.entriesToDelete = ['1'];
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.showWarningDelete = true;
|
||||
draft.entriesToDelete = [];
|
||||
});
|
||||
|
||||
expect(reducer(state, toggleModalDelete())).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('TOGGLE_MODAL_DELETE_ALL', () => {
|
||||
it('should set the showModalConfirmButtonLoading to false', () => {
|
||||
state.showModalConfirmButtonLoading = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.showModalConfirmButtonLoading = false;
|
||||
draft.showWarningDeleteAll = true;
|
||||
});
|
||||
|
||||
expect(reducer(state, toggleModalDeleteAll())).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should set the didDeleteData to false if showWarningDeleteAll is falsy', () => {
|
||||
state.showWarningDeleteAll = false;
|
||||
state.didDeleteData = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.didDeleteData = false;
|
||||
draft.showWarningDeleteAll = true;
|
||||
});
|
||||
|
||||
expect(reducer(state, toggleModalDeleteAll())).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should not change the didDeleteData to false if showWarningDeleteAll is truthy', () => {
|
||||
state.showWarningDeleteAll = true;
|
||||
state.didDeleteData = true;
|
||||
|
||||
const expected = produce(state, draft => {
|
||||
draft.didDeleteData = true;
|
||||
draft.showWarningDeleteAll = false;
|
||||
});
|
||||
|
||||
expect(reducer(state, toggleModalDeleteAll())).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,24 +1,34 @@
|
||||
import * as React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import React from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Text } from '@strapi/parts/Text';
|
||||
import { getTrad } from '../../utils';
|
||||
import useHasI18n from '../../hooks/useHasI18n';
|
||||
|
||||
const DeleteModalAdditionalInfos = () => {
|
||||
const hasI18nEnabled = useHasI18n();
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
if (!hasI18nEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<span>
|
||||
<FormattedMessage
|
||||
id={getTrad('Settings.list.actions.deleteAdditionalInfos')}
|
||||
values={{
|
||||
em: chunks => <em>{chunks}</em>,
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
<Text textColor="danger500">
|
||||
{formatMessage(
|
||||
{
|
||||
id: getTrad('Settings.list.actions.deleteAdditionalInfos'),
|
||||
defaultMessage:
|
||||
'This will delete the active locale versions <em>(from Internationalization)</em>',
|
||||
},
|
||||
{
|
||||
em: chunks => (
|
||||
<Text textColor="danger500" bold>
|
||||
{chunks}
|
||||
</Text>
|
||||
),
|
||||
}
|
||||
)}
|
||||
</Text>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user