From 044a8ac3decf4d82b132694fb610e014c9837dbc Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 22 Jul 2020 16:20:31 +0200 Subject: [PATCH 1/5] style: destruct to satisfy eslint --- .../public/datatable_visualization/expression.tsx | 5 +++-- .../editor_frame/config_panel/config_panel.tsx | 13 +++++++------ .../editor_frame/data_panel_wrapper.tsx | 7 ++++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/lens/public/datatable_visualization/expression.tsx b/x-pack/plugins/lens/public/datatable_visualization/expression.tsx index 143bec227ebeeb..02186ecf09b4bc 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/expression.tsx @@ -160,6 +160,7 @@ export function DatatableComponent(props: DatatableRenderProps) { formatters[column.id] = props.formatFactory(column.formatHint); }); + const { onClickValue } = props; const handleFilterClick = useMemo( () => (field: string, value: unknown, colIndex: number, negate: boolean = false) => { const col = firstTable.columns[colIndex]; @@ -180,9 +181,9 @@ export function DatatableComponent(props: DatatableRenderProps) { ], timeFieldName, }; - props.onClickValue(desanitizeFilterContext(data)); + onClickValue(desanitizeFilterContext(data)); }, - [firstTable] + [firstTable, onClickValue] ); const bucketColumns = firstTable.columns diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 73126b814f2567..dae9b085730712 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -36,32 +36,33 @@ function LayerPanels( dispatch, activeDatasourceId, datasourceMap, + dispatch, } = props; const setVisualizationState = useMemo( () => (newState: unknown) => { - props.dispatch({ + dispatch({ type: 'UPDATE_VISUALIZATION_STATE', visualizationId: activeVisualization.id, newState, clearStagedPreview: false, }); }, - [props.dispatch, activeVisualization] + [dispatch, activeVisualization] ); const updateDatasource = useMemo( () => (datasourceId: string, newState: unknown) => { - props.dispatch({ + dispatch({ type: 'UPDATE_DATASOURCE_STATE', updater: () => newState, datasourceId, clearStagedPreview: false, }); }, - [props.dispatch] + [dispatch] ); const updateAll = useMemo( () => (datasourceId: string, newDatasourceState: unknown, newVisualizationState: unknown) => { - props.dispatch({ + dispatch({ type: 'UPDATE_STATE', subType: 'UPDATE_ALL_STATES', updater: (prevState) => { @@ -83,7 +84,7 @@ function LayerPanels( }, }); }, - [props.dispatch] + [dispatch] ); const layerIds = activeVisualization.getLayerIds(visualizationState); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx index 0f74abe97c418c..5a92f7b5ed5248 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx @@ -27,16 +27,17 @@ interface DataPanelWrapperProps { } export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => { + const { dispatch, activeDatasource } = props; const setDatasourceState: StateSetter = useMemo( () => (updater) => { - props.dispatch({ + dispatch({ type: 'UPDATE_DATASOURCE_STATE', updater, - datasourceId: props.activeDatasource!, + datasourceId: activeDatasource!, clearStagedPreview: true, }); }, - [props.dispatch, props.activeDatasource] + [dispatch, activeDatasource] ); const datasourceProps: DatasourceDataPanelProps = { From 01ae064d9c29e9dc950859be918a1e3c9dbcb995 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 29 Jul 2020 16:17:12 +0200 Subject: [PATCH 2/5] eslint: add easy hooks corrections --- x-pack/plugins/lens/public/app_plugin/app.tsx | 8 +++++++- .../public/debounced_component/debounced_component.tsx | 8 +++----- .../editor_frame/config_panel/config_panel.tsx | 1 - .../editor_frame/suggestion_panel.tsx | 5 +++-- .../editor_frame/workspace_panel/workspace_panel.tsx | 4 ++-- .../dimension_panel/field_select.tsx | 3 +-- .../lens/public/xy_visualization/xy_expression.tsx | 2 +- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 2a7eaff32fa081..815ee17e414e86 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -163,7 +163,13 @@ export function App({ filterSubscription.unsubscribe(); timeSubscription.unsubscribe(); }; - }, [data.query.filterManager, data.query.timefilter.timefilter]); + }, [ + data.query.filterManager, + data.query.timefilter.timefilter, + core.uiSettings, + data.query, + history, + ]); useEffect(() => { onAppLeave((actions) => { diff --git a/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx b/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx index 08f55850b119ec..0e148798cdf75e 100644 --- a/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx +++ b/x-pack/plugins/lens/public/debounced_component/debounced_component.tsx @@ -17,13 +17,11 @@ export function debouncedComponent(component: FunctionComponent, return (props: TProps) => { const [cachedProps, setCachedProps] = useState(props); - const debouncePropsChange = debounce(setCachedProps, delay); - const delayRender = useMemo(() => debouncePropsChange, []); + const debouncePropsChange = useMemo(() => debounce(setCachedProps, delay), [setCachedProps]); // cancel debounced prop change if component has been unmounted in the meantime - useEffect(() => () => debouncePropsChange.cancel(), []); - - delayRender(props); + useEffect(() => () => debouncePropsChange.cancel(), [debouncePropsChange]); + debouncePropsChange(props); return React.createElement(MemoizedComponent, cachedProps); }; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index dae9b085730712..5f041a8d8562f1 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -36,7 +36,6 @@ function LayerPanels( dispatch, activeDatasourceId, datasourceMap, - dispatch, } = props; const setVisualizationState = useMemo( () => (newState: unknown) => { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index b06b316ec79aa3..1ebf6b8b97c3e8 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -203,6 +203,7 @@ export function SuggestionPanel({ return { suggestions: newSuggestions, currentStateExpression: newStateExpression }; }, [ + frame, currentDatasourceStates, currentVisualizationState, currentVisualizationId, @@ -215,7 +216,7 @@ export function SuggestionPanel({ return (props: ReactExpressionRendererProps) => ( ); - }, [plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$, ExpressionRendererComponent]); + }, [plugins.data.query.timefilter.timefilter]); const [lastSelectedSuggestion, setLastSelectedSuggestion] = useState(-1); @@ -226,7 +227,7 @@ export function SuggestionPanel({ if (!stagedPreview && lastSelectedSuggestion !== -1) { setLastSelectedSuggestion(-1); } - }, [stagedPreview]); + }, [stagedPreview, lastSelectedSuggestion]); if (!activeDatasourceId) { return null; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index 9f5b6665b31d3c..f9364bf6728c7a 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -162,7 +162,7 @@ export function InnerWorkspacePanel({ const autoRefreshFetch$ = useMemo( () => plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$(), - [plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$] + [plugins.data.query.timefilter.timefilter] ); useEffect(() => { @@ -173,7 +173,7 @@ export function InnerWorkspacePanel({ expressionBuildError: undefined, })); } - }, [expression]); + }, [expression, localState.expressionBuildError]); function onDrop() { if (suggestionForDraggedField) { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx index 35c510521b35b7..26d5fa3927f4ad 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx @@ -137,10 +137,9 @@ export function FieldSelect({ }, [ incompatibleSelectedOperationType, selectedColumnOperationType, - selectedColumnSourceField, - operationFieldSupportMatrix, currentIndexPattern, fieldMap, + operationByField, ]); return ( diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx index 871b626d625608..a3468e109e75bc 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_expression.tsx @@ -180,7 +180,7 @@ export function XYChartReportable(props: XYChartRenderProps) { // reporting from printing a blank chart placeholder. useEffect(() => { setState({ isReady: true }); - }, []); + }, [setState]); return ( From 3d974dd43186eac05402f6e8b59d8de8804cdaf2 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Wed, 29 Jul 2020 16:43:10 +0200 Subject: [PATCH 3/5] another easy ones --- .../lens/public/indexpattern_datasource/datapanel.tsx | 11 ++++++++++- .../dimension_panel/field_select.tsx | 1 + .../lens/public/xy_visualization/xy_config_panel.tsx | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx index bb564214e4fabf..bdcce52314634a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx @@ -409,7 +409,16 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ filters, chartsThemeService: charts.theme, }), - [core, data, currentIndexPattern, dateRange, query, filters, localState.nameFilter] + [ + core, + data, + currentIndexPattern, + dateRange, + query, + filters, + localState.nameFilter, + charts.theme, + ] ); return ( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx index 26d5fa3927f4ad..93fde2b14d9294 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx @@ -140,6 +140,7 @@ export function FieldSelect({ currentIndexPattern, fieldMap, operationByField, + existingFields, ]); return ( diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx index 59c4b393df467a..6d5bc7808a678f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel.tsx @@ -379,7 +379,7 @@ const ColorPicker = ({ } setState(updateLayer(state, { ...layer, yConfig: newYConfigs }, index)); }, 256), - [state, layer, accessor, index] + [state, setState, layer, accessor, index] ); const colorPicker = ( From efba090ae3097a7e4e220f074459ccdd07d13df7 Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 30 Jul 2020 07:44:54 +0200 Subject: [PATCH 4/5] inline eslint rule for difficult cases --- .eslintrc.js | 6 - x-pack/plugins/lens/public/app_plugin/app.tsx | 106 ++++----- .../editor_frame/editor_frame.tsx | 210 ++++++++++-------- .../workspace_panel/chart_switch.tsx | 1 + .../workspace_panel/workspace_panel.tsx | 92 ++++---- x-pack/plugins/lens/public/loader.tsx | 44 ++-- 6 files changed, 243 insertions(+), 216 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c9f9d96f9ddaee..447a4ccbd39f75 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -132,12 +132,6 @@ module.exports = { 'react-hooks/rules-of-hooks': 'off', }, }, - { - files: ['x-pack/plugins/lens/**/*.{js,mjs,ts,tsx}'], - rules: { - 'react-hooks/exhaustive-deps': 'off', - }, - }, { files: ['x-pack/plugins/ml/**/*.{js,mjs,ts,tsx}'], rules: { diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 815ee17e414e86..78d1210ca0a9d5 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -216,57 +216,61 @@ export function App({ ]); }, [core.application, core.chrome, core.http.basePath, state.persistedDoc]); - useEffect(() => { - if (docId && (!state.persistedDoc || state.persistedDoc.id !== docId)) { - setState((s) => ({ ...s, isLoading: true })); - docStorage - .load(docId) - .then((doc) => { - getAllIndexPatterns( - doc.state.datasourceMetaData.filterableIndexPatterns, - data.indexPatterns, - core.notifications - ) - .then((indexPatterns) => { - // Don't overwrite any pinned filters - data.query.filterManager.setAppFilters(doc.state.filters); - setState((s) => ({ - ...s, - isLoading: false, - persistedDoc: doc, - lastKnownDoc: doc, - query: doc.state.query, - indexPatternsForTopNav: indexPatterns, - })); - }) - .catch(() => { - setState((s) => ({ ...s, isLoading: false })); - - redirectTo(); - }); - }) - .catch(() => { - setState((s) => ({ ...s, isLoading: false })); - - core.notifications.toasts.addDanger( - i18n.translate('xpack.lens.app.docLoadingError', { - defaultMessage: 'Error loading saved document', - }) - ); - - redirectTo(); - }); - } - }, [ - core.notifications, - data.indexPatterns, - data.query.filterManager, - docId, - // TODO: These dependencies are changing too often - // docStorage, - // redirectTo, - // state.persistedDoc, - ]); + useEffect( + () => { + if (docId && (!state.persistedDoc || state.persistedDoc.id !== docId)) { + setState((s) => ({ ...s, isLoading: true })); + docStorage + .load(docId) + .then((doc) => { + getAllIndexPatterns( + doc.state.datasourceMetaData.filterableIndexPatterns, + data.indexPatterns, + core.notifications + ) + .then((indexPatterns) => { + // Don't overwrite any pinned filters + data.query.filterManager.setAppFilters(doc.state.filters); + setState((s) => ({ + ...s, + isLoading: false, + persistedDoc: doc, + lastKnownDoc: doc, + query: doc.state.query, + indexPatternsForTopNav: indexPatterns, + })); + }) + .catch(() => { + setState((s) => ({ ...s, isLoading: false })); + + redirectTo(); + }); + }) + .catch(() => { + setState((s) => ({ ...s, isLoading: false })); + + core.notifications.toasts.addDanger( + i18n.translate('xpack.lens.app.docLoadingError', { + defaultMessage: 'Error loading saved document', + }) + ); + + redirectTo(); + }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + core.notifications, + data.indexPatterns, + data.query.filterManager, + docId, + // TODO: These dependencies are changing too often + // docStorage, + // redirectTo, + // state.persistedDoc, + ] + ); const runSave = async ( saveProps: Omit & { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx index bcceb1222ce036..48a3511a8f3594 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx @@ -62,34 +62,38 @@ export function EditorFrame(props: EditorFrameProps) { ); // Initialize current datasource and all active datasources - useEffect(() => { - // prevents executing dispatch on unmounted component - let isUnmounted = false; - if (!allLoaded) { - Object.entries(props.datasourceMap).forEach(([datasourceId, datasource]) => { - if ( - state.datasourceStates[datasourceId] && - state.datasourceStates[datasourceId].isLoading - ) { - datasource - .initialize(state.datasourceStates[datasourceId].state || undefined) - .then((datasourceState) => { - if (!isUnmounted) { - dispatch({ - type: 'UPDATE_DATASOURCE_STATE', - updater: datasourceState, - datasourceId, - }); - } - }) - .catch(onError); - } - }); - } - return () => { - isUnmounted = true; - }; - }, [allLoaded]); + useEffect( + () => { + // prevents executing dispatch on unmounted component + let isUnmounted = false; + if (!allLoaded) { + Object.entries(props.datasourceMap).forEach(([datasourceId, datasource]) => { + if ( + state.datasourceStates[datasourceId] && + state.datasourceStates[datasourceId].isLoading + ) { + datasource + .initialize(state.datasourceStates[datasourceId].state || undefined) + .then((datasourceState) => { + if (!isUnmounted) { + dispatch({ + type: 'UPDATE_DATASOURCE_STATE', + updater: datasourceState, + datasourceId, + }); + } + }) + .catch(onError); + } + }); + } + return () => { + isUnmounted = true; + }; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [allLoaded, onError] + ); const datasourceLayers: Record = {}; Object.keys(props.datasourceMap) @@ -156,83 +160,95 @@ export function EditorFrame(props: EditorFrameProps) { }, }; - useEffect(() => { - if (props.doc) { - dispatch({ - type: 'VISUALIZATION_LOADED', - doc: props.doc, - }); - } else { - dispatch({ - type: 'RESET', - state: getInitialState(props), - }); - } - }, [props.doc]); + useEffect( + () => { + if (props.doc) { + dispatch({ + type: 'VISUALIZATION_LOADED', + doc: props.doc, + }); + } else { + dispatch({ + type: 'RESET', + state: getInitialState(props), + }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [props.doc] + ); // Initialize visualization as soon as all datasources are ready - useEffect(() => { - if (allLoaded && state.visualization.state === null && activeVisualization) { - const initialVisualizationState = activeVisualization.initialize(framePublicAPI); - dispatch({ - type: 'UPDATE_VISUALIZATION_STATE', - visualizationId: activeVisualization.id, - newState: initialVisualizationState, - }); - } - }, [allLoaded, activeVisualization, state.visualization.state]); + useEffect( + () => { + if (allLoaded && state.visualization.state === null && activeVisualization) { + const initialVisualizationState = activeVisualization.initialize(framePublicAPI); + dispatch({ + type: 'UPDATE_VISUALIZATION_STATE', + visualizationId: activeVisualization.id, + newState: initialVisualizationState, + }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [allLoaded, activeVisualization, state.visualization.state] + ); // The frame needs to call onChange every time its internal state changes - useEffect(() => { - const activeDatasource = - state.activeDatasourceId && !state.datasourceStates[state.activeDatasourceId].isLoading - ? props.datasourceMap[state.activeDatasourceId] - : undefined; + useEffect( + () => { + const activeDatasource = + state.activeDatasourceId && !state.datasourceStates[state.activeDatasourceId].isLoading + ? props.datasourceMap[state.activeDatasourceId] + : undefined; - if (!activeDatasource || !activeVisualization) { - return; - } + if (!activeDatasource || !activeVisualization) { + return; + } - const indexPatterns: DatasourceMetaData['filterableIndexPatterns'] = []; - Object.entries(props.datasourceMap) - .filter(([id, datasource]) => { - const stateWrapper = state.datasourceStates[id]; - return ( - stateWrapper && - !stateWrapper.isLoading && - datasource.getLayers(stateWrapper.state).length > 0 - ); - }) - .forEach(([id, datasource]) => { - indexPatterns.push( - ...datasource.getMetaData(state.datasourceStates[id].state).filterableIndexPatterns - ); - }); + const indexPatterns: DatasourceMetaData['filterableIndexPatterns'] = []; + Object.entries(props.datasourceMap) + .filter(([id, datasource]) => { + const stateWrapper = state.datasourceStates[id]; + return ( + stateWrapper && + !stateWrapper.isLoading && + datasource.getLayers(stateWrapper.state).length > 0 + ); + }) + .forEach(([id, datasource]) => { + indexPatterns.push( + ...datasource.getMetaData(state.datasourceStates[id].state).filterableIndexPatterns + ); + }); - const doc = getSavedObjectFormat({ - activeDatasources: Object.keys(state.datasourceStates).reduce( - (datasourceMap, datasourceId) => ({ - ...datasourceMap, - [datasourceId]: props.datasourceMap[datasourceId], - }), - {} - ), - visualization: activeVisualization, - state, - framePublicAPI, - }); + const doc = getSavedObjectFormat({ + activeDatasources: Object.keys(state.datasourceStates).reduce( + (datasourceMap, datasourceId) => ({ + ...datasourceMap, + [datasourceId]: props.datasourceMap[datasourceId], + }), + {} + ), + visualization: activeVisualization, + state, + framePublicAPI, + }); - props.onChange({ filterableIndexPatterns: indexPatterns, doc }); - }, [ - activeVisualization, - state.datasourceStates, - state.visualization, - props.query, - props.dateRange, - props.filters, - props.savedQuery, - state.title, - ]); + props.onChange({ filterableIndexPatterns: indexPatterns, doc }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + activeVisualization, + state.datasourceStates, + state.visualization, + props.query, + props.dateRange, + props.filters, + props.savedQuery, + state.title, + ] + ); return ( diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx index a0d803d05d98b8..88b791a7875efe 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx @@ -188,6 +188,7 @@ export function ChartSwitch(props: Props) { ...visualizationType, selection: getSelection(visualizationType.visualizationId, visualizationType.id), })), + // eslint-disable-next-line react-hooks/exhaustive-deps [ flyoutOpen, props.visualizationMap, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index f9364bf6728c7a..b3a12271f377b2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -85,29 +85,33 @@ export function InnerWorkspacePanel({ const dragDropContext = useContext(DragContext); - const suggestionForDraggedField = useMemo(() => { - if (!dragDropContext.dragging || !activeDatasourceId) { - return; - } + const suggestionForDraggedField = useMemo( + () => { + if (!dragDropContext.dragging || !activeDatasourceId) { + return; + } - const hasData = Object.values(framePublicAPI.datasourceLayers).some( - (datasource) => datasource.getTableSpec().length > 0 - ); + const hasData = Object.values(framePublicAPI.datasourceLayers).some( + (datasource) => datasource.getTableSpec().length > 0 + ); - const suggestions = getSuggestions({ - datasourceMap: { [activeDatasourceId]: datasourceMap[activeDatasourceId] }, - datasourceStates, - visualizationMap: - hasData && activeVisualizationId - ? { [activeVisualizationId]: visualizationMap[activeVisualizationId] } - : visualizationMap, - activeVisualizationId, - visualizationState, - field: dragDropContext.dragging, - }); + const suggestions = getSuggestions({ + datasourceMap: { [activeDatasourceId]: datasourceMap[activeDatasourceId] }, + datasourceStates, + visualizationMap: + hasData && activeVisualizationId + ? { [activeVisualizationId]: visualizationMap[activeVisualizationId] } + : visualizationMap, + activeVisualizationId, + visualizationState, + field: dragDropContext.dragging, + }); - return suggestions.find((s) => s.visualizationId === activeVisualizationId) || suggestions[0]; - }, [dragDropContext.dragging]); + return suggestions.find((s) => s.visualizationId === activeVisualizationId) || suggestions[0]; + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [dragDropContext.dragging] + ); const [localState, setLocalState] = useState({ expressionBuildError: undefined as string | undefined, @@ -117,28 +121,32 @@ export function InnerWorkspacePanel({ const activeVisualization = activeVisualizationId ? visualizationMap[activeVisualizationId] : null; - const expression = useMemo(() => { - try { - return buildExpression({ - visualization: activeVisualization, - visualizationState, - datasourceMap, - datasourceStates, - framePublicAPI, - }); - } catch (e) { - // Most likely an error in the expression provided by a datasource or visualization - setLocalState((s) => ({ ...s, expressionBuildError: e.toString() })); - } - }, [ - activeVisualization, - visualizationState, - datasourceMap, - datasourceStates, - framePublicAPI.dateRange, - framePublicAPI.query, - framePublicAPI.filters, - ]); + const expression = useMemo( + () => { + try { + return buildExpression({ + visualization: activeVisualization, + visualizationState, + datasourceMap, + datasourceStates, + framePublicAPI, + }); + } catch (e) { + // Most likely an error in the expression provided by a datasource or visualization + setLocalState((s) => ({ ...s, expressionBuildError: e.toString() })); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + activeVisualization, + visualizationState, + datasourceMap, + datasourceStates, + framePublicAPI.dateRange, + framePublicAPI.query, + framePublicAPI.filters, + ] + ); const onEvent = useCallback( (event: ExpressionRendererEvent) => { diff --git a/x-pack/plugins/lens/public/loader.tsx b/x-pack/plugins/lens/public/loader.tsx index ebbb006d837b04..f6e179e9a6aa69 100644 --- a/x-pack/plugins/lens/public/loader.tsx +++ b/x-pack/plugins/lens/public/loader.tsx @@ -16,28 +16,32 @@ export function Loader(props: { load: () => Promise; loadDeps: unknown[ const prevRequest = useRef | undefined>(undefined); const nextRequest = useRef<(() => void) | undefined>(undefined); - useEffect(function performLoad() { - if (prevRequest.current) { - nextRequest.current = performLoad; - return; - } + useEffect( + function performLoad() { + if (prevRequest.current) { + nextRequest.current = performLoad; + return; + } - setIsProcessing(true); - prevRequest.current = props - .load() - .catch(() => {}) - .then(() => { - const reload = nextRequest.current; - prevRequest.current = undefined; - nextRequest.current = undefined; + setIsProcessing(true); + prevRequest.current = props + .load() + .catch(() => {}) + .then(() => { + const reload = nextRequest.current; + prevRequest.current = undefined; + nextRequest.current = undefined; - if (reload) { - reload(); - } else { - setIsProcessing(false); - } - }); - }, props.loadDeps); + if (reload) { + reload(); + } else { + setIsProcessing(false); + } + }); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + props.loadDeps + ); if (!isProcessing) { return null; From 9c3cf8cc02522c4d688479323f45db51f855fe7f Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Thu, 30 Jul 2020 07:58:27 +0200 Subject: [PATCH 5/5] fix: tests for suggestions breaking --- .../editor_frame_service/editor_frame/suggestion_panel.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index 1ebf6b8b97c3e8..9904a9771b96d2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -227,7 +227,8 @@ export function SuggestionPanel({ if (!stagedPreview && lastSelectedSuggestion !== -1) { setLastSelectedSuggestion(-1); } - }, [stagedPreview, lastSelectedSuggestion]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [stagedPreview]); if (!activeDatasourceId) { return null;