Skip to content

Commit

Permalink
Hammer/frontend changes (#856)
Browse files Browse the repository at this point in the history
* Added console log for all received delivery alerts

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Make task data grid smaller, refactored use of sx

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Tab font sizes

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Schedule font sizes

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Using smaller fonts for othe datagrids

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Cancel button as secondary color

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Confirm dialog when cancelling task

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Fix scale of robot icons

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Cancel confirmation dialog with subtitle

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Confirmation on task cancellation button

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Confirmation dialog for delivery alert cancellation

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Revert robot-three-maker tests

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Removed height restriction during small resolution as that would affect multi-line

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Task and robot summaries at low resolution

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

---------

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>
  • Loading branch information
aaronchongth authored Dec 4, 2023
1 parent 36a5b86 commit dce245b
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 226 deletions.
82 changes: 12 additions & 70 deletions packages/dashboard/src/components/delivery-alert-store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { base } from 'react-components';
import { AppControllerContext } from './app-contexts';
import { RmfAppContext } from './rmf-app';
import { TaskInspector } from './tasks/task-inspector';
import { TaskCancelButton } from './tasks/task-cancellation';

const useStyles = makeStyles((theme: Theme) =>
createStyles({
Expand Down Expand Up @@ -58,7 +59,6 @@ const DeliveryWarningDialog = React.memo((props: DeliveryWarningDialogProps) =>
const [actionTaken, setActionTaken] = React.useState(!onOverride && !onResume);
const [newTaskState, setNewTaskState] = React.useState<TaskState | null>(null);
const [openTaskInspector, setOpenTaskInspector] = React.useState(false);
const [cancelling, setCancelling] = React.useState(false);
const appController = React.useContext(AppControllerContext);
const rmf = React.useContext(RmfAppContext);
const isScreenHeightLessThan800 = useMediaQuery('(max-height:800px)');
Expand All @@ -81,38 +81,11 @@ const DeliveryWarningDialog = React.memo((props: DeliveryWarningDialogProps) =>
}
const sub = rmf.getTaskStateObs(taskState.booking.id).subscribe((taskStateUpdate) => {
setNewTaskState(taskStateUpdate);
setCancelling((prev) => {
if (
prev &&
deliveryAlert.action === 'waiting' &&
taskStateUpdate.status &&
taskStateUpdate.status === 'canceled'
) {
setCancelling(false);
(async () => {
try {
await rmf.deliveryAlertsApi.updateDeliveryAlertActionDeliveryAlertsDeliveryAlertIdActionPost(
deliveryAlert.id,
'cancelled',
);
} catch (e) {
appController.showAlert(
'error',
`Failed to cancel delivery alert ${deliveryAlert.id}: ${(e as Error).message}`,
);
}
setActionTaken(true);
})();
}
return prev;
});

if (
deliveryAlert.action === 'waiting' &&
taskStateUpdate.status &&
taskStateUpdate.status === 'canceled'
) {
setCancelling(false);
(async () => {
try {
await rmf.deliveryAlertsApi.updateDeliveryAlertActionDeliveryAlertsDeliveryAlertIdActionPost(
Expand All @@ -132,20 +105,6 @@ const DeliveryWarningDialog = React.memo((props: DeliveryWarningDialogProps) =>
return () => sub.unsubscribe();
}, [rmf, deliveryAlert, taskState, appController]);

const cancelTask = React.useCallback(
async (task_id: string) => {
if (!rmf) {
console.error('Tasks api not available for task cancellation.');
return;
}
await rmf.tasksApi.postCancelTaskTasksCancelTaskPost({
type: 'cancel_task_request',
task_id: task_id,
});
},
[rmf],
);

const titleUpdateText = (action: string) => {
switch (action) {
case 'override': {
Expand Down Expand Up @@ -191,7 +150,6 @@ const DeliveryWarningDialog = React.memo((props: DeliveryWarningDialogProps) =>
sx={{
'& .MuiFilledInput-root': {
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1.15',
height: isScreenHeightLessThan800 ? '2.2rem' : '3rem',
},
}}
InputLabelProps={{ style: { fontSize: isScreenHeightLessThan800 ? 16 : 20 } }}
Expand All @@ -212,7 +170,6 @@ const DeliveryWarningDialog = React.memo((props: DeliveryWarningDialogProps) =>
sx={{
'& .MuiFilledInput-root': {
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1.15',
height: isScreenHeightLessThan800 ? '2.2rem' : '3rem',
},
}}
InputLabelProps={{ style: { fontSize: isScreenHeightLessThan800 ? 16 : 20 } }}
Expand All @@ -229,7 +186,6 @@ const DeliveryWarningDialog = React.memo((props: DeliveryWarningDialogProps) =>
sx={{
'& .MuiFilledInput-root': {
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1.15',
height: isScreenHeightLessThan800 ? '2.2rem' : '3rem',
},
}}
InputLabelProps={{ style: { fontSize: isScreenHeightLessThan800 ? 16 : 20 } }}
Expand Down Expand Up @@ -258,34 +214,18 @@ const DeliveryWarningDialog = React.memo((props: DeliveryWarningDialogProps) =>
</Button>
) : newTaskState ? (
<Tooltip title="Cancels the current delivery task.">
<Button
<TaskCancelButton
taskId={newTaskState.booking.id}
size="small"
variant="contained"
disabled={actionTaken || cancelling}
color="secondary"
disabled={actionTaken}
buttonText={'Cancel Delivery'}
sx={{
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1rem',
padding: isScreenHeightLessThan800 ? '4px 8px' : '6px 12px',
}}
onClick={() => {
setCancelling(true);
if (newTaskState) {
const task_id = newTaskState.booking.id;
try {
cancelTask(task_id);
appController.showAlert('success', `Successfully cancelled task ${task_id}`);
} catch (e) {
appController.showAlert(
'error',
`Failed to cancel task ${task_id}: ${(e as Error).message}`,
);
setCancelling(false);
}
}
}}
autoFocus
>
{cancelling ? 'Cancelling...' : 'Cancel Delivery'}
</Button>
/>
</Tooltip>
) : (
<Button
Expand Down Expand Up @@ -400,7 +340,6 @@ const DeliveryErrorDialog = React.memo((props: DeliveryErrorDialogProps) => {
sx={{
'& .MuiFilledInput-root': {
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1.15',
height: isScreenHeightLessThan800 ? '2.2rem' : '3rem',
},
}}
InputLabelProps={{ style: { fontSize: isScreenHeightLessThan800 ? 16 : 20 } }}
Expand All @@ -417,7 +356,6 @@ const DeliveryErrorDialog = React.memo((props: DeliveryErrorDialogProps) => {
sx={{
'& .MuiFilledInput-root': {
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1.15',
height: isScreenHeightLessThan800 ? '2.2rem' : '3rem',
},
}}
InputLabelProps={{ style: { fontSize: isScreenHeightLessThan800 ? 16 : 20 } }}
Expand All @@ -434,7 +372,6 @@ const DeliveryErrorDialog = React.memo((props: DeliveryErrorDialogProps) => {
sx={{
'& .MuiFilledInput-root': {
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1.15',
height: isScreenHeightLessThan800 ? '2.2rem' : '3rem',
},
}}
InputLabelProps={{ style: { fontSize: isScreenHeightLessThan800 ? 16 : 20 } }}
Expand Down Expand Up @@ -601,6 +538,11 @@ export const DeliveryAlertStore = React.memo(() => {
return;
}
const sub = rmf.deliveryAlertObsStore.subscribe(async (deliveryAlert) => {
// DEBUG
console.log(
`Got a delivery alert [${deliveryAlert.id}] with action [${deliveryAlert.action}]`,
);

let state: TaskState | undefined = undefined;
if (deliveryAlert.task_id) {
try {
Expand Down
21 changes: 19 additions & 2 deletions packages/dashboard/src/components/robots/robot-summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
TextField,
Theme,
Typography,
useMediaQuery,
} from '@mui/material';
import { makeStyles, createStyles } from '@mui/styles';
import React from 'react';
Expand Down Expand Up @@ -108,6 +109,7 @@ const showBatteryIcon = (robot: RobotState, robotBattery: number) => {
};

export const RobotSummary = React.memo(({ onClose, robot }: RobotSummaryProps) => {
const isScreenHeightLessThan800 = useMediaQuery('(max-height:800px)');
const classes = useStyles();
const rmf = React.useContext(RmfAppContext);

Expand Down Expand Up @@ -228,6 +230,11 @@ export const RobotSummary = React.memo(({ onClose, robot }: RobotSummaryProps) =
maxRows={4}
margin="dense"
value={message.value}
sx={{
'& .MuiFilledInput-root': {
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1.15',
},
}}
/>
</div>
))}
Expand All @@ -249,12 +256,17 @@ export const RobotSummary = React.memo(({ onClose, robot }: RobotSummaryProps) =
onClose();
}}
fullWidth
maxWidth="sm"
maxWidth={isScreenHeightLessThan800 ? 'xs' : 'sm'}
>
<Grid container mb={1} alignItems="center" spacing={1}>
<Grid item xs={2}></Grid>
<Grid item xs={8}>
<DialogTitle align="center">Robot summary: {robotState?.name}</DialogTitle>
<DialogTitle
align="center"
sx={{ fontSize: isScreenHeightLessThan800 ? '1.2rem' : '1.5rem' }}
>
Robot summary: {robotState?.name}
</DialogTitle>
</Grid>
<Grid item xs={2}>
<Grid container justifyContent="flex-end">
Expand Down Expand Up @@ -284,6 +296,11 @@ export const RobotSummary = React.memo(({ onClose, robot }: RobotSummaryProps) =
taskId={taskState ? taskState.booking.id : null}
size="small"
variant="contained"
color="secondary"
sx={{
fontSize: isScreenHeightLessThan800 ? '0.8rem' : '1rem',
padding: isScreenHeightLessThan800 ? '4px 8px' : '6px 12px',
}}
/>
</DialogActions>
{openTaskDetailsLogs && taskState && (
Expand Down
75 changes: 51 additions & 24 deletions packages/dashboard/src/components/tasks/task-cancellation.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, ButtonProps, Theme, Tooltip } from '@mui/material';
import { Button, ButtonProps, Theme, Tooltip, Typography } from '@mui/material';
import { TaskState } from 'api-client';
import React from 'react';
import { AppControllerContext } from '../app-contexts';
Expand All @@ -7,6 +7,7 @@ import { RmfAppContext } from '../rmf-app';
import { UserProfileContext } from 'rmf-auth';
import { Enforcer } from '../permissions';
import { makeStyles, createStyles } from '@mui/styles';
import { ConfirmationDialog } from 'react-components';

const useStyles = makeStyles((theme: Theme) =>
createStyles({
Expand All @@ -20,15 +21,21 @@ const useStyles = makeStyles((theme: Theme) =>

export interface TaskCancelButtonProp extends ButtonProps {
taskId: string | null;
buttonText?: string;
}

export function TaskCancelButton({ taskId, ...otherProps }: TaskCancelButtonProp): JSX.Element {
export function TaskCancelButton({
taskId,
buttonText,
...otherProps
}: TaskCancelButtonProp): JSX.Element {
const classes = useStyles();
const rmf = React.useContext(RmfAppContext);
const appController = React.useContext(AppControllerContext);
const profile = React.useContext(UserProfileContext);

const [taskState, setTaskState] = React.useState<TaskState | null>(null);
const [openConfirmDialog, setOpenConfirmDialog] = React.useState(false);

React.useEffect(() => {
if (!rmf || !taskId) {
Expand Down Expand Up @@ -65,29 +72,49 @@ export function TaskCancelButton({ taskId, ...otherProps }: TaskCancelButtonProp
} catch (e) {
appController.showAlert('error', `Failed to cancel task: ${(e as Error).message}`);
}
setOpenConfirmDialog(false);
}, [appController, taskState, rmf]);

return taskCancellable && userCanCancelTask ? (
<Button onClick={handleCancelTaskClick} autoFocus {...otherProps}>
Cancel Task
</Button>
) : taskCancellable && !userCanCancelTask ? (
<Tooltip title="You don't have permission to cancel tasks.">
<Button disabled className={classes['enableHover']} {...otherProps}>
Cancel Task
</Button>
</Tooltip>
) : (
<Tooltip
title={
taskState && taskState.status
? `${capitalizeFirstLetter(taskState.status)} task cannot be cancelled.`
: `Task cannot be cancelled.`
}
>
<Button disabled className={classes['enableHover']} {...otherProps}>
Cancel Task
</Button>
</Tooltip>
return (
<>
{taskCancellable && userCanCancelTask ? (
<Button onClick={() => setOpenConfirmDialog(true)} autoFocus {...otherProps}>
{buttonText ?? 'Cancel Task'}
</Button>
) : taskCancellable && !userCanCancelTask ? (
<Tooltip title="You don't have permission to cancel tasks.">
<Button disabled className={classes['enableHover']} {...otherProps}>
{buttonText ?? 'Cancel Task'}
</Button>
</Tooltip>
) : (
<Tooltip
title={
taskState && taskState.status
? `${capitalizeFirstLetter(taskState.status)} task cannot be cancelled.`
: `Task cannot be cancelled.`
}
>
<Button disabled className={classes['enableHover']} {...otherProps}>
{buttonText ?? 'Cancel Task'}
</Button>
</Tooltip>
)}
{openConfirmDialog && (
<ConfirmationDialog
confirmText="Confirm"
cancelText="Cancel"
open={openConfirmDialog}
title={`Cancel task [${taskState?.booking.id || 'n/a'}]`}
submitting={undefined}
onClose={() => {
setOpenConfirmDialog(false);
}}
onSubmit={handleCancelTaskClick}
>
<Typography>Are you sure you would like to cancel task?</Typography>
</ConfirmationDialog>
)}
</>
);
}
Loading

0 comments on commit dce245b

Please sign in to comment.