-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate robot table to datagrid (#713)
* Add robot table datagrid file in order to migrate html table to datagrid Signed-off-by: angatupyry <[email protected]> * Export new react-datagrid-table component Signed-off-by: angatupyry <[email protected]> * Use robotDatagridTable component instead of Table Signed-off-by: angatupyry <[email protected]> * Remove pagination options Signed-off-by: angatupyry <[email protected]> * Use robot table interface and remove pagination options Signed-off-by: angatupyry <[email protected]> * Remove paginations options Signed-off-by: angatupyry <[email protected]> * Remove robot table and use datagrid instead Signed-off-by: angatupyry <[email protected]> * Add rowsPerPageOptions and set it with the same value of pageSize Signed-off-by: angatupyry <[email protected]> * Add new component test file Signed-off-by: angatupyry <[email protected]> * Add new component storybook file Signed-off-by: angatupyry <[email protected]> --------- Signed-off-by: angatupyry <[email protected]>
- Loading branch information
1 parent
14c4211
commit 161e7e3
Showing
5 changed files
with
273 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './robot-info'; | ||
export * from './robot-table'; | ||
export * from './robot-table-datagrid'; | ||
export * from './utils'; |
83 changes: 83 additions & 0 deletions
83
packages/react-components/lib/robots/robot-table-datagrid.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { render } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { Status2 as RobotStatus } from 'api-client'; | ||
import React from 'react'; | ||
import { RobotTableData } from './robot-table'; | ||
import { makeRobot } from './test-utils.spec'; | ||
import { RobotDataGridTable } from './robot-table-datagrid'; | ||
|
||
const allStatuses = Object.values(RobotStatus) as RobotStatus[]; | ||
|
||
describe('RobotTable', () => { | ||
it('shows all robots', () => { | ||
const robots = [makeRobot({ name: 'test_robot1' }), makeRobot({ name: 'test_robot2' })]; | ||
const tableData: RobotTableData[] = robots.map((robot) => ({ | ||
fleet: 'test_fleet', | ||
name: robot.name, | ||
})); | ||
const root = render(<RobotDataGridTable robots={tableData} />); | ||
expect(root.getByText('test_robot1')).toBeTruthy(); | ||
expect(root.getByText('test_robot2')).toBeTruthy(); | ||
}); | ||
|
||
it('smoke test for different robot status', () => { | ||
const robots = allStatuses.map((status) => makeRobot({ name: `${status}_robot`, status })); | ||
render( | ||
<RobotDataGridTable | ||
robots={robots.map((robot) => ({ | ||
fleet: 'test_fleet', | ||
name: robot.name, | ||
status: robot.status, | ||
}))} | ||
/>, | ||
); | ||
}); | ||
|
||
it('onRobotClick is called when row is clicked', () => { | ||
const onRobotClick = jasmine.createSpy(); | ||
const root = render( | ||
<RobotDataGridTable | ||
robots={[{ fleet: 'test_fleet', name: 'test_robot' }]} | ||
onRobotClick={onRobotClick} | ||
/>, | ||
); | ||
const robot = root.getByText('test_robot'); | ||
userEvent.click(robot); | ||
expect(onRobotClick).toHaveBeenCalled(); | ||
}); | ||
|
||
it('finish time is shown when it is available', () => { | ||
const root = render( | ||
<RobotDataGridTable | ||
robots={[ | ||
{ fleet: 'test_fleet', name: 'test_robot', estFinishTime: 1000, lastUpdateTime: 900 }, | ||
]} | ||
/>, | ||
); | ||
// TODO: use a less convoluted test when | ||
// https://github.com/testing-library/react-testing-library/issues/1160 | ||
// is resolved. | ||
expect(() => | ||
root.getByText((_, node) => { | ||
if (!node) { | ||
return false; | ||
} | ||
const hasText = (node) => node.textContent === new Date(1000).toLocaleString(); | ||
const nodeHasText = hasText(node); | ||
const childrenDontHaveText = Array.from(node.children).every((child) => !hasText(child)); | ||
return nodeHasText && childrenDontHaveText; | ||
}), | ||
).not.toThrow(); | ||
expect(() => | ||
root.getByText((_, node) => { | ||
if (!node) { | ||
return false; | ||
} | ||
const hasText = (node) => node.textContent === new Date(900).toLocaleString(); | ||
const nodeHasText = hasText(node); | ||
const childrenDontHaveText = Array.from(node.children).every((child) => !hasText(child)); | ||
return nodeHasText && childrenDontHaveText; | ||
}), | ||
).not.toThrow(); | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
packages/react-components/lib/robots/robot-table-datagrid.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react'; | ||
import { RobotDataGridTable } from './robot-table-datagrid'; | ||
import { Status2 as RobotStatus } from 'api-client'; | ||
import { RobotTableData } from './robot-table'; | ||
|
||
// Define the stories | ||
storiesOf('Components/RobotDataGridTable', module).add('Default', () => { | ||
const robots: RobotTableData[] = [ | ||
{ | ||
fleet: 'Fleet A', | ||
name: 'Robot 1', | ||
estFinishTime: new Date('2023-05-01T09:00:00').getTime(), | ||
battery: 0.8, | ||
lastUpdateTime: new Date('2023-05-01T08:30:00').getTime(), | ||
status: RobotStatus.Working, | ||
}, | ||
{ | ||
fleet: 'Fleet B', | ||
name: 'Robot 2', | ||
estFinishTime: new Date('2023-05-01T10:30:00').getTime(), | ||
battery: 0.6, | ||
lastUpdateTime: new Date('2023-05-01T10:00:00').getTime(), | ||
status: RobotStatus.Charging, | ||
}, | ||
{ | ||
fleet: 'Fleet A', | ||
name: 'Robot 3', | ||
estFinishTime: new Date('2023-05-01T11:45:00').getTime(), | ||
battery: 0.9, | ||
lastUpdateTime: new Date('2023-05-01T11:30:00').getTime(), | ||
status: RobotStatus.Idle, | ||
}, | ||
]; | ||
|
||
return <RobotDataGridTable robots={robots} />; | ||
}); |
149 changes: 149 additions & 0 deletions
149
packages/react-components/lib/robots/robot-table-datagrid.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
import { | ||
DataGrid, | ||
GridColDef, | ||
GridEventListener, | ||
GridValueGetterParams, | ||
MuiEvent, | ||
GridRowParams, | ||
GridCellParams, | ||
} from '@mui/x-data-grid'; | ||
import { styled } from '@mui/material'; | ||
import * as React from 'react'; | ||
import { Status2 } from 'api-client'; | ||
import { RobotTableData } from './robot-table'; | ||
|
||
const classes = { | ||
robotErrorCell: 'MuiDataGrid-cell-error-cell', | ||
robotChargingCell: 'MuiDataGrid-cell-charging-cell', | ||
robotWorkingCell: 'MuiDataGrid-cell-working-cell', | ||
robotIdleCell: 'MuiDataGrid-cell-idle-cell', | ||
robotOfflineCell: 'MuiDataGrid-cell-offline-cell', | ||
robotShutdownCell: 'MuiDataGrid-cell-shutdown-cell', | ||
robotDefaultCell: 'MuiDataGrid-cell-defautl-cell', | ||
}; | ||
|
||
const StyledDataGrid = styled(DataGrid)(({ theme }) => ({ | ||
[`& .${classes.robotErrorCell}`]: { | ||
backgroundColor: theme.palette.error.main, | ||
color: theme.palette.getContrastText(theme.palette.success.light), | ||
}, | ||
[`& .${classes.robotChargingCell}`]: { | ||
backgroundColor: theme.palette.info.main, | ||
color: theme.palette.getContrastText(theme.palette.grey[500]), | ||
}, | ||
[`& .${classes.robotWorkingCell}`]: { | ||
backgroundColor: theme.palette.success.main, | ||
color: theme.palette.getContrastText(theme.palette.info.light), | ||
}, | ||
[`& .${classes.robotDefaultCell}`]: { | ||
backgroundColor: theme.palette.warning.main, | ||
color: theme.palette.getContrastText(theme.palette.warning.main), | ||
}, | ||
})); | ||
|
||
export interface RobotDataGridTableProps { | ||
onRobotClick?(ev: MuiEvent<React.MouseEvent<HTMLElement>>, robotName: RobotTableData): void; | ||
robots: RobotTableData[]; | ||
} | ||
|
||
export function RobotDataGridTable({ onRobotClick, robots }: RobotDataGridTableProps): JSX.Element { | ||
const handleEvent: GridEventListener<'rowClick'> = ( | ||
params: GridRowParams, | ||
event: MuiEvent<React.MouseEvent<HTMLElement>>, | ||
) => { | ||
if (onRobotClick) { | ||
onRobotClick(event, params.row); | ||
} | ||
}; | ||
|
||
const columns: GridColDef[] = [ | ||
{ | ||
field: 'fleet', | ||
headerName: 'Fleet', | ||
width: 90, | ||
valueGetter: (params: GridValueGetterParams) => params.row.fleet, | ||
flex: 1, | ||
filterable: true, | ||
}, | ||
{ | ||
field: 'name', | ||
headerName: 'Robot Name', | ||
width: 150, | ||
editable: false, | ||
valueGetter: (params: GridValueGetterParams) => params.row.name, | ||
flex: 1, | ||
filterable: true, | ||
}, | ||
{ | ||
field: 'estFinishTime', | ||
headerName: 'Est. Task Finish Time', | ||
width: 150, | ||
editable: false, | ||
valueGetter: (params: GridValueGetterParams) => | ||
params.row.estFinishTime ? new Date(params.row.estFinishTime).toLocaleString() : '-', | ||
flex: 1, | ||
filterable: true, | ||
}, | ||
{ | ||
field: 'battery', | ||
headerName: 'Battery', | ||
width: 150, | ||
editable: false, | ||
valueGetter: (params: GridValueGetterParams) => (params.row.battery * 100).toFixed(2), | ||
flex: 1, | ||
filterable: true, | ||
}, | ||
{ | ||
field: 'lastUpdateTime', | ||
headerName: 'Last Updated', | ||
width: 150, | ||
editable: false, | ||
valueGetter: (params: GridValueGetterParams) => | ||
params.row.lastUpdateTime ? new Date(params.row.lastUpdateTime).toLocaleString() : '-', | ||
flex: 1, | ||
filterable: true, | ||
}, | ||
{ | ||
field: 'status', | ||
headerName: 'Status', | ||
editable: false, | ||
flex: 1, | ||
filterable: true, | ||
}, | ||
]; | ||
|
||
return ( | ||
<div style={{ height: '100%', width: '100%' }}> | ||
<StyledDataGrid | ||
autoHeight={true} | ||
getRowId={(r) => r.name} | ||
rows={robots} | ||
pageSize={5} | ||
rowHeight={38} | ||
columns={columns} | ||
rowsPerPageOptions={[5]} | ||
onRowClick={handleEvent} | ||
getCellClassName={(params: GridCellParams<string>) => { | ||
if (params.field === 'status') { | ||
switch (params.value) { | ||
case Status2.Error: | ||
return classes.robotErrorCell; | ||
case Status2.Charging: | ||
return classes.robotChargingCell; | ||
case Status2.Working: | ||
return classes.robotWorkingCell; | ||
case Status2.Idle: | ||
case Status2.Offline: | ||
case Status2.Shutdown: | ||
case Status2.Uninitialized: | ||
return classes.robotDefaultCell; | ||
default: | ||
return classes.robotDefaultCell; | ||
} | ||
} | ||
return ''; | ||
}} | ||
/> | ||
</div> | ||
); | ||
} |