Skip to content

Commit

Permalink
Merge pull request #27 from concord-consortium/184773092-scroll-row-v…
Browse files Browse the repository at this point in the history
…alues

184773092 scroll row values
  • Loading branch information
eireland authored Oct 18, 2023
2 parents 773eba7 + 1ce3111 commit 20b3a5b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 11 deletions.
8 changes: 5 additions & 3 deletions src/components/draggable-table-tags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,16 @@ interface DraggagleTableDataProps {
collectionId: number;
attrTitle: string;
style?: React.CSSProperties;
isParent?: boolean;
}

export const DraggagleTableData: React.FC<DraggagleTableDataProps> = ({collectionId, attrTitle, children}) => {
export const DraggagleTableData: React.FC<DraggagleTableDataProps>
= ({collectionId, attrTitle, children, isParent}) => {
const {dragOverId, dragSide} = useDraggableTableContext();
const {style} = getIdAndStyle(collectionId, attrTitle, dragOverId, dragSide);

return (
<td style={style}>
<td style={style} className={`draggable-table-data ${isParent ? "parent-data" : ""}`}>
{children}
</td>
);
Expand All @@ -103,7 +105,7 @@ export const DroppableTableData: React.FC<DroppableTableDataProps> = ({collectio
const dragStyle = getStyle(`${collectionId}`, dragOverId, dragSide);

return (
<td style={{...dragStyle, ...style}}>
<td style={{...dragStyle, ...style}} className="droppable-table-data">
{children}
</td>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/nested-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export const NestedTable = (props: IProps) => {
);
};

const mapCellsFromValues = (collectionId: number, rowKey: string, values: IValues) => {
const mapCellsFromValues = (collectionId: number, rowKey: string, values: IValues, isParent?: boolean) => {
return Object.keys(values).map((key, index) => {
const val = values[key];
if (typeof val === "string" || typeof val === "number") {
Expand All @@ -117,6 +117,7 @@ export const NestedTable = (props: IProps) => {
collectionId={collectionId}
attrTitle={key}
key={`${rowKey}-${val}-${index}}`}
isParent={isParent}
>
{val}
</DraggagleTableData>
Expand Down
76 changes: 70 additions & 6 deletions src/components/portrait-view.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from "react";
import React, { useEffect, useMemo, useState } from "react";
import { ICollection, IProcessedCaseObj, ITableProps } from "../types";
import { DraggableTableContainer, DroppableTableData, DroppableTableHeader } from "./draggable-table-tags";

import css from "./tables.scss";

export type PortraitViewRowProps =
{collectionId: number, caseObj: IProcessedCaseObj, index?: null|number} & ITableProps;
{collectionId: number, caseObj: IProcessedCaseObj, index?: null|number, isParent: boolean} & ITableProps;

export const PortraitViewRow = (props: PortraitViewRowProps) => {
const {paddingStyle, mapCellsFromValues, mapHeadersFromValues, showHeaders,
getClassName, collectionId, caseObj, index} = props;
getClassName, collectionId, caseObj, index, isParent} = props;

const {children, values} = caseObj;

Expand All @@ -28,8 +28,8 @@ export const PortraitViewRow = (props: PortraitViewRowProps) => {
)}
</tr>
}
<tr className={`${css[getClassName(caseObj)]}`}>
{mapCellsFromValues(collectionId, `parent-row-${index}`, values)}
<tr className={`${css[getClassName(caseObj)]} parent-row`}>
{mapCellsFromValues(collectionId, `parent-row-${index}`, values, isParent)}
<DroppableTableData collectionId={collectionId} style={paddingStyle}>
<DraggableTableContainer collectionId={collectionId}>
<table style={paddingStyle} className={`${css.subTable} ${css[getClassName(children[0])]}`}>
Expand All @@ -39,7 +39,8 @@ export const PortraitViewRow = (props: PortraitViewRowProps) => {
...props,
collectionId: child.collection.id,
caseObj: child,
index: i
index: i,
isParent
};
if (i === 0 && !child.children.length) {
return (
Expand All @@ -66,6 +67,68 @@ export const PortraitViewRow = (props: PortraitViewRowProps) => {

export const PortraitView = (props: ITableProps) => {
const {collectionClasses, selectedDataSet, collections, getValueLength} = props;
const thresh = useMemo(() => {
const t: number[] = [];
for (let i = 0; i <= 100; i++) {
t.push(i / 100);
}
return t;
},[]);

const [scrolling, setScrolling] = useState(false);
const [scrollTop, setScrollTop] = useState(0);

useEffect(() => {
const onScroll = (e: any) => {
setScrollTop(e.target.documentElement.scrollTop);
setScrolling(e.target.documentElement.scrollTop > scrollTop);
};
window.addEventListener("scroll", onScroll);

return () => window.removeEventListener("scroll", onScroll);
}, [scrollTop]);

useEffect(() => {
const handleIntersection = (entries: IntersectionObserverEntry[]) => {
entries.forEach((entry) => {
const target = entry.target;
const entryRect = target.getBoundingClientRect();
const entryHeight = entryRect.height;
const intersectionRect = entry.intersectionRect;
const visibleHeight = intersectionRect.height;
const intersectionHeightRatio = visibleHeight/entryHeight;
const cells = Array.from(target.querySelectorAll<HTMLElement>(".parent-data"));

if (cells) {
cells.forEach(cell => {
cell.style.position = "relative";
if (entry.isIntersecting && intersectionHeightRatio < 0.85) {
if (intersectionRect.top === 0) { //we're in the bottom part of the visible rect
cell.style.verticalAlign = "top";
cell.style.top = `${(visibleHeight/2) - entryRect.top - 16}px`;
} else { //we're in the top part of the visible rect
cell.style.verticalAlign = "top";
cell.style.top = `${visibleHeight/2}px`;
}
} else {
cell.style.top = "0";
cell.style.verticalAlign = "middle";
}
});
}
});
};
const observer = new IntersectionObserver(handleIntersection, { threshold: thresh });
document.querySelectorAll(".parent-row").forEach((cell) => {
observer.observe(cell);
});
return () => {
// Clean up the observer when the component unmounts
document.querySelectorAll(".parent-row").forEach((cell) => {
observer.unobserve(cell);
});
};
}, [scrollTop, scrolling, thresh]);

const renderTable = () => {
const parentColl = collections.filter((coll: ICollection) => !coll.parent)[0];
Expand All @@ -90,6 +153,7 @@ export const PortraitView = (props: ITableProps) => {
collectionId={caseObj.collection.id}
caseObj={caseObj}
index={index}
isParent={true}
/>
))}
</tbody>
Expand Down
2 changes: 1 addition & 1 deletion src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export interface ITableProps {
getClassName: (caseObj: IProcessedCaseObj) => string,
selectedDataSet: IDataSet,
collections: Array<ICollection>,
mapCellsFromValues: (collectionId: number, rowKey: string, values: IValues) => void,
mapCellsFromValues: (collectionId: number, rowKey: string, values: IValues, isParent?: boolean) => void,
mapHeadersFromValues: (collectionId: number, rowKey: string, values: IValues) => void,
getValueLength: (firstRow: Array<IValues>) => number
paddingStyle: Record<string, string>
Expand Down

0 comments on commit 20b3a5b

Please sign in to comment.