mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 11:05:39 -04:00
[controls] complete control input builder API (#146764)
ControlGroupRenderer API changes * Added parameter `initialInput: Partial<ControlGroupInput>,` to getCreationOptions method signature so consumers don't need to call `getDefaultControlGroupInput` * Rename prop onEmbeddableLoad -> onLoadComplete * Rename prop getCreationOptions -> getInitialInput controlGroupInputBuilder API changes * Added `addOptionsListControl` method that allows users to pass selectedOptions * Added `addRangeSliderControl` * Added `addTimeSliderControl` Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Devon Thomson <devon.thomson@elastic.co>
This commit is contained in:
parent
f95414f76f
commit
15ed59d6f0
7 changed files with 209 additions and 88 deletions
|
@ -9,23 +9,23 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
|
||||||
import { AppMountParameters } from '@kbn/core/public';
|
import { AppMountParameters } from '@kbn/core/public';
|
||||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||||
import { ControlsExampleStartDeps } from './plugin';
|
import { ControlsExampleStartDeps } from './plugin';
|
||||||
import { BasicReduxExample } from './basic_redux_example';
|
import { BasicReduxExample } from './basic_redux_example';
|
||||||
|
|
||||||
interface Props {
|
const ControlsExamples = ({ dataViewId }: { dataViewId?: string }) => {
|
||||||
dataView: DataView;
|
const examples = dataViewId ? (
|
||||||
}
|
<>
|
||||||
|
<BasicReduxExample dataViewId={dataViewId} />
|
||||||
const ControlsExamples = ({ dataView }: Props) => {
|
</>
|
||||||
|
) : (
|
||||||
|
<div>{'Please install e-commerce sample data to run controls examples.'}</div>
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<KibanaPageTemplate>
|
<KibanaPageTemplate>
|
||||||
<KibanaPageTemplate.Header pageTitle="Controls as a Building Block" />
|
<KibanaPageTemplate.Header pageTitle="Controls as a Building Block" />
|
||||||
<KibanaPageTemplate.Section>
|
<KibanaPageTemplate.Section>{examples}</KibanaPageTemplate.Section>
|
||||||
<BasicReduxExample dataView={dataView} />
|
|
||||||
</KibanaPageTemplate.Section>
|
|
||||||
</KibanaPageTemplate>
|
</KibanaPageTemplate>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -35,8 +35,7 @@ export const renderApp = async (
|
||||||
{ element }: AppMountParameters
|
{ element }: AppMountParameters
|
||||||
) => {
|
) => {
|
||||||
const dataViews = await data.dataViews.find('kibana_sample_data_ecommerce');
|
const dataViews = await data.dataViews.find('kibana_sample_data_ecommerce');
|
||||||
if (dataViews.length > 0) {
|
const dataViewId = dataViews.length > 0 ? dataViews[0].id : undefined;
|
||||||
ReactDOM.render(<ControlsExamples dataView={dataViews[0]} />, element);
|
ReactDOM.render(<ControlsExamples dataViewId={dataViewId} />, element);
|
||||||
}
|
|
||||||
return () => ReactDOM.unmountComponentAtNode(element);
|
return () => ReactDOM.unmountComponentAtNode(element);
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,10 @@ import React, { useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
LazyControlGroupRenderer,
|
LazyControlGroupRenderer,
|
||||||
ControlGroupContainer,
|
ControlGroupContainer,
|
||||||
ControlGroupInput,
|
|
||||||
useControlGroupContainerContext,
|
useControlGroupContainerContext,
|
||||||
ControlStyle,
|
ControlStyle,
|
||||||
} from '@kbn/controls-plugin/public';
|
} from '@kbn/controls-plugin/public';
|
||||||
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
import { withSuspense } from '@kbn/presentation-util-plugin/public';
|
||||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
|
||||||
import {
|
import {
|
||||||
EuiButtonGroup,
|
EuiButtonGroup,
|
||||||
EuiFlexGroup,
|
EuiFlexGroup,
|
||||||
|
@ -26,27 +24,24 @@ import {
|
||||||
EuiText,
|
EuiText,
|
||||||
EuiTitle,
|
EuiTitle,
|
||||||
} from '@elastic/eui';
|
} from '@elastic/eui';
|
||||||
import { getDefaultControlGroupInput } from '@kbn/controls-plugin/common';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
dataView: DataView;
|
|
||||||
}
|
|
||||||
const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);
|
const ControlGroupRenderer = withSuspense(LazyControlGroupRenderer);
|
||||||
|
|
||||||
export const BasicReduxExample = ({ dataView }: Props) => {
|
export const BasicReduxExample = ({ dataViewId }: { dataViewId: string }) => {
|
||||||
const [myControlGroup, setControlGroup] = useState<ControlGroupContainer>();
|
const [controlGroup, setControlGroup] = useState<ControlGroupContainer>();
|
||||||
const [currentControlStyle, setCurrentControlStyle] = useState<ControlStyle>('oneLine');
|
|
||||||
|
|
||||||
const ControlGroupReduxWrapper = useMemo(() => {
|
const ControlGroupReduxWrapper = useMemo(() => {
|
||||||
if (myControlGroup) return myControlGroup.getReduxEmbeddableTools().Wrapper;
|
if (controlGroup) return controlGroup.getReduxEmbeddableTools().Wrapper;
|
||||||
}, [myControlGroup]);
|
}, [controlGroup]);
|
||||||
|
|
||||||
const ButtonControls = () => {
|
const ButtonControls = () => {
|
||||||
const {
|
const {
|
||||||
useEmbeddableDispatch,
|
useEmbeddableDispatch,
|
||||||
|
useEmbeddableSelector: select,
|
||||||
actions: { setControlStyle },
|
actions: { setControlStyle },
|
||||||
} = useControlGroupContainerContext();
|
} = useControlGroupContainerContext();
|
||||||
const dispatch = useEmbeddableDispatch();
|
const dispatch = useEmbeddableDispatch();
|
||||||
|
const controlStyle = select((state) => state.explicitInput.controlStyle);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -71,9 +66,8 @@ export const BasicReduxExample = ({ dataView }: Props) => {
|
||||||
value: 'twoLine' as ControlStyle,
|
value: 'twoLine' as ControlStyle,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
idSelected={currentControlStyle}
|
idSelected={controlStyle}
|
||||||
onChange={(id, value) => {
|
onChange={(id, value) => {
|
||||||
setCurrentControlStyle(value);
|
|
||||||
dispatch(setControlStyle(value));
|
dispatch(setControlStyle(value));
|
||||||
}}
|
}}
|
||||||
type="single"
|
type="single"
|
||||||
|
@ -105,20 +99,17 @@ export const BasicReduxExample = ({ dataView }: Props) => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ControlGroupRenderer
|
<ControlGroupRenderer
|
||||||
onEmbeddableLoad={async (controlGroup) => {
|
onLoadComplete={async (newControlGroup) => {
|
||||||
setControlGroup(controlGroup);
|
setControlGroup(newControlGroup);
|
||||||
}}
|
}}
|
||||||
getCreationOptions={async (controlGroupInputBuilder) => {
|
getInitialInput={async (initialInput, builder) => {
|
||||||
const initialInput: Partial<ControlGroupInput> = {
|
await builder.addDataControlFromField(initialInput, {
|
||||||
...getDefaultControlGroupInput(),
|
dataViewId,
|
||||||
defaultControlWidth: 'small',
|
|
||||||
};
|
|
||||||
await controlGroupInputBuilder.addDataControlFromField(initialInput, {
|
|
||||||
dataViewId: dataView.id ?? 'kibana_sample_data_ecommerce',
|
|
||||||
fieldName: 'customer_first_name.keyword',
|
fieldName: 'customer_first_name.keyword',
|
||||||
|
width: 'small',
|
||||||
});
|
});
|
||||||
await controlGroupInputBuilder.addDataControlFromField(initialInput, {
|
await builder.addDataControlFromField(initialInput, {
|
||||||
dataViewId: dataView.id ?? 'kibana_sample_data_ecommerce',
|
dataViewId,
|
||||||
fieldName: 'customer_last_name.keyword',
|
fieldName: 'customer_last_name.keyword',
|
||||||
width: 'medium',
|
width: 'medium',
|
||||||
grow: false,
|
grow: false,
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||||
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||||
|
* Side Public License, v 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import uuid from 'uuid';
|
||||||
|
import { ControlPanelState } from '../../common';
|
||||||
|
import {
|
||||||
|
DEFAULT_CONTROL_GROW,
|
||||||
|
DEFAULT_CONTROL_WIDTH,
|
||||||
|
} from '../../common/control_group/control_group_constants';
|
||||||
|
import { RangeValue } from '../../common/range_slider/types';
|
||||||
|
import {
|
||||||
|
ControlInput,
|
||||||
|
ControlWidth,
|
||||||
|
DataControlInput,
|
||||||
|
OPTIONS_LIST_CONTROL,
|
||||||
|
RANGE_SLIDER_CONTROL,
|
||||||
|
TIME_SLIDER_CONTROL,
|
||||||
|
} from '..';
|
||||||
|
import { ControlGroupInput } from './types';
|
||||||
|
import { getCompatibleControlType, getNextPanelOrder } from './embeddable/control_group_helpers';
|
||||||
|
|
||||||
|
export interface AddDataControlProps {
|
||||||
|
controlId?: string;
|
||||||
|
dataViewId: string;
|
||||||
|
fieldName: string;
|
||||||
|
grow?: boolean;
|
||||||
|
title?: string;
|
||||||
|
width?: ControlWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AddOptionsListControlProps = AddDataControlProps & {
|
||||||
|
selectedOptions?: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddRangeSliderControlProps = AddDataControlProps & {
|
||||||
|
value?: RangeValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const controlGroupInputBuilder = {
|
||||||
|
addDataControlFromField: async (
|
||||||
|
initialInput: Partial<ControlGroupInput>,
|
||||||
|
controlProps: AddDataControlProps
|
||||||
|
) => {
|
||||||
|
const { controlId, dataViewId, fieldName, title } = controlProps;
|
||||||
|
const panelId = controlId ? controlId : uuid.v4();
|
||||||
|
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>,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
addOptionsListControl: (
|
||||||
|
initialInput: Partial<ControlGroupInput>,
|
||||||
|
controlProps: AddOptionsListControlProps
|
||||||
|
) => {
|
||||||
|
const { controlId, dataViewId, fieldName, selectedOptions, title } = controlProps;
|
||||||
|
const panelId = controlId ? controlId : uuid.v4();
|
||||||
|
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>,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
addRangeSliderControl: (
|
||||||
|
initialInput: Partial<ControlGroupInput>,
|
||||||
|
controlProps: AddRangeSliderControlProps
|
||||||
|
) => {
|
||||||
|
const { controlId, dataViewId, fieldName, title, value } = controlProps;
|
||||||
|
const panelId = controlId ? controlId : uuid.v4();
|
||||||
|
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>,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
addTimeSliderControl: (initialInput: Partial<ControlGroupInput>) => {
|
||||||
|
const panelId = uuid.v4();
|
||||||
|
initialInput.panels = {
|
||||||
|
...initialInput.panels,
|
||||||
|
[panelId]: {
|
||||||
|
order: getNextPanelOrder(initialInput),
|
||||||
|
type: TIME_SLIDER_CONTROL,
|
||||||
|
grow: true,
|
||||||
|
width: 'large',
|
||||||
|
explicitInput: {
|
||||||
|
id: panelId,
|
||||||
|
title: 'timeslider',
|
||||||
|
},
|
||||||
|
} as ControlPanelState<ControlInput>,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWidth(initialInput: Partial<ControlGroupInput>, controlProps: AddDataControlProps) {
|
||||||
|
if (controlProps.width) {
|
||||||
|
return controlProps.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
return initialInput.defaultControlWidth
|
||||||
|
? initialInput.defaultControlWidth
|
||||||
|
: DEFAULT_CONTROL_WIDTH;
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ import { IEmbeddable } from '@kbn/embeddable-plugin/public';
|
||||||
import { useReduxContainerContext } from '@kbn/presentation-util-plugin/public';
|
import { useReduxContainerContext } from '@kbn/presentation-util-plugin/public';
|
||||||
|
|
||||||
import { pluginServices } from '../services';
|
import { pluginServices } from '../services';
|
||||||
import { ControlPanelState, getDefaultControlGroupInput } from '../../common';
|
import { getDefaultControlGroupInput } from '../../common';
|
||||||
import {
|
import {
|
||||||
ControlGroupInput,
|
ControlGroupInput,
|
||||||
ControlGroupOutput,
|
ControlGroupOutput,
|
||||||
|
@ -22,60 +22,29 @@ import {
|
||||||
CONTROL_GROUP_TYPE,
|
CONTROL_GROUP_TYPE,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { ControlGroupContainer } from './embeddable/control_group_container';
|
import { ControlGroupContainer } from './embeddable/control_group_container';
|
||||||
import { DataControlInput } from '../types';
|
|
||||||
import { getCompatibleControlType, getNextPanelOrder } from './embeddable/control_group_helpers';
|
|
||||||
import { controlGroupReducers } from './state/control_group_reducers';
|
import { controlGroupReducers } from './state/control_group_reducers';
|
||||||
|
import { controlGroupInputBuilder } from './control_group_input_builder';
|
||||||
const ControlGroupInputBuilder = {
|
|
||||||
addDataControlFromField: async (
|
|
||||||
initialInput: Partial<ControlGroupInput>,
|
|
||||||
newPanelInput: {
|
|
||||||
title?: string;
|
|
||||||
panelId?: string;
|
|
||||||
fieldName: string;
|
|
||||||
dataViewId: string;
|
|
||||||
} & Partial<ControlPanelState>
|
|
||||||
) => {
|
|
||||||
const { defaultControlGrow, defaultControlWidth } = getDefaultControlGroupInput();
|
|
||||||
const controlGrow = initialInput.defaultControlGrow ?? defaultControlGrow;
|
|
||||||
const controlWidth = initialInput.defaultControlWidth ?? defaultControlWidth;
|
|
||||||
|
|
||||||
const { panelId, dataViewId, fieldName, title, grow, width } = newPanelInput;
|
|
||||||
const newPanelId = panelId || uuid.v4();
|
|
||||||
const nextOrder = getNextPanelOrder(initialInput);
|
|
||||||
const controlType = await getCompatibleControlType({ dataViewId, fieldName });
|
|
||||||
|
|
||||||
initialInput.panels = {
|
|
||||||
...initialInput.panels,
|
|
||||||
[newPanelId]: {
|
|
||||||
order: nextOrder,
|
|
||||||
type: controlType,
|
|
||||||
grow: grow ?? controlGrow,
|
|
||||||
width: width ?? controlWidth,
|
|
||||||
explicitInput: { id: newPanelId, dataViewId, fieldName, title: title ?? fieldName },
|
|
||||||
} as ControlPanelState<DataControlInput>,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface ControlGroupRendererProps {
|
export interface ControlGroupRendererProps {
|
||||||
onEmbeddableLoad: (controlGroupContainer: ControlGroupContainer) => void;
|
onLoadComplete?: (controlGroup: ControlGroupContainer) => void;
|
||||||
getCreationOptions: (
|
getInitialInput: (
|
||||||
builder: typeof ControlGroupInputBuilder
|
initialInput: Partial<ControlGroupInput>,
|
||||||
|
builder: typeof controlGroupInputBuilder
|
||||||
) => Promise<Partial<ControlGroupInput>>;
|
) => Promise<Partial<ControlGroupInput>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ControlGroupRenderer = ({
|
export const ControlGroupRenderer = ({
|
||||||
onEmbeddableLoad,
|
onLoadComplete,
|
||||||
getCreationOptions,
|
getInitialInput,
|
||||||
}: ControlGroupRendererProps) => {
|
}: ControlGroupRendererProps) => {
|
||||||
const controlsRoot = useRef(null);
|
const controlGroupRef = useRef(null);
|
||||||
const [controlGroupContainer, setControlGroupContainer] = useState<ControlGroupContainer>();
|
const [controlGroup, setControlGroup] = useState<ControlGroupContainer>();
|
||||||
const id = useMemo(() => uuid.v4(), []);
|
const id = useMemo(() => uuid.v4(), []);
|
||||||
/**
|
/**
|
||||||
* Use Lifecycles to load initial control group container
|
* Use Lifecycles to load initial control group container
|
||||||
*/
|
*/
|
||||||
useLifecycles(
|
useLifecycles(
|
||||||
|
// onMount
|
||||||
() => {
|
() => {
|
||||||
const { embeddable } = pluginServices.getServices();
|
const { embeddable } = pluginServices.getServices();
|
||||||
(async () => {
|
(async () => {
|
||||||
|
@ -84,25 +53,28 @@ export const ControlGroupRenderer = ({
|
||||||
ControlGroupOutput,
|
ControlGroupOutput,
|
||||||
IEmbeddable<ControlGroupInput, ControlGroupOutput>
|
IEmbeddable<ControlGroupInput, ControlGroupOutput>
|
||||||
>(CONTROL_GROUP_TYPE);
|
>(CONTROL_GROUP_TYPE);
|
||||||
const container = (await factory?.create({
|
const newControlGroup = (await factory?.create({
|
||||||
id,
|
id,
|
||||||
...getDefaultControlGroupInput(),
|
...getDefaultControlGroupInput(),
|
||||||
...(await getCreationOptions(ControlGroupInputBuilder)),
|
...(await getInitialInput(getDefaultControlGroupInput(), controlGroupInputBuilder)),
|
||||||
})) as ControlGroupContainer;
|
})) as ControlGroupContainer;
|
||||||
|
|
||||||
if (controlsRoot.current) {
|
if (controlGroupRef.current) {
|
||||||
container.render(controlsRoot.current);
|
newControlGroup.render(controlGroupRef.current);
|
||||||
|
}
|
||||||
|
setControlGroup(newControlGroup);
|
||||||
|
if (onLoadComplete) {
|
||||||
|
onLoadComplete(newControlGroup);
|
||||||
}
|
}
|
||||||
setControlGroupContainer(container);
|
|
||||||
onEmbeddableLoad(container);
|
|
||||||
})();
|
})();
|
||||||
},
|
},
|
||||||
|
// onUnmount
|
||||||
() => {
|
() => {
|
||||||
controlGroupContainer?.destroy();
|
controlGroup?.destroy();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return <div ref={controlsRoot} />;
|
return <div ref={controlGroupRef} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useControlGroupContainerContext = () =>
|
export const useControlGroupContainerContext = () =>
|
||||||
|
|
|
@ -14,6 +14,12 @@ export type { ControlGroupInput, ControlGroupOutput } from './types';
|
||||||
export { CONTROL_GROUP_TYPE } from './types';
|
export { CONTROL_GROUP_TYPE } from './types';
|
||||||
export { ControlGroupContainerFactory } from './embeddable/control_group_container_factory';
|
export { ControlGroupContainerFactory } from './embeddable/control_group_container_factory';
|
||||||
|
|
||||||
|
export {
|
||||||
|
type AddDataControlProps,
|
||||||
|
type AddOptionsListControlProps,
|
||||||
|
controlGroupInputBuilder,
|
||||||
|
} from './control_group_input_builder';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type ControlGroupRendererProps,
|
type ControlGroupRendererProps,
|
||||||
useControlGroupContainerContext,
|
useControlGroupContainerContext,
|
||||||
|
|
|
@ -22,6 +22,7 @@ export type {
|
||||||
ControlStyle,
|
ControlStyle,
|
||||||
ParentIgnoreSettings,
|
ParentIgnoreSettings,
|
||||||
ControlInput,
|
ControlInput,
|
||||||
|
DataControlInput,
|
||||||
} from '../common/types';
|
} from '../common/types';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
@ -32,9 +33,12 @@ export {
|
||||||
} from '../common';
|
} from '../common';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
type AddDataControlProps,
|
||||||
|
type AddOptionsListControlProps,
|
||||||
type ControlGroupContainer,
|
type ControlGroupContainer,
|
||||||
ControlGroupContainerFactory,
|
ControlGroupContainerFactory,
|
||||||
type ControlGroupInput,
|
type ControlGroupInput,
|
||||||
|
controlGroupInputBuilder,
|
||||||
type ControlGroupOutput,
|
type ControlGroupOutput,
|
||||||
} from './control_group';
|
} from './control_group';
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ export const ControlsContent: React.FC<Props> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LazyControlsRenderer
|
<LazyControlsRenderer
|
||||||
getCreationOptions={async ({ addDataControlFromField }) => ({
|
getInitialInput={async () => ({
|
||||||
id: dataViewId,
|
id: dataViewId,
|
||||||
type: CONTROL_GROUP_TYPE,
|
type: CONTROL_GROUP_TYPE,
|
||||||
timeRange,
|
timeRange,
|
||||||
|
@ -72,7 +72,7 @@ export const ControlsContent: React.FC<Props> = ({
|
||||||
defaultControlWidth: 'small',
|
defaultControlWidth: 'small',
|
||||||
panels: controlPanel,
|
panels: controlPanel,
|
||||||
})}
|
})}
|
||||||
onEmbeddableLoad={(newControlGroup) => {
|
onLoadComplete={(newControlGroup) => {
|
||||||
setControlGroup(newControlGroup);
|
setControlGroup(newControlGroup);
|
||||||
newControlGroup.onFiltersPublished$.subscribe((newFilters) => {
|
newControlGroup.onFiltersPublished$.subscribe((newFilters) => {
|
||||||
setPanelFilters([...newFilters]);
|
setPanelFilters([...newFilters]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue