UNPKG

@craftercms/studio-ui

Version:

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

332 lines (330 loc) 12.4 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, { useMemo } from 'react'; import { useLocale } from '../../hooks/useLocale'; import ListItem from '@mui/material/ListItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import Checkbox from '@mui/material/Checkbox'; import ListItemText from '@mui/material/ListItemText'; import Typography from '@mui/material/Typography'; import List from '@mui/material/List'; import Box from '@mui/material/Box'; import ItemStateIcon from '../ItemStateIcon'; import { getDateScheduled, isEditableAsset } from '../../utils/content'; import { FormattedMessage } from 'react-intl'; import { asLocalizedDateTime } from '../../utils/datetime'; import ItemPublishingTargetIcon from '../ItemPublishingTargetIcon'; import { getItemStateText } from '../ItemDisplay/utils'; import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction'; import Button from '@mui/material/Button'; import InfoIcon from '@mui/icons-material/InfoOutlined'; import { makeStyles } from 'tss-react/mui'; const useStyles = makeStyles()(() => ({ listTitle: { display: 'flex !important', alignItems: 'center', whiteSpace: 'break-spaces' }, selectionList: { paddingTop: 0 }, publishingTargetIcon: { fontSize: '1rem', margin: '0 5px' }, stateScheduledIcon: { fontSize: '1em', marginRight: '5px' }, emptyDependencies: { display: 'flex', alignItems: 'center', padding: '8px', '& svg': { marginRight: '8px' } }, selectAllBtn: { marginLeft: 'auto', fontWeight: 'bold', verticalAlign: 'baseline' }, overflowText: { overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }, itemText: { textOverflow: 'ellipsis', overflow: 'hidden' } })); export function SelectionList(props) { // region const { ... } = props const { title, subtitle, emptyMessage, items, paths = items.map((item) => item.path), onItemClicked, onSelectAllClicked, selectedItems, disabled = false, onEditClick } = props; // endregion const { classes } = useStyles(); const locale = useLocale(); const isAllChecked = useMemo( () => selectedItems ? !(paths === null || paths === void 0 ? void 0 : paths.some((path) => !selectedItems[path])) : null, [paths, selectedItems] ); const isIndeterminate = useMemo( () => selectedItems ? paths === null || paths === void 0 ? void 0 : paths.some( (path) => (selectedItems === null || selectedItems === void 0 ? void 0 : selectedItems[path]) && !isAllChecked ) : null, [paths, selectedItems, isAllChecked] ); return React.createElement( React.Fragment, null, React.createElement( ListItem, { divider: true, dense: true, disableGutters: !Boolean(paths) }, React.createElement( ListItemIcon, null, React.createElement(Checkbox, { color: 'primary', edge: 'start', disabled: disabled || (paths === null || paths === void 0 ? void 0 : paths.length) === 0 || !onSelectAllClicked, indeterminate: isIndeterminate, checked: isAllChecked || isIndeterminate || !onSelectAllClicked, onChange: onSelectAllClicked }) ), React.createElement(ListItemText, { primary: React.createElement( React.Fragment, null, React.createElement(Typography, { variant: 'subtitle1', component: 'h2' }, title), subtitle ? React.createElement(Typography, { component: 'span' }, ` • `, subtitle) : null ), primaryTypographyProps: { classes: { root: classes.listTitle } } }) ), items ? React.createElement( List, { className: classes.selectionList }, items.map((item) => { const labelId = `checkbox-list-label-${item.path}`; return React.createElement( ListItem, { dense: true, key: item.path, disabled: disabled, // @ts-ignore button: Boolean(onItemClicked), onClick: onItemClicked ? (e) => onItemClicked(e, item.path) : void 0 }, onItemClicked && React.createElement( ListItemIcon, null, React.createElement(Checkbox, { color: 'primary', edge: 'start', checked: !!selectedItems[item.path], tabIndex: -1, disableRipple: true, inputProps: { 'aria-labelledby': item.path }, disabled: disabled }) ), React.createElement( ListItemText, { id: labelId }, React.createElement( Typography, { variant: 'subtitle1', className: classes.itemText, title: item.label }, item.label ), (item.stateMap.submitted || item.stateMap.scheduled) && React.createElement( Box, { display: 'flex', alignItems: 'center' }, React.createElement(ItemStateIcon, { displayTooltip: false, className: classes.stateScheduledIcon, item: item }), React.createElement( Typography, { variant: 'body2', color: 'textSecondary' }, getDateScheduled(item) ? item.stateMap.submitted ? React.createElement(FormattedMessage, { id: 'itemPublishingDate.submitted', defaultMessage: 'Submitted for {date}', values: { date: asLocalizedDateTime( getDateScheduled(item), locale.localeCode, locale.dateTimeFormatOptions ) } }) : React.createElement(FormattedMessage, { id: 'itemPublishingDate.scheduled', defaultMessage: 'Scheduled for {date}', values: { date: asLocalizedDateTime( getDateScheduled(item), locale.localeCode, locale.dateTimeFormatOptions ) } }) : item.stateMap.submitted ? React.createElement(FormattedMessage, { id: 'itemPublishingDate.submittedForAsap', defaultMessage: 'Submitted for ASAP' }) : React.createElement(FormattedMessage, { id: 'itemPublishingDate.scheduledForAsap', defaultMessage: 'Scheduled for ASAP' }) ), React.createElement(ItemPublishingTargetIcon, { displayTooltip: false, className: classes.publishingTargetIcon, item: { stateMap: { [item.stateMap.submittedToLive ? 'live' : 'staged']: item.stateMap.submittedToLive || item.stateMap.submittedToStaging } } }), React.createElement( Typography, { variant: 'body2', color: 'textSecondary' }, getItemStateText(item.stateMap, { user: item.lockOwner }) ) ), React.createElement( Typography, { variant: 'body2', color: 'textSecondary', className: classes.itemText, title: item.path }, item.path ) ) ); }) ) : React.createElement( List, null, paths.length ? paths.map((path) => { const labelId = `checkbox-list-label-${path}`; return React.createElement( ListItem, { dense: true, key: path, disabled: disabled, // @ts-ignore button: Boolean(onItemClicked), onClick: onItemClicked ? (e) => onItemClicked(e, path) : null }, onItemClicked && React.createElement( ListItemIcon, null, React.createElement(Checkbox, { color: 'primary', edge: 'start', checked: Boolean(selectedItems[path]), tabIndex: -1, disableRipple: true, inputProps: { 'aria-labelledby': path }, disabled: disabled }) ), React.createElement(ListItemText, { id: labelId, primary: path, primaryTypographyProps: { title: path, classes: { root: classes.overflowText } } }), onEditClick && isEditableAsset(path) && React.createElement( ListItemSecondaryAction, null, React.createElement( Button, { color: 'primary', onClick: (e) => onEditClick(e, path), size: 'small', className: classes.selectAllBtn }, React.createElement(FormattedMessage, { id: 'words.edit', defaultMessage: 'Edit' }) ) ) ); }) : React.createElement( Box, { className: classes.emptyDependencies }, React.createElement(InfoIcon, { color: 'action', fontSize: 'small' }), React.createElement(Typography, { variant: 'caption' }, emptyMessage) ) ) ); }