Files
supabase/apps/studio/components/grid/SupabaseGrid.tsx
Ali Waseem d6e400620d chore(studio): remove old table editor filter bar (#45220)
## Summary

- Removes the legacy Table Editor filter bar and its
`supabase-ui-table-filter-bar` feature-preview flag (opt-out rate
~0.13%, no plans to keep supporting it).
- Merges `HeaderNew` into `Header`, consolidates `useTableFilterNew`
into `useTableFilter`, and adds
`useOptionalTableEditorTableStateSnapshot` so `useTableFilter` can
safely fall back to URL params when called outside the table-editor
provider (e.g. from the sidebar).
- Drops the associated preview modal entry, screenshot, and local
storage key.

Based on the closed PR https://github.com/supabase/supabase/pull/44867.

Closes
[FE-3071](https://linear.app/supabase/issue/FE-3071/remove-old-table-editor-filter-bar).

## Test plan

- [x] `pnpm --filter=studio typecheck` passes
- [x] `pnpm --filter=studio lint` passes
- [x] Open the Table Editor, confirm the new filter bar renders and
filters apply/clear correctly
- [x] Apply filters, reload the page — filters persist via URL params
- [x] Delete a column that has an active filter — filter is removed
cleanly
- [x] Right-click a cell — "Filter by value" still appears for simple
values
- [x] Select rows — row-selection header (copy / export / delete) still
works
- [x] Foreign Row Selector still renders (`FilterPopoverPrimitive`
retained for this usage)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Table filter bar is now permanently available (no longer gated behind
preview feature).

* **Improvements**
* Reorganized table header layout with improved filter UI placement and
styling.
* Streamlined and unified filter behavior across the grid for more
consistent operation.
* Simplified insert row/column functionality with clearer permission
handling.

* **Refactor**
* Consolidated filter system by removing redundant implementations and
feature flags.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-24 14:45:33 +00:00

117 lines
3.8 KiB
TypeScript

import { keepPreviousData } from '@tanstack/react-query'
import { useParams } from 'common'
import { PropsWithChildren, useRef } from 'react'
import { DataGridHandle } from 'react-data-grid'
import { Shortcuts } from './components/common/Shortcuts'
import { Footer } from './components/footer/Footer'
import { Grid } from './components/grid/Grid'
import { Header, HeaderProps } from './components/header/Header'
import { useTableSort } from './hooks/useTableSort'
import { validateMsSqlSorting } from './MsSqlValidation'
import { GridProps } from './types'
import { formatGridDataWithOperationValues } from './utils/queueOperationUtils'
import { isMsSqlForeignTable } from '@/data/table-editor/table-editor-types'
import { useTableRowsQuery } from '@/data/table-rows/table-rows-query'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { RoleImpersonationState } from '@/lib/role-impersonation'
import { EMPTY_ARR } from '@/lib/void'
import { useRoleImpersonationStateSnapshot } from '@/state/role-impersonation-state'
import { useTableEditorStateSnapshot } from '@/state/table-editor'
import { QueuedOperation } from '@/state/table-editor-operation-queue.types'
import { useTableEditorTableStateSnapshot } from '@/state/table-editor-table'
export const SupabaseGrid = ({
customHeader,
gridProps,
children,
}: PropsWithChildren<
Pick<HeaderProps, 'customHeader'> & {
gridProps?: GridProps
}
>) => {
const { id: _id } = useParams()
const tableId = _id ? Number(_id) : undefined
const { data: project } = useSelectedProjectQuery()
const tableEditorSnap = useTableEditorStateSnapshot()
const snap = useTableEditorTableStateSnapshot()
const preflightCheck = !tableEditorSnap.tablesToIgnorePreflightCheck.includes(tableId ?? -1)
const gridRef = useRef<DataGridHandle>(null)
const filters = snap.filters
const { sorts, onApplySorts } = useTableSort()
const roleImpersonationState = useRoleImpersonationStateSnapshot()
const msSqlWarning = isMsSqlForeignTable(snap.originalTable)
? validateMsSqlSorting({ filters, sorts, table: snap.originalTable })
: { warning: null }
const tableQueriesEnabled = msSqlWarning.warning === null
const {
data,
error,
isSuccess,
isError,
isPending: isLoading,
isRefetching,
} = useTableRowsQuery(
{
projectRef: project?.ref,
tableId,
sorts,
filters,
page: snap.page,
preflightCheck,
limit: tableEditorSnap.rowsPerPage,
roleImpersonationState: roleImpersonationState as RoleImpersonationState,
},
{
placeholderData: keepPreviousData,
enabled: tableQueriesEnabled,
retry: (_, error: any) => {
const doesNotExistError = error && error.message?.includes('does not exist')
if (doesNotExistError) onApplySorts([])
return false
},
}
)
const operations = (tableEditorSnap.operationQueue.operations as QueuedOperation[]).filter(
(op) => op.tableId === tableId
)
const baseRows = data?.rows ?? EMPTY_ARR
const rows = formatGridDataWithOperationValues({ operations, rows: baseRows })
return (
<div className="sb-grid h-full flex flex-col">
<Header
customHeader={customHeader}
isRefetching={isRefetching}
tableQueriesEnabled={tableQueriesEnabled}
/>
{msSqlWarning.warning !== null && <msSqlWarning.Component />}
{children || (
<>
<Grid
ref={gridRef}
{...gridProps}
rows={rows}
error={error}
isDisabled={!tableQueriesEnabled}
isLoading={isLoading}
isSuccess={isSuccess}
isError={isError}
/>
<Footer enableForeignRowsQuery={tableQueriesEnabled} />
<Shortcuts gridRef={gridRef} rows={rows} />
</>
)}
</div>
)
}