@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
191 lines (189 loc) • 6.95 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 { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { makeStyles } from 'tss-react/mui';
import React, { useEffect, useState } from 'react';
import DialogBody from '../DialogBody/DialogBody';
import Typography from '@mui/material/Typography';
import TextField from '@mui/material/TextField';
import FormControlLabel from '@mui/material/FormControlLabel';
import Switch from '@mui/material/Switch';
import FormHelperText from '@mui/material/FormHelperText';
import Collapse from '@mui/material/Collapse';
import DateTimeTimezonePicker from '../DateTimeTimezonePicker/DateTimeTimezonePicker';
import DialogFooter from '../DialogFooter/DialogFooter';
import SecondaryButton from '../SecondaryButton';
import PrimaryButton from '../PrimaryButton';
import { useSelection } from '../../hooks/useSelection';
import { createToken } from '../../services/tokens';
import { showErrorDialog } from '../../state/reducers/dialogs/error';
import { useDispatch } from 'react-redux';
import useUpdateRefs from '../../hooks/useUpdateRefs';
import { createAtLeastHalfHourInFutureDate } from '../../utils/datetime';
const translations = defineMessages({
placeholder: {
id: 'words.label',
defaultMessage: 'Label'
},
expiresLabel: {
id: 'createTokenDialog.expiresLabel',
defaultMessage: 'Expire Token'
}
});
const useStyles = makeStyles()(() => ({
expiresWrapper: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between'
}
}));
export function CreateTokenDialogContainer(props) {
const { classes } = useStyles();
const { isSubmitting, onCreated, onClose, onSubmittingAndOrPendingChange } = props;
const [expires, setExpires] = useState(false);
const [expiresAt, setExpiresAt] = useState(createAtLeastHalfHourInFutureDate());
const [label, setLabel] = useState('');
const { formatMessage } = useIntl();
const dispatch = useDispatch();
const onSubmit = (e) => {
e.preventDefault();
e.stopPropagation();
onOk({ label, expiresAt: expires ? expiresAt : null });
};
const locale = useSelection((state) => state.uiConfig.locale);
const functionRefs = useUpdateRefs({
onSubmittingAndOrPendingChange
});
useEffect(() => {
onSubmittingAndOrPendingChange({
hasPendingChanges: Boolean(expires || label)
});
}, [onSubmittingAndOrPendingChange, expires, label]);
const onOk = ({ label, expiresAt }) => {
functionRefs.current.onSubmittingAndOrPendingChange({
isSubmitting: true
});
createToken(label, expiresAt).subscribe(
(token) => {
functionRefs.current.onSubmittingAndOrPendingChange({
isSubmitting: false
});
onCreated?.(token);
},
(response) => {
functionRefs.current.onSubmittingAndOrPendingChange({
isSubmitting: false
});
dispatch(showErrorDialog({ error: response }));
}
);
};
return React.createElement(
'form',
{ onSubmit: onSubmit },
React.createElement(
DialogBody,
null,
React.createElement(
Typography,
{ variant: 'body2' },
React.createElement(FormattedMessage, {
id: 'createTokenDialog.helperText',
defaultMessage:
'Type a name for the new token. The token will be created by the server and shown to you after. Store it securely as you won\u2019t be able to see it\u2019s value again.'
})
),
React.createElement(TextField, {
value: label,
autoFocus: true,
required: true,
placeholder: formatMessage(translations.placeholder),
margin: 'normal',
onChange: (e) => {
setLabel(e.target.value);
}
}),
React.createElement(
'section',
{ className: classes.expiresWrapper },
React.createElement(FormControlLabel, {
control: React.createElement(Switch, {
checked: expires,
color: 'primary',
onChange: (e, checked) => setExpires(checked)
}),
label: formatMessage(translations.expiresLabel)
}),
React.createElement(
FormHelperText,
null,
expires
? React.createElement(FormattedMessage, {
id: 'createTokenDialog.expiresHelperNeverText',
defaultMessage: 'Switch off to never expire.'
})
: React.createElement(FormattedMessage, {
id: 'createTokenDialog.expiresHelperText',
defaultMessage: 'Switch on to set an expiration.'
})
)
),
React.createElement(
Collapse,
{ in: expires, mountOnEnter: true },
React.createElement(DateTimeTimezonePicker, {
onChange: (date) => {
setExpiresAt(date);
},
value: expiresAt,
disablePast: true,
localeCode: locale.localeCode,
dateTimeFormatOptions: locale.dateTimeFormatOptions
})
)
),
React.createElement(
DialogFooter,
null,
React.createElement(
SecondaryButton,
{ onClick: (e) => onClose(e, null) },
React.createElement(FormattedMessage, { id: 'words.cancel', defaultMessage: 'Cancel' })
),
React.createElement(
PrimaryButton,
{ type: 'submit', autoFocus: true, disabled: isSubmitting || label === '', loading: isSubmitting },
React.createElement(FormattedMessage, { id: 'words.submit', defaultMessage: 'Submit' })
)
)
);
}
export default CreateTokenDialogContainer;