portainer/app/react/components/datatables/ColumnVisibilityMenu.tsx

92 lines
2.5 KiB
TypeScript

import _ from 'lodash';
import clsx from 'clsx';
import { Menu, MenuButton, MenuList } from '@reach/menu-button';
import { Columns } from 'lucide-react';
import { Table } from '@tanstack/react-table';
import { Checkbox } from '@@/form-components/Checkbox';
interface Props<D extends object> {
onChange: (value: string[]) => void;
value: string[];
table: Table<D>;
}
export function ColumnVisibilityMenu<D extends object>({
onChange,
value,
table,
}: Props<D>) {
const columnsToHide = table.getAllColumns().filter((col) => col.getCanHide());
if (!columnsToHide.length) {
return null;
}
return (
<Menu className="setting">
{({ isExpanded }) => (
<>
<MenuButton
className={clsx('table-setting-menu-btn', {
'setting-active': isExpanded,
})}
>
<Columns
size="13"
className="space-right"
strokeWidth="3px"
aria-hidden="true"
aria-label="Columns"
/>
</MenuButton>
<MenuList>
<div className="tableMenu">
<div className="menuHeader">Show / Hide Columns</div>
<div className="menuContent">
{columnsToHide.map((column) => (
<div key={column.id}>
<Checkbox
checked={column.getIsVisible()}
label={
typeof column.columnDef.header === 'string'
? column.columnDef.header
: _.capitalize(column.columnDef.id)
}
id={`visibility_${column.id}`}
onChange={(e) =>
handleChangeColumnVisibility(
column.id,
e.target.checked
)
}
/>
</div>
))}
</div>
</div>
</MenuList>
</>
)}
</Menu>
);
function handleChangeColumnVisibility(colId: string, visible: boolean) {
const newValue = visible
? value.filter((id) => id !== colId)
: [...value, colId];
table.setColumnVisibility(
Object.fromEntries(newValue.map((col) => [col, false]))
);
onChange(newValue);
}
}
export function getColumnVisibilityState(hiddenColumns: string[]) {
return {
columnVisibility: Object.fromEntries(
hiddenColumns.map((col) => [col, false])
),
};
}