mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[controls] add example for programmatically interacting with controls (#212665)
Update search control example with buttons to programmatically interact with controls <img width="800" alt="Screenshot 2025-02-27 at 8 41 05 AM" src="https://github.com/user-attachments/assets/e936cdeb-ce51-4fca-a8bc-ec5d983e3155" /> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
e5f40e0a78
commit
8784e4d68d
4 changed files with 67 additions and 12 deletions
|
@ -12,6 +12,7 @@ import { lastValueFrom } from 'rxjs';
|
|||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
EuiCallOut,
|
||||
EuiLoadingSpinner,
|
||||
EuiPanel,
|
||||
|
@ -19,12 +20,16 @@ import {
|
|||
EuiText,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
import { ControlGroupRenderer, ControlGroupRendererApi } from '@kbn/controls-plugin/public';
|
||||
import {
|
||||
ControlGroupRenderer,
|
||||
ControlGroupRendererApi,
|
||||
DefaultControlApi,
|
||||
OptionsListControlApi,
|
||||
} from '@kbn/controls-plugin/public';
|
||||
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import type { Filter, Query, TimeRange } from '@kbn/es-query';
|
||||
import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public';
|
||||
|
||||
import { PLUGIN_ID } from '../../constants';
|
||||
|
||||
interface Props {
|
||||
|
@ -33,6 +38,8 @@ interface Props {
|
|||
navigation: NavigationPublicPluginStart;
|
||||
}
|
||||
|
||||
const DEST_COUNTRY_CONTROL_ID = 'DEST_COUNTRY_CONTROL_ID';
|
||||
|
||||
export const SearchExample = ({ data, dataView, navigation }: Props) => {
|
||||
const [controlFilters, setControlFilters] = useState<Filter[]>([]);
|
||||
const [controlGroupAPI, setControlGroupAPI] = useState<ControlGroupRendererApi | undefined>();
|
||||
|
@ -107,7 +114,8 @@ export const SearchExample = ({ data, dataView, navigation }: Props) => {
|
|||
<EuiText>
|
||||
<p>
|
||||
Pass filters, query, and time range to narrow controls. Combine search bar filters with
|
||||
controls filters to narrow results.
|
||||
controls filters to narrow results. Programmatically interact with individual controls by
|
||||
accessing their API from controlGroupApi.children$.
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="m" />
|
||||
|
@ -130,16 +138,21 @@ export const SearchExample = ({ data, dataView, navigation }: Props) => {
|
|||
query={query}
|
||||
showSearchBar={true}
|
||||
/>
|
||||
|
||||
<ControlGroupRenderer
|
||||
filters={filters}
|
||||
getCreationOptions={async (initialState, builder) => {
|
||||
await builder.addDataControlFromField(initialState, {
|
||||
dataViewId: dataView.id!,
|
||||
title: 'Destintion country',
|
||||
fieldName: 'geo.dest',
|
||||
width: 'medium',
|
||||
grow: false,
|
||||
});
|
||||
await builder.addDataControlFromField(
|
||||
initialState,
|
||||
{
|
||||
dataViewId: dataView.id!,
|
||||
title: 'Destintion country',
|
||||
fieldName: 'geo.dest',
|
||||
width: 'medium',
|
||||
grow: false,
|
||||
},
|
||||
DEST_COUNTRY_CONTROL_ID
|
||||
);
|
||||
await builder.addDataControlFromField(initialState, {
|
||||
dataViewId: dataView.id!,
|
||||
fieldName: 'bytes',
|
||||
|
@ -155,9 +168,42 @@ export const SearchExample = ({ data, dataView, navigation }: Props) => {
|
|||
onApiAvailable={setControlGroupAPI}
|
||||
timeRange={timeRange}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
<EuiCallOut title="Search results">
|
||||
{isSearching ? <EuiLoadingSpinner size="l" /> : <p>Hits: {hits}</p>}
|
||||
</EuiCallOut>
|
||||
|
||||
<EuiSpacer />
|
||||
<EuiButton
|
||||
color="text"
|
||||
isDisabled={!Boolean(controlGroupAPI)}
|
||||
onClick={() => {
|
||||
if (controlGroupAPI) {
|
||||
Object.values(controlGroupAPI.children$.getValue()).forEach((controlApi) => {
|
||||
(controlApi as DefaultControlApi)?.clearSelections();
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
Clear all controls
|
||||
</EuiButton>
|
||||
<EuiSpacer />
|
||||
<EuiButton
|
||||
color="text"
|
||||
isDisabled={!Boolean(controlGroupAPI)}
|
||||
onClick={() => {
|
||||
if (controlGroupAPI) {
|
||||
const controlApi = controlGroupAPI.children$.getValue()[
|
||||
DEST_COUNTRY_CONTROL_ID
|
||||
] as Partial<OptionsListControlApi>;
|
||||
if (controlApi && controlApi.setSelectedOptions) {
|
||||
controlApi.setSelectedOptions(['CN']);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
Set destination country to CN
|
||||
</EuiButton>
|
||||
</EuiPanel>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -299,6 +299,9 @@ export const getOptionsListControlFactory = (): DataControlFactory<
|
|||
if (invalidSelections$.getValue().size) invalidSelections$.next(new Set([]));
|
||||
},
|
||||
hasSelections$: hasSelections$ as PublishingSubject<boolean | undefined>,
|
||||
setSelectedOptions: (options: OptionsListSelection[] | undefined) => {
|
||||
selections.setSelectedOptions(options);
|
||||
},
|
||||
},
|
||||
{
|
||||
...dataControl.comparators,
|
||||
|
|
|
@ -18,7 +18,9 @@ import type {
|
|||
} from '../../../../common/options_list';
|
||||
import type { DataControlApi } from '../types';
|
||||
|
||||
export type OptionsListControlApi = DataControlApi;
|
||||
export type OptionsListControlApi = DataControlApi & {
|
||||
setSelectedOptions: (options: OptionsListSelection[] | undefined) => void;
|
||||
};
|
||||
|
||||
export interface OptionsListComponentState
|
||||
extends Omit<OptionsListControlState, keyof OptionsListDisplaySettings> {
|
||||
|
|
|
@ -21,8 +21,12 @@ export {
|
|||
} from './actions/constants';
|
||||
|
||||
export type { ControlGroupApi, ControlStateTransform } from './control_group/types';
|
||||
|
||||
export type { DataControlApi, DataControlFactory } from './controls/data_controls/types';
|
||||
export type { DefaultControlApi } from './controls/types';
|
||||
export type { OptionsListControlApi } from './controls/data_controls/options_list_control/types';
|
||||
export type { RangesliderControlApi } from './controls/data_controls/range_slider/types';
|
||||
export type { ESQLControlApi } from './controls/esql_control/types';
|
||||
export type { TimesliderControlApi } from './controls/timeslider_control/types';
|
||||
|
||||
export {
|
||||
ControlGroupRenderer,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue