mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
[controls] fix option list control making 2 requests on refresh (#219625)
Fixes https://github.com/elastic/kibana/issues/218663
This commit is contained in:
parent
ae88fa8549
commit
f13c764115
6 changed files with 13 additions and 27 deletions
|
@ -10,7 +10,7 @@
|
||||||
import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query';
|
import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query';
|
||||||
import { PublishesUnifiedSearch, PublishingSubject } from '@kbn/presentation-publishing';
|
import { PublishesUnifiedSearch, PublishingSubject } from '@kbn/presentation-publishing';
|
||||||
import { apiPublishesReload } from '@kbn/presentation-publishing/interfaces/fetch/publishes_reload';
|
import { apiPublishesReload } from '@kbn/presentation-publishing/interfaces/fetch/publishes_reload';
|
||||||
import { BehaviorSubject, debounceTime, map, merge, Observable, switchMap } from 'rxjs';
|
import { BehaviorSubject, debounceTime, map, merge, Observable, switchMap, tap } from 'rxjs';
|
||||||
import { ParentIgnoreSettings } from '../../../common';
|
import { ParentIgnoreSettings } from '../../../common';
|
||||||
|
|
||||||
export interface ControlGroupFetchContext {
|
export interface ControlGroupFetchContext {
|
||||||
|
@ -23,7 +23,8 @@ export function controlGroupFetch$(
|
||||||
ignoreParentSettings$: PublishingSubject<ParentIgnoreSettings | undefined>,
|
ignoreParentSettings$: PublishingSubject<ParentIgnoreSettings | undefined>,
|
||||||
parentApi: Partial<PublishesUnifiedSearch> & {
|
parentApi: Partial<PublishesUnifiedSearch> & {
|
||||||
unifiedSearchFilters$?: PublishingSubject<Filter[] | undefined>;
|
unifiedSearchFilters$?: PublishingSubject<Filter[] | undefined>;
|
||||||
}
|
},
|
||||||
|
onReload?: () => void
|
||||||
): Observable<ControlGroupFetchContext> {
|
): Observable<ControlGroupFetchContext> {
|
||||||
return ignoreParentSettings$.pipe(
|
return ignoreParentSettings$.pipe(
|
||||||
switchMap((parentIgnoreSettings) => {
|
switchMap((parentIgnoreSettings) => {
|
||||||
|
@ -40,7 +41,7 @@ export function controlGroupFetch$(
|
||||||
observables.push(parentApi.timeRange$);
|
observables.push(parentApi.timeRange$);
|
||||||
}
|
}
|
||||||
if (apiPublishesReload(parentApi)) {
|
if (apiPublishesReload(parentApi)) {
|
||||||
observables.push(parentApi.reload$);
|
observables.push(onReload ? parentApi.reload$.pipe(tap(onReload)) : parentApi.reload$);
|
||||||
}
|
}
|
||||||
return observables.length ? merge(...observables) : new BehaviorSubject(undefined);
|
return observables.length ? merge(...observables) : new BehaviorSubject(undefined);
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -135,7 +135,7 @@ export const getControlGroupEmbeddableFactory = () => {
|
||||||
disabledActionIds$,
|
disabledActionIds$,
|
||||||
...unsavedChanges.api,
|
...unsavedChanges.api,
|
||||||
...selectionsManager.api,
|
...selectionsManager.api,
|
||||||
controlFetch$: (controlUuid: string) =>
|
controlFetch$: (controlUuid: string, onReload?: () => void) =>
|
||||||
controlFetch$(
|
controlFetch$(
|
||||||
chaining$(
|
chaining$(
|
||||||
controlUuid,
|
controlUuid,
|
||||||
|
@ -143,7 +143,7 @@ export const getControlGroupEmbeddableFactory = () => {
|
||||||
controlsManager.controlsInOrder$,
|
controlsManager.controlsInOrder$,
|
||||||
controlsManager.api.children$
|
controlsManager.api.children$
|
||||||
),
|
),
|
||||||
controlGroupFetch$(ignoreParentSettings$, parentApi ? parentApi : {})
|
controlGroupFetch$(ignoreParentSettings$, parentApi ? parentApi : {}, onReload)
|
||||||
),
|
),
|
||||||
ignoreParentSettings$,
|
ignoreParentSettings$,
|
||||||
autoApplySelections$,
|
autoApplySelections$,
|
||||||
|
|
|
@ -65,7 +65,7 @@ export type ControlGroupApi = PresentationContainer &
|
||||||
labelPosition: PublishingSubject<ControlLabelPosition>;
|
labelPosition: PublishingSubject<ControlLabelPosition>;
|
||||||
|
|
||||||
asyncResetUnsavedChanges: () => Promise<void>;
|
asyncResetUnsavedChanges: () => Promise<void>;
|
||||||
controlFetch$: (controlUuid: string) => Observable<ControlFetchContext>;
|
controlFetch$: (controlUuid: string, onReload?: () => void) => Observable<ControlFetchContext>;
|
||||||
openAddDataControlFlyout: (options?: {
|
openAddDataControlFlyout: (options?: {
|
||||||
controlStateTransform?: ControlStateTransform;
|
controlStateTransform?: ControlStateTransform;
|
||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {
|
||||||
combineLatest,
|
combineLatest,
|
||||||
debounceTime,
|
debounceTime,
|
||||||
Observable,
|
Observable,
|
||||||
of,
|
|
||||||
startWith,
|
startWith,
|
||||||
switchMap,
|
switchMap,
|
||||||
tap,
|
tap,
|
||||||
|
@ -20,7 +19,6 @@ import {
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
import { PublishingSubject } from '@kbn/presentation-publishing';
|
import { PublishingSubject } from '@kbn/presentation-publishing';
|
||||||
import { apiPublishesReload } from '@kbn/presentation-publishing/interfaces/fetch/publishes_reload';
|
|
||||||
import { OptionsListSuccessResponse } from '../../../../common/options_list/types';
|
import { OptionsListSuccessResponse } from '../../../../common/options_list/types';
|
||||||
import { isValidSearch } from '../../../../common/options_list/is_valid_search';
|
import { isValidSearch } from '../../../../common/options_list/is_valid_search';
|
||||||
import { OptionsListSelection } from '../../../../common/options_list/options_list_selections';
|
import { OptionsListSelection } from '../../../../common/options_list/options_list_selections';
|
||||||
|
@ -32,10 +30,10 @@ import { OptionsListComponentApi, OptionsListComponentState, OptionsListControlA
|
||||||
export function fetchAndValidate$({
|
export function fetchAndValidate$({
|
||||||
api,
|
api,
|
||||||
stateManager,
|
stateManager,
|
||||||
|
controlFetch$,
|
||||||
}: {
|
}: {
|
||||||
api: Pick<OptionsListControlApi, 'dataViews$' | 'field$' | 'setBlockingError' | 'parentApi'> &
|
api: Pick<OptionsListControlApi, 'dataViews$' | 'field$' | 'setBlockingError' | 'parentApi'> &
|
||||||
Pick<OptionsListComponentApi, 'loadMoreSubject'> & {
|
Pick<OptionsListComponentApi, 'loadMoreSubject'> & {
|
||||||
controlFetch$: Observable<ControlFetchContext>;
|
|
||||||
loadingSuggestions$: BehaviorSubject<boolean>;
|
loadingSuggestions$: BehaviorSubject<boolean>;
|
||||||
debouncedSearchString: Observable<string>;
|
debouncedSearchString: Observable<string>;
|
||||||
};
|
};
|
||||||
|
@ -44,6 +42,7 @@ export function fetchAndValidate$({
|
||||||
> & {
|
> & {
|
||||||
selectedOptions: PublishingSubject<OptionsListSelection[] | undefined>;
|
selectedOptions: PublishingSubject<OptionsListSelection[] | undefined>;
|
||||||
};
|
};
|
||||||
|
controlFetch$: (onReload: () => void) => Observable<ControlFetchContext>;
|
||||||
}): Observable<OptionsListSuccessResponse | { error: Error }> {
|
}): Observable<OptionsListSuccessResponse | { error: Error }> {
|
||||||
const requestCache = new OptionsListFetchCache();
|
const requestCache = new OptionsListFetchCache();
|
||||||
let abortController: AbortController | undefined;
|
let abortController: AbortController | undefined;
|
||||||
|
@ -51,7 +50,7 @@ export function fetchAndValidate$({
|
||||||
return combineLatest([
|
return combineLatest([
|
||||||
api.dataViews$,
|
api.dataViews$,
|
||||||
api.field$,
|
api.field$,
|
||||||
api.controlFetch$,
|
controlFetch$(requestCache.clearCache),
|
||||||
api.parentApi.allowExpensiveQueries$,
|
api.parentApi.allowExpensiveQueries$,
|
||||||
api.parentApi.ignoreParentSettings$,
|
api.parentApi.ignoreParentSettings$,
|
||||||
api.debouncedSearchString,
|
api.debouncedSearchString,
|
||||||
|
@ -62,12 +61,6 @@ export function fetchAndValidate$({
|
||||||
startWith(null), // start with null so that `combineLatest` subscription fires
|
startWith(null), // start with null so that `combineLatest` subscription fires
|
||||||
debounceTime(100) // debounce load more so "loading" state briefly shows
|
debounceTime(100) // debounce load more so "loading" state briefly shows
|
||||||
),
|
),
|
||||||
apiPublishesReload(api.parentApi)
|
|
||||||
? api.parentApi.reload$.pipe(
|
|
||||||
tap(() => requestCache.clearCache()),
|
|
||||||
startWith(undefined)
|
|
||||||
)
|
|
||||||
: of(undefined),
|
|
||||||
]).pipe(
|
]).pipe(
|
||||||
tap(() => {
|
tap(() => {
|
||||||
// abort any in progress requests
|
// abort any in progress requests
|
||||||
|
|
|
@ -185,9 +185,9 @@ export const getOptionsListControlFactory = (): DataControlFactory<
|
||||||
loadingSuggestions$,
|
loadingSuggestions$,
|
||||||
debouncedSearchString,
|
debouncedSearchString,
|
||||||
parentApi: controlGroupApi,
|
parentApi: controlGroupApi,
|
||||||
controlFetch$: controlGroupApi.controlFetch$(uuid),
|
|
||||||
},
|
},
|
||||||
stateManager,
|
stateManager,
|
||||||
|
controlFetch$: (onReload: () => void) => controlGroupApi.controlFetch$(uuid, onReload),
|
||||||
}).subscribe((result) => {
|
}).subscribe((result) => {
|
||||||
// if there was an error during fetch, set blocking error and return early
|
// if there was an error during fetch, set blocking error and return early
|
||||||
if (Object.hasOwn(result, 'error')) {
|
if (Object.hasOwn(result, 'error')) {
|
||||||
|
|
|
@ -11,8 +11,7 @@ import type { estypes } from '@elastic/elasticsearch';
|
||||||
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
|
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
|
||||||
import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query';
|
import { AggregateQuery, Filter, Query, TimeRange } from '@kbn/es-query';
|
||||||
import { PublishesDataViews, PublishingSubject } from '@kbn/presentation-publishing';
|
import { PublishesDataViews, PublishingSubject } from '@kbn/presentation-publishing';
|
||||||
import { apiPublishesReload } from '@kbn/presentation-publishing/interfaces/fetch/publishes_reload';
|
import { Observable, combineLatest, lastValueFrom, switchMap, tap } from 'rxjs';
|
||||||
import { Observable, combineLatest, lastValueFrom, of, startWith, switchMap, tap } from 'rxjs';
|
|
||||||
import { dataService } from '../../../services/kibana_services';
|
import { dataService } from '../../../services/kibana_services';
|
||||||
import { ControlFetchContext } from '../../../control_group/control_fetch';
|
import { ControlFetchContext } from '../../../control_group/control_fetch';
|
||||||
import { ControlGroupApi } from '../../../control_group/types';
|
import { ControlGroupApi } from '../../../control_group/types';
|
||||||
|
@ -31,14 +30,7 @@ export function minMax$({
|
||||||
setIsLoading: (isLoading: boolean) => void;
|
setIsLoading: (isLoading: boolean) => void;
|
||||||
}) {
|
}) {
|
||||||
let prevRequestAbortController: AbortController | undefined;
|
let prevRequestAbortController: AbortController | undefined;
|
||||||
return combineLatest([
|
return combineLatest([controlFetch$, dataViews$, fieldName$]).pipe(
|
||||||
controlFetch$,
|
|
||||||
dataViews$,
|
|
||||||
fieldName$,
|
|
||||||
apiPublishesReload(controlGroupApi)
|
|
||||||
? controlGroupApi.reload$.pipe(startWith(undefined))
|
|
||||||
: of(undefined),
|
|
||||||
]).pipe(
|
|
||||||
tap(() => {
|
tap(() => {
|
||||||
if (prevRequestAbortController) {
|
if (prevRequestAbortController) {
|
||||||
prevRequestAbortController.abort();
|
prevRequestAbortController.abort();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue