Untitled
unknown
plain_text
a year ago
6.6 kB
5
Indexable
/* 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;
Editor is loading...
Leave a Comment