@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
171 lines (169 loc) • 6.71 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 { useSpreadStateWithSelected } from '../SiteDashboard/utils';
import DashletCard from '../DashletCard/DashletCard';
import palette from '../../styles/palette';
import { FormattedMessage, useIntl } from 'react-intl';
import React, { useEffect, useMemo } from 'react';
import IconButton from '@mui/material/IconButton';
import { RefreshRounded } from '@mui/icons-material';
import useLocale from '../../hooks/useLocale';
import useEnv from '../../hooks/useEnv';
import useActiveSiteId from '../../hooks/useActiveSiteId';
import { fetchUnpublished } from '../../services/dashboard';
import { DashletEmptyMessage, getItemSkeleton, List, ListItem, ListItemIcon } from '../DashletCard/dashletCommons';
import Checkbox from '@mui/material/Checkbox';
import ListItemText from '@mui/material/ListItemText';
import Typography from '@mui/material/Typography';
import { asLocalizedDateTime } from '../../utils/datetime';
import ItemDisplay from '../ItemDisplay';
import ActionsBar from '../ActionsBar';
import { UNDEFINED } from '../../utils/constants';
import { translations } from '../ItemActionsMenu/translations';
import { itemActionDispatcher } from '../../utils/itemActions';
import { useDispatch } from 'react-redux';
import { parseSandBoxItemToDetailedItem } from '../../utils/content';
export function UnpublishedDashlet(props) {
const { borderLeftColor = palette.blue.tint } = props;
const site = useActiveSiteId();
const locale = useLocale();
const { formatMessage } = useIntl();
const { authoringBase } = useEnv();
const dispatch = useDispatch();
const [
{ loading, total, items, isAllSelected, hasSelected, selected, selectedCount },
setState,
onSelectItem,
onSelectAll,
isSelected
] = useSpreadStateWithSelected({
loading: false,
total: null
});
const onRefresh = useMemo(
() => () => {
setState({ loading: true, items: null, selected: {}, isAllSelected: false });
fetchUnpublished(site, { limit: 10, offset: 0 }).subscribe((items) => {
setState({ loading: false, items, total: items.total });
});
},
[setState, site]
);
const onOptionClicked = (option) =>
itemActionDispatcher({
site,
authoringBase,
dispatch,
formatMessage,
option,
item: items.filter((item) => selected[item.id]).map((item) => parseSandBoxItemToDetailedItem(item))
});
useEffect(() => {
onRefresh();
}, [onRefresh]);
return React.createElement(
DashletCard,
Object.assign({}, props, {
borderLeftColor: borderLeftColor,
title: React.createElement(FormattedMessage, {
id: 'unpublishedDashlet.widgetTitle',
defaultMessage: 'Unpublished Work'
}),
headerAction: React.createElement(IconButton, { onClick: onRefresh }, React.createElement(RefreshRounded, null)),
sxs: { actionsBar: { padding: 0 } },
actionsBar: React.createElement(ActionsBar, {
disabled: loading,
isChecked: isAllSelected,
isIndeterminate: hasSelected && !isAllSelected,
onCheckboxChange: onSelectAll,
onOptionClicked: onOptionClicked,
options: hasSelected
? [
selectedCount === 1 && { id: 'edit', label: formatMessage(translations.edit) },
{ id: 'approvePublish', label: formatMessage(translations.publish) }
].filter(Boolean)
: [],
buttonProps: { size: 'small' },
sxs: {
root: { flexGrow: 1 },
container: { bgcolor: hasSelected ? 'action.selected' : UNDEFINED },
checkbox: { padding: '5px', borderRadius: 0 }
}
})
}),
loading && getItemSkeleton({ numOfItems: 3, showAvatar: true, showCheckbox: true }),
items &&
React.createElement(
List,
null,
items.map((item, index) =>
React.createElement(
ListItem,
{ key: index },
React.createElement(
ListItemIcon,
null,
React.createElement(Checkbox, {
edge: 'start',
checked: isSelected(item),
onChange: (e) => onSelectItem(e, item)
})
),
React.createElement(ListItemText, {
primary: React.createElement(ItemDisplay, { item: item, showPublishingTarget: false }),
secondary: React.createElement(
Typography,
{ color: 'text.secondary', variant: 'body2' },
React.createElement(FormattedMessage, {
id: 'unpublishedDashlet.entrySecondaryText',
defaultMessage: 'Edited by {name} on {date}',
values: {
name: item.modifier,
date: asLocalizedDateTime(item.dateModified, locale.localeCode, locale.dateTimeFormatOptions)
}
})
)
})
)
)
),
(total === 0 || (total && (items === null || items === void 0 ? void 0 : items.length) === 0)) &&
React.createElement(
DashletEmptyMessage,
null,
React.createElement(FormattedMessage, {
id: 'unpublishedDashlet.noUnpublishedItems',
defaultMessage: 'There are no unpublished items'
})
)
);
}
export default UnpublishedDashlet;