@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
134 lines (132 loc) • 5.62 kB
JavaScript
/*
* 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, { useEffect } from 'react';
import { defineMessages, FormattedMessage } from 'react-intl';
import { initToolsPanelConfig, updateToolsPanelWidth } from '../../state/actions/preview';
import { useDispatch } from 'react-redux';
import ResizeableDrawer from '../ResizeableDrawer/ResizeableDrawer';
import { renderWidgets } from '../Widget';
import { Suspencified } from '../Suspencified/Suspencified';
import { makeStyles } from 'tss-react/mui';
import { useSelection } from '../../hooks/useSelection';
import { usePreviewState } from '../../hooks/usePreviewState';
import { useActiveUser } from '../../hooks/useActiveUser';
import { useSiteUIConfig } from '../../hooks/useSiteUIConfig';
import { nnou } from '../../utils/object';
import { getStoredPreviewToolsPanelPage, getStoredPreviewToolsPanelWidth } from '../../utils/state';
import { useActiveSite } from '../../hooks/useActiveSite';
import { blockPreviewIframePointerEvents } from '../Preview/utils';
import { ApiResponseErrorState } from '../ApiResponseErrorState';
import { LoadingState } from '../LoadingState';
import { EmptyState } from '../EmptyState';
defineMessages({
previewSiteExplorerPanelTitle: {
id: 'previewSiteExplorerPanel.title',
defaultMessage: 'Project Explorer'
}
});
const useStyles = makeStyles()((theme) => ({
emptyState: {
margin: `${theme.spacing(4)} ${theme.spacing(1)}`
},
emptyStateImage: {
width: '50%',
marginBottom: theme.spacing(1)
},
loadingViewRoot: {
flex: 1,
flexDirection: 'row'
},
drawerBody: {
paddingBottom: 50
}
}));
export function ToolsPanel() {
const dispatch = useDispatch();
const { id: siteId, uuid } = useActiveSite();
const { classes } = useStyles();
const { showToolsPanel, toolsPanel, toolsPanelWidth, windowSize } = usePreviewState();
const toolsPanelPageStack = useSelection((state) => state.preview.toolsPanelPageStack);
const uiConfig = useSiteUIConfig();
const { username } = useActiveUser();
const { rolesBySite } = useActiveUser();
const isLoading = uiConfig.isFetching;
const isEmpty = toolsPanel?.widgets == null || toolsPanel.widgets.length === 0;
const onWidthChange = (width) => dispatch(updateToolsPanelWidth({ width }));
const loadingStateProps = { styles: { graphic: { width: '90px' } } };
useEffect(() => {
if (nnou(uiConfig.xml) && !toolsPanel) {
const storedPage = getStoredPreviewToolsPanelPage(uuid, username);
const toolsPanelWidth = getStoredPreviewToolsPanelWidth(siteId, username);
dispatch(initToolsPanelConfig({ configXml: uiConfig.xml, storedPage, toolsPanelWidth }));
}
}, [uiConfig.xml, toolsPanel, dispatch, uuid, username, siteId]);
return React.createElement(
ResizeableDrawer,
{
belowToolbar: true,
open: showToolsPanel,
width: toolsPanelWidth,
maxWidth: windowSize,
classes: { drawerBody: classes.drawerBody },
onWidthChange: onWidthChange,
onResizeStart: () => blockPreviewIframePointerEvents(true),
onResizeStop: () => blockPreviewIframePointerEvents(false),
styles: {
resizeHandle: { backgroundColor: 'transparent' },
drawerPaperBelowToolbar: { top: '64px' }
}
},
uiConfig.error
? React.createElement(ApiResponseErrorState, { error: uiConfig.error })
: isLoading
? React.createElement(LoadingState, { ...loadingStateProps })
: isEmpty
? React.createElement(EmptyState, {
sxs: { title: { textAlign: 'center' } },
title: React.createElement(FormattedMessage, { defaultMessage: 'No widgets configured' }),
subtitle: React.createElement(FormattedMessage, {
defaultMessage: 'Add configuration > widgets to `craftercms.components.ToolsPanel` on `ui.xml`'
})
})
: React.createElement(
Suspencified,
{ loadingStateProps: loadingStateProps },
renderWidgets(
toolsPanelPageStack.length
? toolsPanelPageStack.slice(toolsPanelPageStack.length - 1)
: toolsPanel.widgets,
{ userRoles: rolesBySite[siteId] }
)
)
);
}
export default ToolsPanel;