mirror of
https://github.com/supabase/supabase.git
synced 2026-05-12 04:16:08 +08:00
## 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 -->
117 lines
3.8 KiB
TypeScript
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>
|
|
)
|
|
}
|