// Copyright 2022 The Parca Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import {useEffect, useState} from 'react'; import {createColumnHelper, type ColumnDef} from '@tanstack/table-core'; import {useQueryState} from 'nuqs'; import {ProfileType} from '@parca/parser'; import {valueFormatter} from '@parca/utilities'; import {Row} from '../../../Table'; import ColumnsVisibility from '../../../Table/ColumnsVisibility'; import {ColumnName, addPlusSign, getRatioString} from '../../../Table/utils/functions'; import {tableColumnsParser} from '../../../hooks/urlParsers'; import {useProfileViewContext} from '../../context/ProfileViewContext'; interface Props { profileType?: ProfileType; total: bigint; filtered: bigint; } const TableColumnsDropdown = ({profileType, total, filtered}: Props): JSX.Element => { const {compareMode} = useProfileViewContext(); const [tableColumns, setTableColumns] = useQueryState('table_columns', tableColumnsParser); const columnHelper = createColumnHelper(); const unit: string = profileType?.sampleUnit ?? ''; const columns: Array> = [ columnHelper.accessor('flat', { id: 'flat', header: 'Flat', cell: info => valueFormatter(info.getValue(), unit, 2), size: 80, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('flat', { id: 'flatPercentage', header: 'Flat (%)', cell: info => { return getRatioString(info.getValue(), total, filtered); }, size: 120, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('flatDiff', { id: 'flatDiff', header: 'Flat Diff', cell: info => addPlusSign(valueFormatter(info.getValue(), unit, 2)), size: 120, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('flatDiff', { id: 'flatDiffPercentage', header: 'Flat Diff (%)', cell: info => { return getRatioString(info.getValue(), total, filtered); }, size: 120, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('cumulative', { id: 'cumulative', header: 'Cumulative', cell: info => valueFormatter(info.getValue(), unit, 2), size: 150, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('cumulative', { id: 'cumulativePercentage', header: 'Cumulative (%)', cell: info => { return getRatioString(info.getValue(), total, filtered); }, size: 150, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('cumulativeDiff', { id: 'cumulativeDiff', header: 'Cumulative Diff', cell: info => addPlusSign(valueFormatter(info.getValue(), unit, 2)), size: 170, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('cumulativeDiff', { id: 'cumulativeDiffPercentage', header: 'Cumulative Diff (%)', cell: info => { return getRatioString(info.getValue(), total, filtered); }, size: 170, meta: { align: 'right', }, invertSorting: true, }), columnHelper.accessor('name', { id: 'name', header: 'Name', cell: info => info.getValue(), }), columnHelper.accessor('functionSystemName', { id: 'functionSystemName', header: 'Function System Name', cell: info => info.getValue(), }), columnHelper.accessor('functionFileName', { id: 'functionFileName', header: 'Function File Name', cell: info => info.getValue(), }), columnHelper.accessor('mappingFile', { id: 'mappingFile', header: 'Mapping File', cell: info => info.getValue(), }), ]; const [columnVisibility, setColumnVisibility] = useState(() => { return { color: true, flat: true, flatPercentage: false, flatDiff: compareMode, flatDiffPercentage: false, cumulative: true, cumulativePercentage: false, cumulativeDiff: compareMode, cumulativeDiffPercentage: false, name: true, functionSystemName: false, functionFileName: false, mappingFile: false, }; }); useEffect(() => { if (Array.isArray(tableColumns)) { // eslint-disable-next-line react-hooks/set-state-in-effect setColumnVisibility(prevState => { const newState = {...prevState}; (Object.keys(newState) as ColumnName[]).forEach(column => { newState[column] = tableColumns.includes(column); }); return newState; }); } }, [tableColumns]); const updateColumnVisibility = (column: string, isVisible: boolean): void => { const updatedColumns = {...columnVisibility, [column]: isVisible}; const newTableColumns = (Object.keys(updatedColumns) as ColumnName[]).filter( col => updatedColumns[col] ); void setTableColumns(newTableColumns); }; return (
{ updateColumnVisibility(id, visible); }} />
); }; export default TableColumnsDropdown;