@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
183 lines (181 loc) • 7.18 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 useSpreadState from '../../hooks/useSpreadState';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import { FormattedMessage } from 'react-intl';
import DialogContent from '@mui/material/DialogContent';
import Box from '@mui/material/Box';
import { AdapterMoment as DateAdapter } from '@mui/x-date-pickers/AdapterMoment';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import Stack from '@mui/material/Stack';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import TextField from '@mui/material/TextField';
import DialogActions from '@mui/material/DialogActions';
import SecondaryButton from '../SecondaryButton';
import PrimaryButton from '../PrimaryButton';
import React, { useState } from 'react';
export function RangePickerModal(props) {
const { open, onAccept, onClose, onSwitchToTimelineClick } = props;
// Can't ever have data before the release of CrafterCMS 4.0.0
const minDate = new Date('2022-03-30T00:00:00.000Z');
const today = new Date();
const [fromPickerOpen, setFromPickerOpen] = useState(false);
const [toPickerOpen, setToPickerOpen] = useState(false);
const [{ pickerDateFrom, pickerDateTo }, setState] = useSpreadState({
openRangePicker: true,
dateFrom: null,
dateTo: null,
pickerDateFrom: null,
pickerDateTo: null
});
const onDatePickerChange = (field, value) => {
value.setSeconds(0);
value.setMilliseconds(0);
setState({ [field]: value });
};
const onRangePickerAccept = () => {
// Because of the reverse chronological nature of the timeline, people
// may confuse or have a different mental model of what to/from is.
// Here we make sure dates are always coherent with what's expected on the back.
if (pickerDateFrom < pickerDateTo) {
onAccept(pickerDateFrom, pickerDateTo);
} else {
onAccept(pickerDateTo, pickerDateFrom);
}
};
const openFromPicker = () => setFromPickerOpen(true);
const closeFromPicker = () => setFromPickerOpen(false);
const openToPicker = () => setToPickerOpen(true);
const closeToPicker = () => setToPickerOpen(false);
return React.createElement(
Dialog,
{ open: open, onClose: onClose, 'aria-labelledby': 'rangePickerModalTitle' },
React.createElement(
DialogTitle,
{ id: 'rangePickerModalTitle' },
React.createElement(FormattedMessage, {
id: 'activityDashlet.selectRangeModalTitle',
defaultMessage: 'Select Date Range'
})
),
React.createElement(
DialogContent,
null,
React.createElement(
Box,
{ sx: { pt: 1 } },
React.createElement(
LocalizationProvider,
{ dateAdapter: DateAdapter },
React.createElement(
Stack,
{ direction: 'row', spacing: 1 },
React.createElement(DateTimePicker, {
open: fromPickerOpen,
onOpen: openFromPicker,
onClose: closeFromPicker,
onAccept: closeFromPicker,
label: React.createElement(FormattedMessage, { id: 'words.from', defaultMessage: 'From' }),
minDate: minDate,
renderInput: (params) =>
React.createElement(
TextField,
Object.assign({}, params, {
onClick: openFromPicker,
inputProps: Object.assign(Object.assign({}, params.inputProps), {
onChange: (e) => e.preventDefault()
})
})
),
value: pickerDateFrom,
onChange: (arg) => {
let newValue = arg;
newValue.isValid() && onDatePickerChange('pickerDateFrom', newValue.toDate());
}
}),
React.createElement(DateTimePicker, {
open: toPickerOpen,
onOpen: openToPicker,
onClose: closeToPicker,
onAccept: closeToPicker,
maxDate: today,
minDate: minDate,
label: React.createElement(FormattedMessage, { id: 'words.to', defaultMessage: 'To' }),
renderInput: (params) =>
React.createElement(
TextField,
Object.assign({}, params, {
onClick: openToPicker,
inputProps: Object.assign(Object.assign({}, params.inputProps), {
onChange: (e) => e.preventDefault()
})
})
),
value: pickerDateTo,
onChange: (arg) => {
let newValue = arg;
newValue.isValid() && onDatePickerChange('pickerDateTo', newValue.toDate());
}
})
)
)
)
),
React.createElement(
DialogActions,
null,
onSwitchToTimelineClick &&
React.createElement(
SecondaryButton,
{ onClick: onSwitchToTimelineClick, sx: { mr: 'auto' } },
React.createElement(FormattedMessage, {
id: 'activityDashlet.switchToTimeline',
defaultMessage: 'Switch to timeline'
})
),
React.createElement(
SecondaryButton,
{ onClick: onClose },
React.createElement(FormattedMessage, { id: 'words.cancel', defaultMessage: 'Cancel' })
),
React.createElement(
PrimaryButton,
{
disabled: !(pickerDateFrom && pickerDateTo && pickerDateFrom.getTime() !== pickerDateTo.getTime()),
onClick: onRangePickerAccept
},
React.createElement(FormattedMessage, { id: 'words.accept', defaultMessage: 'Accept' })
)
)
);
}
export default RangePickerModal;