From 03567aa40dd667cb6a65db55e8623ab3d5e2e64c Mon Sep 17 00:00:00 2001 From: leutinatasya Date: Wed, 10 Jul 2024 13:22:06 +0300 Subject: [PATCH 1/3] Fix loader logic in group controls --- .../plugins/GroupControl/GroupControl.tsx | 31 ++++++----- .../LocalUpdateLoader/LocalUpdateLoader.tsx | 52 +++++++++++++++++++ .../GroupControlSidebar.tsx | 2 +- .../autoupdateRelatedSelectors.test.ts | 3 +- 4 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 src/ui/components/DashKit/plugins/GroupControl/LocalUpdateLoader/LocalUpdateLoader.tsx diff --git a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx index 91d45bb585..ff0d3a76e7 100644 --- a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx +++ b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx @@ -3,7 +3,6 @@ import React from 'react'; import type {Plugin, PluginWidgetProps, SettingsProps} from '@gravity-ui/dashkit'; import type {Config, StateAndParamsMetaData} from '@gravity-ui/dashkit/helpers'; import {getItemsParams, pluginGroupControlBaseDL} from '@gravity-ui/dashkit/helpers'; -import {Loader} from '@gravity-ui/uikit'; import block from 'bem-cn-lite'; import {I18n} from 'i18n'; import debounce from 'lodash/debounce'; @@ -36,6 +35,7 @@ import type {ControlSettings, GetDistincts, LoadStatus} from '../Control/types'; import DebugInfoTool from '../DebugInfoTool/DebugInfoTool'; import {Control} from './Control/Control'; +import {LocalUpdateLoader} from './LocalUpdateLoader/LocalUpdateLoader'; import type { ContextProps, ExtendedLoadedData, @@ -48,6 +48,8 @@ import {addItemToLocalQueue, filterSignificantParams} from './utils'; import './GroupControl.scss'; const GROUP_CONTROL_LAYOUT_DEBOUNCE_TIME = 20; +const LOADER_SHOW_DELAY = 150; +const LOADER_HIDE_DELAY = 100; type StateProps = ReturnType; @@ -84,9 +86,6 @@ class GroupControl extends React.PureComponent = {}; controlsData: Record = {}; - // a quick loader for imitating action by clicking on apply button - quickActionLoader = false; - // params of current dash state initialParams: Record = {}; @@ -226,7 +225,6 @@ class GroupControl extends React.PureComponent {this.renderControls()} - {isLoading && ( -
- -
- )} + ); @@ -395,6 +396,7 @@ class GroupControl extends React.PureComponent { - this.quickActionLoader = false; - }); + this.setState({localUpdateLoader: true}); } this.onChange({params: newParams, callChangeByClick}); } diff --git a/src/ui/components/DashKit/plugins/GroupControl/LocalUpdateLoader/LocalUpdateLoader.tsx b/src/ui/components/DashKit/plugins/GroupControl/LocalUpdateLoader/LocalUpdateLoader.tsx new file mode 100644 index 0000000000..8287a16bb9 --- /dev/null +++ b/src/ui/components/DashKit/plugins/GroupControl/LocalUpdateLoader/LocalUpdateLoader.tsx @@ -0,0 +1,52 @@ +import React from 'react'; + +import type {LoaderSize} from '@gravity-ui/uikit'; +import {Loader} from '@gravity-ui/uikit'; + +export const LocalUpdateLoader = ({ + show, + showDelay, + hideDelay, + className, + size, + qa, +}: { + show: boolean; + showDelay: number; + hideDelay: number; + className?: string; + size: LoaderSize; + qa?: string; +}) => { + const hideTimer = React.useRef(0); + const [prevShow, setPrevShow] = React.useState(show); + const [showByTimer, setShowByDelay] = React.useState(false); + const [showByCondition, setShowByCondition] = React.useState(false); + + if (show !== prevShow) { + setPrevShow(show); + + if (show) { + if (hideTimer) { + window.clearTimeout(hideTimer.current); + } + hideTimer.current = window.setTimeout(() => { + setShowByCondition(true); + setShowByDelay(true); + + window.setTimeout(() => { + setShowByDelay(false); + }, hideDelay); + }, showDelay); + } + } + + if (!show && showByCondition) { + setShowByCondition(false); + } + + if (showByCondition || showByTimer) { + return ; + } + return null; +}; diff --git a/src/ui/units/dash/containers/Dialogs/GroupControl/GroupControlSidebar/GroupControlSidebar.tsx b/src/ui/units/dash/containers/Dialogs/GroupControl/GroupControlSidebar/GroupControlSidebar.tsx index 9864138d63..566bf8d6a9 100644 --- a/src/ui/units/dash/containers/Dialogs/GroupControl/GroupControlSidebar/GroupControlSidebar.tsx +++ b/src/ui/units/dash/containers/Dialogs/GroupControl/GroupControlSidebar/GroupControlSidebar.tsx @@ -217,7 +217,7 @@ export const GroupControlSidebar = () => { /> { @@ -199,7 +200,7 @@ datalensTest.describe('Dashboards - Autoupdate options of group selectors', () = expect(await getSecondSelectItemsCount(dashboardPage)).toEqual(cityItemsCount); await dashboardPage.expectControlsRequests({ - controlTitles: SELECTORS_TITLES.DATASET_SELECTORS, + controlTitles: SELECTORS_TITLES.SECOND_DATASET_SELECTOR, action: async () => { await page.locator(slct(ControlQA.controlButtonApply)).click(); }, From b76fd033fe559252b805102f26756e61a2fbcab8 Mon Sep 17 00:00:00 2001 From: leutinatasya Date: Thu, 18 Jul 2024 18:16:12 +0300 Subject: [PATCH 2/3] Add individual loaders for autoupdate --- .../plugins/GroupControl/Control/Control.tsx | 8 +++++- .../plugins/GroupControl/GroupControl.tsx | 21 ++++++++++----- .../LocalUpdateLoader/LocalUpdateLoader.tsx | 14 +++------- .../components/Control/Items/Items.js | 27 +++++-------------- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx b/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx index 33d8996140..374a63795c 100644 --- a/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx +++ b/src/ui/components/DashKit/plugins/GroupControl/Control/Control.tsx @@ -97,6 +97,7 @@ type ControlProps = { needReload: boolean; workbookId?: WorkbookId; dependentSelectors?: boolean; + autoUpdating: boolean; }; export const Control = ({ @@ -110,6 +111,7 @@ export const Control = ({ needReload, workbookId, dependentSelectors, + autoUpdating, }: ControlProps) => { const [prevNeedReload, setPrevNeedReload] = React.useState(needReload); const isMounted = useMountedState([]); @@ -397,7 +399,11 @@ export const Control = ({ }; const renderSilentLoader = () => { - if (showSilentLoader || (!control && status === LOAD_STATUS.SUCCESS)) { + if ( + showSilentLoader || + (!control && status === LOAD_STATUS.SUCCESS) || + (autoUpdating && status === LOAD_STATUS.PENDING) + ) { return (
diff --git a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx index ff0d3a76e7..7658c4c140 100644 --- a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx +++ b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx @@ -48,8 +48,7 @@ import {addItemToLocalQueue, filterSignificantParams} from './utils'; import './GroupControl.scss'; const GROUP_CONTROL_LAYOUT_DEBOUNCE_TIME = 20; -const LOADER_SHOW_DELAY = 150; -const LOADER_HIDE_DELAY = 100; +const LOADER_HIDE_DELAY = 500; type StateProps = ReturnType; @@ -86,6 +85,8 @@ class GroupControl extends React.PureComponent = {}; controlsData: Record = {}; + autoUpdating = false; + // params of current dash state initialParams: Record = {}; @@ -224,8 +225,9 @@ class GroupControl extends React.PureComponent {this.renderControls()} ); } @@ -738,6 +744,7 @@ class GroupControl extends React.PureComponent { - const hideTimer = React.useRef(0); const [prevShow, setPrevShow] = React.useState(show); const [showByTimer, setShowByDelay] = React.useState(false); const [showByCondition, setShowByCondition] = React.useState(false); @@ -27,17 +24,14 @@ export const LocalUpdateLoader = ({ setPrevShow(show); if (show) { - if (hideTimer) { - window.clearTimeout(hideTimer.current); - } - hideTimer.current = window.setTimeout(() => { - setShowByCondition(true); - setShowByDelay(true); + setShowByCondition(true); + setShowByDelay(true); + if (hideDelay) { window.setTimeout(() => { setShowByDelay(false); }, hideDelay); - }, showDelay); + } } } diff --git a/src/ui/libs/DatalensChartkit/components/Control/Items/Items.js b/src/ui/libs/DatalensChartkit/components/Control/Items/Items.js index 90cc6b2cf7..a3734d3769 100644 --- a/src/ui/libs/DatalensChartkit/components/Control/Items/Items.js +++ b/src/ui/libs/DatalensChartkit/components/Control/Items/Items.js @@ -176,6 +176,10 @@ function BaseControlInput({ const isInvalid = hasValidationError && !text?.length; + const handleBlur = () => { + onChange(text); + }; + return ( setText(value)} onKeyPress={(event) => event.charCode === 13 && onChange(text)} - onBlur={() => { - // For case: input has `updateOnChange: true`, there is button control with `setInitialParams`. - // Need setTimeout for common microtask queue: firstly fire onBlur (from Input), then onClick (from Button) - // Before fix: in some cases onClick form Button didn't fire at all (or just didn't work, next work) - // (Possible reasons: because of rerendering after onChange form Input). - setTimeout(() => { - onChange(text); - }); - }} + onBlur={handleBlur} label={labelInside ? label : innerLabel} qa={ControlQA.controlInput} // triggered twice, so controlAttrs.onKeyPress is used @@ -468,19 +464,8 @@ function BaseControlButton({label, theme, onChange, qa}) { const size = DL.IS_MOBILE ? MOBILE_SIZE.BUTTON : 's'; - const handleClick = () => { - setTimeout(onChange); - }; - return ( - ); From 01a35c3453c27fb670c234c21d515a05e8df378f Mon Sep 17 00:00:00 2001 From: leutinatasya Date: Thu, 18 Jul 2024 18:36:06 +0300 Subject: [PATCH 3/3] Fixes for quick loader --- .../plugins/GroupControl/GroupControl.tsx | 18 ++++++++++++------ .../LocalUpdateLoader/LocalUpdateLoader.tsx | 3 +++ .../DashKit/plugins/GroupControl/types.ts | 1 - 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx index 7658c4c140..ca9f85debf 100644 --- a/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx +++ b/src/ui/components/DashKit/plugins/GroupControl/GroupControl.tsx @@ -85,6 +85,9 @@ class GroupControl extends React.PureComponent = {}; controlsData: Record = {}; + // a quick loader for imitating action by clicking on apply button + quickActionLoader = false; + autoUpdating = false; // params of current dash state @@ -124,7 +127,6 @@ class GroupControl extends React.PureComponent
); } + private handleLoaderShow = () => { + this.quickActionLoader = false; + }; + private get dependentSelectors() { return this.props.settings.dependentSelectors ?? false; } @@ -397,7 +404,6 @@ class GroupControl extends React.PureComponent void; }) => { const [prevShow, setPrevShow] = React.useState(show); const [showByTimer, setShowByDelay] = React.useState(false); @@ -24,6 +26,7 @@ export const LocalUpdateLoader = ({ setPrevShow(show); if (show) { + onLoaderShow?.(); setShowByCondition(true); setShowByDelay(true); diff --git a/src/ui/components/DashKit/plugins/GroupControl/types.ts b/src/ui/components/DashKit/plugins/GroupControl/types.ts index ec34ee22e5..4c0ce05b5d 100644 --- a/src/ui/components/DashKit/plugins/GroupControl/types.ts +++ b/src/ui/components/DashKit/plugins/GroupControl/types.ts @@ -20,7 +20,6 @@ export interface PluginGroupControlState { isInit: boolean; stateParams: Record; needReload: boolean; - localUpdateLoader: boolean; } export type ResolveMetaResult = {