Skip to content

Commit

Permalink
Warning time to only display color and use labels
Browse files Browse the repository at this point in the history
Signed-off-by: Aaron Chong <aaronchongth@gmail.com>
  • Loading branch information
aaronchongth committed Jun 7, 2024
1 parent 779dad7 commit cbe9c55
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class TaskState(Model):
status = CharField(255, null=True, index=True)
unix_millis_request_time = DatetimeField(null=True, index=True)
requester = CharField(255, null=True, index=True)
unix_millis_warn_time = DatetimeField(null=True, index=True)
pickup = CharField(255, null=True, index=True)
destination = CharField(255, null=True, index=True)
labels = ReverseRelation["TaskLabel"]
Expand Down
11 changes: 0 additions & 11 deletions packages/api-server/api_server/routes/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,6 @@ async def process_msg(
alert = await alert_repo.create_alert(task_state.booking.id, "task")
if alert is not None:
alert_events.alerts.on_next(alert)
elif (
task_state.unix_millis_finish_time
and task_state.unix_millis_warn_time
and task_state.unix_millis_finish_time > task_state.unix_millis_warn_time
):
# TODO(AC): Perhaps set a late alert as its own category
late_alert_id = f"{task_state.booking.id}__late"
if not await alert_repo.alert_original_id_exists(late_alert_id):
alert = await alert_repo.create_alert(late_alert_id, "task")
if alert is not None:
alert_events.alerts.on_next(alert)

elif payload_type == "task_log_update":
task_log = mdl.TaskEventLog(**msg["data"])
Expand Down
4 changes: 0 additions & 4 deletions packages/api-server/api_server/routes/tasks/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,6 @@ async def post_dispatch_task(
task_repo: TaskRepository = Depends(TaskRepository),
logger: LoggerAdapter = Depends(get_logger),
):
task_warn_time = request.request.unix_millis_warn_time

# FIXME: In order to accommodate changing cancellation lots over time, and
# avoiding updating all the saved scheduled tasks in the database, we only
# insert cancellation lots as part of the cancellation behavior before
Expand Down Expand Up @@ -344,8 +342,6 @@ async def post_dispatch_task(
if not resp.__root__.success:
return RawJSONResponse(resp.json(), 400)
new_state = cast(mdl.TaskDispatchResponseItem, resp.__root__).state
if task_warn_time is not None:
new_state.unix_millis_warn_time = task_warn_time
await task_repo.save_task_state(new_state)
await task_repo.save_task_request(new_state, request.request)
return resp.__root__
Expand Down
29 changes: 0 additions & 29 deletions packages/dashboard/src/components/tasks/task-alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,6 @@ export function TaskAlertDialog({ alert, removeAlert }: TaskAlertDialogProps): J
if (errorLogEntries.length !== 0) {
return 'Task error';
}
if (
state.unix_millis_finish_time &&
state.unix_millis_warn_time &&
state.unix_millis_finish_time > state.unix_millis_warn_time
) {
return 'Task warning';
}
return 'Task alert';
};

Expand Down Expand Up @@ -145,20 +138,6 @@ export function TaskAlertDialog({ alert, removeAlert }: TaskAlertDialogProps): J
value: `${completionTimeString}Task completed!`,
},
];
} else if (
state.unix_millis_finish_time &&
state.unix_millis_warn_time &&
state.unix_millis_finish_time > state.unix_millis_warn_time
) {
const completionTimeString = `${new Date(state.unix_millis_finish_time).toLocaleString()}`;
const warningTimeString = `${new Date(state.unix_millis_warn_time).toLocaleString()}`;
content = [
...content,
{
title: 'Late',
value: `Task is estimated to complete at ${completionTimeString}, later than the expected ${warningTimeString}.`,
},
];
}

return content;
Expand All @@ -183,14 +162,6 @@ export function TaskAlertDialog({ alert, removeAlert }: TaskAlertDialogProps): J
return base.palette.error.dark;
}

if (
state.unix_millis_finish_time &&
state.unix_millis_warn_time &&
state.unix_millis_finish_time > state.unix_millis_warn_time
) {
return base.palette.warning.dark;
}

return base.palette.background.default;
};

Expand Down
48 changes: 28 additions & 20 deletions packages/react-components/lib/tasks/create-task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ import React from 'react';
import { Loading } from '..';
import { ConfirmationDialog, ConfirmationDialogProps } from '../confirmation-dialog';
import { PositiveIntField } from '../form-inputs';
import { serializeTaskBookingLabel } from './task-booking-label-utils';
import {
getTaskBookingLabelFromTaskRequest,
serializeTaskBookingLabel,
} from './task-booking-label-utils';

