@@ -35,7 +36,7 @@ export function ErrorUI({ error }: { error: Error }) {
)}
- {error.message}
+ {error}
@@ -64,7 +65,7 @@ export class ErrorBoundary extends React.Component<
render() {
if (this.state.hasError) {
- return
;
+ return
;
}
return this.props.children;
}
diff --git a/ui/desktop/src/components/schedule/CronPicker.tsx b/ui/desktop/src/components/schedule/CronPicker.tsx
index 213081043ff8..4e164d566cd5 100644
--- a/ui/desktop/src/components/schedule/CronPicker.tsx
+++ b/ui/desktop/src/components/schedule/CronPicker.tsx
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from 'react';
import cronstrue from 'cronstrue';
import { ScheduledJob } from '../../schedule';
+import { errorMessage } from '../../utils/conversionUtils';
type Period = 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';
@@ -17,6 +18,7 @@ type ParsedCron = {
interface CronPickerProps {
schedule: ScheduledJob | null;
onChange: (cron: string) => void;
+ isValid: (valid: boolean) => void;
}
const parseCron = (cron: string): ParsedCron => {
@@ -76,16 +78,16 @@ const to12Hour = (hour24: number): { hour: number; isPM: boolean } => {
return { hour: hour24, isPM: false };
};
-export const CronPicker: React.FC
= ({ schedule, onChange }) => {
+export const CronPicker: React.FC = ({ schedule, onChange, isValid }) => {
const [period, setPeriod] = useState('day');
const [second, setSecond] = useState('0');
const [minute, setMinute] = useState('0');
const [hour12, setHour12] = useState(2);
- const [currentCron, setCurrentCron] = useState('');
const [isPM, setIsPM] = useState(true);
const [dayOfWeek, setDayOfWeek] = useState('1');
const [dayOfMonth, setDayOfMonth] = useState('1');
const [month, setMonth] = useState('1');
+ const [readableCron, setReadableCron] = useState('');
useEffect(() => {
const parsed = parseCron(schedule?.cron || '');
@@ -128,16 +130,18 @@ export const CronPicker: React.FC = ({ schedule, onChange }) =>
cron = '0 0 0 * * *';
}
onChange(cron);
- setCurrentCron(cron);
- }, [period, second, minute, hour12, isPM, dayOfWeek, dayOfMonth, month, onChange]);
-
- const getReadable = () => {
- if (!currentCron) {
- return '';
+ if (cron) {
+ const cronWithoutSeconds = cron.split(' ').slice(1).join(' ');
+ try {
+ setReadableCron(cronstrue.toString(cronWithoutSeconds));
+ isValid(true);
+ } catch (e) {
+ isValid(false);
+ setReadableCron('error: ' + errorMessage(e));
+ }
}
- const cronWithoutSeconds = currentCron.split(' ').slice(1).join(' ');
- return cronstrue.toString(cronWithoutSeconds);
- };
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [period, second, minute, hour12, isPM, dayOfWeek, dayOfMonth, month]);
const selectClassName = 'px-2 py-1 border rounded bg-white dark:bg-gray-800 dark:border-gray-600';
@@ -277,7 +281,7 @@ export const CronPicker: React.FC = ({ schedule, onChange }) =>
)}