diff --git a/src/plugins/controls/common/options_list/types.ts b/src/plugins/controls/common/options_list/types.ts index 8835c7f5767f6..1c9555bdc8d90 100644 --- a/src/plugins/controls/common/options_list/types.ts +++ b/src/plugins/controls/common/options_list/types.ts @@ -23,7 +23,9 @@ export interface OptionsListEmbeddableInput extends DataControlInput { hideExclude?: boolean; hideExists?: boolean; hideSort?: boolean; + hideActionBar?: boolean; exclude?: boolean; + placeholder?: string; } export type OptionsListField = FieldSpec & { diff --git a/src/plugins/controls/public/options_list/components/options_list_control.tsx b/src/plugins/controls/public/options_list/components/options_list_control.tsx index 3035eada20caf..98f545718efc6 100644 --- a/src/plugins/controls/public/options_list/components/options_list_control.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_control.tsx @@ -47,6 +47,8 @@ export const OptionsListControl = ({ typeaheadSubject }: { typeaheadSubject: Sub const exclude = select((state) => state.explicitInput.exclude); const id = select((state) => state.explicitInput.id); + const placeholder = select((state) => state.explicitInput.placeholder); + const loading = select((state) => state.output.loading); // debounce loading state so loading doesn't flash when user types @@ -128,7 +130,7 @@ export const OptionsListControl = ({ typeaheadSubject }: { typeaheadSubject: Sub > {hasSelections || existsSelected ? selectionDisplayNode - : OptionsListStrings.control.getPlaceholder()} + : placeholder ?? OptionsListStrings.control.getPlaceholder()} ); diff --git a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx index acb5d24d80659..a8504aba372c8 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover.test.tsx @@ -58,7 +58,7 @@ describe('Options list popover', () => { test('available options list width responds to container size', async () => { let popover = await mountComponent({ popoverProps: { width: 301 } }); let popoverDiv = findTestSubject(popover, 'optionsList-control-popover'); - expect(popoverDiv.getDOMNode().getAttribute('style')).toBe('width: 301px;'); + expect(popoverDiv.getDOMNode().getAttribute('style')).toBe('width: 301px; min-width: 300px;'); // the div cannot be smaller than 301 pixels wide popover = await mountComponent({ popoverProps: { width: 300 } }); diff --git a/src/plugins/controls/public/options_list/components/options_list_popover.tsx b/src/plugins/controls/public/options_list/components/options_list_popover.tsx index 70353524068cd..b5562c43f3be2 100644 --- a/src/plugins/controls/public/options_list/components/options_list_popover.tsx +++ b/src/plugins/controls/public/options_list/components/options_list_popover.tsx @@ -43,6 +43,7 @@ export const OptionsListPopover = ({ const field = select((state) => state.componentState.field); const hideExclude = select((state) => state.explicitInput.hideExclude); + const hideActionBar = select((state) => state.explicitInput.hideActionBar); const fieldName = select((state) => state.explicitInput.fieldName); const title = select((state) => state.explicitInput.title); const id = select((state) => state.explicitInput.id); @@ -52,12 +53,12 @@ export const OptionsListPopover = ({ return (
300 ? width : undefined }} + style={{ width, minWidth: 300 }} data-test-subj={`optionsList-control-popover`} aria-label={OptionsListStrings.popover.getAriaLabel(fieldName)} > {title} - {field?.type !== 'boolean' && ( + {field?.type !== 'boolean' && !hideActionBar && ( { + // clear cache when reload is requested + this.optionsListService.clearOptionsListCache(); this.runOptionsListQuery(); }; diff --git a/src/plugins/controls/public/services/options_list/options_list.story.ts b/src/plugins/controls/public/services/options_list/options_list.story.ts index 62686feee7495..c641e9ee8834a 100644 --- a/src/plugins/controls/public/services/options_list/options_list.story.ts +++ b/src/plugins/controls/public/services/options_list/options_list.story.ts @@ -26,6 +26,8 @@ let optionsListRequestMethod = async (request: OptionsListRequest, abortSignal: ) ); +const clearOptionsListCacheMock = () => {}; + export const replaceOptionsListMethod = ( newMethod: (request: OptionsListRequest, abortSignal: AbortSignal) => Promise ) => (optionsListRequestMethod = newMethod); @@ -33,5 +35,6 @@ export const replaceOptionsListMethod = ( export const optionsListServiceFactory: OptionsListServiceFactory = () => { return { runOptionsListRequest: optionsListRequestMethod, + clearOptionsListCache: clearOptionsListCacheMock, }; }; diff --git a/src/plugins/controls/public/services/options_list/options_list_service.ts b/src/plugins/controls/public/services/options_list/options_list_service.ts index ab8e67666140b..888d2e2efb837 100644 --- a/src/plugins/controls/public/services/options_list/options_list_service.ts +++ b/src/plugins/controls/public/services/options_list/options_list_service.ts @@ -104,6 +104,10 @@ class OptionsListService implements ControlsOptionsListService { return { rejected: true } as OptionsListResponse; } }; + + public clearOptionsListCache = () => { + this.cachedOptionsListRequest.cache = new memoize.Cache(); + }; } export interface OptionsListServiceRequiredServices { diff --git a/src/plugins/controls/public/services/options_list/types.ts b/src/plugins/controls/public/services/options_list/types.ts index d493207df591c..569042b136419 100644 --- a/src/plugins/controls/public/services/options_list/types.ts +++ b/src/plugins/controls/public/services/options_list/types.ts @@ -13,4 +13,6 @@ export interface ControlsOptionsListService { request: OptionsListRequest, abortSignal: AbortSignal ) => Promise; + + clearOptionsListCache: () => void; }