Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8351773
fix(ui): restore per-column quick filter on data grids
VibhavSetlur May 28, 2026
f652f86
feat(ui): add per-column quick search magnifying-glass to data grids
VibhavSetlur May 28, 2026
1bad1e1
fix(lint): move committedFilterRegistry read into effect to avoid ref…
VibhavSetlur May 28, 2026
37f7604
fix(ui): per-column quick filters now AND together across all data grids
VibhavSetlur May 28, 2026
b67ab00
fix(ui): per-column quick filter applies on Enter, not on keystroke
VibhavSetlur May 28, 2026
5ad0f68
fix(ui): per-column quick filters now show up in Filter & Columns pop…
VibhavSetlur May 28, 2026
70c6dd1
feat(ui): stronger active-state indicator on per-column quick filter …
VibhavSetlur May 28, 2026
9f8c6c7
fix(types): relax withQuickSearchHeaders generic to GridValidRowModel
VibhavSetlur May 28, 2026
22e5562
test(e2e): add per-column quick filter tests for Enter, AND stacking,…
VibhavSetlur May 28, 2026
af5f44c
fix(ui): global search applies on Enter, unblocking input alongside p…
VibhavSetlur May 28, 2026
13cef86
test(e2e): add comprehensive per-column quick search tests
VibhavSetlur May 28, 2026
dfc295a
test(e2e): update quick-column-filter tests with improved locators an…
VibhavSetlur May 28, 2026
4b5c6a6
fix(lint): sync ToolbarSearchField draft during render, not in effect
VibhavSetlur May 28, 2026
6251c87
feat(ui): per-column quick search popover gains operator + locked column
VibhavSetlur May 28, 2026
ec31ab8
feat(filter): add between operator, default for dates; fix boolean co…
VibhavSetlur May 28, 2026
ce9834b
fix(ui): widen column headers to accommodate quick-search icon and me…
VibhavSetlur May 28, 2026
05578be
fix(ui): autofocus value input when per-column quick filter popover o…
VibhavSetlur May 28, 2026
c053fae
fix(ui): widen remaining narrow columns for quick-search icon; simpli…
VibhavSetlur May 28, 2026
4a62f15
fix(ui): pin quick filter icon to the right edge of the column header
VibhavSetlur May 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions app/(reference-data)/biochem/compounds/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Link from 'next/link';
import { getCompounds, type Compound, type SolrQueryOpts, EXTERNAL_DBS } from '@/lib/api/biochem';
import { formatFormula } from '@/components/utils/formatFormula';
import { GridHighlightText } from '@/components/GridHighlightText';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import ExportModal from '@/components/ui/ExportModal';
import Chip from '@mui/material/Chip';

