UNPKG

@craftercms/studio-ui

Version:

Services, components, models & utils to build CrafterCMS authoring extensions.

420 lines (418 loc) 19.4 kB
/* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ import React, { lazy, Suspense, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { isPlainObject } from '../../utils/object'; import { useSnackbar } from 'notistack'; import { getHostToHostBus } from '../../utils/subjects'; import { filter } from 'rxjs/operators'; import { showSystemNotification } from '../../state/actions/system'; import Launcher from '../Launcher/Launcher'; import useSelection from '../../hooks/useSelection'; import { useWithPendingChangesCloseRequest } from '../../hooks/useWithPendingChangesCloseRequest'; import MinimizedBar from '../MinimizedBar'; import { RenameAssetDialog } from '../RenameAssetDialog'; const ViewVersionDialog = lazy(() => import('../ViewVersionDialog')); const CompareVersionsDialog = lazy(() => import('../CompareVersionsDialog')); const RejectDialog = lazy(() => import('../RejectDialog')); const EditSiteDialog = lazy(() => import('../EditSiteDialog')); const ConfirmDialog = lazy(() => import('../ConfirmDialog')); const ErrorDialog = lazy(() => import('../ErrorDialog')); const NewContentDialog = lazy(() => import('../NewContentDialog')); const ChangeContentTypeDialog = lazy(() => import('../ChangeContentTypeDialog')); const HistoryDialog = lazy(() => import('../HistoryDialog')); const PublishDialog = lazy(() => import('../PublishDialog')); const DependenciesDialog = lazy(() => import('../DependenciesDialog/DependenciesDialog')); const DeleteDialog = lazy(() => import('../DeleteDialog')); const WorkflowCancellationDialog = lazy(() => import('../WorkflowCancellationDialog')); const LegacyFormDialog = lazy(() => import('../LegacyFormDialog')); const CreateFolderDialog = lazy(() => import('../CreateFolderDialog')); const CopyItemsDialog = lazy(() => import('../CopyDialog')); const CreateFileDialog = lazy(() => import('../CreateFileDialog')); const BulkUploadDialog = lazy(() => import('../UploadDialog')); const SingleFileUploadDialog = lazy(() => import('../SingleFileUploadDialog')); const PreviewDialog = lazy(() => import('../PreviewDialog')); const ItemMenu = lazy(() => import('../ItemActionsMenu')); const ItemMegaMenu = lazy(() => import('../ItemMegaMenu')); const AuthMonitor = lazy(() => import('../AuthMonitor')); const PublishingStatusDialog = lazy(() => import('../PublishingStatusDialog')); const UIBlocker = lazy(() => import('../UIBlocker')); const PathSelectionDialog = lazy(() => import('../PathSelectionDialog')); const UnlockPublisherDialog = lazy(() => import('../UnlockPublisherDialog')); const WidgetDialog = lazy(() => import('../WidgetDialog')); const CodeEditorDialog = lazy(() => import('../CodeEditorDialog')); // @formatter:off function createCallback(action, dispatch) { // prettier-ignore return action ? (output) => { const hasPayload = Boolean(action.payload); const hasOutput = Boolean(output) && isPlainObject(output); const payload = (hasPayload && !hasOutput) // If there's a payload in the original action and there // is no output from the resulting callback, simply use the // original payload ? action.payload // Otherwise, if there's no payload but there is an output sent // to the resulting callback, use the output as the payload : (!hasPayload && hasOutput) ? output : ((hasPayload && hasOutput) // If there's an output and a payload, merge them both into a single object. // We're supposed to be using objects for all our payloads, otherwise this // could fail with literal native values such as strings or numbers. ? Array.isArray(action.payload) // If it's an array, assume is a BATCH_ACTIONS action payload; each item // of the array should be an action, so merge each item with output. ? action.payload.map((a) => (Object.assign(Object.assign({}, a), { payload: Object.assign(Object.assign({}, a.payload), output) }))) // If it's not an array, it's a single action. Merge with output. : Object.assign(Object.assign({}, action.payload), output) // Later, we check if there's a payload to add it : false); dispatch(Object.assign({ type: action.type }, (payload ? { payload } : {}))); } : null; } // @formatter:on function GlobalDialogManager() { var _a, _b, _c; const state = useSelection((state) => state.dialogs); const contentTypesBranch = useSelection((state) => state.contentTypes); const versionsBranch = useSelection((state) => state.versions); const { enqueueSnackbar } = useSnackbar(); const dispatch = useDispatch(); useEffect(() => { const hostToHost$ = getHostToHostBus(); const subscription = hostToHost$ .pipe(filter((e) => e.type === showSystemNotification.type)) .subscribe(({ payload }) => { enqueueSnackbar(payload.message, payload.options); }); return () => { subscription.unsubscribe(); }; }, [enqueueSnackbar]); return React.createElement( Suspense, { fallback: '' }, React.createElement( ConfirmDialog, Object.assign({}, state.confirm, { onOk: createCallback(state.confirm.onOk, dispatch), onCancel: createCallback(state.confirm.onCancel, dispatch), onClose: createCallback(state.confirm.onClose, dispatch), onClosed: createCallback(state.confirm.onClosed, dispatch) }) ), React.createElement( ErrorDialog, Object.assign({}, state.error, { onClose: createCallback(state.error.onClose, dispatch), onClosed: createCallback(state.error.onClosed, dispatch), onDismiss: createCallback(state.error.onDismiss, dispatch) }) ), React.createElement( LegacyFormDialog, Object.assign({}, state.edit, { onClose: createCallback(state.edit.onClose, dispatch), onMinimize: createCallback(state.edit.onMinimize, dispatch), onMaximize: createCallback(state.edit.onMaximize, dispatch), onClosed: createCallback(state.edit.onClosed, dispatch), onSaveSuccess: createCallback(state.edit.onSaveSuccess, dispatch) }) ), React.createElement( CodeEditorDialog, Object.assign({}, state.codeEditor, { onClose: createCallback(state.codeEditor.onClose, dispatch), onMinimize: createCallback(state.codeEditor.onMinimize, dispatch), onMaximize: createCallback(state.codeEditor.onMaximize, dispatch), onClosed: createCallback(state.codeEditor.onClosed, dispatch), onSuccess: createCallback(state.codeEditor.onSuccess, dispatch), onFullScreen: createCallback(state.codeEditor.onFullScreen, dispatch), onCancelFullScreen: createCallback(state.codeEditor.onCancelFullScreen, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.codeEditor.onClose, dispatch) ) }) ), React.createElement( PublishDialog, Object.assign({}, state.publish, { onClose: createCallback(state.publish.onClose, dispatch), onClosed: createCallback(state.publish.onClosed, dispatch), onSuccess: createCallback(state.publish.onSuccess, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.publish.onClose, dispatch) ) }) ), React.createElement( NewContentDialog, Object.assign({}, state.newContent, { onContentTypeSelected: createCallback(state.newContent.onContentTypeSelected, dispatch), onClose: createCallback(state.newContent.onClose, dispatch), onClosed: createCallback(state.newContent.onClosed, dispatch) }) ), React.createElement( ChangeContentTypeDialog, Object.assign({}, state.changeContentType, { onContentTypeSelected: createCallback(state.changeContentType.onContentTypeSelected, dispatch), onClose: createCallback(state.changeContentType.onClose, dispatch), onClosed: createCallback(state.changeContentType.onClosed, dispatch) }) ), React.createElement( DependenciesDialog, Object.assign({}, state.dependencies, { onClose: createCallback(state.dependencies.onClose, dispatch), onClosed: createCallback(state.dependencies.onClosed, dispatch) }) ), React.createElement( DeleteDialog, Object.assign({}, state.delete, { onClose: createCallback(state.delete.onClose, dispatch), onClosed: createCallback(state.delete.onClosed, dispatch), onSuccess: createCallback(state.delete.onSuccess, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.delete.onClose, dispatch) ) }) ), React.createElement( HistoryDialog, Object.assign({}, state.history, { versionsBranch: versionsBranch, onClose: createCallback(state.history.onClose, dispatch), onClosed: createCallback(state.history.onClosed, dispatch) }) ), React.createElement( ViewVersionDialog, Object.assign({}, state.viewVersion, { rightActions: (_a = state.viewVersion.rightActions) === null || _a === void 0 ? void 0 : _a.map((action) => Object.assign(Object.assign({}, action), { onClick: createCallback(action.onClick, dispatch) }) ), leftActions: (_b = state.viewVersion.leftActions) === null || _b === void 0 ? void 0 : _b.map((action) => Object.assign(Object.assign({}, action), { onClick: createCallback(action.onClick, dispatch) }) ), contentTypesBranch: contentTypesBranch, onClose: createCallback(state.viewVersion.onClose, dispatch), onClosed: createCallback(state.viewVersion.onClosed, dispatch) }) ), React.createElement( CompareVersionsDialog, Object.assign({}, state.compareVersions, { rightActions: (_c = state.compareVersions.rightActions) === null || _c === void 0 ? void 0 : _c.map((action) => Object.assign(Object.assign({}, action), { onClick: createCallback(action.onClick, dispatch) }) ), contentTypesBranch: contentTypesBranch, selectedA: (versionsBranch === null || versionsBranch === void 0 ? void 0 : versionsBranch.selected[0]) ? versionsBranch.byId[versionsBranch.selected[0]] : null, selectedB: (versionsBranch === null || versionsBranch === void 0 ? void 0 : versionsBranch.selected[1]) ? versionsBranch.byId[versionsBranch.selected[1]] : null, versionsBranch: versionsBranch, onClose: createCallback(state.compareVersions.onClose, dispatch), onClosed: createCallback(state.compareVersions.onClosed, dispatch) }) ), React.createElement(AuthMonitor, null), React.createElement( WorkflowCancellationDialog, Object.assign({}, state.workflowCancellation, { onClose: createCallback(state.workflowCancellation.onClose, dispatch), onClosed: createCallback(state.workflowCancellation.onClosed, dispatch), onContinue: createCallback(state.workflowCancellation.onContinue, dispatch) }) ), React.createElement( RejectDialog, Object.assign({}, state.reject, { onClose: createCallback(state.reject.onClose, dispatch), onClosed: createCallback(state.reject.onClosed, dispatch), onRejectSuccess: createCallback(state.reject.onRejectSuccess, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.reject.onClose, dispatch) ) }) ), React.createElement( CreateFolderDialog, Object.assign({}, state.createFolder, { onClose: createCallback(state.createFolder.onClose, dispatch), onClosed: createCallback(state.createFolder.onClosed, dispatch), onCreated: createCallback(state.createFolder.onCreated, dispatch), onRenamed: createCallback(state.createFolder.onRenamed, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.createFolder.onClose, dispatch) ) }) ), React.createElement( CreateFileDialog, Object.assign({}, state.createFile, { onClose: createCallback(state.createFile.onClose, dispatch), onClosed: createCallback(state.createFile.onClosed, dispatch), onCreated: createCallback(state.createFile.onCreated, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.createFile.onClose, dispatch) ) }) ), React.createElement( RenameAssetDialog, Object.assign({}, state.renameAsset, { onClose: createCallback(state.renameAsset.onClose, dispatch), onClosed: createCallback(state.renameAsset.onClosed, dispatch), onRenamed: createCallback(state.renameAsset.onRenamed, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.renameAsset.onClose, dispatch) ) }) ), React.createElement( CopyItemsDialog, Object.assign({}, state.copy, { onClose: createCallback(state.copy.onClose, dispatch), onClosed: createCallback(state.copy.onClosed, dispatch), onOk: createCallback(state.copy.onOk, dispatch) }) ), React.createElement( BulkUploadDialog, Object.assign({}, state.upload, { onClose: createCallback(state.upload.onClose, dispatch), onClosed: createCallback(state.upload.onClosed, dispatch) }) ), React.createElement( SingleFileUploadDialog, Object.assign({}, state.singleFileUpload, { onClose: createCallback(state.singleFileUpload.onClose, dispatch), onClosed: createCallback(state.singleFileUpload.onClosed, dispatch), onUploadStart: createCallback(state.singleFileUpload.onUploadStart, dispatch), onUploadComplete: createCallback(state.singleFileUpload.onUploadComplete, dispatch), onUploadError: createCallback(state.singleFileUpload.onUploadError, dispatch) }) ), React.createElement( PreviewDialog, Object.assign({}, state.preview, { onMinimize: createCallback(state.preview.onMinimize, dispatch), onMaximize: createCallback(state.preview.onMaximize, dispatch), onClose: createCallback(state.preview.onClose, dispatch), onClosed: createCallback(state.preview.onClosed, dispatch), onFullScreen: createCallback(state.preview.onFullScreen, dispatch), onCancelFullScreen: createCallback(state.preview.onCancelFullScreen, dispatch) }) ), React.createElement( EditSiteDialog, Object.assign({}, state.editSite, { onClose: createCallback(state.editSite.onClose, dispatch), onClosed: createCallback(state.editSite.onClosed, dispatch), onSaveSuccess: createCallback(state.editSite.onSaveSuccess, dispatch), onSiteImageChange: createCallback(state.editSite.onSiteImageChange, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.editSite.onClose, dispatch) ) }) ), React.createElement( PathSelectionDialog, Object.assign({}, state.pathSelection, { onClose: createCallback(state.pathSelection.onClose, dispatch), onClosed: createCallback(state.pathSelection.onClosed, dispatch), onOk: createCallback(state.pathSelection.onOk, dispatch) }) ), React.createElement( ItemMenu, Object.assign({}, state.itemMenu, { onClose: createCallback(state.itemMenu.onClose, dispatch) }) ), React.createElement( ItemMegaMenu, Object.assign({}, state.itemMegaMenu, { onClose: createCallback(state.itemMegaMenu.onClose, dispatch) }) ), React.createElement(Launcher, Object.assign({}, state.launcher)), React.createElement( PublishingStatusDialog, Object.assign({}, state.publishingStatus, { onClose: createCallback(state.publishingStatus.onClose, dispatch), onRefresh: createCallback(state.publishingStatus.onRefresh, dispatch), onUnlock: createCallback(state.publishingStatus.onUnlock, dispatch) }) ), React.createElement(UnlockPublisherDialog, { open: state.unlockPublisher.open, onError: createCallback(state.unlockPublisher.onError, dispatch), onCancel: createCallback(state.unlockPublisher.onCancel, dispatch), onComplete: createCallback(state.unlockPublisher.onComplete, dispatch) }), React.createElement( WidgetDialog, Object.assign({}, state.widget, { onClose: createCallback(state.widget.onClose, dispatch), onMinimize: createCallback(state.widget.onMinimize, dispatch), onMaximize: createCallback(state.widget.onMaximize, dispatch), onClosed: createCallback(state.widget.onClosed, dispatch), onWithPendingChangesCloseRequest: useWithPendingChangesCloseRequest( createCallback(state.widget.onClose, dispatch) ) }) ), Object.values(state.minimizedTabs).map((tab) => React.createElement(MinimizedBar, { key: tab.id, open: tab.minimized, title: tab.title, subtitle: tab.subtitle, status: tab.status, onMaximize: createCallback(tab.onMaximized, dispatch) }) ), React.createElement(UIBlocker, Object.assign({}, state.uiBlocker)) ); } export default React.memo(GlobalDialogManager);