303 lines
19 KiB
JavaScript
303 lines
19 KiB
JavaScript
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
import * as React from 'react';
|
|
import { Modal, Flex, Field, TextInput, Box, Checkbox, Typography, DatePicker, TimePicker, Button, Combobox, ComboboxOption } from '@strapi/design-system';
|
|
import { formatISO } from 'date-fns';
|
|
import { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz';
|
|
import { Formik, Form, useFormikContext } from 'formik';
|
|
import { useIntl } from 'react-intl';
|
|
import { useLocation } from 'react-router-dom';
|
|
import { pluginId } from '../pluginId.mjs';
|
|
import { getTimezones } from '../utils/time.mjs';
|
|
import { RELEASE_SCHEMA } from '../validation/schemas.mjs';
|
|
|
|
const ReleaseModal = ({ handleClose, open, handleSubmit, initialValues, isLoading = false })=>{
|
|
const { formatMessage } = useIntl();
|
|
const { pathname } = useLocation();
|
|
const isCreatingRelease = pathname === `/plugins/${pluginId}`;
|
|
// Set default first timezone from the list if no system timezone detected
|
|
const { timezoneList, systemTimezone = {
|
|
value: 'UTC+00:00-Africa/Abidjan '
|
|
} } = getTimezones(initialValues.scheduledAt ? new Date(initialValues.scheduledAt) : new Date());
|
|
/**
|
|
* Generate scheduled time using selected date, time and timezone
|
|
*/ const getScheduledTimestamp = (values)=>{
|
|
const { date, time, timezone } = values;
|
|
if (!date || !time || !timezone) return null;
|
|
const timezoneWithoutOffset = timezone.split('&')[1];
|
|
return zonedTimeToUtc(`${date} ${time}`, timezoneWithoutOffset);
|
|
};
|
|
/**
|
|
* Get timezone with offset to show the selected value in the dropdown
|
|
*/ const getTimezoneWithOffset = ()=>{
|
|
const currentTimezone = timezoneList.find((timezone)=>timezone.value.split('&')[1] === initialValues.timezone);
|
|
return currentTimezone?.value || systemTimezone.value;
|
|
};
|
|
return /*#__PURE__*/ jsx(Modal.Root, {
|
|
open: open,
|
|
onOpenChange: handleClose,
|
|
children: /*#__PURE__*/ jsxs(Modal.Content, {
|
|
children: [
|
|
/*#__PURE__*/ jsx(Modal.Header, {
|
|
children: /*#__PURE__*/ jsx(Modal.Title, {
|
|
children: formatMessage({
|
|
id: 'content-releases.modal.title',
|
|
defaultMessage: '{isCreatingRelease, select, true {New release} other {Edit release}}'
|
|
}, {
|
|
isCreatingRelease: isCreatingRelease
|
|
})
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsx(Formik, {
|
|
onSubmit: (values)=>{
|
|
handleSubmit({
|
|
...values,
|
|
timezone: values.timezone ? values.timezone.split('&')[1] : null,
|
|
scheduledAt: values.isScheduled ? getScheduledTimestamp(values) : null
|
|
});
|
|
},
|
|
initialValues: {
|
|
...initialValues,
|
|
timezone: initialValues.timezone ? getTimezoneWithOffset() : systemTimezone.value
|
|
},
|
|
validationSchema: RELEASE_SCHEMA,
|
|
validateOnChange: false,
|
|
children: ({ values, errors, handleChange, setFieldValue })=>{
|
|
return /*#__PURE__*/ jsxs(Form, {
|
|
children: [
|
|
/*#__PURE__*/ jsx(Modal.Body, {
|
|
children: /*#__PURE__*/ jsxs(Flex, {
|
|
direction: "column",
|
|
alignItems: "stretch",
|
|
gap: 6,
|
|
children: [
|
|
/*#__PURE__*/ jsxs(Field.Root, {
|
|
name: "name",
|
|
error: errors.name && formatMessage({
|
|
id: errors.name,
|
|
defaultMessage: errors.name
|
|
}),
|
|
required: true,
|
|
children: [
|
|
/*#__PURE__*/ jsx(Field.Label, {
|
|
children: formatMessage({
|
|
id: 'content-releases.modal.form.input.label.release-name',
|
|
defaultMessage: 'Name'
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsx(TextInput, {
|
|
value: values.name,
|
|
onChange: handleChange
|
|
}),
|
|
/*#__PURE__*/ jsx(Field.Error, {})
|
|
]
|
|
}),
|
|
/*#__PURE__*/ jsx(Box, {
|
|
width: "max-content",
|
|
children: /*#__PURE__*/ jsx(Checkbox, {
|
|
name: "isScheduled",
|
|
checked: values.isScheduled,
|
|
onCheckedChange: (checked)=>{
|
|
setFieldValue('isScheduled', checked);
|
|
if (!checked) {
|
|
// Clear scheduling info from a release on unchecking schedule release, which reset scheduling info in DB
|
|
setFieldValue('date', null);
|
|
setFieldValue('time', '');
|
|
setFieldValue('timezone', null);
|
|
} else {
|
|
// On ticking back schedule release date, time and timezone should be restored to the initial state
|
|
setFieldValue('date', initialValues.date);
|
|
setFieldValue('time', initialValues.time);
|
|
setFieldValue('timezone', initialValues.timezone ?? systemTimezone?.value);
|
|
}
|
|
},
|
|
children: /*#__PURE__*/ jsx(Typography, {
|
|
textColor: values.isScheduled ? 'primary600' : 'neutral800',
|
|
fontWeight: values.isScheduled ? 'semiBold' : 'regular',
|
|
children: formatMessage({
|
|
id: 'modal.form.input.label.schedule-release',
|
|
defaultMessage: 'Schedule release'
|
|
})
|
|
})
|
|
})
|
|
}),
|
|
values.isScheduled && /*#__PURE__*/ jsxs(Fragment, {
|
|
children: [
|
|
/*#__PURE__*/ jsxs(Flex, {
|
|
gap: 4,
|
|
alignItems: "start",
|
|
children: [
|
|
/*#__PURE__*/ jsx(Box, {
|
|
width: "100%",
|
|
children: /*#__PURE__*/ jsxs(Field.Root, {
|
|
name: "date",
|
|
error: errors.date && formatMessage({
|
|
id: errors.date,
|
|
defaultMessage: errors.date
|
|
}),
|
|
required: true,
|
|
children: [
|
|
/*#__PURE__*/ jsx(Field.Label, {
|
|
children: formatMessage({
|
|
id: 'content-releases.modal.form.input.label.date',
|
|
defaultMessage: 'Date'
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsx(DatePicker, {
|
|
onChange: (date)=>{
|
|
const isoFormatDate = date ? formatISO(date, {
|
|
representation: 'date'
|
|
}) : null;
|
|
setFieldValue('date', isoFormatDate);
|
|
},
|
|
clearLabel: formatMessage({
|
|
id: 'content-releases.modal.form.input.clearLabel',
|
|
defaultMessage: 'Clear'
|
|
}),
|
|
onClear: ()=>{
|
|
setFieldValue('date', null);
|
|
},
|
|
value: values.date ? new Date(values.date) : new Date(),
|
|
minDate: utcToZonedTime(new Date(), values.timezone.split('&')[1])
|
|
}),
|
|
/*#__PURE__*/ jsx(Field.Error, {})
|
|
]
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsx(Box, {
|
|
width: "100%",
|
|
children: /*#__PURE__*/ jsxs(Field.Root, {
|
|
name: "time",
|
|
error: errors.time && formatMessage({
|
|
id: errors.time,
|
|
defaultMessage: errors.time
|
|
}),
|
|
required: true,
|
|
children: [
|
|
/*#__PURE__*/ jsx(Field.Label, {
|
|
children: formatMessage({
|
|
id: 'content-releases.modal.form.input.label.time',
|
|
defaultMessage: 'Time'
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsx(TimePicker, {
|
|
onChange: (time)=>{
|
|
setFieldValue('time', time);
|
|
},
|
|
clearLabel: formatMessage({
|
|
id: 'content-releases.modal.form.input.clearLabel',
|
|
defaultMessage: 'Clear'
|
|
}),
|
|
onClear: ()=>{
|
|
setFieldValue('time', '');
|
|
},
|
|
value: values.time || undefined
|
|
}),
|
|
/*#__PURE__*/ jsx(Field.Error, {})
|
|
]
|
|
})
|
|
})
|
|
]
|
|
}),
|
|
/*#__PURE__*/ jsx(TimezoneComponent, {
|
|
timezoneOptions: timezoneList
|
|
})
|
|
]
|
|
})
|
|
]
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsxs(Modal.Footer, {
|
|
children: [
|
|
/*#__PURE__*/ jsx(Modal.Close, {
|
|
children: /*#__PURE__*/ jsx(Button, {
|
|
variant: "tertiary",
|
|
name: "cancel",
|
|
children: formatMessage({
|
|
id: 'cancel',
|
|
defaultMessage: 'Cancel'
|
|
})
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsx(Button, {
|
|
name: "submit",
|
|
loading: isLoading,
|
|
type: "submit",
|
|
children: formatMessage({
|
|
id: 'content-releases.modal.form.button.submit',
|
|
defaultMessage: '{isCreatingRelease, select, true {Continue} other {Save}}'
|
|
}, {
|
|
isCreatingRelease: isCreatingRelease
|
|
})
|
|
})
|
|
]
|
|
})
|
|
]
|
|
});
|
|
}
|
|
})
|
|
]
|
|
})
|
|
});
|
|
};
|
|
const TimezoneComponent = ({ timezoneOptions })=>{
|
|
const { values, errors, setFieldValue } = useFormikContext();
|
|
const { formatMessage } = useIntl();
|
|
const [timezoneList, setTimezoneList] = React.useState(timezoneOptions);
|
|
React.useEffect(()=>{
|
|
if (values.date) {
|
|
// Update the timezone offset which varies with DST based on the date selected
|
|
const { timezoneList } = getTimezones(new Date(values.date));
|
|
setTimezoneList(timezoneList);
|
|
const updatedTimezone = values.timezone && timezoneList.find((tz)=>tz.value.split('&')[1] === values.timezone.split('&')[1]);
|
|
if (updatedTimezone) {
|
|
setFieldValue('timezone', updatedTimezone.value);
|
|
}
|
|
}
|
|
}, [
|
|
setFieldValue,
|
|
values.date,
|
|
values.timezone
|
|
]);
|
|
return /*#__PURE__*/ jsxs(Field.Root, {
|
|
name: "timezone",
|
|
error: errors.timezone && formatMessage({
|
|
id: errors.timezone,
|
|
defaultMessage: errors.timezone
|
|
}),
|
|
required: true,
|
|
children: [
|
|
/*#__PURE__*/ jsx(Field.Label, {
|
|
children: formatMessage({
|
|
id: 'content-releases.modal.form.input.label.timezone',
|
|
defaultMessage: 'Timezone'
|
|
})
|
|
}),
|
|
/*#__PURE__*/ jsx(Combobox, {
|
|
autocomplete: {
|
|
type: 'list',
|
|
filter: 'contains'
|
|
},
|
|
value: values.timezone || undefined,
|
|
textValue: values.timezone ? values.timezone.replace(/&/, ' ') : undefined,
|
|
onChange: (timezone)=>{
|
|
setFieldValue('timezone', timezone);
|
|
},
|
|
onTextValueChange: (timezone)=>{
|
|
setFieldValue('timezone', timezone);
|
|
},
|
|
onClear: ()=>{
|
|
setFieldValue('timezone', '');
|
|
},
|
|
children: timezoneList.map((timezone)=>/*#__PURE__*/ jsx(ComboboxOption, {
|
|
value: timezone.value,
|
|
children: timezone.value.replace(/&/, ' ')
|
|
}, timezone.value))
|
|
}),
|
|
/*#__PURE__*/ jsx(Field.Error, {})
|
|
]
|
|
});
|
|
};
|
|
|
|
export { ReleaseModal };
|
|
//# sourceMappingURL=ReleaseModal.mjs.map
|