fix: document actions being rendered multiple times (#22283)

This commit is contained in:
Rémi de Juvigny 2024-11-29 11:58:46 +01:00 committed by GitHub
parent 11a2566277
commit 7232d30c05
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 39 additions and 5 deletions

View File

@ -3,6 +3,7 @@ import { INJECTION_ZONES } from './components/InjectionZone';
import { PLUGIN_ID } from './constants/plugin'; import { PLUGIN_ID } from './constants/plugin';
import { import {
DEFAULT_ACTIONS, DEFAULT_ACTIONS,
type DocumentActionPosition,
type DocumentActionDescription, type DocumentActionDescription,
} from './pages/EditView/components/DocumentActions'; } from './pages/EditView/components/DocumentActions';
import { import {
@ -94,6 +95,7 @@ interface DocumentActionComponent
| 'publish' | 'publish'
| 'unpublish' | 'unpublish'
| 'update'; | 'update';
position?: DocumentActionDescription['position'];
} }
interface HeaderActionProps extends EditViewContext {} interface HeaderActionProps extends EditViewContext {}
@ -209,7 +211,23 @@ class ContentManagerPlugin {
addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this), addDocumentHeaderAction: this.addDocumentHeaderAction.bind(this),
addEditViewSidePanel: this.addEditViewSidePanel.bind(this), addEditViewSidePanel: this.addEditViewSidePanel.bind(this),
getBulkActions: () => this.bulkActions, getBulkActions: () => this.bulkActions,
getDocumentActions: () => this.documentActions, getDocumentActions: (position?: DocumentActionPosition) => {
/**
* When possible, pre-filter the actions by the components static position property.
* This avoids rendering the actions in multiple places where they weren't displayed,
* which wasn't visible but created issues with useEffect for instance.
* The response should still be filtered by the position, as the static property is new
* and not mandatory to avoid a breaking change.
*/
if (position) {
return this.documentActions.filter(
(action) =>
action.position == undefined || [action.position].flat().includes(position)
);
}
return this.documentActions;
},
getEditViewSidePanels: () => this.editViewSidePanels, getEditViewSidePanels: () => this.editViewSidePanels,
getHeaderActions: () => this.headerActions, getHeaderActions: () => this.headerActions,
}, },

View File

@ -57,5 +57,6 @@ const HistoryAction: DocumentActionComponent = ({ model, document }) => {
}; };
HistoryAction.type = 'history'; HistoryAction.type = 'history';
HistoryAction.position = 'header';
export { HistoryAction }; export { HistoryAction };

View File

