Fix grid scrolling issue (#3583)

* Fix grid scrolling issue

* Remove outline

* Strict null checks

* Strict null checks

* Strict null checks
This commit is contained in:
Michał Miszczyszyn 2023-05-02 12:10:40 +02:00 committed by GitHub
parent cb3f7d971c
commit 7c933f0d9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 38 deletions

2
package-lock.json generated
View file

@ -17,7 +17,7 @@
"@editorjs/list": "^1.7.0",
"@editorjs/paragraph": "^2.8.0",
"@editorjs/quote": "^2.4.0",
"@glideapps/glide-data-grid": "^5.0.0",
"@glideapps/glide-data-grid": "5.2.1",
"@glideapps/glide-data-grid-cells": "^5.2.1",
"@graphiql/plugin-explorer": "^0.1.12",
"@graphiql/react": "^0.15.0",

View file

@ -24,7 +24,7 @@
"@editorjs/list": "^1.7.0",
"@editorjs/paragraph": "^2.8.0",
"@editorjs/quote": "^2.4.0",
"@glideapps/glide-data-grid": "^5.0.0",
"@glideapps/glide-data-grid": "5.2.1",
"@glideapps/glide-data-grid-cells": "^5.2.1",
"@graphiql/plugin-explorer": "^0.1.12",
"@graphiql/react": "^0.15.0",
@ -185,6 +185,16 @@
},
"optionalDependencies": {
"@storybook/react": "^5.1.9",
"@swc/core-darwin-arm64": "1.3.40",
"@swc/core-darwin-x64": "1.3.40",
"@swc/core-linux-arm-gnueabihf": "1.3.40",
"@swc/core-linux-arm64-gnu": "1.3.40",
"@swc/core-linux-arm64-musl": "1.3.40",
"@swc/core-linux-x64-gnu": "1.3.40",
"@swc/core-linux-x64-musl": "1.3.40",
"@swc/core-win32-arm64-msvc": "1.3.40",
"@swc/core-win32-ia32-msvc": "1.3.40",
"@swc/core-win32-x64-msvc": "1.3.40",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^8.0.1",
@ -224,17 +234,7 @@
"mochawesome-report-generator": "^6.0.1",
"prettier": "^2.8.4",
"setup-polly-jest": "^0.9.1",
"ts-jest": "^27.1.5",
"@swc/core-darwin-arm64": "1.3.40",
"@swc/core-darwin-x64": "1.3.40",
"@swc/core-linux-arm-gnueabihf": "1.3.40",
"@swc/core-linux-arm64-gnu": "1.3.40",
"@swc/core-linux-arm64-musl": "1.3.40",
"@swc/core-linux-x64-gnu": "1.3.40",
"@swc/core-linux-x64-musl": "1.3.40",
"@swc/core-win32-arm64-msvc": "1.3.40",
"@swc/core-win32-ia32-msvc": "1.3.40",
"@swc/core-win32-x64-msvc": "1.3.40"
"ts-jest": "^27.1.5"
},
"//@swc/*": "swc packages are required until https://github.com/npm/cli/issues/4828 is fixed",
"jest": {

View file

@ -1,8 +1,10 @@
import "@glideapps/glide-data-grid/dist/index.css";
import { getAppMountUri } from "@dashboard/config";
import useNavigator from "@dashboard/hooks/useNavigator";
import { usePreventHistoryBack } from "@dashboard/hooks/usePreventHistoryBack";
import DataEditor, {
CellClickedEventArgs,
DataEditorProps,
DataEditorRef,
EditableGridCell,
@ -129,10 +131,10 @@ export const Datagrid: React.FC<DatagridProps> = ({
const classes = useStyles();
const { themeValues } = useTheme();
const datagridTheme = useDatagridTheme(readonly, readonly);
const editor = useRef<DataEditorRef>();
const editor = useRef<DataEditorRef | null>(null);
const customRenderers = useCustomCellRenderers();
const hackARef = useRef<HTMLAnchorElement>(null);
const hackARef = useRef<HTMLAnchorElement | null>(null);
const navigate = useNavigator();
const { scrolledToRight, scroller } = useScrollRight();
@ -210,6 +212,10 @@ export const Datagrid: React.FC<DatagridProps> = ({
const handleOnCellEdited = useCallback(
([column, row]: Item, newValue: EditableGridCell): void => {
onCellEdited([column, row], newValue);
if (!editor.current) {
return;
}
editor.current.updateCells(
range(availableColumns.length).map(offset => ({
cell: [column + offset, row],
@ -219,15 +225,6 @@ export const Datagrid: React.FC<DatagridProps> = ({
[onCellEdited, availableColumns],
);
const handleCellClick = useCallback(
(item: Item) => {
if (onRowClick && item[0] !== -1) {
onRowClick(item);
}
},
[onRowClick],
);
const handleRowHover = useCallback(
(args: GridMouseEventArgs) => {
if (hasRowHover) {
@ -249,11 +246,26 @@ export const Datagrid: React.FC<DatagridProps> = ({
hackARef.current.style.width = `${args.bounds.width}px`;
hackARef.current.style.top = `${window.scrollY + args.bounds.y}px`;
hackARef.current.style.height = `${args.bounds.height}px`;
hackARef.current.href = href;
hackARef.current.href =
getAppMountUri() + (href.startsWith("/") ? href.slice(1) : href);
hackARef.current.dataset.reactRouterPath = href;
},
[hasRowHover, rowAnchor],
);
const handleCellClick = useCallback(
(item: Item, args: CellClickedEventArgs) => {
if (onRowClick && item[0] !== -1) {
onRowClick(item);
}
handleRowHover(args);
if (hackARef.current) {
hackARef.current.click();
}
},
[onRowClick, handleRowHover],
);
const handleGridSelectionChange = (gridSelection: GridSelection) => {
// In readonly we not allow selecting cells, but we allow selcting column
if (readonly && !gridSelection.current) {
@ -275,7 +287,7 @@ export const Datagrid: React.FC<DatagridProps> = ({
themeValues.colors.background.interactiveNeutralSecondaryHovering,
bgCellMedium:
themeValues.colors.background.interactiveNeutralSecondaryHovering,
accentLight: undefined,
accentLight: undefined as string | undefined,
};
if (readonly) {
@ -321,6 +333,9 @@ export const Datagrid: React.FC<DatagridProps> = ({
clearTooltip();
}
if (!onColumnResize) {
return;
}
onColumnResize(column, newSize);
},
[clearTooltip, onColumnResize, tooltip],
@ -331,6 +346,9 @@ export const Datagrid: React.FC<DatagridProps> = ({
if (tooltip) {
clearTooltip();
}
if (!onColumnMoved) {
return;
}
onColumnMoved(startIndex, endIndex);
},
[clearTooltip, onColumnMoved, tooltip],
@ -338,7 +356,7 @@ export const Datagrid: React.FC<DatagridProps> = ({
const selectionActionsComponent = useMemo(
() =>
selection?.rows.length > 0
selection?.rows && selection?.rows.length > 0
? selectionActions(Array.from(selection.rows), {
removeRows: handleRemoveRows,
})
@ -346,6 +364,29 @@ export const Datagrid: React.FC<DatagridProps> = ({
[selection, selectionActions, handleRemoveRows],
);
// Hide the link when scrolling over it so that the scroll/wheel events go through to the Datagrid
// Show the link quickly after the last scroll/wheel event
const hideLinkAndShowAfterDelay = useCallback(
(() => {
let timer: ReturnType<typeof setTimeout> | null = null;
return () => {
if (timer) {
clearTimeout(timer);
}
if (hackARef.current) {
hackARef.current.style.display = "none";
}
timer = setTimeout(() => {
if (hackARef.current) {
hackARef.current.style.display = "block";
}
}, 100);
};
})(),
[hackARef],
);
if (loading) {
return (
<Box display="flex" justifyContent="center" marginY={12}>
@ -387,7 +428,7 @@ export const Datagrid: React.FC<DatagridProps> = ({
<CardContent classes={{ root: classes.cardContentRoot }}>
{rowsTotal > 0 ? (
<>
{selection?.rows.length > 0 && (
{selection?.rows && selection?.rows.length > 0 && (
<div className={classes.actionBtnBar}>
{selectionActionsComponent}
</div>
@ -510,16 +551,21 @@ export const Datagrid: React.FC<DatagridProps> = ({
bounds={tooltip?.bounds}
title={tooltip?.title}
/>
{rowAnchor && (
<a
ref={hackARef}
style={{ position: "absolute" }}
tabIndex={-1}
aria-hidden={true}
onWheelCapture={hideLinkAndShowAfterDelay}
onClick={e => {
e.preventDefault();
navigate(e.currentTarget.pathname);
if (e.currentTarget.dataset.reactRouterPath) {
navigate(e.currentTarget.dataset.reactRouterPath);
}
}}
/>
)}
</FullScreenContainer>
);
};