Untitled
/* eslint-disable no-shadow, react/jsx-props-no-spreading */ import React, { useEffect, useRef } from 'react'; import _, { noop } from 'lodash'; import { Scrollbars } from 'react-custom-scrollbars'; import classNames from 'classnames'; import { ContextMenuTrigger, connectMenu } from 'react-contextmenu'; import ReactTooltip from '../../general/reactTooltip'; import { GetDynamicContexOptions } from '../contextMenu'; import { ReactTableScrollPropTypes, ReactTableScrollDefaultProps } from './reactTableScroll.props'; /** * Ensures 2D scrolling when table width is larger than browser width * Moves table header and filter horizontally to be synced with table body * Only supports react-custom-scrollbars component */ const worklistItemMenuId = 'grid-context-menu'; const ReactTableScroll = function (props) { const { children, className, dataCy, getContextMenuOptions, hasFilter, heightStyle, horizontalScroll, isColResizing, onRowDoubleClicked, pageIndex, scrollEvents, style, tableHeader, onHide, viewId, ref } = props; const tbody = useRef(); const verticalScrollPosition = useRef(); const { scroll, start: scrollStart, stop: scrollStop } = scrollEvents; const { confirmation } = getContextMenuOptions || {}; const _className = classNames(className, { 'rt-tbody': true, }); const headHeight = hasFilter ? 72 : 36; useEffect(() => { // Reset scroll position to top-left when pagination change if (tbody && tbody.current) { tbody.current.scrollToTop(); tbody.current.scrollToLeft(); verticalScrollPosition.current = tbody.current.getScrollTop(); } return () => {}; }, [pageIndex, viewId]); useEffect(() => { /* If we just stopped resizing the columns -> Reset vertical scroll position to where it was before we started the resizing */ if (!isColResizing) tbody.current.scrollTop(verticalScrollPosition.current); }, [isColResizing]); useEffect(() => { if (verticalScrollPosition.current) tbody.current.scrollTop(verticalScrollPosition.current); }, [children]); function saveScrollPositionAndStop() { // if we are NOT currently resizing the columns -> Save the current vertical scroll position if (!isColResizing) verticalScrollPosition.current = tbody.current.getScrollTop(); scrollStop(); } function renderContextMenu() { if (!getContextMenuOptions) return null; const ConnectedContextMenu = connectMenu(worklistItemMenuId)(GetDynamicContexOptions); return ( <ConnectedContextMenu getOptions={getContextMenuOptions.getOption} getSelectedEntities={getContextMenuOptions.getSelectedEntities} launchMenu={getContextMenuOptions.launchMenu} setSelectedEntityIds={getContextMenuOptions.setSelectedEntityIds} /> ); } function getWorklistEntityRowOfChild(child) { const tableProps = child.props; const columnsProps = tableProps.children[0].props; if (columnsProps.entity) return columnsProps.entity; const columnCell = columnsProps.children[0].props.children; return columnCell?.props?.original; } // eslint-disable-next-line max-len const renderContent = () => confirmation && !_.isEmpty(confirmation) ? confirmation.renderContent : noop; const getArrowProps = arrowProps => ({ ...arrowProps, style: { left: 180 } }); function getEntities() { if (!getContextMenuOptions && !onRowDoubleClicked) return children; if (!children) return; const rows = children; const container = document.getElementsByClassName('-worklist-table')[0]; return rows.map(child => { const entityOfChild = getWorklistEntityRowOfChild(child); return ( <div key={`child-${entityOfChild ? entityOfChild.id : ''}-${child.key}`} onDoubleClick={evt => onRowDoubleClicked && onRowDoubleClicked(evt, child)}> {getContextMenuOptions ? ( <ContextMenuTrigger collect={prop => prop} data={entityOfChild} holdToDisplay={-1} id={worklistItemMenuId}> <ReactTooltip onCloseClick={onHide} boundariesElement={container} container={container} customStyle={{ width: 'auto' }} forceShow={confirmation && entityOfChild.id === confirmation?.entityId} getArrowProps={getArrowProps} hasCloseIcon={confirmation ? confirmation.hasCloseIcon : false} key="confirmation-popup" offset={450} placement="bottom-start" renderContent={popup => renderContent()(popup)} title={confirmation?.title} trigger="none"> {({ getTriggerProps, triggerRef }) => ( // eslint-disable-next-line react/jsx-props-no-spreading <div className="tooltip-div" {...getTriggerProps({ ref: triggerRef })}> {child} </div> )} </ReactTooltip> </ContextMenuTrigger> ) : ( <div>{child}</div> )} </div> ); }); } return ( <div ref={ref}> <Scrollbars data-cy={dataCy} onScroll={scroll} onScrollStart={scrollStart} onScrollStop={saveScrollPositionAndStop} ref={tbody} renderTrackHorizontal={ horizontalScroll ? ({ style, ...props }) => ( <div {...props} className="scrollbarTrackHorizontal" style={{ ...style, height: '10px' }} /> ) : () => <div /> } renderTrackVertical={({ style, ...props }) => ( <div {...props} className="scrollbarTrackVertical" style={{ ...style, width: '10px', top: `${headHeight}px` }} /> )} className={classNames('tbodyScroll', `tbodyScroll--${_className}`)} style={{ height: heightStyle }}> {tableHeader()} <div className={_className} style={{ ...style }}> {getEntities()} {renderContextMenu()} </div> </Scrollbars> </div> ); }; ReactTableScroll.propTypes = ReactTableScrollPropTypes; ReactTableScroll.defaultProps = ReactTableScrollDefaultProps; export default ReactTableScroll;
Leave a Comment