Skip to content

Commit

Permalink
Ends on scheduling recurrences (#728)
Browse files Browse the repository at this point in the history
* Convert the timestamp to datetime without changing the timezone

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add until value to the scheduling system

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Aligning items hirozontally

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove FormLabel import

Signed-off-by: angatupyry <fierrofenix@gmail.com>

---------

Signed-off-by: angatupyry <fierrofenix@gmail.com>
  • Loading branch information
Angatupyry committed Jul 25, 2023
1 parent fd92cb3 commit c67ffb8
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ def to_job(self) -> Job:
job = schedule.every()
if self.until is not None:
# schedule uses `datetime.now()`, which is tz naive
job = job.until(datetime.fromtimestamp(self.until.timestamp()))
# Assuming self.until is a datetime object with timezone information
# Convert the timestamp to datetime without changing the timezone
job = job.until(datetime.utcfromtimestamp(self.until.timestamp()))

if self.period in (
ScheduledTaskSchedule.Period.Monday,
Expand Down
15 changes: 8 additions & 7 deletions packages/dashboard/src/components/appbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,17 @@ function toApiSchedule(taskRequest: TaskRequest, schedule: Schedule): PostSchedu
const apiSchedules: PostScheduledTaskRequest['schedules'] = [];
const date = new Date(start);
const start_from = start.toISOString();
const until = schedule.until?.toISOString();
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const at = `${hours}:${minutes}`;
schedule.days[0] && apiSchedules.push({ period: 'monday', start_from, at });
schedule.days[1] && apiSchedules.push({ period: 'tuesday', start_from, at });
schedule.days[2] && apiSchedules.push({ period: 'wednesday', start_from, at });
schedule.days[3] && apiSchedules.push({ period: 'thursday', start_from, at });
schedule.days[4] && apiSchedules.push({ period: 'friday', start_from, at });
schedule.days[5] && apiSchedules.push({ period: 'saturday', start_from, at });
schedule.days[6] && apiSchedules.push({ period: 'sunday', start_from, at });
schedule.days[0] && apiSchedules.push({ period: 'monday', start_from, at, until });
schedule.days[1] && apiSchedules.push({ period: 'tuesday', start_from, at, until });
schedule.days[2] && apiSchedules.push({ period: 'wednesday', start_from, at, until });
schedule.days[3] && apiSchedules.push({ period: 'thursday', start_from, at, until });
schedule.days[4] && apiSchedules.push({ period: 'friday', start_from, at, until });
schedule.days[5] && apiSchedules.push({ period: 'saturday', start_from, at, until });
schedule.days[6] && apiSchedules.push({ period: 'sunday', start_from, at, until });
return {
task_request: taskRequest,
schedules: apiSchedules,
Expand Down
71 changes: 71 additions & 0 deletions packages/react-components/lib/tasks/create-task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import {
DialogProps,
DialogTitle,
Divider,
FormControl,
FormControlLabel,
FormHelperText,
Grid,
IconButton,
List,
Expand All @@ -24,6 +27,8 @@ import {
ListItemSecondaryAction,
ListItemText,
MenuItem,
Radio,
RadioGroup,
styled,
TextField,
Typography,
Expand Down Expand Up @@ -652,6 +657,12 @@ export type RecurringDays = [boolean, boolean, boolean, boolean, boolean, boolea
export interface Schedule {
startOn: Date;
days: RecurringDays;
until?: Date;
}

enum ScheduleUntilValue {
NEVER = 'never',
ON = 'on',
}

interface DaySelectorSwitchProps {
Expand Down Expand Up @@ -781,8 +792,28 @@ export function CreateTaskForm({
const [schedule, setSchedule] = React.useState<Schedule>({
startOn: new Date(),
days: [true, true, true, true, true, true, true],
until: undefined,
});
const [atTime, setAtTime] = React.useState(new Date());
const [scheduleUntilValue, setScheduleUntilValue] = React.useState<string>(
ScheduleUntilValue.NEVER,
);

const handleScheduleUntilValue = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.value === ScheduleUntilValue.ON) {
/**
* Since the time change is done in the onchange of the Datepicker,
* we need a defined time if the user saves the value without calling the onChange event of the datepicker
*/
const date = new Date();
date.setHours(23);
date.setMinutes(59);
setSchedule((prev) => ({ ...prev, until: date }));
} else {
setSchedule((prev) => ({ ...prev, until: undefined }));
}
setScheduleUntilValue(event.target.value);
};
// schedule is not supported with batch upload
const scheduleEnabled = taskRequests.length === 1;

Expand Down Expand Up @@ -1246,6 +1277,46 @@ export function CreateTaskForm({
/>
</Grid>
</Grid>
<Grid container marginTop={theme.spacing(1)} marginLeft={theme.spacing(0)}>
<FormControl fullWidth={true}>
<FormHelperText>Ends</FormHelperText>
<RadioGroup
aria-labelledby="controlled-radio-buttons-group"
name="controlled-radio-buttons-group"
value={scheduleUntilValue}
onChange={handleScheduleUntilValue}
row
>
<Grid item xs={6} paddingLeft={theme.spacing(1)}>
<FormControlLabel
value={ScheduleUntilValue.NEVER}
control={<Radio />}
label="Never"
/>
</Grid>
<Grid item xs={2} paddingLeft={theme.spacing(1)}>
<FormControlLabel value={ScheduleUntilValue.ON} control={<Radio />} label="On" />
</Grid>
<Grid item xs={4}>
<DatePicker
value={
scheduleUntilValue === ScheduleUntilValue.NEVER ? new Date() : schedule.until
}
onChange={(date) =>
date &&
setSchedule((prev) => {
date.setHours(23);
date.setMinutes(59);
return { ...prev, until: date };
})
}
disabled={scheduleUntilValue !== ScheduleUntilValue.ON}
renderInput={(props) => <TextField {...props} fullWidth />}
/>
</Grid>
</RadioGroup>
</FormControl>
</Grid>
</ConfirmationDialog>
)}
</>
Expand Down

0 comments on commit c67ffb8

Please sign in to comment.