Skip to content

Commit

Permalink
update to setting values (#28)
Browse files Browse the repository at this point in the history
* update to setting values

* update units
  • Loading branch information
evisdrenova authored Nov 10, 2023
1 parent 633a03c commit 5717779
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 78 deletions.
52 changes: 27 additions & 25 deletions src/NeoCron.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { arrayToString, stringToArray } from './lib/part';
import { Schedule, getSchedule } from './lib/schedule';
import { CronState, ValuePayload } from './types';

const defaultCronString = '* * * * *';

interface Props {
setCronString?: (val: string) => void; //the cron string itself
defaultValue?: string; //if you want to specify a default cron string to start with
setCronString?: (val: string) => void; //updates the cron string itself
disableInput?: boolean; //disable the input and only have drop down selectors
disableSelectors?: boolean; //disable the selectors and only have the input
disableExplainerText?: boolean; //disables the schedule explainer text
Expand All @@ -21,12 +22,12 @@ interface Props {
export default function NeoCron(props: Props): ReactElement {
const {
setCronString = () => {},
defaultValue = '* * * * *',
disableInput = false,
disableSelectors = false,
disableExplainerText = false,
selectorText = 'Run every',
} = props;

const updateSchedule = (state: CronState): CronState => {
const newSchedule = getSchedule(state.array);
setSchedule(newSchedule);
Expand All @@ -37,68 +38,69 @@ export default function NeoCron(props: Props): ReactElement {
};

const getInitialState = (): CronState => {
const expression = defaultValue;
const array = stringToArray(expression);
return updateSchedule({
expression,
array,
expression: defaultCronString,
array: stringToArray(defaultCronString),
error: '',
next: '',
});
};

const [schedule, setSchedule] = useState<Schedule>(
new Schedule(stringToArray('* * * * *'))
new Schedule(stringToArray(defaultCronString))
);
const [state, setState] = useState<CronState>(getInitialState);
const [cronState, setCronState] = useState<CronState>(getInitialState);
const [resetSelectedValues, setResetSelectedValues] =
useState<boolean>(false);

const setExpression = (expression: string) => {
let newState: CronState = { ...state, expression, error: '' };
let newState: CronState = { ...cronState, expression, error: '' };
try {
newState.array = stringToArray(expression);
newState = updateSchedule(newState);
} catch (e: any) {
newState.error = e.message;
}
setState(newState);
setCronState(newState);
};

const setValue = (payload: ValuePayload) => {
const newArray = [...state.array];
const constructCronState = (payload: ValuePayload) => {
const newArray = [...cronState.array];
newArray[payload.index] = payload.values;

let newState: CronState = { ...state, array: newArray, error: '' };
let newState: CronState = { ...cronState, array: newArray, error: '' };
try {
newState.expression = arrayToString(newState.array);
newState = updateSchedule(newState);
} catch (e: any) {
newState.error = e.message;
}
setState(newState);

if (newState.expression !== cronState.expression) {
setCronState(newState);
}
};

useEffect(() => {
if (setCronString) {
setCronString(state.expression);
setCronString(cronState.expression);
}
}, [state.expression]);
}, [cronState.expression]);

const setError = (error: string) => {
setState({ ...state, error: error });
setCronState({ ...cronState, error: error });
};

const resetSchedule = () => {
schedule.reset;
setState(getInitialState());
schedule.reset();
const initSchedule = getInitialState();
setCronState(initSchedule);
setResetSelectedValues(true);
};

return (
<div className="neocron-container">
{!disableInput && (
<CronExpression state={state} setExpression={setExpression} />
<CronExpression cronState={cronState} setExpression={setExpression} />
)}
{disableInput ||
(disableSelectors ? null : (
Expand All @@ -110,17 +112,17 @@ export default function NeoCron(props: Props): ReactElement {
))}
{!disableSelectors && (
<ScheduleSelectors
setValue={setValue}
constructCronState={constructCronState}
resetSchedule={resetSchedule}
state={state}
cronState={cronState}
resetSelectedValues={resetSelectedValues}
setResetSelectedValues={setResetSelectedValues}
setError={setError}
selectorText={selectorText}
/>
)}
<ScheduleExplainer
state={state}
state={cronState}
disableExplainerText={disableExplainerText}
/>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/components/CronExpression.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ import { CronState } from '../types';
import { Input } from './ui/input';

interface Props {
state: CronState;
cronState: CronState;
setExpression: (val: string) => void;
}

export default function CronExpression(props: Props): ReactElement {
const { state, setExpression } = props;
const { cronState, setExpression } = props;
return (
<div>
<Input
type="text"
id="expression"
className="cron-input"
onChange={(e) => setExpression(e.target.value)}
value={state.expression}
value={cronState.expression}
/>
</div>
);
Expand Down
58 changes: 29 additions & 29 deletions src/components/MultiSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ interface Props {
options: Unit;
resetSelectedValues: boolean;
setResetSelectedValues: (val: boolean) => void;
state: CronState;
cronState: CronState;
setError: (val: string) => void;
setValue: (val: SetValueObject) => void;
constructCronState: (val: SetValueObject) => void;
}

export default function MultiSelect(props: Props) {
Expand All @@ -35,8 +35,8 @@ export default function MultiSelect(props: Props) {
options,
resetSelectedValues,
setResetSelectedValues,
state,
setValue,
cronState,
constructCronState,
setError,
} = props;
const [openCombobox, setOpenCombobox] = useState(false);
Expand All @@ -53,11 +53,30 @@ export default function MultiSelect(props: Props) {
}
}, [resetSelectedValues, setResetSelectedValues]);

//this handles converting the cron expression to the selected values if a user types in a string first
//the if(!isFull){...}only updates the values in the UI if the user has changed it otherwise leaves it
//this is to prevent the case where the base cron string is ***** and it selects everything in the drop down
useEffect(() => {
try {
const arr = stringToArray(cronState.expression); //prints the number[][] of all selectors
const allUnits = getUnits(); //get all units so we can find the index of this selectors unit
const index = allUnits.findIndex((unit) => unit.name == options.name);

if (arr && Array.isArray(arr)) {
if (!isFull(arr[index], options)) {
setSelectedValues(arr[index].map(String));
}
}
} catch (e: any) {
setError(e.message);
}
}, [cronState, options]);

useEffect(() => {
if (selectedValues.length > 0) {
setValue({ index: ind, values: selectedValues.map(Number) });
constructCronState({ index: ind, values: selectedValues.map(Number) });
}
}, [selectedValues, setValue, ind]);
}, [selectedValues, ind]);

const toggleOptions = (option: string) => {
setSelectedValues((currentOption) => {
Expand All @@ -73,35 +92,16 @@ export default function MultiSelect(props: Props) {
inputRef?.current?.focus();
};

//this handles converting the cron expression to the selected values if a user types in a string first
//the if(!isFull){...}only updates the values in the UI if the user has changed it otherwise leaves it
//this is to prevent the case where the base cron string is ***** and it selects everything in the drop down
useEffect(() => {
try {
const arr = stringToArray(state.expression); //prints the number[][] array of all selectors
const allUnits = getUnits(); //get all units so we can find the index of this selectors unit
const index = allUnits.findIndex((unit) => unit.name == options.name);

if (arr && Array.isArray(arr)) {
if (!isFull(arr[index], options)) {
setSelectedValues(arr[index].map(String));
}
}
} catch (e: any) {
setError(e.message);
}
}, [state]);

const handleSelectAll = () => {
if (!selectAll) {
setSelectAll(true);
const allOptions = spreadOption(options);
setSelectedValues(allOptions);
setValue({ index: ind, values: allOptions.map(Number) });
constructCronState({ index: ind, values: allOptions.map(Number) });
} else {
setSelectAll(false);
setSelectedValues([]);
setValue({ index: 0, values: [] });
constructCronState({ index: 0, values: [] });
}
};

Expand Down Expand Up @@ -176,10 +176,10 @@ export default function MultiSelect(props: Props) {
key={option}
value={option}
onSelect={() => toggleOptions(option)}
// onSelect={() => setOption(option)}
className={cn(
'flex-1',
isActive && 'multiselect-selected-value'
isActive && 'multiselect-selected-value',
!isActive && 'multiselect-unselected-value'
)}
>
<div>{formatOption(option)}</div>
Expand Down
28 changes: 13 additions & 15 deletions src/components/ScheduleSelectors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import {
} from './ui/select';

interface Props {
setValue: (val: ValuePayload) => void;
constructCronState: (val: ValuePayload) => void;
resetSchedule: () => void;
state: CronState;
cronState: CronState;
resetSelectedValues: boolean;
setResetSelectedValues: (val: boolean) => void;
setError: (val: string) => void;
Expand All @@ -23,18 +23,18 @@ interface Props {

const scheduleSelector: ScheduleSelectorObject[] = [
{ name: 'year', prefix: 'on' },
{ name: 'month', prefix: 'on' },
{ name: 'weekday', prefix: 'on' },
{ name: 'month', prefix: 'on' },
{ name: 'day', prefix: 'and' },
{ name: 'hour', prefix: 'at' },
{ name: 'minute', prefix: ':' },
];

export default function ScheduleSelectors(props: Props): ReactElement {
const {
setValue,
constructCronState,
resetSchedule,
state,
cronState,
resetSelectedValues,
setResetSelectedValues,
setError,
Expand All @@ -58,16 +58,14 @@ export default function ScheduleSelectors(props: Props): ReactElement {
return (
<div key={opt.name} className="flex-container-row">
<div className="prefix-text">{opt.prefix}</div>
<div>
<MultiSelect
options={unit}
setValue={setValue}
setError={setError}
state={state}
resetSelectedValues={resetSelectedValues}
setResetSelectedValues={setResetSelectedValues}
/>
</div>
<MultiSelect
options={unit}
constructCronState={constructCronState}
setError={setError}
cronState={cronState}
resetSelectedValues={resetSelectedValues}
setResetSelectedValues={setResetSelectedValues}
/>
</div>
);
});
Expand Down
12 changes: 6 additions & 6 deletions src/lib/units.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ export const units: Unit[] = [
min: 1,
max: 31,
},
{
name: 'weekday',
min: 0,
max: 6,
alt: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
},
{
name: 'month',
min: 1,
Expand All @@ -42,6 +36,12 @@ export const units: Unit[] = [
'Dec',
],
},
{
name: 'weekday',
min: 0,
max: 6,
alt: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
},
];

//turns the min and max in the option into an array with all of the values
Expand Down

0 comments on commit 5717779

Please sign in to comment.