Skip to content

Commit

Permalink
Fix performance issue on product datagrid (#4894)
Browse files Browse the repository at this point in the history
* Debounce href on row, make all cell cursor pointer

* Fix date cell

* Remove img

* Revert "Remove img"

This reverts commit eb24ac7.

* Imrpove  thumbnail draw

* Revert "Fix date cell"

This reverts commit 265ead7.

* Single date format

* optimaze date with single format

* Improve with all date formats

* Add missing cursor pointer

* Refactor datagrid row hover to hook

* Add changeset

* Improve changeset

* Split row anchor logic

* Refactor DateCell

* wrap  function in useRowAnchor into useCallback

* Fix typo
  • Loading branch information
poulch committed Jun 4, 2024
1 parent 9a6e52d commit cb1c95f
Show file tree
Hide file tree
Showing 15 changed files with 355 additions and 162 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-lions-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

You can now hover over each row in product datagrid and hover effect will be fast and smooth
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export const createGetCellContent =
],
[label],
{
cursor: "pointer",
readonly: true,
allowOverlay: false,
},
Expand Down
69 changes: 21 additions & 48 deletions src/components/Datagrid/Datagrid.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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, {
Expand All @@ -10,7 +9,6 @@ import DataEditor, {
EditableGridCell,
GridCell,
GridColumn,
GridMouseEventArgs,
GridSelection,
HeaderClickedEventArgs,
Item,
Expand Down Expand Up @@ -46,6 +44,8 @@ import useDatagridChange, {
} from "./hooks/useDatagridChange";
import { useFullScreenMode } from "./hooks/useFullScreenMode";
import { usePortalClasses } from "./hooks/usePortalClasses";
import { useRowAnchor } from "./hooks/useRowAnchor";
import { useRowHover } from "./hooks/useRowHover";
import { useScrollRight } from "./hooks/useScrollRight";
import { useTooltipContainer } from "./hooks/useTooltipContainer";
import useStyles, {
Expand Down Expand Up @@ -144,8 +144,6 @@ export const Datagrid: React.FC<DatagridProps> = ({
const datagridTheme = useDatagridTheme(readonly, readonly);
const editor = useRef<DataEditorRef | null>(null);
const customRenderers = useCustomCellRenderers();

const hackARef = useRef<HTMLAnchorElement | null>(null);
const navigate = useNavigator();

const { scrolledToRight, scroller } = useScrollRight();
Expand All @@ -156,9 +154,18 @@ export const Datagrid: React.FC<DatagridProps> = ({
const { clearTooltip, tooltip, setTooltip } = useTooltipContainer();

const [selection, setSelection] = useState<GridSelection>();
const [hoverRow, setHoverRow] = useState<number | undefined>(undefined);
const [areCellsDirty, setCellsDirty] = useState(true);

const { rowAnchorRef, setRowAnchorRef, setAnchorPosition } = useRowAnchor({
getRowAnchorUrl: rowAnchor,
rowMarkers,
});

const { handleRowHover, hoverRow } = useRowHover({
hasRowHover,
onRowHover: setAnchorPosition,
});

// Allow to listen to which row is selected and notfiy parent component
useEffect(() => {
if (onRowSelectionChange && selection) {
Expand Down Expand Up @@ -275,40 +282,6 @@ export const Datagrid: React.FC<DatagridProps> = ({
[onCellEdited, availableColumns],
);

const handleRowHover = useCallback(
(args: GridMouseEventArgs) => {
if (hasRowHover) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, row] = args.location;
setHoverRow(args.kind !== "cell" ? undefined : row);
}

// the code below is responsible for adding native <a> element when hovering over rows in the datagrid
// this makes it possible to open links in a new tab and copy them
if (args.kind !== "cell" || !hackARef.current || !rowAnchor) {
return;
}
const href = rowAnchor(args.location);

if (!href) {
return;
}

if (preventRowClickOnSelectionCheckbox(rowMarkers, args.location[0])) {
return;
}

hackARef.current.style.left = `${window.scrollX + args.bounds.x}px`;
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 =
getAppMountUri() + (href.startsWith("/") ? href.slice(1) : href);
hackARef.current.dataset.reactRouterPath = href;
},
[hasRowHover, rowAnchor, rowMarkers],
);

const handleCellClick = useCallback(
(item: Item, args: CellClickedEventArgs) => {
if (preventRowClickOnSelectionCheckbox(rowMarkers, item[0])) {
Expand All @@ -321,11 +294,11 @@ export const Datagrid: React.FC<DatagridProps> = ({

handleRowHover(args);

if (hackARef.current) {
hackARef.current.click();
if (rowAnchorRef.current) {
rowAnchorRef.current.click();
}
},
[rowMarkers, onRowClick, handleRowHover],
[rowMarkers, onRowClick, handleRowHover, rowAnchorRef],
);

const handleGridSelectionChange = (gridSelection: GridSelection) => {
Expand Down Expand Up @@ -438,17 +411,17 @@ export const Datagrid: React.FC<DatagridProps> = ({
clearTimeout(timer);
}

if (hackARef.current) {
hackARef.current.style.display = "none";
if (rowAnchorRef.current) {
rowAnchorRef.current.style.display = "none";
}
timer = setTimeout(() => {
if (hackARef.current) {
hackARef.current.style.display = "block";
if (rowAnchorRef.current) {
rowAnchorRef.current.style.display = "block";
}
}, 100);
};
})(),
[hackARef],
[rowAnchorRef],
);

if (loading) {
Expand Down Expand Up @@ -611,7 +584,7 @@ export const Datagrid: React.FC<DatagridProps> = ({
/>
{rowAnchor && (
<a
ref={hackARef}
ref={setRowAnchorRef}
style={{ position: "absolute" }}
tabIndex={-1}
aria-hidden={true}
Expand Down
Loading

0 comments on commit cb1c95f

Please sign in to comment.