mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[controls] align controlGroupInputBuilder API in ControlGroupContainer API (#146928)
PR does the following * Mirror controlGroupInputBuilder methods in ControlGroupContainer API: * addOptionsListControl * addRangeSliderControl * addTimeSliderControl * Update existing ControlGroupContainer.addDataControlFromField method have same signature as controlGroupInputBuilder.addDataControlFromField * Use new ControlGroupContainer APIs when adding controls view React components Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
0bf250ad21
commit
92ae81d1f3
5 changed files with 142 additions and 116 deletions
|
@ -6,8 +6,9 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import uuid from 'uuid';
|
||||
import { ControlPanelState } from '../../common';
|
||||
import { ControlPanelState, OptionsListEmbeddableInput } from '../../common';
|
||||
import {
|
||||
DEFAULT_CONTROL_GROW,
|
||||
DEFAULT_CONTROL_WIDTH,
|
||||
|
@ -33,9 +34,7 @@ export interface AddDataControlProps {
|
|||
width?: ControlWidth;
|
||||
}
|
||||
|
||||
export type AddOptionsListControlProps = AddDataControlProps & {
|
||||
selectedOptions?: string[];
|
||||
};
|
||||
export type AddOptionsListControlProps = AddDataControlProps & Partial<OptionsListEmbeddableInput>;
|
||||
|
||||
export type AddRangeSliderControlProps = AddDataControlProps & {
|
||||
value?: RangeValue;
|
||||
|
@ -46,104 +45,113 @@ export const controlGroupInputBuilder = {
|
|||
initialInput: Partial<ControlGroupInput>,
|
||||
controlProps: AddDataControlProps
|
||||
) => {
|
||||
const { controlId, dataViewId, fieldName, title } = controlProps;
|
||||
const panelId = controlId ? controlId : uuid.v4();
|
||||
const panelState = await getDataControlPanelState(initialInput, controlProps);
|
||||
initialInput.panels = {
|
||||
...initialInput.panels,
|
||||
[panelId]: {
|
||||
order: getNextPanelOrder(initialInput),
|
||||
type: await getCompatibleControlType({ dataViewId, fieldName }),
|
||||
grow: getGrow(initialInput, controlProps),
|
||||
width: getWidth(initialInput, controlProps),
|
||||
explicitInput: {
|
||||
id: panelId,
|
||||
dataViewId,
|
||||
fieldName,
|
||||
title: title ?? fieldName,
|
||||
},
|
||||
} as ControlPanelState<DataControlInput>,
|
||||
[panelState.explicitInput.id]: panelState,
|
||||
};
|
||||
},
|
||||
addOptionsListControl: (
|
||||
initialInput: Partial<ControlGroupInput>,
|
||||
controlProps: AddOptionsListControlProps
|
||||
) => {
|
||||
const { controlId, dataViewId, fieldName, selectedOptions, title } = controlProps;
|
||||
const panelId = controlId ? controlId : uuid.v4();
|
||||
const panelState = getOptionsListPanelState(initialInput, controlProps);
|
||||
initialInput.panels = {
|
||||
...initialInput.panels,
|
||||
[panelId]: {
|
||||
order: getNextPanelOrder(initialInput),
|
||||
type: OPTIONS_LIST_CONTROL,
|
||||
grow: getGrow(initialInput, controlProps),
|
||||
width: getWidth(initialInput, controlProps),
|
||||
explicitInput: {
|
||||
id: panelId,
|
||||
dataViewId,
|
||||
fieldName,
|
||||
selectedOptions,
|
||||
title: title ?? fieldName,
|
||||
},
|
||||
} as ControlPanelState<DataControlInput>,
|
||||
[panelState.explicitInput.id]: panelState,
|
||||
};
|
||||
},
|
||||
addRangeSliderControl: (
|
||||
initialInput: Partial<ControlGroupInput>,
|
||||
controlProps: AddRangeSliderControlProps
|
||||
) => {
|
||||
const { controlId, dataViewId, fieldName, title, value } = controlProps;
|
||||
const panelId = controlId ? controlId : uuid.v4();
|
||||
const panelState = getRangeSliderPanelState(initialInput, controlProps);
|
||||
initialInput.panels = {
|
||||
...initialInput.panels,
|
||||
[panelId]: {
|
||||
order: getNextPanelOrder(initialInput),
|
||||
type: RANGE_SLIDER_CONTROL,
|
||||
grow: getGrow(initialInput, controlProps),
|
||||
width: getWidth(initialInput, controlProps),
|
||||
explicitInput: {
|
||||
id: panelId,
|
||||
dataViewId,
|
||||
fieldName,
|
||||
title: title ?? fieldName,
|
||||
value: value ? value : ['', ''],
|
||||
},
|
||||
} as ControlPanelState<DataControlInput>,
|
||||
[panelState.explicitInput.id]: panelState,
|
||||
};
|
||||
},
|
||||
addTimeSliderControl: (initialInput: Partial<ControlGroupInput>) => {
|
||||
const panelId = uuid.v4();
|
||||
const panelState = getTimeSliderPanelState(initialInput);
|
||||
initialInput.panels = {
|
||||
...initialInput.panels,
|
||||
[panelId]: {
|
||||
order: getNextPanelOrder(initialInput),
|
||||
type: TIME_SLIDER_CONTROL,
|
||||
grow: true,
|
||||
width: 'large',
|
||||
explicitInput: {
|
||||
id: panelId,
|
||||
title: 'timeslider',
|
||||
},
|
||||
} as ControlPanelState<ControlInput>,
|
||||
[panelState.explicitInput.id]: panelState,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
function getGrow(initialInput: Partial<ControlGroupInput>, controlProps: AddDataControlProps) {
|
||||
if (typeof controlProps.grow === 'boolean') {
|
||||
return controlProps.grow;
|
||||
}
|
||||
|
||||
return typeof initialInput.defaultControlGrow === 'boolean'
|
||||
? initialInput.defaultControlGrow
|
||||
: DEFAULT_CONTROL_GROW;
|
||||
export async function getDataControlPanelState(
|
||||
input: Partial<ControlGroupInput>,
|
||||
controlProps: AddDataControlProps
|
||||
) {
|
||||
const { controlId, dataViewId, fieldName, title } = controlProps;
|
||||
return {
|
||||
type: await getCompatibleControlType({ dataViewId, fieldName }),
|
||||
...getPanelState(input, controlProps),
|
||||
explicitInput: {
|
||||
id: controlId ? controlId : uuid.v4(),
|
||||
dataViewId,
|
||||
fieldName,
|
||||
title: title ?? fieldName,
|
||||
},
|
||||
} as ControlPanelState<DataControlInput>;
|
||||
}
|
||||
|
||||
function getWidth(initialInput: Partial<ControlGroupInput>, controlProps: AddDataControlProps) {
|
||||
if (controlProps.width) {
|
||||
return controlProps.width;
|
||||
}
|
||||
|
||||
return initialInput.defaultControlWidth
|
||||
? initialInput.defaultControlWidth
|
||||
: DEFAULT_CONTROL_WIDTH;
|
||||
export function getOptionsListPanelState(
|
||||
input: Partial<ControlGroupInput>,
|
||||
controlProps: AddOptionsListControlProps
|
||||
) {
|
||||
const { controlId, dataViewId, fieldName, title, ...rest } = controlProps;
|
||||
return {
|
||||
type: OPTIONS_LIST_CONTROL,
|
||||
...getPanelState(input, controlProps),
|
||||
explicitInput: {
|
||||
id: controlId ? controlId : uuid.v4(),
|
||||
dataViewId,
|
||||
fieldName,
|
||||
title: title ?? fieldName,
|
||||
...rest,
|
||||
},
|
||||
} as ControlPanelState<DataControlInput>;
|
||||
}
|
||||
|
||||
export function getRangeSliderPanelState(
|
||||
input: Partial<ControlGroupInput>,
|
||||
controlProps: AddRangeSliderControlProps
|
||||
) {
|
||||
const { controlId, dataViewId, fieldName, title, ...rest } = controlProps;
|
||||
return {
|
||||
type: RANGE_SLIDER_CONTROL,
|
||||
...getPanelState(input, controlProps),
|
||||
explicitInput: {
|
||||
id: controlId ? controlId : uuid.v4(),
|
||||
dataViewId,
|
||||
fieldName,
|
||||
title: title ?? fieldName,
|
||||
...rest,
|
||||
},
|
||||
} as ControlPanelState<DataControlInput>;
|
||||
}
|
||||
|
||||
export function getTimeSliderPanelState(input: Partial<ControlGroupInput>) {
|
||||
return {
|
||||
type: TIME_SLIDER_CONTROL,
|
||||
order: getNextPanelOrder(input.panels),
|
||||
grow: true,
|
||||
width: 'large',
|
||||
explicitInput: {
|
||||
id: uuid.v4(),
|
||||
title: i18n.translate('controls.controlGroup.timeSlider.title', {
|
||||
defaultMessage: 'Time slider',
|
||||
}),
|
||||
},
|
||||
} as ControlPanelState<ControlInput>;
|
||||
}
|
||||
|
||||
function getPanelState(input: Partial<ControlGroupInput>, controlProps: AddDataControlProps) {
|
||||
return {
|
||||
order: getNextPanelOrder(input.panels),
|
||||
grow: controlProps.grow ?? input.defaultControlGrow ?? DEFAULT_CONTROL_GROW,
|
||||
width: controlProps.width ?? input.defaultControlWidth ?? DEFAULT_CONTROL_WIDTH,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,17 +9,15 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { EuiContextMenuItem } from '@elastic/eui';
|
||||
import type { ControlInput } from '../../types';
|
||||
import { TIME_SLIDER_CONTROL } from '../../time_slider/types';
|
||||
|
||||
interface Props {
|
||||
addNewEmbeddable: (type: string, input: Omit<ControlInput, 'id'>) => void;
|
||||
onCreate: () => void;
|
||||
closePopover?: () => void;
|
||||
hasTimeSliderControl: boolean;
|
||||
}
|
||||
|
||||
export const CreateTimeSliderControlButton = ({
|
||||
addNewEmbeddable,
|
||||
onCreate,
|
||||
closePopover,
|
||||
hasTimeSliderControl,
|
||||
}: Props) => {
|
||||
|
@ -27,11 +25,7 @@ export const CreateTimeSliderControlButton = ({
|
|||
<EuiContextMenuItem
|
||||
icon="plusInCircle"
|
||||
onClick={() => {
|
||||
addNewEmbeddable(TIME_SLIDER_CONTROL, {
|
||||
title: i18n.translate('controls.controlGroup.timeSlider.title', {
|
||||
defaultMessage: 'Time slider',
|
||||
}),
|
||||
});
|
||||
onCreate();
|
||||
if (closePopover) {
|
||||
closePopover();
|
||||
}
|
||||
|
|
|
@ -40,11 +40,22 @@ import { ControlGroupStrings } from '../control_group_strings';
|
|||
import { EditControlGroup } from '../editor/edit_control_group';
|
||||
import { ControlGroup } from '../component/control_group_component';
|
||||
import { controlGroupReducers } from '../state/control_group_reducers';
|
||||
import { ControlEmbeddable, ControlInput, ControlOutput, DataControlInput } from '../../types';
|
||||
import { OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL, TIME_SLIDER_CONTROL } from '../..';
|
||||
import { ControlEmbeddable, ControlInput, ControlOutput } from '../../types';
|
||||
import { CreateControlButton, CreateControlButtonTypes } from '../editor/create_control';
|
||||
import { CreateTimeSliderControlButton } from '../editor/create_time_slider_control';
|
||||
import { TIME_SLIDER_CONTROL } from '../../time_slider';
|
||||
import { getCompatibleControlType, getNextPanelOrder } from './control_group_helpers';
|
||||
import { getNextPanelOrder } from './control_group_helpers';
|
||||
import type {
|
||||
AddDataControlProps,
|
||||
AddOptionsListControlProps,
|
||||
AddRangeSliderControlProps,
|
||||
} from '../control_group_input_builder';
|
||||
import {
|
||||
getDataControlPanelState,
|
||||
getOptionsListPanelState,
|
||||
getRangeSliderPanelState,
|
||||
getTimeSliderPanelState,
|
||||
} from '../control_group_input_builder';
|
||||
|
||||
let flyoutRef: OverlayRef | undefined;
|
||||
export const setFlyoutRef = (newRef: OverlayRef | undefined) => {
|
||||
|
@ -96,23 +107,24 @@ export class ControlGroupContainer extends Container<
|
|||
flyoutRef = undefined;
|
||||
}
|
||||
|
||||
public async addDataControlFromField({
|
||||
uuid,
|
||||
dataViewId,
|
||||
fieldName,
|
||||
title,
|
||||
}: {
|
||||
uuid?: string;
|
||||
dataViewId: string;
|
||||
fieldName: string;
|
||||
title?: string;
|
||||
}) {
|
||||
return this.addNewEmbeddable(await getCompatibleControlType({ dataViewId, fieldName }), {
|
||||
id: uuid,
|
||||
dataViewId,
|
||||
fieldName,
|
||||
title: title ?? fieldName,
|
||||
} as DataControlInput);
|
||||
public async addDataControlFromField(controlProps: AddDataControlProps) {
|
||||
const panelState = await getDataControlPanelState(this.getInput(), controlProps);
|
||||
return this.createAndSaveEmbeddable(panelState.type, panelState);
|
||||
}
|
||||
|
||||
public addOptionsListControl(controlProps: AddOptionsListControlProps) {
|
||||
const panelState = getOptionsListPanelState(this.getInput(), controlProps);
|
||||
return this.createAndSaveEmbeddable(panelState.type, panelState);
|
||||
}
|
||||
|
||||
public addRangeSliderControl(controlProps: AddRangeSliderControlProps) {
|
||||
const panelState = getRangeSliderPanelState(this.getInput(), controlProps);
|
||||
return this.createAndSaveEmbeddable(panelState.type, panelState);
|
||||
}
|
||||
|
||||
public addTimeSliderControl() {
|
||||
const panelState = getTimeSliderPanelState(this.getInput());
|
||||
return this.createAndSaveEmbeddable(panelState.type, panelState);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +150,19 @@ export class ControlGroupContainer extends Container<
|
|||
updateDefaultGrow={(defaultControlGrow: boolean) =>
|
||||
this.updateInput({ defaultControlGrow })
|
||||
}
|
||||
addNewEmbeddable={(type, input) => this.addNewEmbeddable(type, input)}
|
||||
addNewEmbeddable={(type, input) => {
|
||||
if (type === OPTIONS_LIST_CONTROL) {
|
||||
this.addOptionsListControl(input as AddOptionsListControlProps);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === RANGE_SLIDER_CONTROL) {
|
||||
this.addRangeSliderControl(input as AddRangeSliderControlProps);
|
||||
return;
|
||||
}
|
||||
|
||||
this.addDataControlFromField(input as AddDataControlProps);
|
||||
}}
|
||||
closePopover={closePopover}
|
||||
getRelevantDataViewId={() => this.getMostRelevantDataViewId()}
|
||||
setLastUsedDataViewId={(newId) => this.setLastUsedDataViewId(newId)}
|
||||
|
@ -155,7 +179,9 @@ export class ControlGroupContainer extends Container<
|
|||
});
|
||||
return (
|
||||
<CreateTimeSliderControlButton
|
||||
addNewEmbeddable={(type, input) => this.addNewEmbeddable(type, input)}
|
||||
onCreate={() => {
|
||||
this.addTimeSliderControl();
|
||||
}}
|
||||
closePopover={closePopover}
|
||||
hasTimeSliderControl={hasTimeSliderControl}
|
||||
/>
|
||||
|
@ -317,12 +343,10 @@ export class ControlGroupContainer extends Container<
|
|||
partial: Partial<TEmbeddableInput> = {}
|
||||
): ControlPanelState<TEmbeddableInput> {
|
||||
const panelState = super.createNewPanelState(factory, partial);
|
||||
const nextOrder = getNextPanelOrder(this.getInput());
|
||||
return {
|
||||
order: nextOrder,
|
||||
width:
|
||||
panelState.type === TIME_SLIDER_CONTROL ? 'large' : this.getInput().defaultControlWidth,
|
||||
grow: panelState.type === TIME_SLIDER_CONTROL ? true : this.getInput().defaultControlGrow,
|
||||
order: getNextPanelOrder(this.getInput().panels),
|
||||
width: this.getInput().defaultControlWidth,
|
||||
grow: this.getInput().defaultControlGrow,
|
||||
...panelState,
|
||||
} as ControlPanelState<TEmbeddableInput>;
|
||||
}
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { ControlGroupInput } from '../types';
|
||||
import { ControlsPanels } from '../types';
|
||||
import { pluginServices } from '../../services';
|
||||
import { getDataControlFieldRegistry } from '../editor/data_control_editor_tools';
|
||||
|
||||
export const getNextPanelOrder = (initialInput: Partial<ControlGroupInput>) => {
|
||||
export const getNextPanelOrder = (panels?: ControlsPanels) => {
|
||||
let nextOrder = 0;
|
||||
if (Object.keys(initialInput.panels ?? {}).length > 0) {
|
||||
if (Object.keys(panels ?? {}).length > 0) {
|
||||
nextOrder =
|
||||
Object.values(initialInput.panels ?? {}).reduce((highestSoFar, panel) => {
|
||||
Object.values(panels ?? {}).reduce((highestSoFar, panel) => {
|
||||
if (panel.order > highestSoFar) highestSoFar = panel.order;
|
||||
return highestSoFar;
|
||||
}, 0) + 1;
|
||||
|
|
|
@ -398,7 +398,7 @@ export abstract class Container<
|
|||
}
|
||||
}
|
||||
|
||||
private async createAndSaveEmbeddable<
|
||||
protected async createAndSaveEmbeddable<
|
||||
TEmbeddableInput extends EmbeddableInput = EmbeddableInput,
|
||||
TEmbeddable extends IEmbeddable<TEmbeddableInput> = IEmbeddable<TEmbeddableInput>
|
||||
>(type: string, panelState: PanelState) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue