diff --git a/apps/studio/components/grid/components/header/ColumnVisibility.tsx b/apps/studio/components/grid/components/header/ColumnVisibilityPopover.tsx
similarity index 99%
rename from apps/studio/components/grid/components/header/ColumnVisibility.tsx
rename to apps/studio/components/grid/components/header/ColumnVisibilityPopover.tsx
index b78cc5b89fd..6d335f1a926 100644
--- a/apps/studio/components/grid/components/header/ColumnVisibility.tsx
+++ b/apps/studio/components/grid/components/header/ColumnVisibilityPopover.tsx
@@ -115,7 +115,7 @@ function DraggableColumnItem({ column, isVisible, onSelect }: BaseColumnItemProp
)
}
-export const ColumnVisibility = () => {
+export const ColumnVisibilityPopover = () => {
const snap = useTableEditorTableStateSnapshot()
const { hiddenColumns, hideColumn, showColumn } = useTableColumnVisibility()
const { columnOrder, moveColumn } = useTableColumnOrder()
diff --git a/apps/studio/components/grid/components/header/Header.tsx b/apps/studio/components/grid/components/header/Header.tsx
index a66ab802e6c..b828fa9969d 100644
--- a/apps/studio/components/grid/components/header/Header.tsx
+++ b/apps/studio/components/grid/components/header/Header.tsx
@@ -35,7 +35,7 @@ import {
Separator,
SonnerProgress,
} from 'ui'
-import { ColumnVisibility } from './ColumnVisibility'
+import { ColumnVisibilityPopover } from './ColumnVisibilityPopover'
import { FilterPopover } from './filter/FilterPopover'
import { SortPopover } from './sort/SortPopover'
// [Joshen] CSV exports require this guard as a fail-safe if the table is
@@ -98,7 +98,7 @@ const DefaultHeader = () => {
-
+
{canAddNew && (
<>
diff --git a/apps/studio/components/grid/hooks/useTableColumnVisibility.ts b/apps/studio/components/grid/hooks/useTableColumnVisibility.ts
index 499b2895fd6..42a1b49705b 100644
--- a/apps/studio/components/grid/hooks/useTableColumnVisibility.ts
+++ b/apps/studio/components/grid/hooks/useTableColumnVisibility.ts
@@ -1,4 +1,4 @@
-import { useCallback, useEffect, useMemo } from 'react'
+import { useCallback, useMemo } from 'react'
import { useTableEditorFiltersSort } from 'hooks/misc/useTableEditorFiltersSort'
import { useTableEditorTableStateSnapshot } from 'state/table-editor-table'
@@ -7,48 +7,17 @@ import { useTableEditorTableStateSnapshot } from 'state/table-editor-table'
* Provides state and actions for managing table column visibility.
*
* Reads visibility state directly from the Valtio store.
- * Actions update the Valtio store first (triggering automatic persistence)
- * and then update the 'hidden_cols' URL parameter.
+ * Actions update the URL parameter first (triggering route update with the new state)
+ * and then update the Valtio store (triggering automatic persistence to localStorage).
*/
export function useTableColumnVisibility() {
const { hiddenColumns, setParams } = useTableEditorFiltersSort() // Get hiddenColumns from URL
const snap = useTableEditorTableStateSnapshot()
- // Initialize column visibility once based on URL params
- // This ensures Valtio state reflects URL on first load
- useEffect(() => {
- if (!snap.setColumnVisibility || !snap.gridColumns) return
-
- // If URL has hidden columns, synchronize Valtio state with URL
- if (hiddenColumns.length > 0) {
- // First, ensure all columns are visible (reset state)
- snap.gridColumns.forEach((col) => {
- if (col.visible === false) {
- snap.setColumnVisibility(col.key, true)
- }
- })
-
- // Then hide columns based on URL parameters
- hiddenColumns.forEach((columnName) => {
- snap.setColumnVisibility(columnName, false)
- })
- }
- // We don't need an else case - if URL params are empty but Valtio has
- // hidden columns, we should keep those hidden (already in Valtio state)
- }, []) // Empty dependency array - run once on mount
-
- // Derive hidden columns Set directly from Valtio state
+ // Read hidden columns directly from URL parameters
const hiddenColumnsMemo = useMemo(() => {
- const hidden = new Set()
- snap.gridColumns?.forEach((col) => {
- // Consider a column hidden if its visible property is explicitly false
- if (col.visible === false) {
- hidden.add(col.key)
- }
- })
- return hidden
- }, [snap.gridColumns])
-
+ return new Set(hiddenColumns)
+ }, [hiddenColumns])
/**
* Hides a specific column.
* @param columnName Key of the column to hide.
@@ -66,7 +35,6 @@ export function useTableColumnVisibility() {
const newHiddenArray = Array.from(currentHidden).sort()
const newUrlString = newHiddenArray.join(',')
setParams((prev) => ({ ...prev, hidden_cols: newUrlString || undefined }))
-
// 2. Update Valtio State (after URL)
snap.setColumnVisibility(columnName, false)
},
@@ -90,7 +58,6 @@ export function useTableColumnVisibility() {
const newHiddenArray = Array.from(currentHidden).sort()
const newUrlString = newHiddenArray.join(',')
setParams((prev) => ({ ...prev, hidden_cols: newUrlString || undefined }))
-
// 2. Update Valtio State (after URL)
snap.setColumnVisibility(columnName, true)
},
diff --git a/apps/studio/components/grid/types/base.ts b/apps/studio/components/grid/types/base.ts
index adf480896a7..505942ca920 100644
--- a/apps/studio/components/grid/types/base.ts
+++ b/apps/studio/components/grid/types/base.ts
@@ -1,10 +1,12 @@
-import { Filter, Sort } from '@supabase/pg-meta/src/query'
import { CalculatedColumn, RenderHeaderCellProps } from 'react-data-grid'
+export interface ExtendedCalculatedColumn extends CalculatedColumn {
+ visible?: boolean
+}
export interface SavedState {
filters?: string[]
sorts?: string[]
- gridColumns: CalculatedColumn[]
+ gridColumns: ExtendedCalculatedColumn[]
}
export interface DragItem {
diff --git a/apps/studio/components/grid/utils/column.ts b/apps/studio/components/grid/utils/column.ts
index ca2b4de3a0c..8f67c18edc3 100644
--- a/apps/studio/components/grid/utils/column.ts
+++ b/apps/studio/components/grid/utils/column.ts
@@ -1,12 +1,13 @@
import { CalculatedColumn } from 'react-data-grid'
import { ADD_COLUMN_KEY, SELECT_COLUMN_KEY } from '../constants'
import type { SavedState } from '../types'
+import { ExtendedCalculatedColumn } from '../types/base'
export function getInitialGridColumns(
- gridColumns: CalculatedColumn[],
+ gridColumns: ExtendedCalculatedColumn[],
savedState?: SavedState
-) {
- let result = gridColumns
+): ExtendedCalculatedColumn[] {
+ let result = gridColumns as ExtendedCalculatedColumn[]
if (savedState?.gridColumns) {
result = []
@@ -17,8 +18,15 @@ export function getInitialGridColumns(
for (let i = 0; i < stateColumnsFiltered.length; i++) {
const state = stateColumnsFiltered[i]
const found = gridColumns.find((y) => y.key === state.key)
- // merge with savedState item props: width
- if (found) result.push({ ...found, width: state.width, frozen: state.frozen })
+ // merge with savedState item props: width, frozen, visible
+ if (found) {
+ result.push({
+ ...found,
+ width: state.width,
+ frozen: state.frozen,
+ visible: state.visible,
+ })
+ }
}
// check for newly created columns
diff --git a/apps/studio/state/table-editor-table.tsx b/apps/studio/state/table-editor-table.tsx
index b8163b90976..c98797abba2 100644
--- a/apps/studio/state/table-editor-table.tsx
+++ b/apps/studio/state/table-editor-table.tsx
@@ -13,11 +13,9 @@ import { getInitialGridColumns } from 'components/grid/utils/column'
import { getGridColumns } from 'components/grid/utils/gridColumns'
import { Entity } from 'data/table-editor/table-editor-types'
import { useTableEditorStateSnapshot } from './table-editor'
+import { ExtendedCalculatedColumn } from 'components/grid/types/base'
// 1. Define Type
-interface ExtendedCalculatedColumn extends CalculatedColumn {
- visible?: boolean
-}
export const createTableEditorTableState = ({
projectRef,