UNPKG

@grafana/ui

Version:
1 lines • 34.2 kB
{"version":3,"file":"hooks.mjs","sources":["../../../../../src/components/Table/TableNG/hooks.ts"],"sourcesContent":["import { useState, useMemo, useCallback, useRef, useLayoutEffect, RefObject, CSSProperties, useEffect } from 'react';\nimport { Column, DataGridHandle, DataGridProps, SortColumn } from 'react-data-grid';\n\nimport { compareArrayValues, Field, FieldType, formattedValueToString, reduceField, ReducerID } from '@grafana/data';\n\nimport { TableColumnResizeActionCallback } from '../types';\n\nimport { TABLE } from './constants';\nimport { FilterType, FooterFieldState, TableRow, TableSortByFieldState, TableSummaryRow, TypographyCtx } from './types';\nimport {\n getDisplayName,\n processNestedTableRows,\n applySort,\n getColumnTypes,\n getRowHeight,\n computeColWidths,\n buildHeaderHeightMeasurers,\n buildCellHeightMeasurers,\n IS_SAFARI_26,\n} from './utils';\n\n// Helper function to get displayed value\nconst getDisplayedValue = (row: TableRow, key: string, fields: Field[]) => {\n const field = fields.find((field) => getDisplayName(field) === key);\n if (!field || !field.display) {\n return '';\n }\n const displayedValue = formattedValueToString(field.display(row[key]));\n return displayedValue;\n};\n\nexport interface FilteredRowsResult {\n rows: TableRow[];\n filter: FilterType;\n setFilter: React.Dispatch<React.SetStateAction<FilterType>>;\n crossFilterOrder: string[];\n crossFilterRows: Record<string, TableRow[]>;\n}\n\nexport interface FilteredRowsOptions {\n hasNestedFrames: boolean;\n}\n\nexport function useFilteredRows(\n rows: TableRow[],\n fields: Field[],\n { hasNestedFrames }: FilteredRowsOptions\n): FilteredRowsResult {\n // TODO: allow persisted filter selection via url\n const [filter, setFilter] = useState<FilterType>({});\n const filterValues = useMemo(() => Object.entries(filter), [filter]);\n\n const crossFilterOrder: FilteredRowsResult['crossFilterOrder'] = useMemo(\n () => Array.from(new Set(filterValues.map(([key]) => key))),\n [filterValues]\n );\n\n const [filteredRows, crossFilterRows] = useMemo(() => {\n const crossFilterRows: FilteredRowsResult['crossFilterRows'] = {};\n\n const filterRows = (row: TableRow): boolean => {\n for (const [key, value] of filterValues) {\n const displayedValue = getDisplayedValue(row, key, fields);\n if (!value.filteredSet.has(displayedValue)) {\n return false;\n }\n // collect rows for crossFilter\n crossFilterRows[key] = crossFilterRows[key] ?? [];\n crossFilterRows[key].push(row);\n }\n return true;\n };\n\n const filteredRows = hasNestedFrames\n ? processNestedTableRows(rows, (parents) => parents.filter(filterRows))\n : rows.filter(filterRows);\n\n return [filteredRows, crossFilterRows];\n }, [filterValues, rows, fields, hasNestedFrames]);\n\n return {\n rows: filteredRows,\n filter,\n setFilter,\n crossFilterOrder,\n crossFilterRows,\n };\n}\n\nexport interface SortedRowsOptions {\n hasNestedFrames: boolean;\n initialSortBy?: TableSortByFieldState[];\n}\n\nexport interface SortedRowsResult {\n rows: TableRow[];\n sortColumns: SortColumn[];\n setSortColumns: React.Dispatch<React.SetStateAction<SortColumn[]>>;\n}\n\nexport function useSortedRows(\n rows: TableRow[],\n fields: Field[],\n { initialSortBy, hasNestedFrames }: SortedRowsOptions\n): SortedRowsResult {\n const initialSortColumns = useMemo<SortColumn[]>(\n () =>\n initialSortBy?.flatMap(({ displayName, desc }) => {\n if (!fields.some((f) => getDisplayName(f) === displayName)) {\n return [];\n }\n return [\n {\n columnKey: displayName,\n direction: desc ? ('DESC' as const) : ('ASC' as const),\n },\n ];\n }) ?? [],\n [] // eslint-disable-line react-hooks/exhaustive-deps\n );\n const [sortColumns, setSortColumns] = useState<SortColumn[]>(initialSortColumns);\n const columnTypes = useMemo(() => getColumnTypes(fields), [fields]);\n\n const sortedRows = useMemo(\n () => applySort(rows, fields, sortColumns, columnTypes, hasNestedFrames),\n [rows, fields, sortColumns, hasNestedFrames, columnTypes]\n );\n\n return {\n rows: sortedRows,\n sortColumns,\n setSortColumns,\n };\n}\n\nexport interface PaginatedRowsOptions {\n height: number;\n width: number;\n rowHeight: NonNullable<CSSProperties['height']> | ((row: TableRow) => number);\n headerHeight: number;\n footerHeight: number;\n paginationHeight?: number;\n enabled: boolean;\n}\n\nexport interface PaginatedRowsResult {\n rows: TableRow[];\n page: number;\n setPage: React.Dispatch<React.SetStateAction<number>>;\n numPages: number;\n rowsPerPage: number;\n pageRangeStart: number;\n pageRangeEnd: number;\n smallPagination: boolean;\n}\n\n// hand-measured. pagination height is 30px, plus 8px top margin\nconst PAGINATION_HEIGHT = 38;\n\nexport function usePaginatedRows(\n rows: TableRow[],\n { height, width, headerHeight, footerHeight, rowHeight, enabled }: PaginatedRowsOptions\n): PaginatedRowsResult {\n // TODO: allow persisted page selection via url\n const [page, setPage] = useState(0);\n const numRows = rows.length;\n\n // calculate average row height if row height is variable.\n const avgRowHeight = useMemo(() => {\n if (!enabled) {\n return 0;\n }\n\n if (typeof rowHeight === 'number') {\n return rowHeight;\n }\n\n // when using auto-sized rows, we're just going to have to pick a number. the alternative\n // is to measure each row, which we could do but would be expensive.\n if (typeof rowHeight === 'string') {\n return TABLE.MAX_CELL_HEIGHT;\n }\n\n // we'll just measure 100 rows to estimate\n return rows.slice(0, 100).reduce((avg, row, _, { length }) => avg + rowHeight(row) / length, 0);\n }, [rows, rowHeight, enabled]);\n\n const smallPagination = useMemo(() => enabled && width < TABLE.PAGINATION_LIMIT, [enabled, width]);\n\n // using dimensions of the panel, calculate pagination parameters\n const { numPages, rowsPerPage, pageRangeStart, pageRangeEnd } = useMemo((): {\n numPages: number;\n rowsPerPage: number;\n pageRangeStart: number;\n pageRangeEnd: number;\n } => {\n if (!enabled) {\n return { numPages: 0, rowsPerPage: 0, pageRangeStart: 1, pageRangeEnd: numRows };\n }\n\n // calculate number of rowsPerPage based on height stack\n const rowAreaHeight = height - headerHeight - footerHeight - PAGINATION_HEIGHT;\n const heightPerRow = Math.floor(rowAreaHeight / (avgRowHeight || 1));\n // ensure at least one row per page is displayed\n let rowsPerPage = heightPerRow > 1 ? heightPerRow : 1;\n\n // calculate row range for pagination summary display\n const pageRangeStart = page * rowsPerPage + 1;\n let pageRangeEnd = pageRangeStart + rowsPerPage - 1;\n if (pageRangeEnd > numRows) {\n pageRangeEnd = numRows;\n }\n\n const numPages = Math.ceil(numRows / rowsPerPage);\n return {\n numPages,\n rowsPerPage,\n pageRangeStart,\n pageRangeEnd,\n };\n }, [height, headerHeight, footerHeight, avgRowHeight, enabled, numRows, page]);\n\n // safeguard against page overflow on panel resize or other factors\n useLayoutEffect(() => {\n if (!enabled) {\n return;\n }\n\n if (page > numPages) {\n // resets pagination to end\n setPage(numPages - 1);\n }\n }, [numPages, enabled, page, setPage]);\n\n // apply pagination to the sorted rows\n const paginatedRows = useMemo(() => {\n if (!enabled) {\n return rows;\n }\n const pageOffset = page * rowsPerPage;\n return rows.slice(pageOffset, pageOffset + rowsPerPage);\n }, [page, rowsPerPage, rows, enabled]);\n\n return {\n rows: paginatedRows,\n page: enabled ? page : -1,\n setPage,\n numPages,\n rowsPerPage,\n pageRangeStart,\n pageRangeEnd,\n smallPagination,\n };\n}\n\nconst ICON_WIDTH = 16;\nconst ICON_GAP = 4;\n\ninterface UseHeaderHeightOptions {\n enabled: boolean;\n fields: Field[];\n columnWidths: number[];\n sortColumns: SortColumn[];\n typographyCtx: TypographyCtx;\n showTypeIcons?: boolean;\n}\n\nexport function useHeaderHeight({\n fields,\n enabled,\n columnWidths,\n sortColumns,\n typographyCtx,\n showTypeIcons = false,\n}: UseHeaderHeightOptions): number {\n const perIconSpace = ICON_WIDTH + ICON_GAP;\n\n const measurers = useMemo(() => buildHeaderHeightMeasurers(fields, typographyCtx), [fields, typographyCtx]);\n\n const columnAvailableWidths = useMemo(\n () =>\n columnWidths.map((c, idx) => {\n if (idx >= fields.length) {\n return 0; // no width available for this column yet\n }\n\n let width = c - 2 * TABLE.CELL_PADDING - TABLE.BORDER_RIGHT;\n const field = fields[idx];\n\n // filtering icon\n if (field.config?.custom?.filterable) {\n width -= perIconSpace;\n }\n // sorting icon\n if (sortColumns.some((col) => col.columnKey === getDisplayName(field))) {\n width -= perIconSpace;\n }\n // type icon\n if (showTypeIcons) {\n width -= perIconSpace;\n }\n // sadly, the math for this is off by exactly 1 pixel. shrug.\n return Math.floor(width) - 1;\n }),\n [fields, columnWidths, sortColumns, showTypeIcons, perIconSpace]\n );\n\n const headerHeight = useMemo(() => {\n if (!enabled) {\n return 0;\n }\n return getRowHeight(\n fields,\n -1,\n columnAvailableWidths,\n TABLE.HEADER_HEIGHT,\n measurers,\n TABLE.LINE_HEIGHT,\n TABLE.CELL_PADDING\n );\n }, [fields, enabled, columnAvailableWidths, measurers]);\n\n return headerHeight;\n}\n\ninterface UseRowHeightOptions {\n columnWidths: number[];\n fields: Field[];\n hasNestedFrames: boolean;\n defaultHeight: NonNullable<CSSProperties['height']>;\n expandedRows: Set<number>;\n typographyCtx: TypographyCtx;\n maxHeight?: number;\n}\n\nexport function useRowHeight({\n columnWidths,\n fields,\n hasNestedFrames,\n defaultHeight,\n expandedRows,\n typographyCtx,\n maxHeight,\n}: UseRowHeightOptions): NonNullable<CSSProperties['height']> | ((row: TableRow) => number) {\n const measurers = useMemo(\n () => buildCellHeightMeasurers(fields, typographyCtx, maxHeight),\n [fields, typographyCtx, maxHeight]\n );\n const hasWrappedCols = useMemo(() => measurers?.length ?? 0 > 0, [measurers]);\n\n const colWidths = useMemo(() => {\n const columnWidthAffordance = 2 * TABLE.CELL_PADDING + TABLE.BORDER_RIGHT;\n return columnWidths.map((c) => c - columnWidthAffordance);\n }, [columnWidths]);\n\n const rowHeight = useMemo(() => {\n // row height is only complicated when there are nested frames or wrapped columns.\n if ((!hasNestedFrames && !hasWrappedCols) || typeof defaultHeight === 'string') {\n return defaultHeight;\n }\n\n // this cache should get blown away on resize, data refresh, updated fields, etc.\n // caching by __index is ok because sorting does not modify the __index.\n const cache: Array<number | undefined> = Array(fields[0].values.length);\n return (row: TableRow) => {\n // nested rows\n if (row.__depth > 0) {\n // if unexpanded, height === 0\n if (!expandedRows.has(row.__index)) {\n return 0;\n }\n\n const rowCount = row.data?.length ?? 0;\n if (rowCount === 0) {\n return TABLE.NESTED_NO_DATA_HEIGHT + TABLE.CELL_PADDING * 2;\n }\n\n const nestedHeaderHeight = row.data?.meta?.custom?.noHeader ? 0 : defaultHeight;\n return defaultHeight * rowCount + nestedHeaderHeight + TABLE.CELL_PADDING * 2;\n }\n\n // regular rows\n let result = cache[row.__index];\n if (!result) {\n result = cache[row.__index] = getRowHeight(fields, row.__index, colWidths, defaultHeight, measurers);\n }\n return result;\n };\n }, [hasNestedFrames, hasWrappedCols, defaultHeight, fields, colWidths, measurers, expandedRows]);\n\n return rowHeight;\n}\n\n/**\n * react-data-grid is a little unwieldy when it comes to column resize events.\n * we want to detect a few different column resize signals:\n * - dragging the handle (only want to dispatch when handle is released)\n * - double-clicking the handle (sets the column to the minimum width to fit content)\n * `onColumnResize` dispatches events throughout a dragged resize, and `onColumnWidthsChanged` doesn't\n * emit an event when double-click resizing occurs, so we have to build something custom on top of these\n * behaviors in order to get everything working.\n */\ninterface UseColumnResizeState {\n columnKey: string | undefined;\n width: number;\n}\n\nconst INITIAL_COL_RESIZE_STATE = Object.freeze({ columnKey: undefined, width: 0 }) satisfies UseColumnResizeState;\n\nexport function useColumnResize(\n onColumnResize: TableColumnResizeActionCallback = () => {}\n): DataGridProps<TableRow, TableSummaryRow>['onColumnResize'] {\n // these must be refs. if we used setState, we would run into race conditions with these event listeners\n const colResizeState = useRef<UseColumnResizeState>({ ...INITIAL_COL_RESIZE_STATE });\n const pointerIsDown = useRef(false);\n\n // to detect whether we got a double-click resize, we track whether the pointer is currently down\n useLayoutEffect(() => {\n function pointerDown(_event: PointerEvent) {\n pointerIsDown.current = true;\n }\n\n function pointerUp(_event: PointerEvent) {\n pointerIsDown.current = false;\n }\n\n window.addEventListener('pointerdown', pointerDown);\n window.addEventListener('pointerup', pointerUp);\n\n return () => {\n window.removeEventListener('pointerdown', pointerDown);\n window.removeEventListener('pointerup', pointerUp);\n };\n });\n\n const dispatchEvent = useCallback(() => {\n if (colResizeState.current.columnKey) {\n onColumnResize(colResizeState.current.columnKey, Math.floor(colResizeState.current.width));\n colResizeState.current = { ...INITIAL_COL_RESIZE_STATE };\n }\n window.removeEventListener('click', dispatchEvent, { capture: true });\n }, [onColumnResize]);\n\n // this is the callback that gets passed to react-data-grid\n const dataGridResizeHandler = useCallback(\n (column: Column<TableRow, TableSummaryRow>, width: number) => {\n if (!colResizeState.current.columnKey) {\n window.addEventListener('click', dispatchEvent, { capture: true });\n }\n\n colResizeState.current.columnKey = column.key;\n colResizeState.current.width = width;\n\n // when double clicking to resize, this handler will fire, but the pointer will not be down,\n // meaning that we should immediately flush the new width\n if (!pointerIsDown.current) {\n dispatchEvent();\n }\n },\n [dispatchEvent]\n );\n\n return dataGridResizeHandler;\n}\n\nexport function useScrollbarWidth(ref: RefObject<DataGridHandle>, height: number) {\n const [scrollbarWidth, setScrollbarWidth] = useState(0);\n\n useLayoutEffect(() => {\n const el = ref.current?.element;\n\n if (!el || IS_SAFARI_26) {\n return;\n }\n\n const updateScrollbarDimensions = () => {\n setScrollbarWidth(el.offsetWidth - el.clientWidth);\n };\n\n updateScrollbarDimensions();\n\n const resizeObserver = new ResizeObserver(updateScrollbarDimensions);\n resizeObserver.observe(el);\n return () => {\n resizeObserver.disconnect();\n };\n }, [ref, height]);\n\n return scrollbarWidth;\n}\n\nconst numIsEqual = (a: number, b: number) => a === b;\n\nexport function useColWidths(\n visibleFields: Field[],\n availableWidth: number,\n frozenColumns?: number\n): [number[], number] {\n const [widths, setWidths] = useState<number[]>(computeColWidths(visibleFields, availableWidth));\n\n // only replace the widths array if something actually changed\n useEffect(() => {\n const newWidths = computeColWidths(visibleFields, availableWidth);\n if (!compareArrayValues(widths, newWidths, numIsEqual)) {\n setWidths(newWidths);\n }\n }, [availableWidth, widths, visibleFields]);\n\n // this is to avoid buggy situations where all visible columns are frozen\n const numFrozenColsFullyInView = useMemo(() => {\n if (!frozenColumns || frozenColumns <= 0) {\n return -1;\n }\n\n const fullyVisibleCols = widths.reduce(\n ([count, remainingWidth], nextWidth) => {\n if (remainingWidth - nextWidth >= 0) {\n return [count + 1, remainingWidth - nextWidth];\n }\n return [count, 0];\n },\n [0, availableWidth]\n )[0];\n\n // de-noise memoized changes to the columns array, and only change this\n // number when the number of frozen columns changes or once there are fewer\n // visible columns than the number of frozen columns.\n return Math.min(fullyVisibleCols, frozenColumns);\n }, [widths, availableWidth, frozenColumns]);\n\n return [widths, numFrozenColsFullyInView];\n}\n\nconst isReducer = (maybeReducer: string): maybeReducer is ReducerID => maybeReducer in ReducerID;\nconst nonMathReducers = new Set<ReducerID>([\n ReducerID.allValues,\n ReducerID.changeCount,\n ReducerID.count,\n ReducerID.countAll,\n ReducerID.distinctCount,\n ReducerID.first,\n ReducerID.firstNotNull,\n ReducerID.last,\n ReducerID.lastNotNull,\n ReducerID.uniqueValues,\n]);\nconst isNonMathReducer = (reducer: string) => isReducer(reducer) && nonMathReducers.has(reducer);\nconst noFormattingReducers = new Set<ReducerID>([ReducerID.count, ReducerID.countAll]);\nconst shouldReducerSkipFormatting = (reducer: string) => isReducer(reducer) && noFormattingReducers.has(reducer);\n\nexport const useReducerEntries = (\n field: Field,\n rows: TableRow[],\n displayName: string,\n colIdx: number\n): Array<[string, string | null]> => {\n return useMemo(() => {\n const reducers: string[] = field.config.custom?.footer?.reducers ?? [];\n\n if (\n reducers.length === 0 ||\n (field.type !== FieldType.number && reducers.every((reducerId) => !isNonMathReducer(reducerId)))\n ) {\n return [];\n }\n\n // Create a new state object that matches the original behavior exactly\n const newState: FooterFieldState = {\n lastProcessedRowCount: 0,\n ...(field.state || {}), // Preserve any existing state properties\n };\n\n // Assign back to field\n field.state = newState;\n\n const currentRowCount = rows.length;\n const lastRowCount = newState.lastProcessedRowCount;\n\n // Check if we need to invalidate the cache\n if (lastRowCount !== currentRowCount) {\n // Cache should be invalidated as row count has changed\n if (newState.calcs) {\n delete newState.calcs;\n }\n // Update the row count tracker\n newState.lastProcessedRowCount = currentRowCount;\n }\n\n // Calculate all specified reducers\n const results: Record<string, number | null> = reduceField({\n field: {\n ...field,\n values: rows.map((row) => row[displayName]),\n },\n reducers,\n });\n\n return reducers.map((reducerId) => {\n if (\n results[reducerId] === undefined ||\n // For non-number fields, only show special count reducers\n (field.type !== FieldType.number && !isNonMathReducer(reducerId)) ||\n // for countAll, only show the reducer in the first column\n (reducerId === ReducerID.countAll && colIdx !== 0)\n ) {\n return [reducerId, null];\n }\n\n const value = results[reducerId];\n let result = null;\n if (!shouldReducerSkipFormatting(reducerId) && field.display) {\n result = formattedValueToString(field.display(value));\n } else if (value != null) {\n result = String(value);\n }\n\n return [reducerId, result];\n });\n }, [field, rows, displayName, colIdx]);\n};\n"],"names":["field","crossFilterRows","filteredRows","rowsPerPage","pageRangeStart","pageRangeEnd","numPages"],"mappings":"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"}