Skip to content

Commit

Permalink
Merge pull request #84 from ceph/custom-filter
Browse files Browse the repository at this point in the history
  • Loading branch information
zmc authored Nov 21, 2024
2 parents 9a03741 + 9d6cacc commit 238f606
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 12 deletions.
156 changes: 145 additions & 11 deletions src/components/RunList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { useMemo } from 'react';
import { SetStateAction, useMemo } from 'react';
import { useState } from "react";
import OpenInNewIcon from "@mui/icons-material/OpenInNew";
import Grid from '@mui/material/Grid';
import Button from '@mui/material/Button';
import type {
DecodedValueMap,
QueryParamConfigMap,
Expand All @@ -9,11 +12,13 @@ import { useDebounce } from "usehooks-ts";
import {
useMaterialReactTable,
MaterialReactTable,
MRT_TableHeadCellFilterContainer,
type MRT_ColumnDef,
type MRT_PaginationState,
type MRT_Updater,
type MRT_ColumnFiltersState,
type MRT_TableOptions,
type MRT_TableInstance,
} from 'material-react-table';
import { type Theme } from "@mui/material/styles";
import { parse } from "date-fns";
Expand All @@ -31,6 +36,10 @@ import {
RunStatuses,
} from "../../lib/paddles.d";
import useDefaultTableOptions from "../../lib/table";
import Typography from '@mui/material/Typography';
import Box from '@mui/material/Box';
import Badge from '@mui/material/Badge';
import Menu from '@mui/material/Menu';


const DEFAULT_PAGE_SIZE = 25;
Expand All @@ -45,7 +54,6 @@ const _columns: MRT_ColumnDef<Run>[] = [
header: "link",
maxSize: 12,
enableColumnFilter: false,
enableColumnActions: false,
Cell: ({ row }) => {
return (
<IconLink to={`/runs/${row.original.name}`}>
Expand All @@ -62,14 +70,14 @@ const _columns: MRT_ColumnDef<Run>[] = [
return row.original.status.replace("finished ", "");
},
filterSelectOptions: Object.values(RunStatuses),
size: 40,
enableColumnActions: false,
maxSize: 25,
},
{
accessorKey: "user",
header: "user",
maxSize: 45,
enableColumnActions: false,
enableColumnFilter: false,
},
{
id: "scheduled",
Expand All @@ -81,23 +89,23 @@ const _columns: MRT_ColumnDef<Run>[] = [
const date_: string[] = row.original.scheduled.split(" ");
return <div> {date_[0]} <br /> {date_[1]} </div>
},
size: 50,
size: 35,
},
{
id: "started",
header: "started",
accessorFn: (row: Run) => formatDate(row.started),
enableColumnFilter: false,
sortingFn: "datetime",
size: 125,
size: 35,
},
{
id: "posted",
header: "updated",
accessorFn: (row: Run) => formatDate(row.posted),
enableColumnFilter: false,
sortingFn: "datetime",
size: 125,
maxSize: 35,
},
{
id: "runtime",
Expand All @@ -115,16 +123,16 @@ const _columns: MRT_ColumnDef<Run>[] = [
{
accessorKey: "suite",
header: "suite",
size: 70,
size: 50,
},
{
accessorKey: "branch",
header: "branch",
maxSize: 75,
maxSize: 70,
},
{
accessorKey: "machine_type",
header: "machine_type",
header: "machine type",
size: 30,
},
{
Expand Down Expand Up @@ -200,6 +208,9 @@ type RunListProps = {
}

export default function RunList(props: RunListProps) {
const [openFilterMenu, setOpenFilterMenu] = useState<boolean>(false);
const [dropMenuAnchorEl, setDropMenuAnchor] = useState<null | HTMLElement>(null);

const { params, setter, tableOptions } = props;
const options = useDefaultTableOptions<Run>();
const debouncedParams = useDebounce(params, 500);
Expand All @@ -220,6 +231,15 @@ export default function RunList(props: RunListProps) {
pageIndex: params.page || 0,
pageSize: params.pageSize || DEFAULT_PAGE_SIZE,
};
const toggleFilterMenu = (event: { currentTarget: SetStateAction<HTMLElement | null>; }) => {
if (dropMenuAnchorEl) {
setDropMenuAnchor(null);
setOpenFilterMenu(false);
} else {
setDropMenuAnchor(event.currentTarget);
setOpenFilterMenu(true);
}
}
const onColumnFiltersChange = (updater: MRT_Updater<MRT_ColumnFiltersState>) => {
if ( ! ( updater instanceof Function ) ) return;
const result: RunListParams = {pageSize: pagination.pageSize};
Expand Down Expand Up @@ -267,12 +287,19 @@ export default function RunList(props: RunListProps) {
data: data,
manualPagination: true,
manualFiltering: true,
enableColumnActions: false,
onPaginationChange,
rowCount: Infinity,
muiPaginationProps: {
showLastButton: false,
},
onColumnFiltersChange,
columnFilterDisplayMode: 'custom',
enableColumnFilters: false,
muiFilterTextFieldProps: ({ column }) => ({
label: column.columnDef.header,
placeholder: '',
}),
initialState: {
...options.initialState,
columnVisibility: {
Expand All @@ -297,8 +324,115 @@ export default function RunList(props: RunListProps) {
if ( category ) return { className: category };
return {};
},
renderTopToolbarCustomActions: ({ table }) => (
<Box sx={{ padding: '4px' }}>
<Badge
color="primary"
overlap="circular"
badgeContent={table.getState().columnFilters.reduce((count, filter) => (filter.value ? count + 1 : count), 0)}
>
<Button
id="filter-button"
onClick={toggleFilterMenu}
>
Filters
</Button>
</Badge>
</Box>
),
...tableOptions,
});

if (query.isError) return null;
return <MaterialReactTable table={table} />
return (
<div>
<div>
<Typography variant="body2" gutterBottom color="gray" textAlign={"right"}>
{ table.getState().columnFilters.map((column) => {
let filterValue = column.value;
if (column.id == "scheduled") {
const parsedDate = new Date(column.value as string);
filterValue = (parsedDate.toISOString().split('T')[0])
}
return (column.value ? `${column.id}: '${filterValue}' ` : "")
} )}
</Typography>
<Menu
id="filter-menu"
anchorEl={dropMenuAnchorEl}
open={openFilterMenu}
onClose={toggleFilterMenu}
MenuListProps={{
'aria-labelledby': 'filter-button',
}}
>
<FilterMenu isOpen={openFilterMenu} table={table} />
</Menu>
</div>
<MaterialReactTable table={table} />
</div>
)
}


// FilterMenu

type FilterMenuProps = {
isOpen: boolean;
table: MRT_TableInstance<Run>;
};


const FILTER_SECTIONS = ["run", "build", "result"]
const FILTER_SECTIONS_COLUMNS = [
["scheduled", "suite", "machine_type", "user"],
["branch", "sha1"],
["status"],
]

function FilterMenu({ isOpen, table}: FilterMenuProps) {
if (!isOpen) {
return null;
}

return (
<Box
sx={{
padding: '1em',
margin: '0px 0.5em',
border: '2px dashed grey',
borderRadius: '8px',
}}
>
{FILTER_SECTIONS_COLUMNS.map((_, sectionIndex) => (
<Box
key={`section-${sectionIndex}`}
sx={{
marginBottom: '1em',
marginLeft: '0.5em',
}}
>
<Typography variant="body2" gutterBottom color="gray">
Filter by {FILTER_SECTIONS[sectionIndex]} details...
</Typography>
<Grid container spacing={1} alignItems="center">
{table.getLeafHeaders().map((header) => {
if (FILTER_SECTIONS_COLUMNS[sectionIndex].includes(header.id)) {
return (
<Grid item xs={2} key={header.id} marginLeft={"1.2em"}>
<MRT_TableHeadCellFilterContainer
header={header}
table={table}
style={{ backgroundColor: 'transparent', width: '100%' }}
/>
</Grid>
);
}
return null;
})}
</Grid>
</Box>
))}
</Box>
)
}
9 changes: 8 additions & 1 deletion src/lib/paddles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,19 @@ function getURL(endpoint: string, params?: GetURLParams) {
}

function useRuns(params: GetURLParams): UseQueryResult<Run[]> {
let baseUrl = "/runs/";
const params_ = { ...params };
if (params_.pageSize) {
params_.count = params.pageSize;
delete params_.pageSize;
}
const url = getURL("/runs/", params);
if (params_.machine_type) {
// this is to handle difference in machine_type filter
// in two endpoints /node/?machine_type=xyz and /runs/machine_type/xyz
baseUrl += "machine_type/" + params_.machine_type + "/";
delete params_.machine_type;
}
const url = getURL(baseUrl, params);
const query = useQuery(["runs", { url }], {
select: (data: Run[]) =>
data.map((item) => {
Expand Down
13 changes: 13 additions & 0 deletions src/lib/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ export default function useDefaultTableOptions<TData extends MRT_RowData>(): Par
mrtTheme: {
baseBackgroundColor: theme.palette.background.default,
},
muiTableHeadCellProps: {
sx: {
'& .Mui-TableHeadCell-Content': {
fontSize: "0.8em",
},
'& .MuiTableSortLabel-root': {
display: "none",
},
'&:hover .MuiTableSortLabel-root': {
display: "block",
},
},
},
muiTableBodyCellProps: {
sx: {
color: "black",
Expand Down

0 comments on commit 238f606

Please sign in to comment.