From 973306461c23efff95ceb3ad1cbbe2815bd5da11 Mon Sep 17 00:00:00 2001 From: Kasia Kucharczyk <2536609+kkucharc@users.noreply.github.com> Date: Thu, 4 Feb 2021 22:22:16 +0100 Subject: [PATCH] [11907] Added detecting top scroll on Dashboard header (#12953) --- .../dashboard/components/dnd/handleHover.js | 5 ++- .../dashboard/components/dnd/handleScroll.ts | 42 +++++++++++++++++++ .../src/dashboard/util/getDropPosition.js | 7 +++- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 superset-frontend/src/dashboard/components/dnd/handleScroll.ts diff --git a/superset-frontend/src/dashboard/components/dnd/handleHover.js b/superset-frontend/src/dashboard/components/dnd/handleHover.js index 3eb20c10e..789a5cc14 100644 --- a/superset-frontend/src/dashboard/components/dnd/handleHover.js +++ b/superset-frontend/src/dashboard/components/dnd/handleHover.js @@ -18,6 +18,7 @@ */ import { throttle } from 'lodash'; import getDropPosition from '../../util/getDropPosition'; +import handleScroll from './handleScroll'; const HOVER_THROTTLE_MS = 100; @@ -27,7 +28,9 @@ function handleHover(props, monitor, Component) { const dropPosition = getDropPosition(monitor, Component); - if (!dropPosition) { + handleScroll(dropPosition); + + if (!dropPosition || dropPosition === 'SCROLL_TOP') { Component.setState(() => ({ dropIndicator: null })); return; } diff --git a/superset-frontend/src/dashboard/components/dnd/handleScroll.ts b/superset-frontend/src/dashboard/components/dnd/handleScroll.ts new file mode 100644 index 000000000..66d801f47 --- /dev/null +++ b/superset-frontend/src/dashboard/components/dnd/handleScroll.ts @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +let scrollTopDashboardInterval: any; +const SCROLL_STEP = 120; +const INTERVAL_DELAY = 50; + +export default function handleScroll(dropPosition: string) { + if (dropPosition === 'SCROLL_TOP') { + if (!scrollTopDashboardInterval) { + scrollTopDashboardInterval = setInterval(() => { + let scrollTop = document.documentElement.scrollTop - SCROLL_STEP; + if (scrollTop < 0) { + scrollTop = 0; + } + window.scroll({ + top: scrollTop, + behavior: 'smooth', + }); + }, INTERVAL_DELAY); + } + } + if (dropPosition !== 'SCROLL_TOP' && scrollTopDashboardInterval) { + clearInterval(scrollTopDashboardInterval); + scrollTopDashboardInterval = null; + } +} diff --git a/superset-frontend/src/dashboard/util/getDropPosition.js b/superset-frontend/src/dashboard/util/getDropPosition.js index 49c70dc9e..b2b2ec509 100644 --- a/superset-frontend/src/dashboard/util/getDropPosition.js +++ b/superset-frontend/src/dashboard/util/getDropPosition.js @@ -17,12 +17,13 @@ * under the License. */ import isValidChild from './isValidChild'; -import { TAB_TYPE, TABS_TYPE } from './componentTypes'; +import { DASHBOARD_ROOT_TYPE, TAB_TYPE, TABS_TYPE } from './componentTypes'; export const DROP_TOP = 'DROP_TOP'; export const DROP_RIGHT = 'DROP_RIGHT'; export const DROP_BOTTOM = 'DROP_BOTTOM'; export const DROP_LEFT = 'DROP_LEFT'; +export const SCROLL_TOP = 'SCROLL_TOP'; // this defines how close the mouse must be to the edge of a component to display // a sibling type drop indicator @@ -54,6 +55,10 @@ export default function getDropPosition(monitor, Component) { return null; } + if (component.type === DASHBOARD_ROOT_TYPE) { + return SCROLL_TOP; + } + // TODO need a better solution to prevent nested tabs if ( draggingItem.type === TABS_TYPE &&