Skip to content

Commit

Permalink
Port/date initiator columns (#702)
Browse files Browse the repository at this point in the history
* Date column in Tasks section (#689)

* Add unix-millis-request-time field in taskstate

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

* Generate taskstate model according to the rmf_api_msgs changes

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

* Generate api client to get the new field

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

* Save unix request time as now() and use previous value if the method is update

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

* Show unix_millis_request_time in dashboard

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

* Add Unix_millis_request_time into booking instead of taskstate directly

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

* Access to unix_millis_request_time field through booking

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

* Get previous task_state and if is not none use its request_time value

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

---------

Signed-off-by: fierro <fierrofenix@gmail.com>
(cherry picked from commit 7ea986d)
Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Fix/request date export (#690)

* Added date column to minimal export, only update fields of task state when it has not been created before

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

* Use create and get_or_none, and save model if it exists

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

---------

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>
(cherry picked from commit a1ea778)
Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Feature/task initiator (#692)

* Add initiator column in taskstate model

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

* Initiator field has been added on client side

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

* Set initiator field with the previous value if its is updated or use self.user.username if its is created

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

* Add initiator as column in datagrid and show it in TaskSection

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

* Populate initiator field with self.user.name when task is created

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

* Add initiator column to minimal export

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

* Set initiator column to minimal export

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

* In update method, fill the initiator field with the previous db_task_state value

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

---------

Signed-off-by: fierro <fierrofenix@gmail.com>
(cherry picked from commit 86700da)
Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Adding user and request time to requests before submitting

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

* api-server, use requester instead of initiator for task_request and task_state

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

* Initiator to Requester

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

* Update api-client

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

* Using N/A instead of unknown for fields

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

* pylint

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

* Changing N/A to unknown

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

* Adding try catch for username promise

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

---------

Signed-off-by: fierro <fierrofenix@gmail.com>
Signed-off-by: Aaron Chong <aaronchongth@gmail.com>
Co-authored-by: César Rolón <37310205+Angatupyry@users.noreply.github.com>
  • Loading branch information
aaronchongth and Angatupyry authored Jul 4, 2023
1 parent bd1b279 commit b39540c
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 14 deletions.
32 changes: 28 additions & 4 deletions packages/api-client/lib/openapi/api.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/api-client/lib/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { version as rmfModelVer } from 'rmf-models';

export const version = {
rmfModels: rmfModelVer,
rmfServer: '3bf607613b024426c272808520a476744fc80f3e',
rmfServer: 'edde41e899bcd3ad5d9b6b4c51c482032aa39993',
openapiGenerator: '6.2.1',
};
18 changes: 17 additions & 1 deletion packages/api-client/schema/index.ts

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions packages/api-server/api_server/models/rmf_api/task_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class TaskRequest(BaseModel):
unix_millis_earliest_start_time: Optional[int] = Field(
None, description="(Optional) The earliest time that this task may start"
)
unix_millis_request_time: Optional[int] = Field(
None, description="(Optional) The time that this request was initiated"
)
priority: Optional[Dict[str, Any]] = Field(
None,
description="(Optional) The priority of this task. This must match a priority schema supported by a fleet.",
Expand All @@ -24,3 +27,7 @@ class TaskRequest(BaseModel):
labels: Optional[List[str]] = Field(
None, description="Labels to describe the purpose of the task dispatch request"
)
requester: Optional[str] = Field(
None,
description="(Optional) An identifier for the entity that requested this task",
)
17 changes: 11 additions & 6 deletions packages/api-server/api_server/models/rmf_api/task_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@ class Killed(BaseModel):
class Booking(BaseModel):
id: str = Field(..., description="The unique identifier for this task")
unix_millis_earliest_start_time: Optional[int] = None
unix_millis_request_time: Optional[int] = None
priority: Optional[Union[Dict[str, Any], str]] = Field(
None, description="Priority information about this task"
)
labels: Optional[List[str]] = Field(
None, description="Information about how and why this task was booked"
)
requester: Optional[str] = Field(
None,
description="(Optional) An identifier for the entity that requested this task",
)


class Category(BaseModel):
Expand All @@ -64,6 +69,12 @@ class Assignment(BaseModel):
expected_robot_name: Optional[str] = None


class Dispatch(BaseModel):
status: Status1
assignment: Optional[Assignment] = None
errors: Optional[List[error.Error]] = None


class EstimateMillis(BaseModel):
__root__: conint(ge=0) = Field(
...,
Expand Down Expand Up @@ -145,12 +156,6 @@ class SkipPhaseRequest(BaseModel):
)


class Dispatch(BaseModel):
status: Status1
assignment: Optional[Assignment] = None
errors: Optional[List[error.Error]] = None


class Phase(BaseModel):
id: Id
category: Optional[Category] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class TaskState(Model):
unix_millis_start_time = DatetimeField(null=True, index=True)
unix_millis_finish_time = DatetimeField(null=True, index=True)
status = CharField(255, null=True, index=True)
unix_millis_request_time = DatetimeField(null=True, index=True)
requester = CharField(255, null=True, index=True)


class TaskEventLog(Model):
Expand Down
9 changes: 8 additions & 1 deletion packages/api-server/api_server/repositories/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, user: User):
self.user = user

async def save_task_state(self, task_state: TaskState) -> None:
await ttm.TaskState.update_or_create(
await DbTaskState.update_or_create(
{
"data": task_state.json(),
"category": task_state.category.__root__
Expand All @@ -45,6 +45,13 @@ async def save_task_state(self, task_state: TaskState) -> None:
"unix_millis_finish_time": task_state.unix_millis_finish_time
and datetime.fromtimestamp(task_state.unix_millis_finish_time / 1000),
"status": task_state.status if task_state.status else None,
"unix_millis_request_time": task_state.booking.unix_millis_request_time
and datetime.fromtimestamp(
task_state.booking.unix_millis_request_time / 1000
),
"requester": task_state.booking.requester
if task_state.booking.requester
else None,
},
id_=task_state.booking.id,
)
Expand Down
16 changes: 16 additions & 0 deletions packages/dashboard/src/components/appbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea
const [workcells, setWorkcells] = React.useState<string[]>();
const [favoritesTasks, setFavoritesTasks] = React.useState<TaskFavorite[]>([]);
const [refreshTaskAppCount, setRefreshTaskAppCount] = React.useState(0);
const [username, setUsername] = React.useState<string | null>(null);
const [alertListAnchor, setAlertListAnchor] = React.useState<HTMLElement | null>(null);
const [unacknowledgedAlertsNum, setUnacknowledgedAlertsNum] = React.useState(0);
const [unacknowledgedAlertList, setUnacknowledgedAlertList] = React.useState<Alert[]>([]);
Expand All @@ -180,6 +181,20 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea
}
}

React.useEffect(() => {
if (!rmf) {
return;
}
(async () => {
try {
const user = (await rmf.defaultApi.getUserUserGet()).data;
setUsername(user.username);
} catch (e) {
console.log(`error getting username: ${(e as Error).message}`);
}
})();
}, [rmf]);

React.useEffect(() => {
const sub = AppEvents.refreshTaskAppCount.subscribe((currentValue) => {
setRefreshTaskAppCount(currentValue);
Expand Down Expand Up @@ -557,6 +572,7 @@ export const AppBar = React.memo(({ extraToolbarItems }: AppBarProps): React.Rea
</Menu>
{openCreateTaskForm && (
<CreateTaskForm
user={username ? username : 'unknown user'}
cleaningZones={placeNames}
loopWaypoints={placeNames}
deliveryWaypoints={placeNames}
Expand Down
15 changes: 14 additions & 1 deletion packages/dashboard/src/components/tasks/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,23 @@ export function downloadCsvFull(timestamp: Date, allTasks: TaskState[]) {
export function downloadCsvMinimal(timestamp: Date, allTasks: TaskState[]) {
const columnSeparator = ';';
const rowSeparator = '\n';
const keys = ['ID', 'Category', 'Assignee', 'Start Time', 'End Time', 'State'];
const keys = [
'Date',
'Requester',
'ID',
'Category',
'Assignee',
'Start Time',
'End Time',
'State',
];
let csvContent = keys.join(columnSeparator) + rowSeparator;
allTasks.forEach((task) => {
const values = [
task.booking.unix_millis_request_time
? `${new Date(task.booking.unix_millis_request_time).toLocaleDateString()}`
: 'unknown',
task.booking.requester ? task.booking.requester : 'unknown',
task.booking.id,
task.category ? task.category : 'unknown',
task.assigned_to ? task.assigned_to.name : 'unknown',
Expand Down
9 changes: 9 additions & 0 deletions packages/react-components/lib/tasks/create-task.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,9 @@ function defaultTask(): TaskRequest {
category: 'patrol',
description: defaultLoopTask(),
unix_millis_earliest_start_time: 0,
unix_millis_request_time: Date.now(),
priority: { type: 'binary', value: 0 },
requester: '',
};
}

Expand Down Expand Up @@ -758,6 +760,7 @@ export interface CreateTaskFormProps
/**
* Shows extra UI elements suitable for submittng batched tasks. Default to 'false'.
*/
user: string;
allowBatch?: boolean;
cleaningZones?: string[];
loopWaypoints?: string[];
Expand All @@ -778,6 +781,7 @@ export interface CreateTaskFormProps
}

export function CreateTaskForm({
user,
cleaningZones = [],
loopWaypoints = [],
deliveryWaypoints = [],
Expand Down Expand Up @@ -894,6 +898,11 @@ export function CreateTaskForm({
return;
}

for (const t of taskRequests) {
t.requester = user;
t.unix_millis_request_time = Date.now();
}

const submittingSchedule = scheduling && scheduleEnabled;
try {
setSubmitting(true);
Expand Down
36 changes: 36 additions & 0 deletions packages/react-components/lib/tasks/task-table-datagrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,42 @@ export function TaskDataGridTable({
);

const columns: GridColDef[] = [
{
field: 'unix_millis_request_time',
headerName: 'Date',
width: 150,
editable: false,
renderCell: (cellValues) => {
return (
<TextField
variant="standard"
value={
cellValues.row.booking.unix_millis_request_time
? `${new Date(
cellValues.row.booking.unix_millis_request_time,
).toLocaleDateString()}`
: 'unknown'
}
InputProps={{ disableUnderline: true }}
multiline
/>
);
},
flex: 1,
filterOperators: getMinimalDateOperators,
filterable: true,
},
{
field: 'requester',
headerName: 'Requester',
width: 150,
editable: false,
valueGetter: (params: GridValueGetterParams) =>
params.row.booking.requester ? params.row.booking.requester : 'unknown',
flex: 1,
filterOperators: getMinimalStringFilterOperators,
filterable: true,
},
{
field: 'id_',
headerName: 'ID',
Expand Down

0 comments on commit b39540c

Please sign in to comment.