mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Lens] refactor - move debounce one layer up for thresholds (remove updater) (#113222)
* [Lens] remove updater from vis * removing blur handle * fix * blur fix Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6eebf2433d
commit
b73d939d6c
7 changed files with 61 additions and 54 deletions
|
@ -57,7 +57,7 @@ export async function initializeDatasources(
|
|||
return states;
|
||||
}
|
||||
|
||||
export const createDatasourceLayers = memoizeOne(function createDatasourceLayers(
|
||||
export const getDatasourceLayers = memoizeOne(function getDatasourceLayers(
|
||||
datasourceStates: DatasourceStates,
|
||||
datasourceMap: DatasourceMap
|
||||
) {
|
||||
|
@ -111,7 +111,7 @@ export async function persistedStateToExpression(
|
|||
{ isFullEditor: false }
|
||||
);
|
||||
|
||||
const datasourceLayers = createDatasourceLayers(datasourceStates, datasourceMap);
|
||||
const datasourceLayers = getDatasourceLayers(datasourceStates, datasourceMap);
|
||||
|
||||
const datasourceId = getActiveDatasourceIdFromDoc(doc);
|
||||
if (datasourceId == null) {
|
||||
|
|
|
@ -215,11 +215,11 @@ export function PieComponent(
|
|||
},
|
||||
});
|
||||
|
||||
const [state, setState] = useState({ isReady: false });
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
// It takes a cycle for the chart to render. This prevents
|
||||
// reporting from printing a blank chart placeholder.
|
||||
useEffect(() => {
|
||||
setState({ isReady: true });
|
||||
setIsReady(true);
|
||||
}, []);
|
||||
|
||||
const hasNegative = firstTable.rows.some((row) => {
|
||||
|
@ -273,7 +273,7 @@ export function PieComponent(
|
|||
reportTitle={props.args.title}
|
||||
reportDescription={props.args.description}
|
||||
className="lnsPieExpression__container"
|
||||
isReady={state.isReady}
|
||||
isReady={isReady}
|
||||
>
|
||||
<Chart>
|
||||
<Settings
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { Dispatch, MiddlewareAPI, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { LensStoreDeps } from '..';
|
||||
import { lensSlice } from '../lens_slice';
|
||||
import { loadInitial as loadInitialAction, navigateAway } from '..';
|
||||
import { loadInitial } from './load_initial';
|
||||
import { subscribeToExternalContext } from './subscribe_to_external_context';
|
||||
|
||||
|
@ -18,9 +18,9 @@ export const initMiddleware = (storeDeps: LensStoreDeps) => (store: MiddlewareAP
|
|||
store.dispatch
|
||||
);
|
||||
return (next: Dispatch) => (action: PayloadAction) => {
|
||||
if (lensSlice.actions.loadInitial.match(action)) {
|
||||
if (loadInitialAction.match(action)) {
|
||||
return loadInitial(store, storeDeps, action.payload);
|
||||
} else if (lensSlice.actions.navigateAway.match(action)) {
|
||||
} else if (navigateAway.match(action)) {
|
||||
return unsubscribeFromExternalContext();
|
||||
}
|
||||
next(action);
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
import { Dispatch, MiddlewareAPI, Action } from '@reduxjs/toolkit';
|
||||
import { isEqual } from 'lodash';
|
||||
import { lensSlice } from './lens_slice';
|
||||
import { onActiveDataChange } from '.';
|
||||
|
||||
/** cancels updates to the store that don't change the state */
|
||||
export const optimizingMiddleware = () => (store: MiddlewareAPI) => {
|
||||
return (next: Dispatch) => (action: Action) => {
|
||||
if (lensSlice.actions.onActiveDataChange.match(action)) {
|
||||
if (onActiveDataChange.match(action)) {
|
||||
if (isEqual(store.getState().lens.activeData, action.payload)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { SavedObjectReference } from 'kibana/server';
|
|||
import { LensState } from './types';
|
||||
import { extractFilterReferences } from '../persistence';
|
||||
import { Datasource, DatasourceMap, VisualizationMap } from '../types';
|
||||
import { createDatasourceLayers } from '../editor_frame_service/editor_frame';
|
||||
import { getDatasourceLayers } from '../editor_frame_service/editor_frame';
|
||||
|
||||
export const selectPersistedDoc = (state: LensState) => state.lens.persistedDoc;
|
||||
export const selectQuery = (state: LensState) => state.lens.query;
|
||||
|
@ -141,13 +141,13 @@ export const selectAreDatasourcesLoaded = createSelector(
|
|||
|
||||
export const selectDatasourceLayers = createSelector(
|
||||
[selectDatasourceStates, selectDatasourceMap],
|
||||
(datasourceStates, datasourceMap) => createDatasourceLayers(datasourceStates, datasourceMap)
|
||||
(datasourceStates, datasourceMap) => getDatasourceLayers(datasourceStates, datasourceMap)
|
||||
);
|
||||
|
||||
export const selectFramePublicAPI = createSelector(
|
||||
[selectDatasourceStates, selectActiveData, selectDatasourceMap],
|
||||
(datasourceStates, activeData, datasourceMap) => ({
|
||||
datasourceLayers: createDatasourceLayers(datasourceStates, datasourceMap),
|
||||
datasourceLayers: getDatasourceLayers(datasourceStates, datasourceMap),
|
||||
activeData,
|
||||
})
|
||||
);
|
||||
|
|
|
@ -191,20 +191,18 @@ function getIconForSeriesType(seriesType: SeriesType): IconType {
|
|||
const MemoizedChart = React.memo(XYChart);
|
||||
|
||||
export function XYChartReportable(props: XYChartRenderProps) {
|
||||
const [state, setState] = useState({
|
||||
isReady: false,
|
||||
});
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
|
||||
// It takes a cycle for the XY chart to render. This prevents
|
||||
// reporting from printing a blank chart placeholder.
|
||||
useEffect(() => {
|
||||
setState({ isReady: true });
|
||||
}, [setState]);
|
||||
setIsReady(true);
|
||||
}, [setIsReady]);
|
||||
|
||||
return (
|
||||
<VisualizationContainer
|
||||
className="lnsXyExpression__container"
|
||||
isReady={state.isReady}
|
||||
isReady={isReady}
|
||||
reportTitle={props.args.title}
|
||||
reportDescription={props.args.description}
|
||||
>
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
*/
|
||||
|
||||
import './xy_config_panel.scss';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiButtonGroup, EuiComboBox, EuiFormRow, EuiIcon, EuiRange } from '@elastic/eui';
|
||||
import type { PaletteRegistry } from 'src/plugins/charts/public';
|
||||
import type { VisualizationDimensionEditorProps } from '../../types';
|
||||
import { State } from '../types';
|
||||
import { State, XYState } from '../types';
|
||||
import { FormatFactory } from '../../../common';
|
||||
import { YConfig } from '../../../common/expressions';
|
||||
import { LineStyle, FillStyle } from '../../../common/expressions/xy_chart';
|
||||
|
@ -116,29 +116,35 @@ export const ThresholdPanel = (
|
|||
}
|
||||
) => {
|
||||
const { state, setState, layerId, accessor } = props;
|
||||
const index = state.layers.findIndex((l) => l.layerId === layerId);
|
||||
const layer = state.layers[index];
|
||||
|
||||
const { inputValue: localState, handleInputChange: setLocalState } = useDebouncedValue<XYState>({
|
||||
value: state,
|
||||
onChange: setState,
|
||||
});
|
||||
|
||||
const index = localState.layers.findIndex((l) => l.layerId === layerId);
|
||||
const layer = localState.layers[index];
|
||||
|
||||
const setYConfig = useCallback(
|
||||
(yConfig: Partial<YConfig> | undefined) => {
|
||||
if (yConfig == null) {
|
||||
return;
|
||||
}
|
||||
setState((currState) => {
|
||||
const currLayer = currState.layers[index];
|
||||
const newYConfigs = [...(currLayer.yConfig || [])];
|
||||
const existingIndex = newYConfigs.findIndex(
|
||||
(yAxisConfig) => yAxisConfig.forAccessor === accessor
|
||||
);
|
||||
if (existingIndex !== -1) {
|
||||
newYConfigs[existingIndex] = { ...newYConfigs[existingIndex], ...yConfig };
|
||||
} else {
|
||||
newYConfigs.push({ forAccessor: accessor, ...yConfig });
|
||||
}
|
||||
return updateLayer(currState, { ...currLayer, yConfig: newYConfigs }, index);
|
||||
});
|
||||
const newYConfigs = [...(layer.yConfig || [])];
|
||||
const existingIndex = newYConfigs.findIndex(
|
||||
(yAxisConfig) => yAxisConfig.forAccessor === accessor
|
||||
);
|
||||
if (existingIndex !== -1) {
|
||||
newYConfigs[existingIndex] = { ...newYConfigs[existingIndex], ...yConfig };
|
||||
} else {
|
||||
newYConfigs.push({
|
||||
forAccessor: accessor,
|
||||
...yConfig,
|
||||
});
|
||||
}
|
||||
setLocalState(updateLayer(localState, { ...layer, yConfig: newYConfigs }, index));
|
||||
},
|
||||
[accessor, index, setState]
|
||||
[accessor, index, localState, layer, setLocalState]
|
||||
);
|
||||
|
||||
const currentYConfig = layer.yConfig?.find((yConfig) => yConfig.forAccessor === accessor);
|
||||
|
@ -291,35 +297,38 @@ const LineThicknessSlider = ({
|
|||
value: number;
|
||||
onChange: (value: number) => void;
|
||||
}) => {
|
||||
const onChangeWrapped = useCallback(
|
||||
(newValue) => {
|
||||
if (Number.isInteger(newValue)) {
|
||||
onChange(getSafeValue(newValue, newValue, minRange, maxRange));
|
||||
}
|
||||
},
|
||||
[onChange]
|
||||
);
|
||||
const { inputValue, handleInputChange } = useDebouncedValue<number | ''>(
|
||||
{ value, onChange: onChangeWrapped },
|
||||
{ allowFalsyValue: true }
|
||||
);
|
||||
const [unsafeValue, setUnsafeValue] = useState<string>(String(value));
|
||||
|
||||
return (
|
||||
<EuiRange
|
||||
fullWidth
|
||||
data-test-subj="lnsXY_lineThickness"
|
||||
value={inputValue}
|
||||
value={unsafeValue}
|
||||
showInput
|
||||
min={minRange}
|
||||
max={maxRange}
|
||||
step={1}
|
||||
compressed
|
||||
onChange={(e) => {
|
||||
const newValue = e.currentTarget.value;
|
||||
handleInputChange(newValue === '' ? '' : Number(newValue));
|
||||
onChange={({ currentTarget: { value: newValue } }) => {
|
||||
setUnsafeValue(newValue);
|
||||
const convertedValue = newValue === '' ? '' : Number(newValue);
|
||||
const safeValue = getSafeValue(Number(newValue), Number(newValue), minRange, maxRange);
|
||||
// only update onChange is the value is valid and in range
|
||||
if (convertedValue === safeValue) {
|
||||
onChange(safeValue);
|
||||
}
|
||||
}}
|
||||
onBlur={() => {
|
||||
handleInputChange(getSafeValue(inputValue, value, minRange, maxRange));
|
||||
if (unsafeValue !== String(value)) {
|
||||
const safeValue = getSafeValue(
|
||||
unsafeValue === '' ? unsafeValue : Number(unsafeValue),
|
||||
value,
|
||||
minRange,
|
||||
maxRange
|
||||
);
|
||||
onChange(safeValue);
|
||||
setUnsafeValue(String(safeValue));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue