From 21c9cb69adf67ba42c14cbc9489c889ba8acecaf Mon Sep 17 00:00:00 2001 From: Fernando Chavez Date: Wed, 26 Apr 2023 11:57:05 +0200 Subject: [PATCH 1/7] Add a new bulkActionsBar prop to DynamicTable from helper-plugins and changes to the table on content manager to have the new bulk publish buttons --- .../DynamicTable/BulkActionsBar/index.js | 85 +++++++++++++++++++ .../components/DynamicTable/index.js | 12 ++- .../src/components/DynamicTable/index.js | 59 ++++++++----- 3 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js new file mode 100644 index 0000000000..c06661b702 --- /dev/null +++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/BulkActionsBar/index.js @@ -0,0 +1,85 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { Button } from '@strapi/design-system'; +import { useIntl } from 'react-intl'; +import ConfirmDialogDeleteAll from '../ConfirmDialogDeleteAll'; +import { useTracking } from '@strapi/helper-plugin'; + +const BulkActionsBar = ({ + showPublish, + showDelete, + onConfirmDeleteAll, + selectedEntries, + clearSelectedEntries, +}) => { + const { formatMessage } = useIntl(); + const { trackUsage } = useTracking(); + + const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false); + const [showConfirmDeleteAll, setShowConfirmDeleteAll] = useState(false); + + const handleToggleShowDeleteAllModal = () => { + if (!showConfirmDeleteAll) { + trackUsage('willBulkDeleteEntries'); + } + + setShowConfirmDeleteAll((prev) => !prev); + }; + + const handleConfirmDeleteAll = async () => { + try { + setIsConfirmButtonLoading(true); + await onConfirmDeleteAll(selectedEntries); + handleToggleShowDeleteAllModal(); + clearSelectedEntries(); + setIsConfirmButtonLoading(false); + } catch (err) { + setIsConfirmButtonLoading(false); + handleToggleShowDeleteAllModal(); + } + }; + + return ( + <> + {showPublish && ( + <> + + + + )} + {showDelete && ( + <> + + + + )} + + ); +}; + +BulkActionsBar.defaultProps = { + showPublishUnpublish: false, + showDelete: false, + onConfirmDeleteAll: () => {}, +}; + +BulkActionsBar.propTypes = { + showPublishUnpublish: PropTypes.bool, + showDelete: PropTypes.bool, + onConfirmDeleteAll: PropTypes.func, + selectedEntries: PropTypes.array.isRequired, + clearSelectedEntries: PropTypes.func.isRequired, +}; + +export default BulkActionsBar; diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js index 721dbd8fb5..77bcd4155a 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js @@ -9,9 +9,9 @@ import { INJECT_COLUMN_IN_TABLE } from '../../../exposedHooks'; import { selectDisplayedHeaders } from '../../pages/ListView/selectors'; import { getTrad } from '../../utils'; import TableRows from './TableRows'; -import ConfirmDialogDeleteAll from './ConfirmDialogDeleteAll'; import ConfirmDialogDelete from './ConfirmDialogDelete'; import { PublicationState } from './CellContent/PublicationState/PublicationState'; +import BulkActionsBar from './BulkActionsBar'; const DynamicTable = ({ canCreate, @@ -89,17 +89,23 @@ const DynamicTable = ({ return ( + } > { - const [entriesToDelete, setEntriesToDelete] = useState([]); + const [selectedEntries, setSelectedEntries] = useState([]); const [showConfirmDeleteAll, setShowConfirmDeleteAll] = useState(false); const [showConfirmDelete, setShowConfirmDelete] = useState(false); const [isConfirmButtonLoading, setIsConfirmButtonLoading] = useState(false); @@ -44,7 +45,7 @@ const Table = ({ const ROW_COUNT = rows.length + 1; const COL_COUNT = headers.length + (withBulkActions ? 1 : 0) + (withMainAction ? 1 : 0); const hasFilters = query?.filters !== undefined; - const areAllEntriesSelected = entriesToDelete.length === rows.length && rows.length > 0; + const areAllEntriesSelected = selectedEntries.length === rows.length && rows.length > 0; const content = hasFilters ? { @@ -57,9 +58,9 @@ const Table = ({ const handleConfirmDeleteAll = async () => { try { setIsConfirmButtonLoading(true); - await onConfirmDeleteAll(entriesToDelete); + await onConfirmDeleteAll(selectedEntries); handleToggleConfirmDeleteAll(); - setEntriesToDelete([]); + setSelectedEntries([]); setIsConfirmButtonLoading(false); } catch (err) { setIsConfirmButtonLoading(false); @@ -71,7 +72,7 @@ const Table = ({ try { setIsConfirmButtonLoading(true); // await onConfirmDeleteAll(entriesToDelete); - await onConfirmDelete(entriesToDelete[0]); + await onConfirmDelete(selectedEntries[0]); handleToggleConfirmDelete(); setIsConfirmButtonLoading(false); } catch (err) { @@ -82,9 +83,9 @@ const Table = ({ const handleSelectAll = () => { if (!areAllEntriesSelected) { - setEntriesToDelete(rows.map((row) => row.id)); + setSelectedEntries(rows.map((row) => row.id)); } else { - setEntriesToDelete([]); + setSelectedEntries([]); } }; @@ -98,19 +99,19 @@ const Table = ({ const handleToggleConfirmDelete = () => { if (showConfirmDelete) { - setEntriesToDelete([]); + setSelectedEntries([]); } setShowConfirmDelete((prev) => !prev); }; const handleClickDelete = (id) => { - setEntriesToDelete([id]); + setSelectedEntries([id]); handleToggleConfirmDelete(); }; const handleSelectRow = ({ name, value }) => { - setEntriesToDelete((prev) => { + setSelectedEntries((prev) => { if (value) { return prev.concat(name); } @@ -119,6 +120,10 @@ const Table = ({ }); }; + const clearSelectedEntries = () => { + setSelectedEntries([]); + }; + const ConfirmDeleteAllComponent = components?.ConfirmDialogDeleteAll ? components.ConfirmDialogDeleteAll : ConfirmDialog; @@ -129,7 +134,7 @@ const Table = ({ return ( <> - {entriesToDelete.length > 0 && ( + {selectedEntries.length > 0 && ( @@ -140,17 +145,25 @@ const Table = ({ id: 'content-manager.components.TableDelete.label', defaultMessage: '{number, plural, one {# entry} other {# entries}} selected', }, - { number: entriesToDelete.length } + { number: selectedEntries.length } )} - + {bulkActionsBar ? ( + React.cloneElement(bulkActionsBar, { + ...bulkActionsBar.props, + selectedEntries, + clearSelectedEntries, + }) + ) : ( + + )} @@ -159,7 +172,7 @@ const Table = ({ cloneElement(child, { - entriesToDelete, + entriesToDelete: selectedEntries, onClickDelete: handleClickDelete, onSelectRow: handleSelectRow, headers, @@ -219,6 +232,7 @@ Table.defaultProps = { rows: [], withBulkActions: false, withMainAction: false, + bulkActionsBar: undefined, }; Table.propTypes = { @@ -248,6 +262,7 @@ Table.propTypes = { rows: PropTypes.array, withBulkActions: PropTypes.bool, withMainAction: PropTypes.bool, + bulkActionsBar: PropTypes.node, }; export default Table; From e0e272fedeebc5b186b3601f77b9bd0e79d0bb0f Mon Sep 17 00:00:00 2001 From: Fernando Chavez Date: Wed, 26 Apr 2023 12:10:49 +0200 Subject: [PATCH 2/7] Send the canPublish permissions to the DynamicTable on content manager --- .../admin/src/content-manager/components/DynamicTable/index.js | 3 ++- .../admin/admin/src/content-manager/pages/ListView/index.js | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js index 77bcd4155a..863ded72f0 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js @@ -16,6 +16,7 @@ import BulkActionsBar from './BulkActionsBar'; const DynamicTable = ({ canCreate, canDelete, + canPublish, contentTypeName, action, isBulkable, @@ -101,7 +102,7 @@ const DynamicTable = ({ withMainAction={canDelete && isBulkable} bulkActionsBar={ diff --git a/packages/core/admin/admin/src/content-manager/pages/ListView/index.js b/packages/core/admin/admin/src/content-manager/pages/ListView/index.js index c60295aba1..0ab7b436dd 100644 --- a/packages/core/admin/admin/src/content-manager/pages/ListView/index.js +++ b/packages/core/admin/admin/src/content-manager/pages/ListView/index.js @@ -64,6 +64,7 @@ function ListView({ canCreate, canDelete, canRead, + canPublish, data, getData, getDataSucceeded, @@ -331,6 +332,7 @@ function ListView({ Date: Wed, 26 Apr 2023 12:20:38 +0200 Subject: [PATCH 3/7] add canPublish to conditions to show the bulk buttons --- .../admin/src/content-manager/components/DynamicTable/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js index 863ded72f0..b6d36f9b21 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js @@ -99,7 +99,7 @@ const DynamicTable = ({ onOpenDeleteAllModalTrackedEvent="willBulkDeleteEntries" rows={rows} withBulkActions - withMainAction={canDelete && isBulkable} + withMainAction={(canDelete || canPublish) && isBulkable} bulkActionsBar={ Date: Wed, 26 Apr 2023 14:22:29 +0200 Subject: [PATCH 4/7] change cloneElement for a render function on helper-plugin's dynamicTable --- .../components/DynamicTable/index.js | 6 ++++-- .../src/components/DynamicTable/index.js | 14 +++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js index b6d36f9b21..c684d508d3 100644 --- a/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js +++ b/packages/core/admin/admin/src/content-manager/components/DynamicTable/index.js @@ -100,13 +100,15 @@ const DynamicTable = ({ rows={rows} withBulkActions withMainAction={(canDelete || canPublish) && isBulkable} - bulkActionsBar={ + renderBulkActionsBar={({ selectedEntries, clearSelectedEntries }) => ( - } + )} > { const [selectedEntries, setSelectedEntries] = useState([]); @@ -148,12 +148,8 @@ const Table = ({ { number: selectedEntries.length } )} - {bulkActionsBar ? ( - React.cloneElement(bulkActionsBar, { - ...bulkActionsBar.props, - selectedEntries, - clearSelectedEntries, - }) + {renderBulkActionsBar ? ( + renderBulkActionsBar({ selectedEntries, clearSelectedEntries }) ) : (