feat(web): enhance action column functionality in data grid components
quality / commitlint (push) Skipped
quality / changes (push) Successful in 6s
quality / go (push) Skipped
quality / bird2 (push) Skipped
quality / docker-check (push) Skipped
quality / openapi (push) Successful in 23s
quality / web (push) Successful in 1m4s
CD / quality (push) Successful in 1m36s
CD / publish (push) Successful in 2m55s

- Introduced `KIT_ACTION_COLUMN_SIZE` for consistent action column sizing across data grids.
- Updated `applyKitActionColumn` to enforce action column properties such as fixed size, no sorting, and no resizing.
- Enhanced `kitColumnPinning` logic to conditionally enable pinning based on horizontal scrolling.
- Added tests for `applyKitActionColumn` and `kitColumnPinning` to ensure expected behavior.
- Adjusted `AccessApiKeysGrid`, `ScheduleModulesGrid`, and `ResourcePageFiltered` components to utilize new action column features.
This commit is contained in:
Denozordec
2026-08-23 02:58:07 +07:00
parent 2d29a892f9
commit 764a4e5b4e
5 changed files with 172 additions and 20 deletions
@@ -87,6 +87,81 @@ export const kitDataGridTableClassNames = {
edgeCell: 'first:ps-3 last:pe-3',
} as const
/**
* Compact action column size from data-grid-filtering-2.
* Preview: https://reui.io/preview/base/data-grid-filtering-2
*/
export const KIT_ACTION_COLUMN_SIZE = 56
const ACTION_CELL_ALIGN = 'flex items-center justify-end'
function lastColumnId<T extends object>(columns: DataGridColumnDef<T>[]): string {
const last = columns[columns.length - 1]
if (!last) return ''
if (last.id) return last.id
if ('accessorKey' in last && typeof last.accessorKey === 'string') return last.accessorKey
return ''
}
function wrapActionCell<T extends object>(
cell: DataGridColumnDef<T>['cell'],
): DataGridColumnDef<T>['cell'] {
if (typeof cell !== 'function') {
return () => <div className={ACTION_CELL_ALIGN}>{cell as ReactNode}</div>
}
return (ctx) => <div className={ACTION_CELL_ALIGN}>{cell(ctx)}</div>
}
/**
* filtering-2 action column DNA: locked width, no sort/resize, inner justify-end
* (flex on the cell wrapper, never on `td` — that breaks rowBorder alignment).
* Preview: https://reui.io/preview/base/data-grid-filtering-2
*/
export function applyKitActionColumn<T extends object>(
columns: DataGridColumnDef<T>[],
opts: { pinLastColumn?: boolean } = {},
): DataGridColumnDef<T>[] {
if (columns.length === 0) return columns
const last = columns[columns.length - 1]
const lastId = lastColumnId(columns)
if (lastId !== 'actions' && !opts.pinLastColumn) return columns
const size = last.size ?? KIT_ACTION_COLUMN_SIZE
return [
...columns.slice(0, -1),
{
...last,
size,
minSize: last.minSize ?? size,
maxSize: last.maxSize ?? size,
enableSorting: false,
enableResizing: false,
cell: last.cell ? wrapActionCell(last.cell) : last.cell,
},
]
}
/** End-pin only when the grid actually scrolls horizontally (not for action columns). */
export function kitColumnPinning(opts: {
pinLastColumn?: boolean
horizontalScroll?: boolean
lastColId: string
pinLeftColumnIds?: string[]
}): {
enablePinning: boolean
columnPinning: { start: string[]; end: string[] }
} {
const pinLeft = opts.pinLeftColumnIds ?? []
const pinEnd = Boolean(opts.pinLastColumn && opts.horizontalScroll && opts.lastColId)
return {
enablePinning: pinEnd || pinLeft.length > 0,
columnPinning: {
start: pinLeft,
end: pinEnd ? [opts.lastColId] : [],
},
}
}
function loadStoredColumnVisibility(key: string): ColumnVisibilityState | undefined {
try {
const raw = localStorage.getItem(key)
@@ -281,6 +356,7 @@ export function FrameDataGrid<TData extends object>({
expandedContent,
getRowCanExpand,
pinLeftColumnIds,
horizontalScroll = false,
tableWidth = 'fixed',
columnPinControls = false,
}: FrameDataGridProps<TData>) {
@@ -345,21 +421,23 @@ export function FrameDataGrid<TData extends object>({
}
const tableColumns: DataGridColumnDef<TData>[] = applyColumnPinControls(
[
...(expandedContent ? [expandColumn] : []),
...(enableRowSelection ? [selectColumn] : []),
...columns,
],
applyKitActionColumn(
[
...(expandedContent ? [expandColumn] : []),
...(enableRowSelection ? [selectColumn] : []),
...columns,
],
{ pinLastColumn },
),
columnPinControls,
)
const lastColId = pinLastColumn ? (tableColumns[tableColumns.length - 1]?.id ?? '') : ''
const pinLeft = pinLeftColumnIds ?? []
const enablePinning = pinLastColumn || pinLeft.length > 0
const columnPinning = {
start: pinLeft,
end: pinLastColumn && lastColId ? [lastColId] : [],
}
const { enablePinning, columnPinning } = kitColumnPinning({
pinLastColumn,
horizontalScroll,
lastColId: lastColumnId(tableColumns),
pinLeftColumnIds,
})
const table = useTable({
features: dataGridFeatures,