@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
223 lines (221 loc) • 7.75 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 Box from '@mui/material/Box';
import React, { useMemo, useState } from 'react';
import { useEffect, Suspense } from 'react';
import useSiteUIConfig from '../../hooks/useSiteUIConfig';
import useDashboardState from '../../hooks/useDashboardState';
import useActiveUser from '../../hooks/useActiveUser';
import useActiveSiteId from '../../hooks/useActiveSiteId';
import { useDispatch } from 'react-redux';
import { initDashboardConfig } from '../../state/actions/dashboard';
import { renderWidgets } from '../Widget';
import EmptyState from '../EmptyState';
import { FormattedMessage } from 'react-intl';
import Skeleton from '@mui/material/Skeleton';
import { useTheme } from '@mui/material/styles';
import Grid from '@mui/material/Grid';
import ActivityDashlet from '../ActivityDashlet/ActivityDashlet';
import DevContentOpsDashlet from '../DevContentOpsDashlet/DevContentOpsDashlet';
import useMediaQuery from '@mui/material/useMediaQuery';
import { IconGuideDashlet } from '../IconGuideDashlet';
import { SiteDashboardContext } from './useSiteDashboardContext';
export function Dashboard(props) {
const { mountMode, onMinimize } = props;
const {
palette: { mode }
} = useTheme();
const desktopScreen = useMediaQuery('(min-width: 1100px)');
const site = useActiveSiteId();
const user = useActiveUser();
const userRoles = user.rolesBySite[site];
const uiConfig = useSiteUIConfig();
const dashboard = useDashboardState();
const dispatch = useDispatch();
const [showActivityFeed, setShowActivityFeed] = useState(true);
const [freezeScroll, setFreezeScroll] = useState(false);
const context = useMemo(
() => ({
onDashletMaximize: () => {
setShowActivityFeed(false);
setFreezeScroll(true);
},
onDashletMinimize: () => {
setShowActivityFeed(true);
setFreezeScroll(false);
}
}),
[]
);
useEffect(() => {
if (uiConfig.xml && !dashboard) {
dispatch(initDashboardConfig({ configXml: uiConfig.xml }));
}
}, [uiConfig.xml, dashboard, dispatch]);
const height = 400;
return React.createElement(
SiteDashboardContext.Provider,
{ value: context },
React.createElement(
Box,
{
sx: {
position: 'relative',
p: 2,
bgcolor: 'background.default',
...(desktopScreen
? {
height: mountMode === 'dialog' ? '100%' : 'calc(100% - 65px)',
overflow: 'hidden'
}
: {
height: freezeScroll ? '100%' : 'auto',
overflowY: freezeScroll ? 'hidden' : 'auto'
})
}
},
React.createElement(
Grid,
{
container: true,
spacing: 2,
sx: {
alignItems: 'baseline',
alignContent: 'baseline',
...(desktopScreen
? {
width: showActivityFeed ? '70%' : '100%',
height: '100%',
position: 'absolute',
overflowY: freezeScroll ? 'hide' : 'auto',
pb: 2,
pr: 2
}
: {})
}
},
React.createElement(
Grid,
{
item: true,
xs: 12,
md: 12,
sx: {
display: 'flex',
flexWrap: 'wrap'
}
},
React.createElement(DevContentOpsDashlet, {
sxs: {
card: {
width: '100%'
}
}
})
),
React.createElement(
Suspense,
{ fallback: React.createElement(DashboardSkeleton, null) },
dashboard
? Boolean(dashboard?.mainSection?.widgets?.length)
? renderWidgets(dashboard.mainSection.widgets, {
userRoles,
defaultProps: { contentHeight: height, onMinimize, maximizable: true },
createMapperFn: (mapper) => (widget, index) =>
React.createElement(Grid, { item: true, xs: 12, md: 6, key: index }, mapper(widget, index))
})
: React.createElement(
Grid,
{ item: true, xs: 12 },
React.createElement(EmptyState, {
title: React.createElement(FormattedMessage, {
id: 'siteDashboard.emptyStateMessageTitle',
defaultMessage: 'No widgets to display'
}),
subtitle: React.createElement(FormattedMessage, {
id: 'siteDashboard.emptyStateMessageSubtitle',
defaultMessage: "Add widgets at your project's User Interface Configuration"
})
})
)
: React.createElement(DashboardSkeleton, null)
),
desktopScreen &&
React.createElement(
Grid,
{ item: true, md: 12, sx: { flexWrap: 'wrap' } },
React.createElement(IconGuideDashlet, null)
)
),
React.createElement(ActivityDashlet, {
sxs: {
card: {
// Using display prop to hide Dashlet to avoid unmounting component
display: showActivityFeed ? 'flex' : 'none',
flexDirection: 'column',
...(desktopScreen
? {
width: '30%',
position: 'absolute',
right: 0,
top: 0,
bottom: 0,
borderRadius: 0
}
: {
mt: 2
})
}
},
contentHeight: desktopScreen ? null : height,
onMinimize: onMinimize,
collapsible: !desktopScreen
}),
!desktopScreen && React.createElement(Box, { sx: { mt: 2 } }, React.createElement(IconGuideDashlet, null))
)
);
}
function DashboardSkeleton() {
return React.createElement(
React.Fragment,
null,
new Array(3)
.fill(null)
.map((nothing, index) =>
React.createElement(
Grid,
{ item: true, xs: 12, md: 6, key: index },
React.createElement(Skeleton, { variant: 'rectangular', sx: { height: 350 } })
)
)
);
}
export default Dashboard;