Expand Down Expand Up @@ -111,11 +111,11 @@ const columns: GridColDef<Compound>[] = [
{
field: 'formula',
headerName: 'Formula',
width: 140,
width: 160,
renderCell: (params) => formatFormula(params.value)
},
{ field: 'mass', headerName: 'Mass', width: 100, type: 'number' },
{ field: 'charge', headerName: 'Charge', width: 80, type: 'number' },
{ field: 'charge', headerName: 'Charge', width: 120, type: 'number' },
{
field: 'synonyms',
headerName: 'Synonyms',
Expand Down Expand Up @@ -252,7 +252,7 @@ export default function CompoundsPage() {

<DataGrid<Compound>
rows={data?.docs ?? []}
columns={columns}
columns={withQuickSearchHeaders(columns)}
rowCount={data?.numFound ?? 0}
loading={isFetching}
pageSizeOptions={[10, 25, 50, 100]}
Expand All @@ -271,7 +271,6 @@ export default function CompoundsPage() {
getRowHeight={() => 'auto'}
disableRowSelectionOnClick
hideFooter
disableColumnMenu
sx={{
border: '1px solid #e0e0e0',
'& .MuiDataGrid-cell': {
Expand Down
16 changes: 10 additions & 6 deletions app/(reference-data)/biochem/reactions/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import IconButton from '@mui/material/IconButton';
/* import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline'; */
/* import ReactionCommentModal from '@/components/ui/ReactionCommentModal'; */
import { GridHighlightText } from '@/components/GridHighlightText';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import ExportModal from '@/components/ui/ExportModal';
import TruncatedWithTooltip from '@/components/ui/TruncatedWithTooltip';

Expand Down Expand Up @@ -294,20 +294,25 @@ export default function ReactionsPage() {
{
field: 'is_transport',
headerName: 'Transport',
width: 90,
width: 130,
// Underlying value is a JS boolean; declaring the column type lets
// the per-column quick filter offer is/is-not (with a Yes/No
// dropdown) instead of string `contains`, which never matches
// boolean docs in Solr.
type: 'boolean',
renderCell: (params) => <GridHighlightText text={params.row.is_transport ? 'Yes' : 'No'} />,
},
{ field: 'deltag', headerName: 'ΔG', width: 80, type: 'number' },
{
field: 'status',
headerName: 'Status',
width: 110,
width: 130,
renderCell: (params) => <GridHighlightText text={params.value as string} />
},
{
field: 'ec_numbers',
headerName: 'EC Numbers',
width: 160,
width: 180,
sortable: false,
renderCell: (params) => {
const ecNumbers = params.row.ec_numbers ?? [];
Expand Down Expand Up @@ -411,7 +416,7 @@ export default function ReactionsPage() {

<DataGrid<Reaction>
rows={data?.docs ?? []}
columns={columns}
columns={withQuickSearchHeaders(columns)}
rowCount={data?.numFound ?? 0}
loading={isFetching}
pageSizeOptions={[10, 25, 50, 100]}
Expand All @@ -430,7 +435,6 @@ export default function ReactionsPage() {
getRowHeight={() => 'auto'}
disableRowSelectionOnClick
hideFooter
disableColumnMenu
sx={{
border: '1px solid #e0e0e0',
'& .MuiDataGrid-cell': {
Expand Down
5 changes: 2 additions & 3 deletions app/(reference-data)/genomes/Annotations/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Typography from '@mui/material/Typography';
import Link from 'next/link';
import { parseWorkspaceGetObject, workspaceGet } from '@/lib/api/workspace';
import { USE_NEW_PROXY } from '@/lib/api/config';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import { useToolbarGridFiltering } from '@/lib/hooks/useToolbarGridFiltering';

interface SubsystemItem {
Expand Down Expand Up @@ -201,7 +201,7 @@ export default function SubsystemsPage() {
</Typography>
<DataGrid<SubsystemItem>
rows={filteredRows}
columns={columns}
columns={withQuickSearchHeaders(columns)}
loading={isLoading}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={paginationModel}
Expand All @@ -219,7 +219,6 @@ export default function SubsystemsPage() {
},
}}
hideFooter
disableColumnMenu
getRowId={(row) => row.id}
disableRowSelectionOnClick
getRowHeight={() => 'auto'}
Expand Down
13 changes: 6 additions & 7 deletions app/(reference-data)/genomes/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Typography from '@mui/material/Typography';
import Alert from '@mui/material/Alert';
import { workspaceLs } from '@/lib/api/workspace';
import { USE_NEW_PROXY } from '@/lib/api/config';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import { useToolbarGridFiltering } from '@/lib/hooks/useToolbarGridFiltering';

interface PlantModelItem {
Expand Down Expand Up @@ -55,10 +55,10 @@ const columns: GridColDef<PlantModelItem>[] = [
)
},
{ field: 'source', headerName: 'Domain', width: 140 },
{ field: 'numReactions', headerName: 'Reactions', width: 100, type: 'number' },
{ field: 'numGenes', headerName: 'Genes', width: 80, type: 'number' },
{ field: 'fbaCount', headerName: 'FBA', width: 80, type: 'number' },
{ field: 'gapfills', headerName: 'Gapfills', width: 80, type: 'number' },
{ field: 'numReactions', headerName: 'Reactions', width: 130, type: 'number' },
{ field: 'numGenes', headerName: 'Genes', width: 110, type: 'number' },
{ field: 'fbaCount', headerName: 'FBA', width: 100, type: 'number' },
{ field: 'gapfills', headerName: 'Gapfills', width: 120, type: 'number' },
{
field: 'modDate',
headerName: 'Modification Date',
Expand Down Expand Up @@ -122,7 +122,7 @@ export default function PlantsPage() {
</Alert>
<DataGrid<PlantModelItem>
rows={filteredRows}
columns={columns}
columns={withQuickSearchHeaders(columns)}
loading={isLoading}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={paginationModel}
Expand All @@ -140,7 +140,6 @@ export default function PlantsPage() {
},
}}
hideFooter
disableColumnMenu
getRowId={(row) => row.id}
disableRowSelectionOnClick
autoHeight
Expand Down
5 changes: 2 additions & 3 deletions app/(reference-data)/list-media/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Typography from '@mui/material/Typography';
import { workspaceLs } from '@/lib/api/workspace';
import { listPublicMediaFromApi } from '@/lib/api/modelseed';
import { USE_MODELSEED_API, USE_NEW_PROXY } from '@/lib/api/config';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import { useToolbarGridFiltering } from '@/lib/hooks/useToolbarGridFiltering';

interface MediaItem {
Expand Down Expand Up @@ -112,7 +112,7 @@ export default function MediaPage() {
</Typography>
<DataGrid<MediaItem>
rows={filteredRows}
columns={columns}
columns={withQuickSearchHeaders(columns)}
loading={isLoading}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={paginationModel}
Expand All @@ -130,7 +130,6 @@ export default function MediaPage() {
},
}}
hideFooter
disableColumnMenu
getRowId={(row) => row.id}
disableRowSelectionOnClick
onRowClick={(params) => goToMediaPath(params.row.path)}
Expand Down
4 changes: 2 additions & 2 deletions app/(user-data)/my-jobs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { getJobsFromApi } from '@/lib/api/modelseed';
import { listTrackedJobs, TrackedJob } from '@/lib/api/jobTracker';
import { USE_MODELSEED_API } from '@/lib/api/config';
import AuthGuard from '@/components/auth/AuthGuard';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import ExportModal from '@/components/ui/ExportModal';
import { useToolbarGridFiltering } from '@/lib/hooks/useToolbarGridFiltering';

Expand Down Expand Up @@ -409,7 +409,7 @@ function MyJobsContent() {

<DataGrid<JobRow>
rows={filteredRows}
columns={columns}
columns={withQuickSearchHeaders(columns)}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={pagination}
onPaginationModelChange={setPagination}
Expand Down
11 changes: 5 additions & 6 deletions app/(user-data)/my-models/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { useAuth } from '@/components/auth/AuthProvider';
import DownloadModelMenu from '@/components/ui/DownloadModelMenu';
import DeleteModelModal from '@/components/ui/DeleteModelModal';
import CopyModelModal from '@/components/ui/CopyModelModal';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import { useToolbarGridFiltering } from '@/lib/hooks/useToolbarGridFiltering';
import {
isActiveJobStatus,
Expand Down Expand Up @@ -477,10 +477,10 @@ export default function MyModelsPage() {
</Link>
)
},
{ field: 'numReactions', headerName: 'Reactions', width: 100, type: 'number' },
{ field: 'numGenes', headerName: 'Genes', width: 100, type: 'number' },
{ field: 'numReactions', headerName: 'Reactions', width: 130, type: 'number' },
{ field: 'numGenes', headerName: 'Genes', width: 110, type: 'number' },
{ field: 'fbaCount', headerName: 'FBA', width: 100, type: 'number' },
{ field: 'gapfills', headerName: 'Gapfilling', width: 100, type: 'number' },
{ field: 'gapfills', headerName: 'Gapfilling', width: 130, type: 'number' },
{
field: 'status',
headerName: 'Status',
Expand Down Expand Up @@ -726,7 +726,7 @@ export default function MyModelsPage() {
) : (
<DataGrid<MyModelItem>
rows={filteredRows}
columns={columns}
columns={withQuickSearchHeaders(columns)}
loading={isLoading}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={paginationModel}
Expand All @@ -750,7 +750,6 @@ export default function MyModelsPage() {
},
}}
hideFooter
disableColumnMenu
checkboxSelection
disableMultipleRowSelection={false}
rowSelectionModel={{
Expand Down
5 changes: 2 additions & 3 deletions app/(user-data)/myMedia/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { USE_MODELSEED_API } from '@/lib/api/config';
import { exportMediaFromApi, listMyMediaFromApi } from '@/lib/api/modelseed';
import { workspaceDelete } from '@/lib/api/workspace';
import { useAuth } from '@/components/auth/AuthProvider';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import ExportModal from '@/components/ui/ExportModal';
import { parseWorkspaceDate } from '@/lib/utils/date';
import { useToolbarGridFiltering } from '@/lib/hooks/useToolbarGridFiltering';
Expand Down Expand Up @@ -268,7 +268,7 @@ export default function MyMediaPage() {
) : (
<DataGrid<MyMediaItem>
rows={filteredRows}
columns={columns}
columns={withQuickSearchHeaders(columns)}
loading={isLoading}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={paginationModel}
Expand All @@ -287,7 +287,6 @@ export default function MyMediaPage() {
},
}}
hideFooter
disableColumnMenu
getRowId={(row) => row.id}
disableRowSelectionOnClick
onRowClick={(params) => goToMediaPath(params.row.path)}
Expand Down
58 changes: 48 additions & 10 deletions app/fba/[...path]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import { useAuth } from '@/components/auth/AuthProvider';
import { workspaceGet, workspaceLs, workspaceDownloadUrl, parseWorkspaceGetObject } from '@/lib/api/workspace';
import { USE_MODELSEED_API } from '@/lib/api/config';
import ChemicalEquation from '@/components/ui/ChemicalEquation';
import DataControlHeader from '@/components/layout/DataControlHeader';
import DataControlHeader, { withQuickSearchHeaders } from '@/components/layout/DataControlHeader';
import { useToolbarGridFiltering } from '@/lib/hooks/useToolbarGridFiltering';

/* ---------- types ---------- */

Expand Down Expand Up @@ -600,6 +601,19 @@ export default function FbaPage({ params }: { params: Promise<{ path: string[] }
[fbaData],
);

const rxnFiltering = useToolbarGridFiltering<FbaReactionFlux>({
rows: rxnFluxes,
onFilterApplied: () => setRxnPagination((p) => ({ ...p, page: 0 })),
});
const exchFiltering = useToolbarGridFiltering<FbaExchangeFlux>({
rows: exchFluxes,
onFilterApplied: () => setExchPagination((p) => ({ ...p, page: 0 })),
});
const mapFiltering = useToolbarGridFiltering<FbaPathwayMap>({
rows: pathwayMaps,
onFilterApplied: () => setMapPagination((p) => ({ ...p, page: 0 })),
});

const fluxByReaction = useMemo(() => buildFluxByReaction(rxnFluxes), [rxnFluxes]);
const maxAbsFlux = useMemo(() => {
let maxAbs = 1;
Expand Down Expand Up @@ -828,16 +842,24 @@ export default function FbaPage({ params }: { params: Promise<{ path: string[] }

{tabIndex === 0 && (
<DataGrid<FbaReactionFlux>
rows={rxnFluxes}
columns={rxnColumns}
rows={rxnFiltering.filteredRows}
columns={withQuickSearchHeaders(rxnColumns)}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={rxnPagination}
onPaginationModelChange={setRxnPagination}
sortModel={rxnSort}
onSortModelChange={setRxnSort}
filterModel={rxnFiltering.filterModel}
filterMode="server"
onFilterModelChange={rxnFiltering.handleFilterModelChange}
showToolbar
slots={{ toolbar: DataControlHeader }}
slotProps={{ toolbar: { showQuickFilter: true } }}
slotProps={{
toolbar: {
showQuickFilter: true,
onApplyFilterModel: rxnFiltering.handleToolbarApplyFilterModel,
},
}}
hideFooter
disableRowSelectionOnClick
getRowId={(row) => row.id}
Expand All @@ -847,16 +869,24 @@ export default function FbaPage({ params }: { params: Promise<{ path: string[] }

{tabIndex === 1 && (
<DataGrid<FbaExchangeFlux>
rows={exchFluxes}
columns={exchColumns}
rows={exchFiltering.filteredRows}
columns={withQuickSearchHeaders(exchColumns)}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={exchPagination}
onPaginationModelChange={setExchPagination}
sortModel={exchSort}
onSortModelChange={setExchSort}
filterModel={exchFiltering.filterModel}
filterMode="server"
onFilterModelChange={exchFiltering.handleFilterModelChange}
showToolbar
slots={{ toolbar: DataControlHeader }}
slotProps={{ toolbar: { showQuickFilter: true } }}
slotProps={{
toolbar: {
showQuickFilter: true,
onApplyFilterModel: exchFiltering.handleToolbarApplyFilterModel,
},
}}
hideFooter
disableRowSelectionOnClick
getRowId={(row) => row.id}
Expand Down Expand Up @@ -889,16 +919,24 @@ export default function FbaPage({ params }: { params: Promise<{ path: string[] }

{pathwayMaps.length > 0 && (
<DataGrid<FbaPathwayMap>
rows={pathwayMaps}
columns={mapColumns}
rows={mapFiltering.filteredRows}
columns={withQuickSearchHeaders(mapColumns)}
pageSizeOptions={[10, 25, 50, 100]}
paginationModel={mapPagination}
onPaginationModelChange={setMapPagination}
sortModel={mapSort}
onSortModelChange={setMapSort}
filterModel={mapFiltering.filterModel}
filterMode="server"
onFilterModelChange={mapFiltering.handleFilterModelChange}
showToolbar
slots={{ toolbar: DataControlHeader }}
slotProps={{ toolbar: { showQuickFilter: true } }}
slotProps={{
toolbar: {
showQuickFilter: true,
onApplyFilterModel: mapFiltering.handleToolbarApplyFilterModel,
},
}}
hideFooter
disableRowSelectionOnClick
getRowId={(row) => row.id}
Expand Down
Loading
Loading