@ -742,6 +742,7 @@ const PublishAction: DocumentActionComponent = ({
}; };
PublishAction.type = 'publish'; PublishAction.type = 'publish';
PublishAction.position = 'panel';
const UpdateAction: DocumentActionComponent = ({ const UpdateAction: DocumentActionComponent = ({
activeTab, activeTab,
@ -878,6 +879,7 @@ const UpdateAction: DocumentActionComponent = ({
}; };
UpdateAction.type = 'update'; UpdateAction.type = 'update';
UpdateAction.position = 'panel';
const UNPUBLISH_DRAFT_OPTIONS = { const UNPUBLISH_DRAFT_OPTIONS = {
KEEP: 'keep', KEEP: 'keep',
@ -1028,6 +1030,7 @@ const UnpublishAction: DocumentActionComponent = ({
}; };
UnpublishAction.type = 'unpublish'; UnpublishAction.type = 'unpublish';
UnpublishAction.position = 'panel';
const DiscardAction: DocumentActionComponent = ({ const DiscardAction: DocumentActionComponent = ({
activeTab, activeTab,
@ -1086,8 +1089,15 @@ const DiscardAction: DocumentActionComponent = ({
}; };
DiscardAction.type = 'discard'; DiscardAction.type = 'discard';
DiscardAction.position = 'panel';
const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction]; const DEFAULT_ACTIONS = [PublishAction, UpdateAction, UnpublishAction, DiscardAction];
export { DocumentActions, DocumentActionsMenu, DocumentActionButton, DEFAULT_ACTIONS }; export { DocumentActions, DocumentActionsMenu, DocumentActionButton, DEFAULT_ACTIONS };
export type { DocumentActionDescription, DialogOptions, NotificationOptions, ModalOptions }; export type {
DocumentActionDescription,
DocumentActionPosition,
DialogOptions,
NotificationOptions,
ModalOptions,
};

View File

@ -167,7 +167,7 @@ const HeaderToolbar = () => {
}} }}
descriptions={( descriptions={(
plugins['content-manager'].apis as ContentManagerPlugin['config']['apis'] plugins['content-manager'].apis as ContentManagerPlugin['config']['apis']
).getDocumentActions()} ).getDocumentActions('header')}
> >
{(actions) => { {(actions) => {
const headerActions = actions.filter((action) => { const headerActions = actions.filter((action) => {
@ -470,6 +470,7 @@ const ConfigureTheViewAction: DocumentActionComponent = ({ collectionType, model
}; };
ConfigureTheViewAction.type = 'configure-the-view'; ConfigureTheViewAction.type = 'configure-the-view';
ConfigureTheViewAction.position = 'header';
const EditTheModelAction: DocumentActionComponent = ({ model }) => { const EditTheModelAction: DocumentActionComponent = ({ model }) => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -489,6 +490,7 @@ const EditTheModelAction: DocumentActionComponent = ({ model }) => {
}; };
EditTheModelAction.type = 'edit-the-model'; EditTheModelAction.type = 'edit-the-model';
EditTheModelAction.position = 'header';
const DeleteAction: DocumentActionComponent = ({ documentId, model, collectionType, document }) => { const DeleteAction: DocumentActionComponent = ({ documentId, model, collectionType, document }) => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -578,6 +580,7 @@ const DeleteAction: DocumentActionComponent = ({ documentId, model, collectionTy
}; };
DeleteAction.type = 'delete'; DeleteAction.type = 'delete';
DeleteAction.position = ['header', 'table-row'];
const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction]; const DEFAULT_HEADER_ACTIONS = [EditTheModelAction, ConfigureTheViewAction, DeleteAction];

View File

@ -115,7 +115,7 @@ const ActionsPanelContent = () => {
props={props} props={props}
descriptions={( descriptions={(
plugins['content-manager'].apis as ContentManagerPlugin['config']['apis'] plugins['content-manager'].apis as ContentManagerPlugin['config']['apis']
).getDocumentActions()} ).getDocumentActions('panel')}
> >
{(actions) => <DocumentActions actions={actions} />} {(actions) => <DocumentActions actions={actions} />}
</DescriptionComponentRenderer> </DescriptionComponentRenderer>

View File

@ -53,7 +53,7 @@ const TableActions = ({ document }: TableActionsProps) => {
<DescriptionComponentRenderer <DescriptionComponentRenderer
props={props} props={props}
descriptions={(plugins['content-manager'].apis as ContentManagerPlugin['config']['apis']) descriptions={(plugins['content-manager'].apis as ContentManagerPlugin['config']['apis'])
.getDocumentActions() .getDocumentActions('table-row')
// We explicitly remove the PublishAction from description so we never render it and we don't make unnecessary requests. // We explicitly remove the PublishAction from description so we never render it and we don't make unnecessary requests.
.filter((action) => action.name !== 'PublishAction')} .filter((action) => action.name !== 'PublishAction')}
> >
@ -125,6 +125,7 @@ const EditAction: DocumentActionComponent = ({ documentId }) => {
}; };
EditAction.type = 'edit'; EditAction.type = 'edit';
EditAction.position = 'table-row';
/** /**
* Because the icon system is completely broken, we have to do * Because the icon system is completely broken, we have to do
@ -227,6 +228,7 @@ const CloneAction: DocumentActionComponent = ({ model, documentId }) => {
}; };
CloneAction.type = 'clone'; CloneAction.type = 'clone';
CloneAction.position = 'table-row';
/** /**
* Because the icon system is completely broken, we have to do * Because the icon system is completely broken, we have to do