Untitled

 avatar
unknown
plain_text
23 days ago
4.8 kB
2
Indexable
/* eslint-disable no-shadow, react/jsx-props-no-spreading */
import React, { useRef, useEffect } from 'react';
import { Scrollbars } from 'react-custom-scrollbars';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { ContextMenuTrigger, connectMenu } from 'react-contextmenu';
import ReactTooltip from '../../general/reactTooltip';
import { GetDynamicContexOptions } from '../contextMenu';
import { ReactTableScrollPropTypes, ReactTableScrollDefaultProps } from './reactTableScroll.props';

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,
    virtualizer, // New virtualizer prop
  } = props;

  const tbodyRef = useRef();
  const verticalScrollPosition = useRef();

  // Destructure scroll events
  const { scroll, start: scrollStart, stop: scrollStop } = scrollEvents;

  // Scroll to the correct position when pagination or view changes
  useEffect(() => {
    if (tbodyRef.current) {
      tbodyRef.current.scrollTop(0);
      verticalScrollPosition.current = tbodyRef.current.getScrollTop();
    }
  }, [pageIndex, viewId]);

  // Preserve scroll position when resizing ends
  useEffect(() => {
    if (!isColResizing && verticalScrollPosition.current) {
      tbodyRef.current.scrollTop(verticalScrollPosition.current);
    }
  }, [isColResizing]);

  // Handle scroll events to update the virtualizer
  const handleScroll = () => {
    if (tbodyRef.current) {
      virtualizer.scrollToOffset(tbodyRef.current.getScrollTop());
    }
  };

  // Render context menu if enabled
  const renderContextMenu = () => {
    if (!getContextMenuOptions) return null;
    const ConnectedContextMenu = connectMenu(worklistItemMenuId)(GetDynamicContexOptions);
    return (
      <ConnectedContextMenu
        getOptions={getContextMenuOptions.getOption}
        getSelectedEntities={getContextMenuOptions.getSelectedEntities}
        launchMenu={getContextMenuOptions.launchMenu}
        setSelectedEntityIds={getContextMenuOptions.setSelectedEntityIds}
      />
    );
  };

  return (
    <div className="rt-scroll-container">
      <Scrollbars
        ref={tbodyRef}
        data-cy={dataCy}
        onScroll={handleScroll}
        onScrollStart={scrollStart}
        onScrollStop={() => {
          verticalScrollPosition.current = tbodyRef.current.getScrollTop();
          scrollStop();
        }}
        renderTrackHorizontal={
          horizontalScroll
            ? ({ style, ...props }) => (
                <div
                  {...props}
                  className="scrollbarTrackHorizontal"
                  style={{ ...style, height: '10px' }}
                />
              )
            : () => <div />
        }
        renderTrackVertical={({ style, ...props }) => (
          <div {...props} className="scrollbarTrackVertical" style={{ ...style, width: '10px' }} />
        )}
        style={{ height: heightStyle }}
        className={classNames('tbodyScroll', className)}
      >
        {tableHeader()}

        <div
          style={{
            height: `${virtualizer.getTotalSize()}px`,
            position: 'relative',
          }}
        >
          {virtualizer.getVirtualItems().map(virtualRow => (
            <div
              key={virtualRow.index}
              style={{
                position: 'absolute',
                top: `${virtualRow.start}px`,
                left: 0,
                width: '100%',
              }}
              onDoubleClick={evt =>
                onRowDoubleClicked && onRowDoubleClicked(evt, children[virtualRow.index])
              }
            >
              {children[virtualRow.index]}
            </div>
          ))}
        </div>

        {renderContextMenu()}
      </Scrollbars>
    </div>
  );
};

ReactTableScroll.propTypes = {
  virtualizer: PropTypes.object.isRequired,
  children: PropTypes.array.isRequired,
  className: PropTypes.string,
  dataCy: PropTypes.string,
  getContextMenuOptions: PropTypes.object,
  hasFilter: PropTypes.bool,
  heightStyle: PropTypes.string,
  horizontalScroll: PropTypes.bool,
  isColResizing: PropTypes.bool,
  onRowDoubleClicked: PropTypes.func,
  pageIndex: PropTypes.number,
  scrollEvents: PropTypes.shape({
    scroll: PropTypes.func,
    start: PropTypes.func,
    stop: PropTypes.func,
  }),
  style: PropTypes.object,
  tableHeader: PropTypes.func.isRequired,
  onHide: PropTypes.func,
  viewId: PropTypes.string,
};

ReactTableScroll.defaultProps = ReactTableScrollDefaultProps;

export default ReactTableScroll;
Leave a Comment