/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import {CopyOutlined, FilterOutlined, TableOutlined} from '@ant-design/icons'; import {Checkbox, Menu} from 'antd'; import { DataTableDispatch, getSelectedItem, getSelectedItems, getValueAtPath, Selection, } from './DataTableWithPowerSearchManager'; import React from 'react'; import { _tryGetFlipperLibImplementation, _DataSourceView, } from 'flipper-plugin-core'; import {DataTableColumn} from './DataTableWithPowerSearch'; import {toFirstUpper} from '../../utils/toFirstUpper'; import {renderColumnValue} from './TableRow'; import {textContent} from '../../utils/textContent'; const {Item, SubMenu} = Menu; export function tableContextMenuFactory( dataView: _DataSourceView, dispatch: DataTableDispatch, selection: Selection, columns: DataTableColumn[], visibleColumns: DataTableColumn[], onCopyRows: ( rows: T[], visibleColumns: DataTableColumn[], ) => string = defaultOnCopyRows, onContextMenu?: (selection: undefined | T) => React.ReactElement, sideBySideOption?: React.ReactElement, ) { const lib = _tryGetFlipperLibImplementation(); if (!lib) { return ( Menu not ready ); } const hasSelection = selection.items.size > 0 ?? false; return ( {onContextMenu ? onContextMenu(getSelectedItem(dataView, selection)) : null} } disabled={!hasSelection}> {visibleColumns.map((column, idx) => ( { dispatch({ type: 'setSearchExpressionFromSelection', column, }); }}> {friendlyColumnTitle(column)} ))} } disabled={!hasSelection}> { const items = getSelectedItems(dataView, selection); if (items.length) { lib.writeTextToClipboard(onCopyRows(items, visibleColumns)); } }}> Copy row(s) {lib.isFB && ( { const items = getSelectedItems(dataView, selection); if (items.length) { lib.createPaste(onCopyRows(items, visibleColumns)); } }}> Create paste )} { const items = getSelectedItems(dataView, selection); if (items.length) { lib.writeTextToClipboard(rowsToJson(items)); } }}> Copy row(s) (JSON) {lib.isFB && ( { const items = getSelectedItems(dataView, selection); if (items.length) { lib.createPaste(rowsToJson(items)); } }}> Create paste (JSON) )} } disabled={!hasSelection}> {visibleColumns.map((column, idx) => ( { const items = getSelectedItems(dataView, selection); if (items.length) { lib.writeTextToClipboard( items .map((item) => '' + getValueAtPath(item, column.key)) .join('\n'), ); } }}> {friendlyColumnTitle(column)} ))} {columns.map((column, idx) => ( { e.stopPropagation(); e.preventDefault(); dispatch({type: 'toggleColumnVisibility', column: column.key}); }}> {friendlyColumnTitle(column)} ))} { dispatch({type: 'resetFilters'}); }}> Reset filters { dispatch({type: 'reset'}); }}> Reset view {sideBySideOption} ); } function friendlyColumnTitle(column: DataTableColumn): string { const name = column.title || column.key; return toFirstUpper(name); } function defaultOnCopyRows( items: T[], visibleColumns: DataTableColumn[], ) { return ( visibleColumns.map(friendlyColumnTitle).join('\t') + '\n' + items .map((row, idx) => visibleColumns .map((col) => textContent(renderColumnValue(col, row, true, idx))) .join('\t'), ) .join('\n') ); } function rowsToJson(items: T[]) { return JSON.stringify(items.length > 1 ? items : items[0], null, 2); }