UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

160 lines (159 loc) 8.62 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import * as React from 'react'; import { CheckBox } from '../../../components/CheckBox'; import FormLayout, { FormRow } from '../../../components/FormLayout'; import Radio from '../../../components/Radio'; import AdaptableInput from '../../Components/AdaptableInput'; import { useOnePageAdaptableWizardContext } from '../../Wizard/OnePageAdaptableWizard'; import { Box } from '../../../components/Flex'; import { Card } from '../../../components/Card'; import { SingleSelect } from '../../../components/NewSelect'; import ObjectFactory from '../../../Utilities/ObjectFactory'; import { buildCronExpression, buildRunAtIso, inferPresetFromCron, isScheduleValid as validateSchedule, parseOneOffDateFromRunAt, parseTimeFromSchedule, } from '../../../Utilities/Helpers/Scheduling/ScheduleHelper'; export const isScheduleValid = (holder) => { if (!holder?.Schedule) { return 'Schedule is not specified'; } return validateSchedule(holder.Schedule); }; const daysMap = [ { label: 'Monday', value: 'Monday' }, { label: 'Tuesday', value: 'Tuesday' }, { label: 'Wednesday', value: 'Wednesday' }, { label: 'Thursday', value: 'Thursday' }, { label: 'Friday', value: 'Friday' }, { label: 'Saturday', value: 'Saturday' }, { label: 'Sunday', value: 'Sunday' }, ]; const PRESET_OPTIONS = [ { value: 'daily', label: 'Every Day' }, { value: 'weekdays', label: 'Weekdays (Mon–Fri)' }, { value: 'selectedDays', label: 'Selected Days' }, { value: 'monthly', label: 'Monthly' }, { value: 'custom', label: 'Custom Cron' }, ]; const DEFAULT_SELECTED_DAYS = ['Monday']; function buildScheduleFromUiState(params) { if (params.isOneOff) { const date = params.oneOffDate || new Date().toISOString().slice(0, 10); return { IsOneOff: true, RunAt: buildRunAtIso(date, params.hour, params.minute), }; } return { IsOneOff: false, CronExpression: buildCronExpression(params.preset, params.hour, params.minute, { days: params.selectedDays, dayOfMonth: params.dayOfMonth, customExpression: params.customCron, }), }; } export const ScheduleBuilderWizard = (props) => { const { data } = useOnePageAdaptableWizardContext(); const schedule = data?.Schedule ?? ObjectFactory.CreateDefaultSchedule(); const isOneOff = schedule.IsOneOff; const { hour: initialHour, minute: initialMinute } = parseTimeFromSchedule(schedule); const inferred = inferPresetFromCron(schedule.CronExpression); const [hour, setHour] = React.useState(initialHour); const [minute, setMinute] = React.useState(initialMinute); const [preset, setPreset] = React.useState(inferred.preset); const [selectedDays, setSelectedDays] = React.useState(inferred.days); const [dayOfMonth, setDayOfMonth] = React.useState(inferred.dayOfMonth); const [customCron, setCustomCron] = React.useState(schedule.CronExpression ?? ''); const [oneOffDate, setOneOffDate] = React.useState(parseOneOffDateFromRunAt(schedule.RunAt)); React.useEffect(() => { const { hour: h, minute: m } = parseTimeFromSchedule(schedule); const inf = inferPresetFromCron(schedule.CronExpression); setHour(h); setMinute(m); setPreset(inf.preset); setSelectedDays(inf.days); setDayOfMonth(inf.dayOfMonth); setCustomCron(schedule.CronExpression ?? ''); setOneOffDate(parseOneOffDateFromRunAt(schedule.RunAt)); }, [schedule.IsOneOff, schedule.RunAt, schedule.CronExpression]); const commit = React.useCallback((overrides) => { const next = buildScheduleFromUiState({ isOneOff, oneOffDate, hour, minute, preset, selectedDays, dayOfMonth, customCron, ...overrides, }); props.onChange({ ...data, Schedule: next }); }, [ isOneOff, oneOffDate, hour, minute, preset, selectedDays, dayOfMonth, customCron, data, props, ]); const handleFrequencyChange = (oneOff) => { if (oneOff) { commit({ isOneOff: true, oneOffDate: oneOffDate || new Date().toISOString().slice(0, 10), }); } else { commit({ isOneOff: false }); } }; const handleTimeChange = (event) => { const [h, m] = (event.target.value || '09:00') .split(':') .map((item) => parseInt(item, 10)); setHour(h); setMinute(m); commit({ hour: h, minute: m }); }; const handleOneOffDateChange = (event) => { const value = event.target.value; setOneOffDate(value); commit({ oneOffDate: value }); }; const handlePresetChange = (value) => { setPreset(value); const days = value === 'selectedDays' && selectedDays.length === 0 ? DEFAULT_SELECTED_DAYS : selectedDays; if (value === 'selectedDays' && selectedDays.length === 0) { setSelectedDays(days); } commit({ preset: value, selectedDays: days }); }; const handleDayChange = (checked, day) => { const next = checked ? [...selectedDays, day] : selectedDays.filter((d) => d !== day); if (next.length === 0) { return; } setSelectedDays(next); setPreset('selectedDays'); commit({ selectedDays: next, preset: 'selectedDays' }); }; const handleDayOfMonthChange = (event) => { const dom = parseInt(event.target.value, 10) || 1; setDayOfMonth(dom); commit({ dayOfMonth: dom }); }; const handleCustomCronChange = (event) => { const value = event.target.value; setCustomCron(value); commit({ customCron: value, preset: 'custom' }); }; const timeValue = `${`${hour}`.padStart(2, '0')}:${`${minute}`.padStart(2, '0')}`; return (_jsx(Box, { "data-name": "schedule-setup", children: _jsxs(Card, { shadow: false, children: [_jsxs(Card.Title, { children: [_jsx(Box, { className: "twa:font-medium", children: "Schedule" }), _jsx(Box, { className: "twa:text-xs twa:opacity-70 twa:font-normal twa:max-w-[520px]", children: "Configure when this should run" })] }), _jsx(Card.Body, { children: _jsxs(FormLayout, { children: [_jsxs(FormRow, { label: "Frequency", children: [_jsx(Radio, { "data-name": "frequency-recurring", className: "twa:mr-2", value: "recurring", checked: !isOneOff, onChange: (checked) => checked && handleFrequencyChange(false), children: "Recurring" }), _jsx(Radio, { "data-name": "frequency-one-off", checked: isOneOff, value: "oneoff", onChange: (checked) => checked && handleFrequencyChange(true), children: "One-off" })] }), isOneOff ? (_jsx(FormRow, { label: "Date", children: _jsx(AdaptableInput, { "data-name": "one-off-date", className: "twa:w-[300px]", type: "date", placeholder: "Date", onChange: handleOneOffDateChange, value: oneOffDate }) })) : (_jsxs(_Fragment, { children: [_jsx(FormRow, { label: "Pattern", children: _jsx(Box, { className: "twa:max-w-[300px]", children: _jsx(SingleSelect, { className: "twa:w-full", "data-name": "recurrence-preset", items: PRESET_OPTIONS, value: preset, placeholder: "Select pattern", onValueChange: handlePresetChange }) }) }), preset === 'selectedDays' && (_jsx(FormRow, { label: "Days", children: daysMap.map((day) => (_jsx(CheckBox, { "data-name": `day-${day.value}`, className: "twa:ml-2 twa:w-1/3", value: day.value, checked: selectedDays.includes(day.value), onChange: (checked) => handleDayChange(checked, day.value), children: day.label }, day.value))) })), preset === 'monthly' && (_jsx(FormRow, { label: "Day of month", children: _jsx(AdaptableInput, { "data-name": "day-of-month", className: "twa:w-[120px]", type: "number", min: 1, max: 31, value: dayOfMonth, onChange: handleDayOfMonthChange }) })), preset === 'custom' && (_jsx(FormRow, { label: "Cron expression", children: _jsx(AdaptableInput, { "data-name": "custom-cron", className: "twa:w-[300px]", placeholder: "minute hour day month weekday", value: customCron, onChange: handleCustomCronChange }) }))] })), (isOneOff || preset !== 'custom') && (_jsx(FormRow, { label: "Time", children: _jsx(AdaptableInput, { "data-name": "time", className: "twa:w-[300px]", value: timeValue, type: "time", onChange: handleTimeChange }) }))] }) })] }) })); };