@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
215 lines (213 loc) • 7.69 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 DashletCard from '../DashletCard/DashletCard';
import palette from '../../styles/palette';
import { FormattedMessage } from 'react-intl';
import React, { useEffect, useMemo, useState } from 'react';
import useSpreadState from '../../hooks/useSpreadState';
import useActiveSiteId from '../../hooks/useActiveSiteId';
import { fetchPublishingStats } from '../../services/dashboard';
import Skeleton from '@mui/material/Skeleton';
import Stack from '@mui/material/Stack';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import { contentEvent, deleteContentEvent, publishEvent, workflowEvent } from '../../state/actions/system';
import { getHostToHostBus } from '../../utils/subjects';
import { filter } from 'rxjs/operators';
function DevContentOpsStats(props) {
const { stats, sx } = props;
return React.createElement(
React.Fragment,
null,
stats &&
React.createElement(
Stack,
{ direction: 'row', spacing: 2, sx: sx?.root },
React.createElement(
Box,
null,
React.createElement(Typography, {
component: 'span',
children: stats.numberOfPublishes,
lineHeight: 1,
sx: { fontWeight: (theme) => theme.typography.fontWeightMedium }
}),
' ',
React.createElement(Typography, {
component: 'span',
children: React.createElement(FormattedMessage, { defaultMessage: 'Publishes' })
})
),
React.createElement(
Box,
null,
React.createElement(Typography, {
component: 'span',
children: stats.numberOfNewAndPublishedItems,
lineHeight: 1,
sx: { fontWeight: (theme) => theme.typography.fontWeightMedium }
}),
' ',
React.createElement(Typography, {
component: 'span',
children: React.createElement(FormattedMessage, { defaultMessage: 'Created & Published' })
})
),
React.createElement(
Box,
null,
React.createElement(Typography, {
component: 'span',
children: stats.numberOfEditedAndPublishedItems,
lineHeight: 1,
sx: { fontWeight: (theme) => theme.typography.fontWeightMedium }
}),
' ',
React.createElement(Typography, {
component: 'span',
children: React.createElement(FormattedMessage, { defaultMessage: 'Edited & Published' })
})
)
)
);
}
export function DevContentOpsDashlet(props) {
const { borderLeftColor = palette.teal.main } = props;
const site = useActiveSiteId();
const [{ stats, loading }, setState] = useSpreadState({
stats: null,
loading: false
});
const [days, setDays] = useState(30);
const onRefresh = useMemo(
() => (backgroundRefresh) => {
if (!backgroundRefresh) {
setState({ stats: null, loading: true });
}
fetchPublishingStats(site, days).subscribe((stats) => {
setState({ stats, loading: false });
});
},
[site, setState, days]
);
useEffect(() => {
onRefresh();
}, [onRefresh]);
// region Item Updates Propagation
useEffect(() => {
const events = [deleteContentEvent.type, workflowEvent.type, publishEvent.type, contentEvent.type];
const hostToHost$ = getHostToHostBus();
const subscription = hostToHost$.pipe(filter((e) => events.includes(e.type))).subscribe(({ type, payload }) => {
onRefresh(true);
});
return () => {
subscription.unsubscribe();
};
}, [onRefresh]);
// endregion
return React.createElement(
DashletCard,
{
...props,
sxs: { content: { pt: 2, pb: (theme) => `${theme.spacing(2)} !important` }, ...props.sxs },
borderLeftColor: borderLeftColor
},
React.createElement(
React.Fragment,
null,
React.createElement(
Box,
{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' },
React.createElement(
Typography,
{ variant: 'h6' },
React.createElement(FormattedMessage, {
id: 'devContentOpsDashlet.widgetTitle',
defaultMessage: 'DevContentOps'
})
),
React.createElement(DevContentOpsStats, {
stats: stats,
sx: { root: { ml: 2, display: { xs: 'none', lg: 'flex' } } }
}),
React.createElement(
Select,
{
variant: 'standard',
disableUnderline: true,
value: days,
onChange: (e) => setDays(e.target.value),
SelectDisplayProps: { style: { paddingLeft: '8px' } }
},
React.createElement(
MenuItem,
{ value: 3 },
React.createElement(FormattedMessage, { defaultMessage: '{days} days', values: { days: 3 } })
),
React.createElement(
MenuItem,
{ value: 7 },
React.createElement(FormattedMessage, { defaultMessage: '{days} days', values: { days: 7 } })
),
React.createElement(
MenuItem,
{ value: 30 },
React.createElement(FormattedMessage, {
defaultMessage: '{months} {months, plural, one {month} other {months}}',
values: { months: 1 }
})
),
React.createElement(
MenuItem,
{ value: 90 },
React.createElement(FormattedMessage, {
defaultMessage: '{months} {months, plural, one {month} other {months}}',
values: { months: 3 }
})
),
React.createElement(
MenuItem,
{ value: 365 },
React.createElement(FormattedMessage, {
defaultMessage: '{years} {years, plural, one {year} other {years}}',
values: { years: 1 }
})
)
)
),
React.createElement(DevContentOpsStats, { stats: stats, sx: { root: { mt: 1, display: { lg: 'none' } } } })
),
loading && React.createElement(Skeleton, null)
);
}
export default DevContentOpsDashlet;