UNPKG

@craftercms/studio-ui

Version:

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

199 lines (197 loc) 7.67 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, { useEffect } from 'react'; import { getItemViewOption, isPage, previewPage } from '../SiteDashboard/utils'; import DashletCard from '../DashletCard/DashletCard'; import { DashletEmptyMessage, DashletItemOptions, getItemSkeleton, List, ListItem, ListSubheader } from '../DashletCard/dashletCommons'; import palette from '../../styles/palette'; import { FormattedMessage, useIntl } from 'react-intl'; import Typography from '@mui/material/Typography'; import ListItemText from '@mui/material/ListItemText'; import { fetchExpired, fetchExpiring } from '../../services/dashboard'; import useSpreadState from '../../hooks/useSpreadState'; import useLocale from '../../hooks/useLocale'; import useActiveSiteId from '../../hooks/useActiveSiteId'; import RefreshRounded from '@mui/icons-material/RefreshRounded'; import { asLocalizedDateTime } from '../../utils/datetime'; import Divider from '@mui/material/Divider'; import { forkJoin } from 'rxjs'; import ItemDisplay from '../ItemDisplay'; import { itemActionDispatcher } from '../../utils/itemActions'; import useEnv from '../../hooks/useEnv'; import { useDispatch } from 'react-redux'; import LoadingIconButton from '../LoadingIconButton'; const renderExpiredItems = (items, locale, onItemClick, expired) => items.map((item, index) => { const isItemPreviewable = isPage(item.sandboxItem.systemType) || item.sandboxItem.availableActionsMap.view; return React.createElement( ListItem, { key: index, secondaryAction: React.createElement(DashletItemOptions, { path: item.sandboxItem.path }) }, React.createElement(ListItemText, { primary: React.createElement(ItemDisplay, { item: item.sandboxItem, onClick: (e) => (isItemPreviewable ? onItemClick(e, item.sandboxItem) : null), showNavigableAsLinks: isItemPreviewable, styles: { ...(isItemPreviewable && { root: { cursor: 'pointer' } }) } }), secondary: React.createElement( Typography, { color: expired ? 'error.main' : 'text.secondary', variant: 'body2' }, React.createElement(FormattedMessage, { id: 'expiringDashlet.expiredOn', defaultMessage: '{expirationText} on {date}', values: { date: asLocalizedDateTime(item.expiredDateTime, locale.localeCode, locale.dateTimeFormatOptions), expirationText: expired ? 'Expired' : 'Expires' } }) ) }) ); }); export function ExpiringDashlet(props) { const { borderLeftColor = palette.purple.tint, days = 30, onMinimize } = props; const site = useActiveSiteId(); const locale = useLocale(); const [state, setState] = useSpreadState({ expiring: null, expired: null, refresh: 0, loading: false }); const { formatMessage } = useIntl(); const { authoringBase } = useEnv(); const dispatch = useDispatch(); const onRefresh = () => setState({ refresh: ++state.refresh }); const onItemClick = (e, item) => { if (isPage(item.systemType)) { e.stopPropagation(); previewPage(site, authoringBase, item, dispatch, onMinimize); } else if (item.availableActionsMap.view) { e.stopPropagation(); itemActionDispatcher({ site, authoringBase, dispatch, formatMessage, option: getItemViewOption(item), item }); } }; useEffect(() => { // eslint-disable-next-line @typescript-eslint/no-unused-vars const foo = state.refresh + 1; const oneDay = 8.64e7; const now = new Date(); setState({ loading: true, expiring: null, expired: null }); forkJoin({ expiring: fetchExpiring(site, { dateFrom: now.toISOString(), dateTo: new Date(now.getTime() + oneDay * days).toISOString() }), expired: fetchExpired(site, { limit: 10 }) }).subscribe(({ expiring, expired }) => { setState({ expiring, expired, loading: false }); }); }, [setState, site, days, state.refresh]); return React.createElement( DashletCard, { ...props, borderLeftColor: borderLeftColor, title: React.createElement(FormattedMessage, { id: 'words.expiring', defaultMessage: 'Expiring' }), headerAction: React.createElement( LoadingIconButton, { onClick: onRefresh, loading: state.loading }, React.createElement(RefreshRounded, null) ) }, state.loading && React.createElement(List, null, getItemSkeleton({ numOfItems: 5, showAvatar: false, showCheckbox: false })), state.expired && (state.expired.length === 0 ? React.createElement( DashletEmptyMessage, null, React.createElement(FormattedMessage, { id: 'expiringDashlet.noExpiredItems', defaultMessage: 'There are no expired items to display at this time' }) ) : React.createElement( List, { subheader: React.createElement( ListSubheader, null, React.createElement(FormattedMessage, { id: 'words.expired', defaultMessage: 'Expired' }) ) }, renderExpiredItems(state.expired, locale, onItemClick, true) )), React.createElement(Divider, { sx: { mt: 1, mb: 1 } }), state.expiring && (state.expiring.length === 0 ? React.createElement( DashletEmptyMessage, { sx: { mt: 0 } }, React.createElement(FormattedMessage, { id: 'expiringDashlet.noExpiringItems', defaultMessage: 'There are no items expiring in the next {days} days', values: { days } }) ) : React.createElement( List, { subheader: React.createElement( ListSubheader, null, React.createElement(FormattedMessage, { id: 'expiringDashlet.expiringNextNDays', defaultMessage: 'Expiring (next {days} days)', values: { days } }) ) }, renderExpiredItems(state.expiring, locale, onItemClick) )) ); } export default ExpiringDashlet;