diff --git a/package-lock.json b/package-lock.json index 873a3ac5..86be79da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3658,26 +3658,32 @@ } }, "@material-ui/data-grid": { - "version": "4.0.0-alpha.19", - "resolved": "https://registry.npmjs.org/@material-ui/data-grid/-/data-grid-4.0.0-alpha.19.tgz", - "integrity": "sha512-DqBbRZPAREti4XM/AbaUy8hLaNMAvZLUbwQ82UWGkwkv5zF6fhtSEl51W/q+bkvpLwok6SuJyJvoUE5zrlmaUw==", + "version": "4.0.0-alpha.33", + "resolved": "https://registry.npmjs.org/@material-ui/data-grid/-/data-grid-4.0.0-alpha.33.tgz", + "integrity": "sha512-aIZvqcYCmttTYsbwcMEcT+OIa8oZQH5BdOAylvcvl1MtoL6VNTmHbsB7N7iAxrnChLJZq9ChkXh3boQsnMgt0g==", "requires": { "@material-ui/utils": "^5.0.0-alpha.14", + "clsx": "^1.0.4", "prop-types": "^15.7.2", "reselect": "^4.0.0" }, "dependencies": { "@material-ui/utils": { - "version": "5.0.0-alpha.24", - "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-5.0.0-alpha.24.tgz", - "integrity": "sha512-di0zaQKHiRi6NwPAt/4mRNfUYTa5aWVTqfzTYN/OdnQTGtOLPPFo9Om+uYgkunZIOa3lsahveo6ieH/YgFnJfQ==", + "version": "5.0.0-beta.0", + "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-5.0.0-beta.0.tgz", + "integrity": "sha512-eBBqd+53NBUCgTU6TFGlhN0GsAPmnrHwdVBW6y4t/jP6sEXgDjVaJm5FKSYKkkCl+iRfZEAfdYyCeAn04eummw==", "requires": { "@babel/runtime": "^7.4.4", "@types/prop-types": "^15.7.3", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.7.2", - "react-is": "^16.8.0 || ^17.0.0" + "react-is": "^17.0.0" } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" } } }, @@ -4866,9 +4872,9 @@ } }, "@types/react-is": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.0.tgz", - "integrity": "sha512-A0DQ1YWZ0RG2+PV7neAotNCIh8gZ3z7tQnDJyS2xRPDNtAtSPcJ9YyfMP8be36Ha0kQRzbZCrrTMznA4blqO5g==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-X6jVqDIibL2sY0Qtth5EzNeUgPyoCWeBZdmE5xKr7hI4zaQDwN0VaQd7pJnlOB0mDGnOVH0cZZVXg9cnWhztQg==", "requires": { "@types/react": "*" } @@ -22051,7 +22057,8 @@ }, "ssri": { "version": "6.0.1", - "resolved": "", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "requires": { "figgy-pudding": "^3.5.1" } diff --git a/package.json b/package.json index 62799bb0..a2801eb6 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@material-ui/core": "^4.11.2", - "@material-ui/data-grid": "^4.0.0-alpha.19", + "@material-ui/data-grid": "^4.0.0-alpha.33", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.57", "@testing-library/jest-dom": "^5.11.1", diff --git a/src/components/TestDetailsDialog/index.tsx b/src/components/TestDetailsDialog/index.tsx index e355a6f8..cefbfb57 100644 --- a/src/components/TestDetailsDialog/index.tsx +++ b/src/components/TestDetailsDialog/index.tsx @@ -12,7 +12,16 @@ const useStyles = makeStyles((theme) => ({ export const TestDetailsDialog: React.FunctionComponent = () => { const classes = useStyles(); - const { testRuns, selectedTestRunId } = useTestRunState(); + const { + testRuns: allTestRuns, + filteredTestRuns, + selectedTestRunId, + } = useTestRunState(); + + const testRuns = React.useMemo(() => filteredTestRuns ?? allTestRuns, [ + allTestRuns, + filteredTestRuns, + ]); const selectedTestRunIndex = React.useMemo( () => testRuns.findIndex((t) => t.id === selectedTestRunId), diff --git a/src/components/TestRunList/BulkOperation.tsx b/src/components/TestRunList/BulkOperation.tsx index 85bbc276..5f9c2ae1 100644 --- a/src/components/TestRunList/BulkOperation.tsx +++ b/src/components/TestRunList/BulkOperation.tsx @@ -5,7 +5,11 @@ import { Tooltip, LinearProgress, } from "@material-ui/core"; -import { BaseComponentProps, RowModel } from "@material-ui/data-grid"; +import { + GridRowData, + GridSelectionState, + useGridSlotComponentProps, +} from "@material-ui/data-grid"; import { BaseModal } from "../BaseModal"; import { useSnackbar } from "notistack"; import { Delete, LayersClear, ThumbDown, ThumbUp } from "@material-ui/icons"; @@ -13,9 +17,8 @@ import { testRunService } from "../../services"; import { TestStatus } from "../../types"; import { head } from "lodash"; -export const BulkOperation: React.FunctionComponent = ( - props: BaseComponentProps -) => { +export const BulkOperation: React.FunctionComponent = () => { + const props = useGridSlotComponentProps(); const { enqueueSnackbar } = useSnackbar(); const [approveDialogOpen, setApproveDialogOpen] = React.useState(false); const [rejectDialogOpen, setRejectDialogOpen] = React.useState(false); @@ -31,7 +34,7 @@ export const BulkOperation: React.FunctionComponent = ( const isMerge: boolean = React.useMemo( () => !!head( - props.rows.filter((value: RowModel) => + props.rows.filter((value: GridRowData) => ids.includes(value.id.toString()) ) )?.merge, @@ -42,18 +45,18 @@ export const BulkOperation: React.FunctionComponent = ( () => props.rows .filter( - (value: RowModel) => + (value: GridRowData) => ids.includes(value.id.toString()) && [TestStatus.new, TestStatus.unresolved].includes( value.status.toString() ) ) - .map((value: RowModel) => value.id.toString()), + .map((value: GridRowData) => value.id.toString()), // eslint-disable-next-line [ids] ); - const selectedRows: Record = props.state.selection; + const selectedRows: GridSelectionState = props.state.selection; const count = Object.keys(selectedRows).length; const toggleApproveDialogOpen = () => { diff --git a/src/components/TestRunList/DataGridCustomToolbar.tsx b/src/components/TestRunList/DataGridCustomToolbar.tsx index 9d759e68..88b324ba 100644 --- a/src/components/TestRunList/DataGridCustomToolbar.tsx +++ b/src/components/TestRunList/DataGridCustomToolbar.tsx @@ -1,22 +1,19 @@ import React from "react"; import { Toolbar, Box } from "@material-ui/core"; import { - BaseComponentProps, - DensitySelector, - FilterToolbarButton, + GridToolbarDensitySelector, + GridToolbarFilterButton, } from "@material-ui/data-grid"; import { BulkOperation } from "./BulkOperation"; -export const DataGridCustomToolbar: React.FunctionComponent = ( - props: BaseComponentProps -) => { +export const DataGridCustomToolbar: React.FunctionComponent = () => { return ( <> - - + + - + diff --git a/src/components/TestRunList/StatusFilterOperators.tsx b/src/components/TestRunList/StatusFilterOperators.tsx index a6ffe80a..18303f1b 100644 --- a/src/components/TestRunList/StatusFilterOperators.tsx +++ b/src/components/TestRunList/StatusFilterOperators.tsx @@ -2,12 +2,12 @@ import { FormControl, InputLabel, Select } from "@material-ui/core"; import React from "react"; import { useTestRunState } from "../../contexts"; import { - FilterInputValueProps, - getStringOperators, + GridFilterInputValueProps, + getGridStringOperators, } from "@material-ui/data-grid"; import { TestStatus } from "../../types"; -const StatusInputComponent = (props: FilterInputValueProps) => { +const StatusInputComponent = (props: GridFilterInputValueProps) => { const { item, applyValue } = props; const { testRuns } = useTestRunState(); @@ -42,7 +42,7 @@ const StatusInputComponent = (props: FilterInputValueProps) => { ); }; -export const StatusFilterOperators = getStringOperators() +export const StatusFilterOperators = getGridStringOperators() .filter((operator) => operator.value === "equals") .map((operator) => ({ ...operator, diff --git a/src/components/TestRunList/TagFilterOperators.tsx b/src/components/TestRunList/TagFilterOperators.tsx index c3ef8a9e..7d598aa2 100644 --- a/src/components/TestRunList/TagFilterOperators.tsx +++ b/src/components/TestRunList/TagFilterOperators.tsx @@ -2,11 +2,11 @@ import { FormControl, InputLabel, Select } from "@material-ui/core"; import React from "react"; import { useTestRunState } from "../../contexts"; import { - FilterInputValueProps, - getStringOperators, + GridFilterInputValueProps, + getGridStringOperators, } from "@material-ui/data-grid"; -const TagInputComponent = (props: FilterInputValueProps) => { +const TagInputComponent = (props: GridFilterInputValueProps) => { const { item, applyValue } = props; const { testRuns } = useTestRunState(); @@ -51,7 +51,7 @@ const TagInputComponent = (props: FilterInputValueProps) => { ); }; -export const TagFilterOperators = getStringOperators() +export const TagFilterOperators = getGridStringOperators() .filter((operator) => operator.value === "contains") .map((operator) => ({ ...operator, diff --git a/src/components/TestRunList/index.tsx b/src/components/TestRunList/index.tsx index 286b2974..3ff3c621 100644 --- a/src/components/TestRunList/index.tsx +++ b/src/components/TestRunList/index.tsx @@ -11,22 +11,26 @@ import { import { useSnackbar } from "notistack"; import { DataGrid, - ColDef, - RowParams, - CellParams, + GridCellParams, + GridColDef, + GridRowParams, + GridValueGetterParams, + GridValueFormatterParams, + GridFilterModelParams, } from "@material-ui/data-grid"; import { DataGridCustomToolbar } from "./DataGridCustomToolbar"; import { StatusFilterOperators } from "./StatusFilterOperators"; import { TagFilterOperators } from "./TagFilterOperators"; +import { TestRun } from "../../types"; -const columnsDef: ColDef[] = [ +const columnsDef: GridColDef[] = [ { field: "id", hide: true, filterable: false }, { field: "name", headerName: "Name", flex: 1 }, { field: "tags", headerName: "Tags", flex: 1, - valueGetter: (params: CellParams) => { + valueGetter: (params: GridValueGetterParams) => { const tags: Array = [ params.row["os"], params.row["device"], @@ -39,10 +43,10 @@ const columnsDef: ColDef[] = [ "" ); }, - renderCell: (params: CellParams) => ( + renderCell: (params: GridCellParams) => ( {params - .getValue("tags") + .getValue(params.id, "tags") ?.toString() .split(";") .map( @@ -64,8 +68,12 @@ const columnsDef: ColDef[] = [ field: "status", headerName: "Status", flex: 0.3, - renderCell: (params: CellParams) => { - return ; + renderCell: (params: GridValueFormatterParams) => { + return ( + + ); }, filterOperators: StatusFilterOperators, }, @@ -101,7 +109,6 @@ const TestRunList: React.FunctionComponent = () => { pageSize={10} rowsPerPageOptions={[10, 20, 30]} loading={loading} - showToolbar={true} components={{ Toolbar: DataGridCustomToolbar, }} @@ -109,8 +116,19 @@ const TestRunList: React.FunctionComponent = () => { disableColumnSelector disableColumnMenu disableSelectionOnClick - onRowClick={(param: RowParams) => { - selectTestRun(testRunDispatch, param.getValue("id")?.toString()); + onRowClick={(param: GridRowParams) => { + selectTestRun( + testRunDispatch, + param.getValue(param.id, "id")?.toString() + ); + }} + onFilterModelChange={(params: GridFilterModelParams) => { + testRunDispatch({ + type: "filter", + payload: Array.from( + params.visibleRows.values() + ) as Array, + }); }} /> )} diff --git a/src/contexts/testRun.context.tsx b/src/contexts/testRun.context.tsx index 923efaee..80ef3bca 100644 --- a/src/contexts/testRun.context.tsx +++ b/src/contexts/testRun.context.tsx @@ -47,6 +47,11 @@ interface IRejectAction { payload: TestRun; } +interface IFilterAction { + type: "filter"; + payload: Array; +} + type IAction = | IRequestAction | IGetAction @@ -55,11 +60,13 @@ type IAction = | IUpdateAction | IApproveAction | IRejectAction + | IFilterAction | ISelectAction; type Dispatch = (action: IAction) => void; type State = { selectedTestRunId?: string; + filteredTestRuns?: Array; testRuns: Array; loading: boolean; }; @@ -83,6 +90,11 @@ function testRunReducer(state: State, action: IAction): State { ...state, selectedTestRunId: action.payload, }; + case "filter": + return { + ...state, + filteredTestRuns: action.payload, + }; case "request": return { ...state,