mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Lens] Clean and inline disabling of react-hooks/exhaustive-deps eslint rule (#70010)
This commit is contained in:
parent
aa75f80afd
commit
626fbc2948
15 changed files with 282 additions and 238 deletions
|
@ -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: {
|
||||
|
|
|
@ -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) => {
|
||||
|
@ -210,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 }));
|
||||
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 }));
|
||||
redirectTo();
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
setState((s) => ({ ...s, isLoading: false }));
|
||||
|
||||
core.notifications.toasts.addDanger(
|
||||
i18n.translate('xpack.lens.app.docLoadingError', {
|
||||
defaultMessage: 'Error loading saved document',
|
||||
})
|
||||
);
|
||||
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,
|
||||
]);
|
||||
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<OnSaveProps, 'onTitleDuplicate' | 'newDescription'> & {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,13 +17,11 @@ export function debouncedComponent<TProps>(component: FunctionComponent<TProps>,
|
|||
|
||||
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);
|
||||
};
|
||||
|
|
|
@ -39,29 +39,29 @@ function LayerPanels(
|
|||
} = 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 +83,7 @@ function LayerPanels(
|
|||
},
|
||||
});
|
||||
},
|
||||
[props.dispatch]
|
||||
[dispatch]
|
||||
);
|
||||
const layerIds = activeVisualization.getLayerIds(visualizationState);
|
||||
|
||||
|
|
|
@ -27,16 +27,17 @@ interface DataPanelWrapperProps {
|
|||
}
|
||||
|
||||
export const DataPanelWrapper = memo((props: DataPanelWrapperProps) => {
|
||||
const { dispatch, activeDatasource } = props;
|
||||
const setDatasourceState: StateSetter<unknown> = 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 = {
|
||||
|
|
|
@ -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<string, DatasourcePublicAPI> = {};
|
||||
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 (
|
||||
<RootDragDropProvider>
|
||||
|
|
|
@ -205,6 +205,7 @@ export function SuggestionPanel({
|
|||
|
||||
return { suggestions: newSuggestions, currentStateExpression: newStateExpression };
|
||||
}, [
|
||||
frame,
|
||||
currentDatasourceStates,
|
||||
currentVisualizationState,
|
||||
currentVisualizationId,
|
||||
|
@ -217,7 +218,7 @@ export function SuggestionPanel({
|
|||
return (props: ReactExpressionRendererProps) => (
|
||||
<ExpressionRendererComponent {...props} reload$={autoRefreshFetch$} />
|
||||
);
|
||||
}, [plugins.data.query.timefilter.timefilter.getAutoRefreshFetch$, ExpressionRendererComponent]);
|
||||
}, [plugins.data.query.timefilter.timefilter]);
|
||||
|
||||
const [lastSelectedSuggestion, setLastSelectedSuggestion] = useState<number>(-1);
|
||||
|
||||
|
@ -228,6 +229,7 @@ export function SuggestionPanel({
|
|||
if (!stagedPreview && lastSelectedSuggestion !== -1) {
|
||||
setLastSelectedSuggestion(-1);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [stagedPreview]);
|
||||
|
||||
if (!activeDatasourceId) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) => {
|
||||
|
@ -162,7 +170,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 +181,7 @@ export function InnerWorkspacePanel({
|
|||
expressionBuildError: undefined,
|
||||
}));
|
||||
}
|
||||
}, [expression]);
|
||||
}, [expression, localState.expressionBuildError]);
|
||||
|
||||
function onDrop() {
|
||||
if (suggestionForDraggedField) {
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -139,10 +139,10 @@ export function FieldSelect({
|
|||
}, [
|
||||
incompatibleSelectedOperationType,
|
||||
selectedColumnOperationType,
|
||||
selectedColumnSourceField,
|
||||
operationFieldSupportMatrix,
|
||||
currentIndexPattern,
|
||||
fieldMap,
|
||||
operationByField,
|
||||
existingFields,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
|
|
@ -16,28 +16,32 @@ export function Loader(props: { load: () => Promise<unknown>; loadDeps: unknown[
|
|||
const prevRequest = useRef<Promise<unknown> | 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;
|
||||
|
|
|
@ -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 = (
|
||||
|
|
|
@ -180,7 +180,7 @@ export function XYChartReportable(props: XYChartRenderProps) {
|
|||
// reporting from printing a blank chart placeholder.
|
||||
useEffect(() => {
|
||||
setState({ isReady: true });
|
||||
}, []);
|
||||
}, [setState]);
|
||||
|
||||
return (
|
||||
<VisualizationContainer className="lnsXyExpression__container" isReady={state.isReady}>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue