diff --git a/src/legacy/ui/public/vis/editors/config/editor_config_providers.test.ts b/src/legacy/ui/public/vis/editors/config/editor_config_providers.test.ts index fa15f8642c4dcf..66223f2107ebc6 100644 --- a/src/legacy/ui/public/vis/editors/config/editor_config_providers.test.ts +++ b/src/legacy/ui/public/vis/editors/config/editor_config_providers.test.ts @@ -51,7 +51,7 @@ describe('EditorConfigProvider', () => { expect(provider).not.toHaveBeenCalled(); const aggType = {} as AggType; const aggConfig = {} as AggConfig; - registry.getConfigForAgg(aggType, indexPattern, aggConfig); + registry.getConfigForAgg(indexPattern, aggConfig); expect(provider).toHaveBeenCalledWith(aggType, indexPattern, aggConfig); }); @@ -64,7 +64,7 @@ describe('EditorConfigProvider', () => { expect(provider2).not.toHaveBeenCalled(); const aggType = {} as AggType; const aggConfig = {} as AggConfig; - registry.getConfigForAgg(aggType, indexPattern, aggConfig); + registry.getConfigForAgg(indexPattern, aggConfig); expect(provider).toHaveBeenCalledWith(aggType, indexPattern, aggConfig); expect(provider2).toHaveBeenCalledWith(aggType, indexPattern, aggConfig); }); @@ -75,7 +75,7 @@ describe('EditorConfigProvider', () => { } function getOutputConfig(reg: EditorConfigProviderRegistry) { - return reg.getConfigForAgg({} as AggType, indexPattern, {} as AggConfig).singleParam; + return reg.getConfigForAgg(indexPattern, {} as AggConfig).singleParam; } it('should have hidden true if at least one config was hidden true', () => { diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_common_props.ts b/src/legacy/ui/public/vis/editors/default/components/agg_common_props.ts index 465f598987b82d..f1adfed646b585 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_common_props.ts +++ b/src/legacy/ui/public/vis/editors/default/components/agg_common_props.ts @@ -18,9 +18,15 @@ */ import { AggType } from 'ui/agg_types'; -import { AggConfig, VisState } from 'ui/vis'; +import { AggConfig, VisState, VisParams } from 'ui/vis'; import { AggGroupNames } from '../agg_groups'; -import { EditorActions } from '../state/actions'; +import { Schema } from '../schemas'; + +type AggId = AggConfig['id']; +type AggParams = AggConfig['params']; + +export type AddSchema = (schemas: Schema) => void; +export type ReorderAggs = (sourceAgg: AggConfig, destinationAgg: AggConfig) => void; export interface DefaultEditorAggCommonProps { formIsTouched: boolean; @@ -28,15 +34,15 @@ export interface DefaultEditorAggCommonProps { lastParentPipelineAggTitle?: string; metricAggs: AggConfig[]; state: VisState; - setAggParamValue: ( - aggId: AggConfig['id'], + setAggParamValue: ( + aggId: AggId, paramName: T, - value: AggConfig['params'][T] + value: AggParams[T] ) => void; - setStateParamValue: EditorActions['setStateParamValue']; - onAggTypeChange: (aggId: AggConfig['id'], aggType: AggType) => void; - onToggleEnableAgg: (aggId: AggConfig['id'], isEnable: boolean) => void; - removeAgg: (aggId: AggConfig['id']) => void; + setStateParamValue: (paramName: T, value: VisParams[T]) => void; + onAggTypeChange: (aggId: AggId, aggType: AggType) => void; + onToggleEnableAgg: (aggId: AggId, isEnable: boolean) => void; + removeAgg: (aggId: AggId) => void; setTouched: (isTouched: boolean) => void; setValidity: (isValid: boolean) => void; } diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx b/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx index 360561b893c8fe..c0c0e89ceec9d1 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg_group.tsx @@ -34,7 +34,7 @@ import { AggConfig } from '../../../../agg_types/agg_config'; import { aggGroupNamesMap, AggGroupNames } from '../agg_groups'; import { DefaultEditorAgg } from './agg'; import { DefaultEditorAggAdd } from './agg_add'; -import { DefaultEditorAggCommonProps } from './agg_common_props'; +import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from './agg_common_props'; import { isInvalidAggsTouched, isAggRemovable, @@ -43,12 +43,11 @@ import { } from './agg_group_helper'; import { aggGroupReducer, initAggsState, AGGS_ACTION_KEYS } from './agg_group_state'; import { Schema } from '../schemas'; -import { EditorActions } from '../state/actions'; export interface DefaultEditorAggGroupProps extends DefaultEditorAggCommonProps { schemas: Schema[]; - addSchema: (schemas: Schema) => void; - reorderAggs: EditorActions['reorderAggs']; + addSchema: AddSchema; + reorderAggs: ReorderAggs; } function DefaultEditorAggGroup({ diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_param.tsx b/src/legacy/ui/public/vis/editors/default/components/agg_param.tsx index 2c636c12c198b5..60be94166a4770 100644 --- a/src/legacy/ui/public/vis/editors/default/components/agg_param.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/agg_param.tsx @@ -20,11 +20,11 @@ import React, { useCallback, useEffect } from 'react'; import { AggParamEditorProps, AggParamCommonProps } from './agg_param_props'; -import { EditorActions } from '../state/actions'; +import { DefaultEditorAggCommonProps } from './agg_common_props'; interface DefaultEditorAggParamProps extends AggParamCommonProps { paramEditor: React.ComponentType>; - setAggParamValue: EditorActions['setAggParamValue']; + setAggParamValue: DefaultEditorAggCommonProps['setAggParamValue']; } function DefaultEditorAggParam(props: DefaultEditorAggParamProps) { diff --git a/src/legacy/ui/public/vis/editors/default/components/bottom_bar.tsx b/src/legacy/ui/public/vis/editors/default/components/bottom_bar.tsx index 4030c12e28d117..a9b2a8fb54bc75 100644 --- a/src/legacy/ui/public/vis/editors/default/components/bottom_bar.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/bottom_bar.tsx @@ -23,16 +23,17 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { Vis } from 'ui/vis'; import { useEditorContext } from '../state'; +import { discardChanges, EditorAction } from '../state/actions'; interface DefaultEditorBottomBarProps { vis: Vis; state: any; - discardChanges(vis: Vis): void; + dispatch: React.Dispatch; } -function DefaultEditorBottomBar({ discardChanges, vis, state }: DefaultEditorBottomBarProps) { +function DefaultEditorBottomBar({ dispatch, vis, state }: DefaultEditorBottomBarProps) { const { enableAutoApply } = vis.type.editorConfig; - const onClickDiscard = useCallback(() => discardChanges(vis), [discardChanges, vis]); + const onClickDiscard = useCallback(() => dispatch(discardChanges(vis)), [dispatch, vis]); const { isDirty, setDirty } = useEditorContext(); const applyChanges = useCallback(() => { diff --git a/src/legacy/ui/public/vis/editors/default/components/sidebar/data_tab.tsx b/src/legacy/ui/public/vis/editors/default/components/sidebar/data_tab.tsx index a211b0f05f031c..d0c8f7d5e96396 100644 --- a/src/legacy/ui/public/vis/editors/default/components/sidebar/data_tab.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/sidebar/data_tab.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { useMemo } from 'react'; +import React, { useMemo, useCallback } from 'react'; import { findLast } from 'lodash'; import { EuiSpacer } from '@elastic/eui'; @@ -27,25 +27,36 @@ import { MetricAggType } from 'ui/agg_types/metrics/metric_agg_type'; import { VisState } from 'ui/vis'; import { DefaultEditorAggGroup } from '../agg_group'; import { AggGroupNames } from '../../agg_groups'; -import { EditorActions } from '../../state/actions'; +import { + EditorAction, + addNewAgg, + removeAgg, + reorderAggs, + setAggParamValue, + changeAggType, + toggleEnabledAgg, +} from '../../state/actions'; import { ISchemas } from '../../schemas'; +import { AddSchema, ReorderAggs, DefaultEditorAggCommonProps } from '../agg_common_props'; export interface DefaultEditorDataTabProps { - actions: EditorActions; + dispatch: React.Dispatch; metricAggs: AggConfig[]; schemas: ISchemas; state: VisState; setTouched(isTouched: boolean): void; setValidity(isValid: boolean): void; + setStateValue: DefaultEditorAggCommonProps['setStateParamValue']; } function DefaultEditorDataTab({ - actions, + dispatch, metricAggs, schemas, state, setTouched, setValidity, + setStateValue, }: DefaultEditorDataTabProps) { const lastParentPipelineAgg = useMemo( () => @@ -57,19 +68,45 @@ function DefaultEditorDataTab({ ); const lastParentPipelineAggTitle = lastParentPipelineAgg && lastParentPipelineAgg.type.title; + const addSchema: AddSchema = useCallback(schema => dispatch(addNewAgg(schema)), [dispatch]); + + const onAggRemove: DefaultEditorAggCommonProps['removeAgg'] = useCallback( + aggId => dispatch(removeAgg(aggId)), + [dispatch] + ); + + const onReorderAggs: ReorderAggs = useCallback((...props) => dispatch(reorderAggs(...props)), [ + dispatch, + ]); + + const onAggParamValueChange: DefaultEditorAggCommonProps['setAggParamValue'] = useCallback( + (...props) => dispatch(setAggParamValue(...props)), + [dispatch] + ); + + const onAggTypeChange: DefaultEditorAggCommonProps['onAggTypeChange'] = useCallback( + (...props) => dispatch(changeAggType(...props)), + [dispatch] + ); + + const onToggleEnableAgg: DefaultEditorAggCommonProps['onToggleEnableAgg'] = useCallback( + (...props) => dispatch(toggleEnabledAgg(...props)), + [dispatch] + ); + const commonProps = { - addSchema: actions.addNewAgg, + addSchema, lastParentPipelineAggTitle, metricAggs, state, - reorderAggs: actions.reorderAggs, - setAggParamValue: actions.setAggParamValue, - setStateParamValue: actions.setStateParamValue, - onAggTypeChange: actions.changeAggType, - onToggleEnableAgg: actions.toggleEnabledAgg, + reorderAggs: onReorderAggs, + setAggParamValue: onAggParamValueChange, + setStateParamValue: setStateValue, + onAggTypeChange, + onToggleEnableAgg, setValidity, setTouched, - removeAgg: actions.removeAgg, + removeAgg: onAggRemove, }; return ( diff --git a/src/legacy/ui/public/vis/editors/default/components/sidebar/sidebar.tsx b/src/legacy/ui/public/vis/editors/default/components/sidebar/sidebar.tsx index b64a1e4f7a245f..d82b3e96e1921b 100644 --- a/src/legacy/ui/public/vis/editors/default/components/sidebar/sidebar.tsx +++ b/src/legacy/ui/public/vis/editors/default/components/sidebar/sidebar.tsx @@ -17,18 +17,19 @@ * under the License. */ -import React, { useMemo, useState } from 'react'; +import React, { useMemo, useState, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; -import { get } from 'lodash'; +import { get, isEqual } from 'lodash'; import { Vis, VisState } from 'ui/vis'; import { PersistedState } from 'ui/persisted_state'; import { DefaultEditorNavBar, OptionTab } from './navbar'; -import { EditorActions } from '../../state/actions'; +import { setStateParamValue, EditorAction } from '../../state/actions'; import { AggGroupNames } from '../../agg_groups'; +import { DefaultEditorAggCommonProps } from '../agg_common_props'; interface DefaultEditorSideBarProps { - actions: EditorActions; + dispatch: React.Dispatch; optionTabs: OptionTab[]; state: VisState; uiState: PersistedState; @@ -36,7 +37,7 @@ interface DefaultEditorSideBarProps { } function DefaultEditorSideBar({ - actions, + dispatch, optionTabs, state, uiState, @@ -56,13 +57,25 @@ function DefaultEditorSideBar({ const setValidity = () => {}; const setTouched = () => {}; + const setStateValue: DefaultEditorAggCommonProps['setStateParamValue'] = useCallback( + (paramName, value) => { + const shouldUpdate = !isEqual(state.params[paramName], value); + + if (shouldUpdate) { + dispatch(setStateParamValue(paramName, value)); + } + }, + [dispatch] + ); + const dataTabProps = { - actions, + dispatch, metricAggs, state, schemas: vis.type.schemas, setValidity, setTouched, + setStateValue, }; const optionTabProps = { @@ -71,7 +84,7 @@ function DefaultEditorSideBar({ stateParams: state.params, vis, uiState, - setValue: actions.setStateParamValue, + setValue: setStateValue, setValidity, setTouched, }; diff --git a/src/legacy/ui/public/vis/editors/default/controls/agg_control_props.tsx b/src/legacy/ui/public/vis/editors/default/controls/agg_control_props.tsx index 0e237261a473e4..55cd237a56689d 100644 --- a/src/legacy/ui/public/vis/editors/default/controls/agg_control_props.tsx +++ b/src/legacy/ui/public/vis/editors/default/controls/agg_control_props.tsx @@ -18,11 +18,11 @@ */ import { AggConfig, VisParams } from 'ui/vis'; -import { EditorActions } from '../state/actions'; +import { DefaultEditorAggCommonProps } from '../components/agg_common_props'; export interface AggControlProps { agg: AggConfig; editorStateParams: VisParams; - setAggParamValue: EditorActions['setAggParamValue']; - setStateParamValue: EditorActions['setStateParamValue']; + setAggParamValue: DefaultEditorAggCommonProps['setAggParamValue']; + setStateParamValue: DefaultEditorAggCommonProps['setStateParamValue']; } diff --git a/src/legacy/ui/public/vis/editors/default/default_editor.tsx b/src/legacy/ui/public/vis/editors/default/default_editor.tsx index 62d7e453a6da44..52edea061c655b 100644 --- a/src/legacy/ui/public/vis/editors/default/default_editor.tsx +++ b/src/legacy/ui/public/vis/editors/default/default_editor.tsx @@ -44,7 +44,7 @@ function DefaultEditor({ const [visHandler, setVisHandler] = useState(null); // const [sidebarStyle, setSidebarStyle] = useState({}); const { vis } = savedObj; - const [state, actions] = useEditorReducer(vis); + const [state, dispatch] = useEditorReducer(vis); useEffect(() => { async function visualize() { @@ -104,11 +104,11 @@ function DefaultEditor({ vis={vis} state={state} uiState={uiState} - actions={actions} + dispatch={dispatch} /> - + ); } diff --git a/src/legacy/ui/public/vis/editors/default/state/actions.ts b/src/legacy/ui/public/vis/editors/default/state/actions.ts index e9d9f9d878b27a..bdeb12ebaba6ff 100644 --- a/src/legacy/ui/public/vis/editors/default/state/actions.ts +++ b/src/legacy/ui/public/vis/editors/default/state/actions.ts @@ -35,7 +35,7 @@ type ChangeAggType = ActionType< EditorStateActionTypes.CHANGE_AGG_TYPE, { aggId: AggId; value: AggConfig['type'] } >; -type SetAggParamValue = ActionType< +type SetAggParamValue = ActionType< EditorStateActionTypes.SET_AGG_PARAM_VALUE, { aggId: AggId; @@ -43,7 +43,7 @@ type SetAggParamValue = ActionType< value: AggParams[T]; } >; -type SetStateParamValue = ActionType< +type SetStateParamValue = ActionType< EditorStateActionTypes.SET_STATE_PARAM_VALUE, { paramName: T; value: AggParams[T] } >; @@ -145,7 +145,7 @@ const toggleEnabledAgg: EditorActions['toggleEnabledAgg'] = (aggId, enabled) => }, }); -export const editorActions = { +export { addNewAgg, discardChanges, changeAggType, diff --git a/src/legacy/ui/public/vis/editors/default/state/index.ts b/src/legacy/ui/public/vis/editors/default/state/index.ts index 60fe83d1653ca1..ec1e63d32b66a5 100644 --- a/src/legacy/ui/public/vis/editors/default/state/index.ts +++ b/src/legacy/ui/public/vis/editors/default/state/index.ts @@ -17,37 +17,27 @@ * under the License. */ -import { useMemo, useReducer } from 'react'; +import { useReducer, useCallback } from 'react'; import { Vis, VisState } from 'ui/vis'; import { editorStateReducer, initEditorState } from './reducers'; import { EditorStateActionTypes } from './constants'; -import { editorActions, EditorActions } from './actions'; +import { EditorAction } from './actions'; export * from './editor_state_context'; -export function useEditorReducer(vis: Vis): [VisState, EditorActions] { +export function useEditorReducer(vis: Vis): [VisState, React.Dispatch] { const [state, dispatch] = useReducer(editorStateReducer, vis, initEditorState); - const actions = useMemo( - () => - (Object.keys(editorActions) as Array).reduce( - (wrappedDispatchActions, actionCreator) => { - wrappedDispatchActions[actionCreator] = (...params: any) => { - const action = editorActions[actionCreator](...params); + const wrappedDispatch = useCallback( + (action: EditorAction) => { + vis.emit('dirtyStateChange', { + isDirty: action.type !== EditorStateActionTypes.DISCARD_CHANGES, + }); - vis.emit('dirtyStateChange', { - isDirty: action.type !== EditorStateActionTypes.DISCARD_CHANGES, - }); - - dispatch(action); - }; - - return wrappedDispatchActions; - }, - {} as EditorActions - ), + dispatch(action); + }, [vis] ); - return [state, actions]; + return [state, wrappedDispatch]; }