@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
377 lines (375 loc) • 12.3 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 React from 'react';
import { makeStyles } from 'tss-react/mui';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Typography from '@mui/material/Typography';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import Collapse from '@mui/material/Collapse';
import FormControl from '@mui/material/FormControl';
import Link from '@mui/material/Link';
import DateTimePicker from '../DateTimePicker/DateTimePicker';
import TextFieldWithMax from '../TextFieldWithMax/TextFieldWithMax';
import FormLabel from '@mui/material/FormLabel';
import { useSelection } from '../../hooks/useSelection';
import Alert from '@mui/material/Alert';
import { capitalize } from '../../utils/string';
const messages = defineMessages({
emailLabel: {
id: 'publishForm.emailLabel',
defaultMessage: "Email me the reviewer's feedback"
},
scheduling: {
id: 'publishForm.scheduling',
defaultMessage: 'Scheduling'
},
schedulingNow: {
id: 'publishForm.schedulingNow',
defaultMessage: 'Now'
},
schedulingLater: {
id: 'publishForm.schedulingLater',
defaultMessage: 'Later'
},
schedulingLaterDisabled: {
id: 'publishForm.schedulingLaterDisabled',
defaultMessage: 'Later (disabled on first publish)'
},
publishingTarget: {
id: 'common.publishingTarget',
defaultMessage: 'Publishing Target'
},
publishingTargetLoading: {
id: 'publishForm.publishingTargetLoading',
defaultMessage: 'Loading...'
},
publishingTargetError: {
id: 'publishForm.publishingTargetError',
defaultMessage: 'Publishing targets load failed.'
},
publishingTargetRetry: {
id: 'publishForm.publishingTargetRetry',
defaultMessage: 'retry'
},
publishingTargetSuccess: {
id: 'publishForm.publishingTargetSuccess',
defaultMessage: 'Success'
},
submissionComment: {
id: 'publishForm.submissionComment',
defaultMessage: 'Submission Comment'
},
live: {
id: 'words.live',
defaultMessage: 'Live'
},
staging: {
id: 'words.staging',
defaultMessage: 'Staging'
}
});
const useStyles = makeStyles()((theme) => ({
root: {
width: 'auto'
},
title: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center'
},
checkboxes: {
marginBottom: '10px'
},
formSection: {
width: '100%',
marginBottom: '20px'
},
formInputs: {
fontSize: '14px'
},
selectInput: {
padding: '10px 12px'
},
publishingTargetLoaderContainer: {
paddingTop: '24px',
display: 'inline-flex'
},
publishingTargetLoader: {
border: '1px solid #ced4da',
padding: '10px 12px',
borderRadius: '4px',
width: '100%'
},
publishingTargetEmpty: {
padding: '10px 12px',
borderRadius: '4px',
width: '100%'
},
datePicker: {
position: 'relative',
paddingLeft: '30px',
paddingBottom: '20px',
'&::before': {
content: '""',
position: 'absolute',
width: '5px',
height: '100%',
top: '0',
left: '7px',
backgroundColor: theme.palette.background.paper,
borderRadius: '5px'
}
},
radioGroup: {
paddingTop: '10px',
fontSize: '14px'
},
radioInput: {
padding: '4px',
marginLeft: '5px',
marginRight: '5px'
},
selectIcon: {
right: '12px'
},
mixedDatesWarningMessage: {
marginBottom: '10px'
},
mixedTargetsWarningMessage: {
marginTop: '10px'
}
}));
export function PublishDialogForm(props) {
const { classes } = useStyles();
const { formatMessage } = useIntl();
const {
state,
published,
isRequestPublish,
showRequestApproval,
publishingChannels,
publishingTargetsStatus,
onPublishingChannelsFailRetry,
disabled = true,
mixedPublishingDates,
mixedPublishingTargets,
submissionCommentRequired,
onChange
} = props;
const setSubmitDisabled = (...args) => void 0;
const onDateTimeChange = setSubmitDisabled;
const locale = useSelection((state) => state.uiConfig.locale);
const handleDateTimePickerChange = (dateChangeData) => {
onChange({
// @ts-ignore
target: {
name: 'scheduledDateTime',
type: 'dateTimePicker',
// @ts-ignore
value: dateChangeData
}
});
};
const handleDatePickerError = () => {
onDateTimeChange(null);
};
return React.createElement(
'form',
{ className: classes.root },
React.createElement(
'section',
{ className: classes.checkboxes },
showRequestApproval &&
React.createElement(FormControlLabel, {
control: React.createElement(Checkbox, {
size: 'small',
checked: state.requestApproval,
onChange: onChange,
disabled: disabled,
name: 'requestApproval'
}),
label: React.createElement(FormattedMessage, {
id: 'publishForm.requestApproval',
defaultMessage: 'Request approval'
})
}),
isRequestPublish &&
React.createElement(FormControlLabel, {
label: formatMessage(messages.emailLabel),
control: React.createElement(Checkbox, {
size: 'small',
checked: state.emailOnApprove,
onChange: onChange,
value: 'emailOnApprove',
color: 'primary',
disabled: disabled,
name: 'emailOnApprove'
})
})
),
React.createElement(
FormControl,
{ fullWidth: true, className: classes.formSection },
React.createElement(FormLabel, { component: 'legend' }, formatMessage(messages.scheduling)),
React.createElement(
RadioGroup,
{ className: classes.radioGroup, value: state.scheduling, onChange: onChange, name: 'scheduling' },
mixedPublishingDates &&
React.createElement(
Alert,
{ severity: 'warning', className: classes.mixedDatesWarningMessage },
React.createElement(FormattedMessage, {
id: 'publishForm.mixedPublishingDates',
defaultMessage: 'Items have mixed publishing date/time schedules.'
})
),
React.createElement(FormControlLabel, {
value: 'now',
control: React.createElement(Radio, { color: 'primary', className: classes.radioInput }),
label: formatMessage(messages.schedulingNow),
classes: { label: classes.formInputs },
disabled: disabled
}),
React.createElement(FormControlLabel, {
value: 'custom',
control: React.createElement(Radio, { color: 'primary', className: classes.radioInput }),
label: published ? formatMessage(messages.schedulingLater) : formatMessage(messages.schedulingLaterDisabled),
classes: { label: classes.formInputs },
disabled: !published || disabled
})
),
React.createElement(
Collapse,
{
in: state.scheduling === 'custom',
timeout: 300,
className: state.scheduling === 'custom' ? classes.datePicker : ''
},
React.createElement(DateTimePicker, {
onChange: handleDateTimePickerChange,
onError: handleDatePickerError,
value: state.scheduledDateTime,
localeCode: locale.localeCode,
dateTimeFormatOptions: locale.dateTimeFormatOptions,
timeZone: state.scheduledTimeZone,
disablePast: true,
disabled: disabled
})
)
),
React.createElement(
FormControl,
{ fullWidth: true, className: classes.formSection },
React.createElement(FormLabel, { component: 'legend' }, formatMessage(messages.publishingTarget)),
publishingChannels
? publishingChannels.length
? React.createElement(
RadioGroup,
{
className: classes.radioGroup,
value: state.publishingTarget,
onChange: onChange,
name: 'publishingTarget'
},
publishingChannels.map((publishingChannel) =>
React.createElement(FormControlLabel, {
key: publishingChannel.name,
disabled: disabled,
value: publishingChannel.name,
control: React.createElement(Radio, { color: 'primary', className: classes.radioInput }),
label: messages[publishingChannel.name]
? formatMessage(messages[publishingChannel.name])
: capitalize(publishingChannel.name),
classes: { label: classes.formInputs }
})
)
)
: React.createElement(
'div',
{ className: classes.publishingTargetLoaderContainer },
React.createElement(
Typography,
{ variant: 'body1', className: classes.publishingTargetEmpty },
'No publishing channels are available.'
)
)
: React.createElement(
'div',
{ className: classes.publishingTargetLoaderContainer },
React.createElement(
Typography,
{
variant: 'body1',
component: 'span',
className: `${classes.publishingTargetLoader} ${classes.formInputs}`,
color: publishingTargetsStatus === 'Error' ? 'error' : 'initial'
},
formatMessage(messages[`publishingTarget${publishingTargetsStatus}`]),
publishingTargetsStatus === 'Error' &&
React.createElement(
Link,
{ href: '#', onClick: () => onPublishingChannelsFailRetry() },
'(',
formatMessage(messages.publishingTargetRetry),
')'
)
)
),
mixedPublishingTargets &&
React.createElement(
Alert,
{ severity: 'warning', className: classes.mixedTargetsWarningMessage },
React.createElement(FormattedMessage, {
id: 'publishForm.mixedPublishingTargets',
defaultMessage: 'Items have mixed publishing targets.'
})
)
),
React.createElement(TextFieldWithMax, {
id: 'publishDialogFormSubmissionComment',
name: 'submissionComment',
label: React.createElement(FormattedMessage, {
id: 'publishForm.submissionComment',
defaultMessage: 'Submission Comment'
}),
fullWidth: true,
onChange: onChange,
value: state.submissionComment,
multiline: true,
disabled: disabled,
required: submissionCommentRequired
})
);
}
export default PublishDialogForm;