[Control Group] Add override options of openAddDataControlFlyout (#153007)

## Summary

This PR adds the option to provide, custom props when calling
`openAddDataControlFlyout`. For example, users of the API may want
different placeholder than default for any new options list that is
added.

Currently, in security solution, we need a custom placeholder for newly
added controls. Hence, this PR. Please let me know if this is not the
best way to do this.



https://user-images.githubusercontent.com/7485038/232775198-a111d711-ffba-4d26-8c70-c2af08008e05.mov
This commit is contained in:
Jatin Kathuria 2023-04-19 16:58:48 +02:00 committed by GitHub
parent 271d9aa68c
commit 6d8d1708fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 5 deletions

View file

@ -21,18 +21,23 @@ import {
EuiTitle,
} from '@elastic/eui';
import { ViewMode } from '@kbn/embeddable-plugin/public';
import { OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '@kbn/controls-plugin/common';
import {
LazyControlGroupRenderer,
ControlGroupContainer,
ControlGroupInput,
ACTION_EDIT_CONTROL,
ACTION_DELETE_CONTROL,
} from '@kbn/controls-plugin/public';
import { withSuspense } from '@kbn/presentation-util-plugin/public';
import { ACTION_EDIT_CONTROL, ACTION_DELETE_CONTROL } from '@kbn/controls-plugin/public';
import { ControlInputTransform } from '@kbn/controls-plugin/common/types';
const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);
const INPUT_KEY = 'kbnControls:saveExample:input';
const WITH_CUSTOM_PLACEHOLDER = 'Custom Placeholder';
export const EditExample = () => {
const [isSaving, setIsSaving] = useState(false);
const [isLoading, setIsLoading] = useState(false);
@ -85,6 +90,7 @@ export const EditExample = () => {
setToggleIconIdToSelectedMapIcon({
[ACTION_EDIT_CONTROL]: disabledActions.includes(ACTION_EDIT_CONTROL),
[ACTION_DELETE_CONTROL]: disabledActions.includes(ACTION_DELETE_CONTROL),
[WITH_CUSTOM_PLACEHOLDER]: false,
});
} catch (e) {
// ignore parse errors
@ -94,6 +100,24 @@ export const EditExample = () => {
return input;
}
const controlInputTransform: ControlInputTransform = (newState, type) => {
if (type === OPTIONS_LIST_CONTROL && toggleIconIdToSelectedMapIcon[WITH_CUSTOM_PLACEHOLDER]) {
return {
...newState,
placeholder: 'Custom Placeholder',
};
}
if (type === RANGE_SLIDER_CONTROL) {
return {
...newState,
value: ['0', '4'],
};
}
return newState;
};
return (
<>
<EuiTitle>
@ -111,7 +135,7 @@ export const EditExample = () => {
iconType="plusInCircle"
isDisabled={controlGroup === undefined}
onClick={() => {
controlGroup!.openAddDataControlFlyout();
controlGroup!.openAddDataControlFlyout(controlInputTransform);
}}
>
Add control
@ -132,6 +156,11 @@ export const EditExample = () => {
label: 'Disable delete action',
value: ACTION_DELETE_CONTROL,
},
{
id: WITH_CUSTOM_PLACEHOLDER,
label: WITH_CUSTOM_PLACEHOLDER,
value: WITH_CUSTOM_PLACEHOLDER,
},
]}
idToSelectedMap={toggleIconIdToSelectedMapIcon}
type="multi"

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
export type { ControlWidth } from './types';
export type { ControlWidth, ControlInputTransform } from './types';
// Control Group exports
export {

View file

@ -32,3 +32,8 @@ export type DataControlInput = ControlInput & {
fieldName: string;
dataViewId: string;
};
export type ControlInputTransform = (
newState: Partial<ControlInput>,
controlType: string
) => Partial<ControlInput>;

View file

@ -97,6 +97,7 @@ export const ControlEditor = ({
const { useEmbeddableSelector: select } = useControlGroupContainerContext();
const editorConfig = select((state) => state.componentState.editorConfig);
const customFilterPredicate = select((state) => state.componentState.fieldFilterPredicate);
const [defaultTitle, setDefaultTitle] = useState<string>();
const [currentTitle, setCurrentTitle] = useState(title ?? '');
@ -195,7 +196,10 @@ export const ControlEditor = ({
)}
<EuiFormRow label={ControlGroupStrings.manageControl.getFieldTitle()}>
<FieldPicker
filterPredicate={(field: DataViewField) => Boolean(fieldRegistry?.[field.name])}
filterPredicate={(field: DataViewField) => {
const customPredicate = customFilterPredicate ? customFilterPredicate(field) : true;
return Boolean(fieldRegistry?.[field.name]) && customPredicate;
}}
selectedFieldName={selectedField}
dataView={selectedDataView}
onSelectField={(field) => {

View file

@ -8,6 +8,7 @@
import React from 'react';
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
import { ControlInputTransform } from '../../../common/types';
import type {
AddDataControlProps,
AddOptionsListControlProps,
@ -24,7 +25,10 @@ import {
DEFAULT_CONTROL_WIDTH,
} from '../../../common/control_group/control_group_constants';
export function openAddDataControlFlyout(this: ControlGroupContainer) {
export function openAddDataControlFlyout(
this: ControlGroupContainer,
controlInputTransform?: ControlInputTransform
) {
const {
overlays: { openFlyout, openConfirm },
controls: { getControlFactory },
@ -76,6 +80,10 @@ export function openAddDataControlFlyout(this: ControlGroupContainer) {
controlInput = factory.presaveTransformFunction(controlInput);
}
if (controlInputTransform) {
controlInput = controlInputTransform({ ...controlInput }, type);
}
if (type === OPTIONS_LIST_CONTROL) {
this.addOptionsListControl(controlInput as AddOptionsListControlProps);
return;

View file

@ -19,6 +19,7 @@ export { ACTION_EDIT_CONTROL, ACTION_DELETE_CONTROL } from './actions';
export {
type AddDataControlProps,
type AddOptionsListControlProps,
type AddRangeSliderControlProps,
controlGroupInputBuilder,
} from './control_group_input_builder';

View file

@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
import { DataViewField } from '@kbn/data-views-plugin/common';
import { ContainerOutput } from '@kbn/embeddable-plugin/public';
import { ReduxEmbeddableState } from '@kbn/presentation-util-plugin/public';
import { ControlGroupInput } from '../../common/control_group/types';
@ -34,6 +35,7 @@ export interface ControlGroupSettings {
hideWidthSettings?: boolean;
hideAdditionalSettings?: boolean;
};
fieldFilterPredicate?: (field: DataViewField) => boolean;
}
export {

View file

@ -35,6 +35,7 @@ export {
export {
type AddDataControlProps,
type AddOptionsListControlProps,
type AddRangeSliderControlProps,
type ControlGroupContainer,
ControlGroupContainerFactory,
type ControlGroupInput,