import React from "react"; import Table from "./Table"; import type { AddNewRowActions, CompactMode, ReactTableColumnProps, ReactTableFilter, StickyType, } from "./Constants"; import type { Row } from "react-table"; import type { EventType } from "constants/AppsmithActionConstants/ActionConstants"; import equal from "fast-deep-equal/es6"; import type { EditableCell, TableVariant } from "../constants"; import { ColumnTypes } from "../constants"; import { useCallback } from "react"; export interface ColumnMenuOptionProps { content: string | JSX.Element; closeOnClick?: boolean; isSelected?: boolean; editColumnName?: boolean; columnAccessor?: string; id?: string; category?: boolean; options?: ColumnMenuSubOptionProps[]; onClick?: (columnIndex: number, isSelected: boolean) => void; } export interface ColumnMenuSubOptionProps { content: string | JSX.Element; isSelected?: boolean; closeOnClick?: boolean; onClick?: (columnIndex: number) => void; id?: string; category?: boolean; isHeader?: boolean; } interface ReactTableComponentProps { widgetId: string; widgetName: string; searchKey: string; isDisabled?: boolean; isVisible?: boolean; isLoading: boolean; editMode: boolean; editableCell: EditableCell; width: number; height: number; pageSize: number; totalRecordsCount?: number; tableData: Array>; disableDrag: (disable: boolean) => void; onBulkEditDiscard: () => void; onBulkEditSave: () => void; onRowClick: (rowData: Record, rowIndex: number) => void; selectAllRow: (pageData: Row>[]) => void; unSelectAllRow: (pageData: Row>[]) => void; updatePageNo: (pageNo: number, event?: EventType) => void; sortTableColumn: (column: string, asc: boolean) => void; nextPageClick: () => void; prevPageClick: () => void; pageNo: number; serverSidePaginationEnabled: boolean; selectedRowIndex: number; selectedRowIndices: number[]; multiRowSelection?: boolean; hiddenColumns?: string[]; triggerRowSelection: boolean; columnWidthMap?: { [key: string]: number }; handleResizeColumn: (columnWidthMap: { [key: string]: number }) => void; handleReorderColumn: (columnOrder: string[]) => void; searchTableData: (searchKey: any) => void; filters?: ReactTableFilter[]; applyFilter: (filters: ReactTableFilter[]) => void; columns: ReactTableColumnProps[]; compactMode?: CompactMode; isVisibleSearch?: boolean; isVisibleFilters?: boolean; isVisibleDownload?: boolean; isVisiblePagination?: boolean; delimiter: string; isSortable?: boolean; accentColor: string; borderRadius: string; boxShadow: string; borderColor?: string; borderWidth?: number; variant?: TableVariant; isEditableCellsValid?: Record; primaryColumnId?: string; isAddRowInProgress: boolean; allowAddNewRow: boolean; onAddNewRow: () => void; onAddNewRowAction: ( type: AddNewRowActions, onActionComplete: () => void, ) => void; allowRowSelection: boolean; allowSorting: boolean; disabledAddNewRowSave: boolean; handleColumnFreeze?: (columnName: string, sticky?: StickyType) => void; canFreezeColumn?: boolean; } function ReactTableComponent(props: ReactTableComponentProps) { const { allowAddNewRow, allowRowSelection, allowSorting, applyFilter, borderColor, borderWidth, canFreezeColumn, columns, columnWidthMap, compactMode, delimiter, disabledAddNewRowSave, disableDrag, editableCell, editMode, filters, handleColumnFreeze, handleReorderColumn, handleResizeColumn, height, isAddRowInProgress, isLoading, isSortable, isVisibleDownload, isVisibleFilters, isVisiblePagination, isVisibleSearch, multiRowSelection, nextPageClick, onAddNewRow, onAddNewRowAction, onBulkEditDiscard, onBulkEditSave, onRowClick, pageNo, pageSize, prevPageClick, primaryColumnId, searchKey, searchTableData, selectAllRow, selectedRowIndex, selectedRowIndices, serverSidePaginationEnabled, sortTableColumn: _sortTableColumn, tableData, totalRecordsCount, triggerRowSelection, unSelectAllRow, updatePageNo, variant, widgetId, widgetName, width, } = props; const sortTableColumn = useCallback( (columnIndex: number, asc: boolean) => { if (allowSorting) { if (columnIndex === -1) { _sortTableColumn("", asc); } else { const column = columns[columnIndex]; const columnType = column.metaProperties?.type || ColumnTypes.TEXT; if ( columnType !== ColumnTypes.IMAGE && columnType !== ColumnTypes.VIDEO ) { _sortTableColumn(column.alias, asc); } } } }, [_sortTableColumn, allowSorting, columns], ); const selectTableRow = useCallback( (row: { original: Record; index: number }) => { if (allowRowSelection) { onRowClick(row.original, row.index); } }, [allowRowSelection, onRowClick], ); const toggleAllRowSelect = useCallback( (isSelect: boolean, pageData: Row>[]) => { if (allowRowSelection) { if (isSelect) { selectAllRow(pageData); } else { unSelectAllRow(pageData); } } }, [allowRowSelection, selectAllRow, unSelectAllRow], ); const memoziedDisableDrag = useCallback( () => disableDrag(true), [disableDrag], ); const memoziedEnableDrag = useCallback( () => disableDrag(false), [disableDrag], ); return ( ); } export default React.memo(ReactTableComponent, (prev, next) => { return ( prev.applyFilter === next.applyFilter && prev.compactMode === next.compactMode && prev.delimiter === next.delimiter && prev.disableDrag === next.disableDrag && prev.editMode === next.editMode && prev.isSortable === next.isSortable && prev.filters === next.filters && prev.handleReorderColumn === next.handleReorderColumn && prev.handleResizeColumn === next.handleResizeColumn && prev.height === next.height && prev.isLoading === next.isLoading && prev.isVisibleDownload === next.isVisibleDownload && prev.isVisibleFilters === next.isVisibleFilters && prev.isVisiblePagination === next.isVisiblePagination && prev.isVisibleSearch === next.isVisibleSearch && prev.nextPageClick === next.nextPageClick && prev.onRowClick === next.onRowClick && prev.pageNo === next.pageNo && prev.pageSize === next.pageSize && prev.prevPageClick === next.prevPageClick && prev.searchKey === next.searchKey && prev.searchTableData === next.searchTableData && prev.selectedRowIndex === next.selectedRowIndex && prev.selectedRowIndices === next.selectedRowIndices && prev.serverSidePaginationEnabled === next.serverSidePaginationEnabled && prev.sortTableColumn === next.sortTableColumn && prev.totalRecordsCount === next.totalRecordsCount && prev.triggerRowSelection === next.triggerRowSelection && prev.updatePageNo === next.updatePageNo && prev.widgetId === next.widgetId && prev.widgetName === next.widgetName && prev.width === next.width && prev.borderRadius === next.borderRadius && prev.boxShadow === next.boxShadow && prev.borderWidth === next.borderWidth && prev.borderColor === next.borderColor && prev.accentColor === next.accentColor && //shallow equal possible equal(prev.columnWidthMap, next.columnWidthMap) && //static reference prev.tableData === next.tableData && // Using JSON stringify becuase isEqual doesnt work with functions, // and we are not changing the columns manually. prev.columns === next.columns && equal(prev.editableCell, next.editableCell) && prev.variant === next.variant && prev.primaryColumnId === next.primaryColumnId && equal(prev.isEditableCellsValid, next.isEditableCellsValid) && prev.isAddRowInProgress === next.isAddRowInProgress && prev.allowAddNewRow === next.allowAddNewRow && prev.allowRowSelection === next.allowRowSelection && prev.allowSorting === next.allowSorting && prev.disabledAddNewRowSave === next.disabledAddNewRowSave && prev.canFreezeColumn === next.canFreezeColumn ); });