interface TaskDefinition {
task_definition_id: string;
Expand Down Expand Up @@ -1403,9 +1406,23 @@ export function CreateTaskForm({
setScheduleUntilValue(event.target.value);
};

const [warnTimeChecked, setWarnTimeChecked] = React.useState(false);
const existingBookingLabel = requestTask
? getTaskBookingLabelFromTaskRequest(requestTask)
: undefined;
let existingWarnTime: Date | null = null;
if (existingBookingLabel && existingBookingLabel.description.unix_millis_warn_time) {
const warnTimeInt = parseInt(existingBookingLabel.description.unix_millis_warn_time as string);
if (!Number.isNaN(warnTimeInt)) {
existingWarnTime = new Date(warnTimeInt);
}
}
const [warnTime, setWarnTime] = React.useState<Date | null>(existingWarnTime);
const handleWarnTimeCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setWarnTimeChecked(event.target.checked);
if (event.target.checked) {
setWarnTime(new Date());
} else {
setWarnTime(null);
}
};

const handleTaskDescriptionChange = (newCategory: string, newDesc: TaskDescription) => {
Expand Down Expand Up @@ -1570,6 +1587,10 @@ export function CreateTaskForm({
return;
}

if (warnTime !== null) {
requestBookingLabel.description.unix_millis_warn_time = `${warnTime.valueOf()}`;
}

const labelString = serializeTaskBookingLabel(requestBookingLabel);
if (labelString) {
request.labels = [labelString];
Expand Down Expand Up @@ -1779,7 +1800,7 @@ export function CreateTaskForm({
</Grid>
<Grid item xs={1}>
<Checkbox
checked={warnTimeChecked}
checked={warnTime !== null}
onChange={handleWarnTimeCheckboxChange}
inputProps={{ 'aria-label': 'controlled' }}
sx={{
Expand All @@ -1789,24 +1810,11 @@ export function CreateTaskForm({
</Grid>
<Grid item xs={isScreenHeightLessThan800 ? 5 : 4}>
<DateTimePicker
disabled={!warnTimeChecked}
disabled={warnTime === null}
inputFormat={'MM/dd/yyyy HH:mm'}
value={
taskRequest.unix_millis_warn_time
? new Date(taskRequest.unix_millis_warn_time)
: new Date()
}
value={warnTime}
onChange={(date) => {
if (!date || !warnTimeChecked) {
return;
}
taskRequest.unix_millis_warn_time = date.valueOf();
setTaskRequest((prev) => {
return {
...prev,
unix_millis_warn_time: date.valueOf(),
};
});
setWarnTime(date);
}}
label="Warn Time"
renderInput={(props) => (
Expand Down
22 changes: 21 additions & 1 deletion packages/react-components/lib/tasks/task-booking-label-utils.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ajv } from '../utils/schema-utils';
import schema from 'api-client/dist/schema';
import type { TaskBookingLabel, TaskState } from 'api-client';
import type { TaskBookingLabel, TaskRequest, TaskState } from 'api-client';

const validateTaskBookingLabel = ajv.compile(schema.components.schemas.TaskBookingLabel);

Expand Down Expand Up @@ -44,3 +44,23 @@ export function getTaskBookingLabelFromTaskState(taskState: TaskState): TaskBook
}
return requestLabel;
}

export function getTaskBookingLabelFromTaskRequest(
taskRequest: TaskRequest,
): TaskBookingLabel | null {
let requestLabel: TaskBookingLabel | null = null;
if (taskRequest.labels) {
for (const label of taskRequest.labels) {
try {
const parsedLabel = getTaskBookingLabelFromJsonString(label);
if (parsedLabel) {
requestLabel = parsedLabel;
break;
}
} catch (e) {
continue;
}
}
}
return requestLabel;
}
95 changes: 86 additions & 9 deletions packages/react-components/lib/tasks/task-table-datagrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ import {
GridFilterModel,
GridSortModel,
} from '@mui/x-data-grid';
import { styled, Stack, Typography, Tooltip, useMediaQuery, SxProps, Theme } from '@mui/material';
import {
Box,
styled,
Stack,
Typography,
Tooltip,
useMediaQuery,
SxProps,
Theme,
} from '@mui/material';
import * as React from 'react';
import { TaskState, ApiServerModelsRmfApiTaskStateStatus as Status } from 'api-client';
import { InsertInvitation as ScheduleIcon, Person as UserIcon } from '@mui/icons-material/';
Expand All @@ -25,6 +34,7 @@ const classes = {
taskPendingCell: 'MuiDataGrid-cell-pending-cell',
taskQueuedCell: 'MuiDataGrid-cell-queued-cell',
taskUnknownCell: 'MuiDataGrid-cell-unknown-cell',
taskLateCell: 'MuiDataGrid-cell-late-cell',
};

const StyledDataGrid = styled(DataGrid)(({ theme }) => ({
Expand Down Expand Up @@ -52,6 +62,10 @@ const StyledDataGrid = styled(DataGrid)(({ theme }) => ({
backgroundColor: theme.palette.warning.main,
color: theme.palette.getContrastText(theme.palette.warning.main),
},
[`& .${classes.taskLateCell}`]: {
backgroundColor: theme.palette.warning.main,
color: theme.palette.getContrastText(theme.palette.warning.main),
},
}));

export interface Tasks {
Expand Down Expand Up @@ -226,10 +240,25 @@ export function TaskDataGridTable({
headerName: 'Start Time',
width: 150,
editable: false,
renderCell: (cellValues) =>
cellValues.row.unix_millis_start_time
? `${new Date(cellValues.row.unix_millis_start_time).toLocaleTimeString()}`
: 'n/a',
renderCell: (cellValues) => {
const startDateTime = cellValues.row.unix_millis_start_time
? new Date(cellValues.row.unix_millis_start_time)
: undefined;
const startTimeString = startDateTime ? `${startDateTime.toLocaleTimeString()}` : 'n/a';
return (
<Tooltip
title={
<React.Fragment>
<Typography>
Start time: {startDateTime ? startDateTime.toLocaleString() : 'n/a'}
</Typography>
</React.Fragment>
}
>
<Box component="div">{startTimeString}</Box>
</Tooltip>
);
},
flex: 1,
filterOperators: getMinimalDateOperators,
filterable: true,
Expand All @@ -239,10 +268,37 @@ export function TaskDataGridTable({
headerName: 'End Time',
width: 150,
editable: false,
renderCell: (cellValues) =>
cellValues.row.unix_millis_finish_time
? `${new Date(cellValues.row.unix_millis_finish_time).toLocaleTimeString()}`
: 'n/a',
renderCell: (cellValues) => {
const bookingLabel = getTaskBookingLabelFromTaskState(cellValues.row);
let warnDateTime: Date | undefined = undefined;
if (bookingLabel?.description.unix_millis_warn_time) {
const warnMillisNum = parseInt(bookingLabel.description.unix_millis_warn_time as string);
if (!Number.isNaN(warnMillisNum)) {
warnDateTime = new Date(warnMillisNum);
}
}

const finishDateTime = cellValues.row.unix_millis_finish_time
? new Date(cellValues.row.unix_millis_finish_time)
: undefined;
const finishTimeString = finishDateTime ? `${finishDateTime.toLocaleTimeString()}` : 'n/a';
return (
<Tooltip
title={
<React.Fragment>
<Typography>
Warning time: {warnDateTime ? warnDateTime.toLocaleString() : 'n/a'}
</Typography>
<Typography>
Finish time: {finishDateTime ? finishDateTime.toLocaleString() : 'n/a'}
</Typography>
</React.Fragment>
}
>
<Box component="div">{finishTimeString}</Box>
</Tooltip>
);
},
flex: 1,
filterOperators: getMinimalDateOperators,
filterable: true,
Expand Down Expand Up @@ -313,6 +369,27 @@ export function TaskDataGridTable({
default:
return classes.taskUnknownCell;
}
} else if (params.field === 'unix_millis_finish_time') {
if (!params.value) {
return classes.taskUnknownCell;
}

const bookingLabel = getTaskBookingLabelFromTaskState(params.row);
let warnDateTime: Date | undefined = undefined;
if (bookingLabel?.description.unix_millis_warn_time) {
const warnMillisNum = parseInt(
bookingLabel.description.unix_millis_warn_time as string,
);
if (!Number.isNaN(warnMillisNum)) {
warnDateTime = new Date(warnMillisNum);
}
}

const finishDateTime = params.value ? new Date(params.value) : undefined;

if (warnDateTime && finishDateTime && finishDateTime > warnDateTime) {
return classes.taskLateCell;
}
}
return '';
}}
Expand Down

0 comments on commit cbe9c55

Please sign in to comment.