pierrejeambrun commented on code in PR #76083:
URL: https://github.com/apache/airflow/pull/76083#discussion_r4514811741
##########
airflow-core/src/airflow/ui/src/layouts/Details/Grid/useGridScrollRestore.ts:
##########
@@ -16,72 +16,210 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { useLayoutEffect } from "react";
+import type { RefObject } from "react";
+import { useLayoutEffect, useRef } from "react";
import type { Virtualizer } from "@tanstack/react-virtual";
import { ROW_HEIGHT } from "./constants";
import type { GridTask } from "./utils";
-// Last Grid scrollTop per Dag. Module scope so it outlives the Grid
remounting.
-const gridScrollTops = new Map<string, number>();
+// Each axis is absent until it has actually been scrollable: a Dag whose runs
have not arrived
+// reports 0 for an axis that cannot move, and storing that 0 would read back
as a real position.
+type ScrollPosition = {
+ left?: number;
+ top?: number;
+};
+
+// Last Grid scroll offsets per Dag. Module scope so they outlive the Grid
remounting.
+const gridScrollPositions = new Map<string, ScrollPosition>();
type Params = {
dagId: string;
flatNodes: Array<GridTask>;
// Height of the sticky header above the rows (also the virtualizer's
scrollPaddingStart).
headerPad: number;
+ isRtl: boolean;
rowVirtualizer: Virtualizer<HTMLDivElement, Element>;
+ runIds: Array<string>;
selectedGroupId?: string;
+ selectedRunId?: string;
selectedTaskId?: string;
+ // Gantt view shares one scroller with the Grid, where the horizontal axis
is the Gantt's timeline.
+ sharesScroller: boolean;
+ taskNameColumnRef: RefObject<HTMLDivElement | null>;
+};
+
+// Horizontal counterpart to the virtualizer's scrollToIndex, with the same
meaning of `align`.
+//
+// Run columns scroll beneath the sticky task name column, so a column tucked
behind it is as hidden
+// as one past the far edge. The visible scrollport is clientWidth wide
(unlike the bounding rect, it
+// excludes the vertical scrollbar), minus that column: on the left in LTR, on
the right in RTL, where
+// the scrollbar also moves to the left. Returns whether the run's column was
found.
+const scrollRunIntoView = ({
+ align,
+ isRtl,
+ scrollEl,
+ selectedRunId,
+ taskNameColumn,
+}: {
+ align: "center" | "nearest";
+ isRtl: boolean;
+ scrollEl: HTMLElement;
+ selectedRunId: string | undefined;
+ taskNameColumn: HTMLDivElement | null;
+}) => {
+ if (selectedRunId === undefined) {
+ return false;
+ }
+
+ // Both the duration bar and the task instance column carry the run id;
either one gives the
+ // column's x position, so take whichever the query finds first.
+ const column =
scrollEl.querySelector(`[data-run-id="${CSS.escape(selectedRunId)}"]`);
+
+ if (!column) {
+ return false;
+ }
+
+ const columnRect = column.getBoundingClientRect();
+ const viewRect = scrollEl.getBoundingClientRect();
+ const nameColumnWidth = taskNameColumn?.getBoundingClientRect().width ?? 0;
+ const visibleStart = isRtl ? viewRect.right - scrollEl.clientWidth :
viewRect.left + nameColumnWidth;
+ const visibleEnd = isRtl ? viewRect.right - nameColumnWidth : viewRect.left
+ scrollEl.clientWidth;
Review Comment:
When there's a saved horizontal offset and the selected run is off to the
right, `nearest` puts it flush against the scrollport edge, which is now where
the pinned Reset/Newer buttons sit. I reproduced this locally by scrolling
fully left, then navigating to a newer run: its duration bar ended up under
"Reset to latest" and clicking it hit the button. Before, the 32px spacer kept
that edge free. Could we pull the visible end in by the same reserved width
(`scrollbarSpacerWidth`) when those buttons are shown?
Selected run outlined in red, with the "Reset to latest" button drawn over
its bar:
<img width="208" alt="Selected run under the Reset to latest button"
src="https://raw.githubusercontent.com/astronomer/airflow/de5e9b3118fe4d74a520f3c8c03a8b2df2cac439/76083/nearest-under-button.png"
/>
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]