fix(base): refresh grid headers when a property is renamed

This commit is contained in:
Philipinho
2026-04-18 20:51:14 +01:00
parent b88c060df8
commit f812162a26
4 changed files with 23 additions and 8 deletions
@@ -186,6 +186,7 @@ export function BaseTable({ baseId }: BaseTableProps) {
/> />
<GridContainer <GridContainer
table={table} table={table}
properties={base.properties}
onCellUpdate={handleCellUpdate} onCellUpdate={handleCellUpdate}
onAddRow={handleAddRow} onAddRow={handleAddRow}
baseId={baseId} baseId={baseId}
@@ -16,7 +16,7 @@ import {
horizontalListSortingStrategy, horizontalListSortingStrategy,
} from "@dnd-kit/sortable"; } from "@dnd-kit/sortable";
import { restrictToHorizontalAxis } from "@dnd-kit/modifiers"; import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
import { IBaseRow, EditingCell } from "@/features/base/types/base.types"; import { IBaseRow, IBaseProperty, EditingCell } from "@/features/base/types/base.types";
import { editingCellAtom, activePropertyMenuAtom, propertyMenuDirtyAtom, propertyMenuCloseRequestAtom } from "@/features/base/atoms/base-atoms"; import { editingCellAtom, activePropertyMenuAtom, propertyMenuDirtyAtom, propertyMenuCloseRequestAtom } from "@/features/base/atoms/base-atoms";
import { useColumnResize } from "@/features/base/hooks/use-column-resize"; import { useColumnResize } from "@/features/base/hooks/use-column-resize";
import { useGridKeyboardNav } from "@/features/base/hooks/use-grid-keyboard-nav"; import { useGridKeyboardNav } from "@/features/base/hooks/use-grid-keyboard-nav";
@@ -34,6 +34,7 @@ const OVERSCAN = 10;
type GridContainerProps = { type GridContainerProps = {
table: Table<IBaseRow>; table: Table<IBaseRow>;
properties: IBaseProperty[];
onCellUpdate: (rowId: string, propertyId: string, value: unknown) => void; onCellUpdate: (rowId: string, propertyId: string, value: unknown) => void;
onAddRow?: () => void; onAddRow?: () => void;
baseId?: string; baseId?: string;
@@ -47,6 +48,7 @@ type GridContainerProps = {
export function GridContainer({ export function GridContainer({
table, table,
properties,
onCellUpdate, onCellUpdate,
onAddRow, onAddRow,
baseId, baseId,
@@ -240,6 +242,7 @@ export function GridContainer({
table={table} table={table}
baseId={baseId} baseId={baseId}
columnOrder={table.getState().columnOrder} columnOrder={table.getState().columnOrder}
properties={properties}
loadedRowIds={rowIds} loadedRowIds={rowIds}
onPropertyCreated={handlePropertyCreated} onPropertyCreated={handlePropertyCreated}
/> />
@@ -46,16 +46,15 @@ const typeIcons: Record<string, typeof IconLetterT> = {
type GridHeaderCellProps = { type GridHeaderCellProps = {
header: Header<IBaseRow, unknown>; header: Header<IBaseRow, unknown>;
property: IBaseProperty | undefined;
loadedRowIds: string[]; loadedRowIds: string[];
}; };
export const GridHeaderCell = memo(function GridHeaderCell({ export const GridHeaderCell = memo(function GridHeaderCell({
header, header,
property,
loadedRowIds, loadedRowIds,
}: GridHeaderCellProps) { }: GridHeaderCellProps) {
const property = header.column.columnDef.meta?.property as
| IBaseProperty
| undefined;
const isRowNumber = header.column.id === "__row_number"; const isRowNumber = header.column.id === "__row_number";
const isPinned = header.column.getIsPinned(); const isPinned = header.column.getIsPinned();
const pinOffset = isPinned ? header.column.getStart("left") : undefined; const pinOffset = isPinned ? header.column.getStart("left") : undefined;
@@ -1,6 +1,6 @@
import { memo } from "react"; import { memo, useMemo } from "react";
import { Table, ColumnOrderState } from "@tanstack/react-table"; import { Table, ColumnOrderState } from "@tanstack/react-table";
import { IBaseRow } from "@/features/base/types/base.types"; import { IBaseRow, IBaseProperty } from "@/features/base/types/base.types";
import { GridHeaderCell } from "./grid-header-cell"; import { GridHeaderCell } from "./grid-header-cell";
import { CreatePropertyPopover } from "@/features/base/components/property/create-property-popover"; import { CreatePropertyPopover } from "@/features/base/components/property/create-property-popover";
import classes from "@/features/base/styles/grid.module.css"; import classes from "@/features/base/styles/grid.module.css";
@@ -9,8 +9,9 @@ type GridHeaderProps = {
table: Table<IBaseRow>; table: Table<IBaseRow>;
baseId?: string; baseId?: string;
// Passed explicitly to break memo when columns change // Passed explicitly to break memo when columns change
// (table ref is stable from useReactTable, so memo won't fire without this) // (table ref is stable from useReactTable, so memo won't fire without these)
columnOrder: ColumnOrderState; columnOrder: ColumnOrderState;
properties: IBaseProperty[];
loadedRowIds: string[]; loadedRowIds: string[];
onPropertyCreated?: () => void; onPropertyCreated?: () => void;
}; };
@@ -20,15 +21,26 @@ export const GridHeader = memo(function GridHeader({
baseId, baseId,
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
columnOrder: _columnOrder, columnOrder: _columnOrder,
properties,
loadedRowIds, loadedRowIds,
onPropertyCreated, onPropertyCreated,
}: GridHeaderProps) { }: GridHeaderProps) {
const headerGroups = table.getHeaderGroups(); const headerGroups = table.getHeaderGroups();
const propertyById = useMemo(() => {
const map = new Map<string, IBaseProperty>();
for (const p of properties) map.set(p.id, p);
return map;
}, [properties]);
return ( return (
<div className={classes.headerRow} role="row"> <div className={classes.headerRow} role="row">
{headerGroups[0]?.headers.map((header) => ( {headerGroups[0]?.headers.map((header) => (
<GridHeaderCell key={header.id} header={header} loadedRowIds={loadedRowIds} /> <GridHeaderCell
key={header.id}
header={header}
property={propertyById.get(header.column.id)}
loadedRowIds={loadedRowIds}
/>
))} ))}
{baseId && ( {baseId && (
<CreatePropertyPopover <CreatePropertyPopover