mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 12:47:13 +01:00
Custom date range selection.
This commit is contained in:
parent
7a8ab94bba
commit
4e103152b2
19 changed files with 545 additions and 40 deletions
41
components/forms/DatePickerForm.js
Normal file
41
components/forms/DatePickerForm.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import React, { useState } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { isAfter } from 'date-fns';
|
||||
import Calendar from 'components/common/Calendar';
|
||||
import Button from 'components/common/Button';
|
||||
import { FormButtons } from 'components/layout/FormLayout';
|
||||
import { getDateRangeValues } from 'lib/date';
|
||||
import styles from './DatePickerForm.module.css';
|
||||
|
||||
export default function DatePickerForm({
|
||||
startDate: defaultStartDate,
|
||||
endDate: defaultEndDate,
|
||||
minDate,
|
||||
maxDate,
|
||||
onChange,
|
||||
onClose,
|
||||
}) {
|
||||
const [startDate, setStartDate] = useState(defaultStartDate);
|
||||
const [endDate, setEndDate] = useState(defaultEndDate);
|
||||
|
||||
function handleSave() {
|
||||
onChange({ ...getDateRangeValues(startDate, endDate), value: 'custom' });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.calendars}>
|
||||
<Calendar date={startDate} minDate={minDate} maxDate={endDate} onChange={setStartDate} />
|
||||
<Calendar date={endDate} minDate={startDate} maxDate={maxDate} onChange={setEndDate} />
|
||||
</div>
|
||||
<FormButtons>
|
||||
<Button variant="action" onClick={handleSave} disabled={isAfter(startDate, endDate)}>
|
||||
<FormattedMessage id="button.save" defaultMessage="Save" />
|
||||
</Button>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage id="button.cancel" defaultMessage="Cancel" />
|
||||
</Button>
|
||||
</FormButtons>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
25
components/forms/DatePickerForm.module.css
Normal file
25
components/forms/DatePickerForm.module.css
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 800px;
|
||||
max-width: 100vw;
|
||||
}
|
||||
|
||||
.calendars {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.calendars > div:first-child {
|
||||
padding-right: 20px;
|
||||
border-right: 1px solid var(--gray300);
|
||||
}
|
||||
|
||||
.calendars > div:last-child {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 768px) {
|
||||
.calendars {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,10 +10,12 @@ import FormLayout, {
|
|||
} from 'components/layout/FormLayout';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const CONFIRMATION_WORD = 'DELETE';
|
||||
|
||||
const validate = ({ confirmation }) => {
|
||||
const errors = {};
|
||||
|
||||
if (confirmation !== 'DELETE') {
|
||||
if (confirmation !== CONFIRMATION_WORD) {
|
||||
errors.confirmation = !confirmation ? (
|
||||
<FormattedMessage id="label.required" defaultMessage="Required" />
|
||||
) : (
|
||||
|
|
@ -44,7 +46,7 @@ export default function DeleteForm({ values, onSave, onClose }) {
|
|||
validate={validate}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{() => (
|
||||
{props => (
|
||||
<Form>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
|
|
@ -63,7 +65,7 @@ export default function DeleteForm({ values, onSave, onClose }) {
|
|||
<FormattedMessage
|
||||
id="message.type-delete"
|
||||
defaultMessage="Type {delete} in the box below to confirm."
|
||||
values={{ delete: <b>DELETE</b> }}
|
||||
values={{ delete: <b>{CONFIRMATION_WORD}</b> }}
|
||||
/>
|
||||
</p>
|
||||
<FormRow>
|
||||
|
|
@ -71,7 +73,11 @@ export default function DeleteForm({ values, onSave, onClose }) {
|
|||
<FormError name="confirmation" />
|
||||
</FormRow>
|
||||
<FormButtons>
|
||||
<Button type="submit" variant="danger">
|
||||
<Button
|
||||
type="submit"
|
||||
variant="danger"
|
||||
disabled={props.values.confirmation !== CONFIRMATION_WORD}
|
||||
>
|
||||
<FormattedMessage id="button.delete" defaultMessage="Delete" />
|
||||
</Button>
|
||||
<Button onClick={onClose}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue