Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fixed jumping issue by manually calculating row heights #775

Merged
merged 5 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe('AddMetadataRow Component', () => {
const addButton = screen.getByText('ADD').closest('button') as HTMLElement;
userEvent.click(addButton);

const errorMessage = screen.getByText('All metadata keys must be unique');
const errorMessage = screen.getByText('All keys must be unique');
expect(errorMessage).toBeInTheDocument();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const AddMetadataRow: React.FC<IAddMetadataRowModel> = (props) => {
variant="outlined"
placeholder={keyPlaceholderText || 'New metadata key'}
fullWidth
helperText={!isValid ? errorMessage || 'All metadata keys must be unique' : ''}
helperText={!isValid ? errorMessage || 'All keys must be unique' : ''}
error={!isValid}
value={metadataRow.metadataKey}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ const EditAnalyses: React.FC<{ disabled: boolean }> = React.memo(({ disabled })
};

useEffect(() => {
if (!selectedAnalysisId && analyses.length > 0) {
const exists = analyses.find((analysis) => analysis.id === selectedAnalysisId);

if ((analyses.length > 0 && !selectedAnalysisId) || (!exists && analyses.length > 0)) {
// select the first analysis on first render
setSelectedAnalysisId(analyses[0].id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const hotSettings: HotTableProps = {
width: '100%',
fixedColumnsStart: 2,
wordWrap: true,
autoRowSize: true,
autoRowSize: false,
afterGetRowHeaderRenderers: (headerRenderers) => {
headerRenderers.push((row, TH) => {
TH.className = styles['no-top-bottom-borders'];
Expand Down Expand Up @@ -150,12 +150,13 @@ export const createColumnHeader = (
export const createColumns = (noteKeys: NoteKeyType[], disable?: boolean) =>
[
{
className: `${styles['study-col']} ${styles['read-only-col']} truncate`,
className: `${styles['study-col']} ${styles['read-only-col']}`,
readOnly: true,
},
{
className: styles['read-only-col'],
className: `${styles['read-only-col']} ${styles['truncate']}`,
readOnly: true,
wordWrap: false,
},
...noteKeys.map((x) => {
return {
Expand All @@ -173,7 +174,8 @@ export const createColumns = (noteKeys: NoteKeyType[], disable?: boolean) =>
}),
] as ColumnSettings[];

// we can assume that the input is already sorted
// we can assume that the hashmap maintains order and is sorted by key
// this function gets all merge cells and only merge cells. If a cell does not need to be merged, a mergeCellObj is not creatd
export const getMergeCells = (
hotDataToStudyMapping: Map<number, { studyId: string; analysisId: string }>
) => {
Expand Down Expand Up @@ -206,3 +208,62 @@ export const getMergeCells = (

return mergeCells;
};

const getCalculatedRowHeight = (title: string, maxWidthInPx: number) => {
const container = document.createElement('td');
container.style.maxWidth = `${maxWidthInPx - 10}px`; // account for padding and borders
container.style.width = `${maxWidthInPx - 10}px`; // account for padding and borders

container.style.fontSize = '13px'; // handsontable default font size
container.style.fontFamily =
'-apple-system, system-ui, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Helvetica Neue", Arial, sans-serif';
container.style.lineHeight = '21px'; // handsontable default line height
container.style.border = '1px solid black';
container.style.padding = '0px 4px';
container.style.fontWeight = '400';
container.style.display = 'table-cell';
container.style.textAlign = 'center';

container.innerText = title;
document.body.appendChild(container);
const height = container.offsetHeight;
container.parentNode?.removeChild(container);
return height;
};

export const getRowHeights = (
hotData: AnnotationNoteValue[][],
mergeCells: MergeCellsSettings[],
maxWidthInPx: number
) => {
const rowHeights: number[] = [];
let currIndex = 0;

mergeCells.forEach(({ row, col, rowspan, colspan }) => {
while (currIndex < row) {
// sometimes the merge cells skip a few rows as they do not need to be merged.
// we therefore need to account for that by calculting those row heights (which have rowspan = 1)
const currIndexTitle = hotData[currIndex][0] as string;
rowHeights.push(getCalculatedRowHeight(currIndexTitle, maxWidthInPx));
currIndex++;
}
const title = hotData[row][0] as string;
const height = getCalculatedRowHeight(title, maxWidthInPx);

const potentialRowHeight = Math.ceil(height / rowspan);
if (rowspan * 23 >= height) {
// the title is smaller than the space taken up by the analyses
for (let i = 0; i < rowspan; i++) {
rowHeights.push(potentialRowHeight < 23 ? 23 : potentialRowHeight);
}
} else {
// the title is bigger than the space taken up by the analyses
// we want to split that space evenly
for (let i = 0; i < rowspan; i++) {
rowHeights.push(potentialRowHeight);
}
}
currIndex = currIndex + rowspan;
});
return rowHeights;
};
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const AnnotationsHotTable: React.FC<{ annotationId?: string }> = React.memo((pro
noteKeys,
hotDataToStudyMapping,
isEdited,
rowHeights,
} = useEditAnnotationsHotTable(props.annotationId, !canEdit);

useEffect(() => {
Expand Down Expand Up @@ -166,7 +167,7 @@ const AnnotationsHotTable: React.FC<{ annotationId?: string }> = React.memo((pro
TD: HTMLTableCellElement,
controller: SelectionController
): void => {
const isRowHeader = coords.col === -1;
const isRowHeader = coords.col === -1 || coords.col === 0;
if (isRowHeader) {
event.stopImmediatePropagation();
return;
Expand Down Expand Up @@ -224,7 +225,7 @@ const AnnotationsHotTable: React.FC<{ annotationId?: string }> = React.memo((pro

return (
<Box>
{theUserOwnsThisAnnotation && !canEdit && (
{theUserOwnsThisAnnotation && canEdit && (
<Box
className="neurosynth-annotation-component"
sx={[AnnotationsHotTableStyles.addMetadataRow]}
Expand All @@ -235,7 +236,7 @@ const AnnotationsHotTable: React.FC<{ annotationId?: string }> = React.memo((pro
showMetadataValueInput={false}
allowNumber={false}
allowNone={false}
errorMessage="cannot add annotation - this key may already exist"
errorMessage="can't add column (key already exists)"
/>
</Box>
)}
Expand All @@ -249,6 +250,7 @@ const AnnotationsHotTable: React.FC<{ annotationId?: string }> = React.memo((pro
disableVisualSelection={!canEdit}
colHeaders={hotColumnHeaders}
colWidths={colWidths}
rowHeights={rowHeights}
columns={hotColumns}
data={JSON.parse(JSON.stringify(hotData))}
afterOnCellMouseUp={handleCellMouseUp}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
createColumnHeader,
getMergeCells,
createColumns,
getRowHeights,
} from 'components/HotTables/EditAnnotationsHotTable/EditAnnotationsHotTable.helpers';

const useEditAnnotationsHotTable = (annotationId?: string, disableEdit?: boolean) => {
Expand Down Expand Up @@ -82,16 +83,21 @@ const useEditAnnotationsHotTable = (annotationId?: string, disableEdit?: boolean
}, [annotationsHotState.noteKeys]);

const colWidths = useMemo(() => {
return createColWidths(annotationsHotState.noteKeys, 200, 150, 200);
return createColWidths(annotationsHotState.noteKeys, 300, 150, 200);
}, [annotationsHotState.noteKeys]);

const rowHeights = useMemo(() => {
return getRowHeights(annotationsHotState.hotData, annotationsHotState.mergeCells, 300);
}, [annotationsHotState.hotData, annotationsHotState.mergeCells]);

return {
theUserOwnsThisAnnotation,
getAnnotationIsLoading,
getAnnotationIsError,
hotColumnHeaders,
setAnnotationsHotState,
colWidths,
rowHeights,
...annotationsHotState,
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const useEditStudyAnnotationsHotTable = (readonly?: boolean) => {
const MIN_HEIGHT_PX = 100;
const MAX_HEIGHT_PX = 500;
const HEADER_HEIGHT_PX = 26;
const ROW_HEIGHT_PX = 24 + 24; // +24 to padd row height a little bit
const ROW_HEIGHT_PX = 24; // +24 to padd row height a little bit

const visibleNotes = (notes || []).filter((x) => x.study === studyId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@
.null {
color: gray !important;
text-align: center !important;
}
}
Loading