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 91d45bb585..ca9f85debf 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,7 @@ import {addItemToLocalQueue, filterSignificantParams} from './utils';
import './GroupControl.scss';
const GROUP_CONTROL_LAYOUT_DEBOUNCE_TIME = 20;
+const LOADER_HIDE_DELAY = 500;
type StateProps = ReturnType
;
@@ -87,6 +88,8 @@ class GroupControl extends React.PureComponent = {};
@@ -124,7 +127,6 @@ class GroupControl extends React.PureComponent
{this.renderControls()}
- {isLoading && (
-
-
-
- )}
+
);
}
+ private handleLoaderShow = () => {
+ this.quickActionLoader = false;
+ };
+
private get dependentSelectors() {
return this.props.settings.dependentSelectors ?? false;
}
@@ -417,8 +426,8 @@ class GroupControl extends React.PureComponent
);
}
@@ -732,10 +750,8 @@ class GroupControl extends React.PureComponent {
- this.quickActionLoader = false;
- });
}
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..236247b662
--- /dev/null
+++ b/src/ui/components/DashKit/plugins/GroupControl/LocalUpdateLoader/LocalUpdateLoader.tsx
@@ -0,0 +1,49 @@
+import React from 'react';
+
+import type {LoaderSize} from '@gravity-ui/uikit';
+import {Loader} from '@gravity-ui/uikit';
+
+export const LocalUpdateLoader = ({
+ show,
+ hideDelay,
+ className,
+ size,
+ qa,
+ onLoaderShow,
+}: {
+ show: boolean;
+ hideDelay: number;
+ className?: string;
+ size: LoaderSize;
+ qa?: string;
+ onLoaderShow?: () => void;
+}) => {
+ 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) {
+ onLoaderShow?.();
+ setShowByCondition(true);
+ setShowByDelay(true);
+
+ if (hideDelay) {
+ window.setTimeout(() => {
+ setShowByDelay(false);
+ }, hideDelay);
+ }
+ }
+ }
+
+ if (!show && showByCondition) {
+ setShowByCondition(false);
+ }
+
+ if (showByCondition || showByTimer) {
+ return ;
+ }
+ return null;
+};
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 = {
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 (
-