[Lens] Fixes the types of the DatasourceLayers (#138371)

* [Lens] Fixes the types of the DatasourceLayers

* Remove unecessary if
This commit is contained in:
Stratoula Kalafateli 2022-08-09 17:03:06 +03:00 committed by GitHub
parent b40663299a
commit 9e690e6669
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 142 additions and 107 deletions

View file

@ -47,7 +47,7 @@ export function DraggableDimensionButton({
group: VisualizationDimensionGroupConfig;
label: string;
children: ReactElement;
layerDatasource: Datasource<unknown, unknown>;
layerDatasource?: Datasource<unknown, unknown>;
datasourceLayers: DatasourceLayers;
state: unknown;
accessorIndex: number;

View file

@ -118,7 +118,7 @@ export function EmptyDimensionButton({
onDrop: (source: DragDropIdentifier, dropTarget: DragDropIdentifier, dropType?: DropType) => void;
onClick: (id: string) => void;
group: VisualizationDimensionGroupConfig;
layerDatasource: Datasource<unknown, unknown>;
layerDatasource?: Datasource<unknown, unknown>;
datasourceLayers: DatasourceLayers;
state: unknown;
}) {

View file

@ -75,20 +75,22 @@ export function LayerPanels(
[activeVisualization, dispatchLens]
);
const updateDatasource = useMemo(
() => (datasourceId: string, newState: unknown) => {
dispatchLens(
updateDatasourceState({
updater: (prevState: unknown) =>
typeof newState === 'function' ? newState(prevState) : newState,
datasourceId,
clearStagedPreview: false,
})
);
() => (datasourceId: string | undefined, newState: unknown) => {
if (datasourceId) {
dispatchLens(
updateDatasourceState({
updater: (prevState: unknown) =>
typeof newState === 'function' ? newState(prevState) : newState,
datasourceId,
clearStagedPreview: false,
})
);
}
},
[dispatchLens]
);
const updateDatasourceAsync = useMemo(
() => (datasourceId: string, newState: unknown) => {
() => (datasourceId: string | undefined, newState: unknown) => {
// React will synchronously update if this is triggered from a third party component,
// which we don't want. The timeout lets user interaction have priority, then React updates.
setTimeout(() => {
@ -99,43 +101,49 @@ export function LayerPanels(
);
const updateAll = useMemo(
() => (datasourceId: string, newDatasourceState: unknown, newVisualizationState: unknown) => {
// React will synchronously update if this is triggered from a third party component,
// which we don't want. The timeout lets user interaction have priority, then React updates.
() =>
(
datasourceId: string | undefined,
newDatasourceState: unknown,
newVisualizationState: unknown
) => {
if (!datasourceId) return;
// React will synchronously update if this is triggered from a third party component,
// which we don't want. The timeout lets user interaction have priority, then React updates.
setTimeout(() => {
dispatchLens(
updateState({
updater: (prevState) => {
const updatedDatasourceState =
typeof newDatasourceState === 'function'
? newDatasourceState(prevState.datasourceStates[datasourceId].state)
: newDatasourceState;
setTimeout(() => {
dispatchLens(
updateState({
updater: (prevState) => {
const updatedDatasourceState =
typeof newDatasourceState === 'function'
? newDatasourceState(prevState.datasourceStates[datasourceId].state)
: newDatasourceState;
const updatedVisualizationState =
typeof newVisualizationState === 'function'
? newVisualizationState(prevState.visualization.state)
: newVisualizationState;
const updatedVisualizationState =
typeof newVisualizationState === 'function'
? newVisualizationState(prevState.visualization.state)
: newVisualizationState;
return {
...prevState,
datasourceStates: {
...prevState.datasourceStates,
[datasourceId]: {
state: updatedDatasourceState,
isLoading: false,
return {
...prevState,
datasourceStates: {
...prevState.datasourceStates,
[datasourceId]: {
state: updatedDatasourceState,
isLoading: false,
},
},
},
visualization: {
...prevState.visualization,
state: updatedVisualizationState,
},
};
},
})
);
}, 0);
},
visualization: {
...prevState.visualization,
state: updatedVisualizationState,
},
};
},
})
);
}, 0);
},
[dispatchLens]
);
@ -187,10 +195,10 @@ export function LayerPanels(
onRemoveLayer={() => {
const datasourcePublicAPI = props.framePublicAPI.datasourceLayers?.[layerId];
const datasourceId = datasourcePublicAPI?.datasourceId;
const layerDatasource = datasourceMap[datasourceId];
const layerDatasourceState = datasourceStates?.[datasourceId]?.state;
if (datasourceId) {
const layerDatasource = datasourceMap[datasourceId];
const layerDatasourceState = datasourceStates?.[datasourceId]?.state;
const trigger = props.uiActions.getTrigger(UPDATE_FILTER_REFERENCES_TRIGGER);
const action = props.uiActions.getAction(UPDATE_FILTER_REFERENCES_ACTION);

View file

@ -54,10 +54,10 @@ export function LayerPanel(
layerIndex: number;
isOnlyLayer: boolean;
updateVisualization: StateSetter<unknown>;
updateDatasource: (datasourceId: string, newState: unknown) => void;
updateDatasourceAsync: (datasourceId: string, newState: unknown) => void;
updateDatasource: (datasourceId: string | undefined, newState: unknown) => void;
updateDatasourceAsync: (datasourceId: string | undefined, newState: unknown) => void;
updateAll: (
datasourceId: string,
datasourceId: string | undefined,
newDatasourcestate: unknown,
newVisualizationState: unknown
) => void;
@ -112,8 +112,8 @@ export function LayerPanel(
const datasourcePublicAPI = framePublicAPI.datasourceLayers?.[layerId];
const datasourceId = datasourcePublicAPI?.datasourceId;
const layerDatasourceState = datasourceStates?.[datasourceId]?.state;
const layerDatasource = props.datasourceMap[datasourceId];
const layerDatasourceState = datasourceId ? datasourceStates?.[datasourceId]?.state : undefined;
const layerDatasource = datasourceId ? props.datasourceMap[datasourceId] : undefined;
const layerDatasourceConfigProps = {
state: layerDatasourceState,
@ -339,11 +339,11 @@ export function LayerPanel(
nextPublicAPI.getTableSpec().map(({ columnId }) => columnId)
);
const removed = datasourcePublicAPI
.getTableSpec()
?.getTableSpec()
.map(({ columnId }) => columnId)
.filter((columnId) => !nextTable.has(columnId));
let nextVisState = props.visualizationState;
removed.forEach((columnId) => {
removed?.forEach((columnId) => {
nextVisState = activeVisualization.removeDimension({
layerId,
columnId,
@ -433,7 +433,7 @@ export function LayerPanel(
groupIndex={groupIndex}
key={columnId}
state={layerDatasourceState}
label={columnLabelMap?.[columnId]}
label={columnLabelMap?.[columnId] ?? ''}
layerDatasource={layerDatasource}
datasourceLayers={framePublicAPI.datasourceLayers}
layerIndex={layerIndex}
@ -445,7 +445,7 @@ export function LayerPanel(
<div className="lnsLayerPanel__dimension">
<DimensionButton
accessorConfig={accessorConfig}
label={columnLabelMap?.[accessorConfig.columnId]}
label={columnLabelMap?.[accessorConfig.columnId] ?? ''}
group={group}
onClick={(id: string) => {
setActiveDimension({
@ -508,7 +508,7 @@ export function LayerPanel(
<>
{activeVisualization?.renderDimensionTrigger?.({
columnId,
label: columnLabelMap[columnId],
label: columnLabelMap?.[columnId] ?? '',
hideTooltip,
invalid: group.invalid,
invalidMessage: group.invalidMessage,

View file

@ -269,7 +269,7 @@ export function getTopSuggestionForField(
field: DragDropIdentifier
) {
const hasData = Object.values(datasourceLayers).some(
(datasourceLayer) => datasourceLayer.getTableSpec().length > 0
(datasourceLayer) => datasourceLayer && datasourceLayer.getTableSpec().length > 0
);
const activeVisualization = visualization.activeId

View file

@ -197,7 +197,7 @@ describe('chart_switch', () => {
const visualizationMap = mockVisualizationMap();
visualizationMap.visB.getSuggestions.mockReturnValueOnce([]);
const frame = mockFrame(['a']);
(frame.datasourceLayers.a.getTableSpec as jest.Mock).mockReturnValue([]);
(frame.datasourceLayers.a?.getTableSpec as jest.Mock).mockReturnValue([]);
const datasourceMap = mockDatasourceMap();
const datasourceStates = mockDatasourceStates();
const { instance, lensStore } = await mountWithProvider(
@ -407,7 +407,7 @@ describe('chart_switch', () => {
const visualizationMap = mockVisualizationMap();
visualizationMap.visB.getSuggestions.mockReturnValueOnce([]);
const frame = mockFrame(['a']);
(frame.datasourceLayers.a.getTableSpec as jest.Mock).mockReturnValue([]);
(frame.datasourceLayers.a?.getTableSpec as jest.Mock).mockReturnValue([]);
const { instance } = await mountWithProvider(
<ChartSwitch
@ -599,7 +599,8 @@ describe('chart_switch', () => {
it('should not remove layers and initialize with existing state when switching between subtypes without data', async () => {
const frame = mockFrame(['a']);
frame.datasourceLayers.a.getTableSpec = jest.fn().mockReturnValue([]);
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.a.getTableSpec = jest.fn().mockReturnValue([]);
const visualizationMap = mockVisualizationMap();
visualizationMap.visC.getSuggestions = jest.fn().mockReturnValue([]);
visualizationMap.visC.switchVisualizationType = jest.fn(() => 'switched');

View file

@ -155,7 +155,7 @@ export const ChartSwitch = memo(function ChartSwitch(props: Props) {
((_type: string, initialState: unknown) => initialState);
const layers = Object.entries(props.framePublicAPI.datasourceLayers);
const containsData = layers.some(
([_layerId, datasource]) => datasource.getTableSpec().length > 0
([_layerId, datasource]) => datasource && datasource.getTableSpec().length > 0
);
// Always show the active visualization as a valid selection
if (
@ -190,7 +190,7 @@ export const ChartSwitch = memo(function ChartSwitch(props: Props) {
dataLoss = 'everything';
} else if (layers.length > 1 && layers.length !== topSuggestion.keptLayerIds.length) {
dataLoss = 'layers';
} else if (topSuggestion.columns !== layers[0][1].getTableSpec().length) {
} else if (topSuggestion.columns !== layers[0][1]?.getTableSpec().length) {
dataLoss = 'columns';
} else {
dataLoss = 'nothing';

View file

@ -7,7 +7,7 @@
import { Datatable } from '@kbn/expressions-plugin/common';
import { createMockDatasource } from '../../mocks';
import { FramePublicAPI, OperationDescriptor } from '../../types';
import { OperationDescriptor, DatasourcePublicAPI } from '../../types';
import {
hasNumericHistogramDimension,
validateAxisDomain,
@ -58,7 +58,7 @@ describe('validateZeroInclusivityExtent', () => {
});
describe('hasNumericHistogramDimension', () => {
const datasourceLayers: FramePublicAPI['datasourceLayers'] = {
const datasourceLayers: Record<string, DatasourcePublicAPI> = {
first: createMockDatasource('test').publicAPIMock,
};
it('should return true if a numeric histogram is present', () => {

View file

@ -45,7 +45,7 @@ export function validateAxisDomain(extents?: { lowerBound?: number; upperBound?:
* @returns boolean
*/
export function hasNumericHistogramDimension(
datasourceLayer: DatasourcePublicAPI,
datasourceLayer: DatasourcePublicAPI | undefined,
columnId?: string
) {
if (!columnId) {

View file

@ -718,7 +718,7 @@ export interface VisualizationSuggestion<T = unknown> {
previewIcon: IconType;
}
export type DatasourceLayers = Record<string, DatasourcePublicAPI>;
export type DatasourceLayers = Partial<Record<string, DatasourcePublicAPI>>;
export interface FramePublicAPI {
datasourceLayers: DatasourceLayers;

View file

@ -12,6 +12,7 @@ import {
FramePublicAPI,
OperationDescriptor,
VisualizationDimensionEditorProps,
DatasourcePublicAPI,
} from '../../../types';
import { DatatableVisualizationState } from '../visualization';
import { createMockDatasource, createMockFramePublicAPI } from '../../../mocks';
@ -221,7 +222,8 @@ describe('data table dimension editor', () => {
it('should not show the dynamic coloring option for a bucketed operation', () => {
frame.activeData!.first.columns[0].meta.type = 'number';
frame.datasourceLayers.first.getOperationForColumnId = jest.fn(
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.first.getOperationForColumnId = jest.fn(
() => ({ isBucketed: true } as OperationDescriptor)
);
state.columns[0].colorMode = 'cell';

View file

@ -587,10 +587,10 @@ function getDataSourceAndSortedColumns(
layerId: string
) {
const datasource = datasourceLayers[state.layerId];
const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId);
const originalOrder = datasource?.getTableSpec().map(({ columnId }) => columnId);
// When we add a column it could be empty, and therefore have no order
const sortedColumns = Array.from(
new Set(originalOrder.concat(state.columns.map(({ columnId }) => columnId)))
new Set(originalOrder?.concat(state.columns.map(({ columnId }) => columnId)))
);
return { datasource, sortedColumns };
}

View file

@ -122,7 +122,7 @@ const toExpression = (
const datasource = datasourceLayers[state.layerId];
const datasourceExpression = datasourceExpressionsByLayers[state.layerId];
const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId);
const originalOrder = datasource?.getTableSpec().map(({ columnId }) => columnId);
if (!originalOrder || !state.metricAccessor) {
return null;
}

View file

@ -160,7 +160,7 @@ export const getHeatmapVisualization = ({
getConfiguration({ state, frame, layerId }) {
const datasourceLayer = frame.datasourceLayers[layerId];
const originalOrder = datasourceLayer.getTableSpec().map(({ columnId }) => columnId);
const originalOrder = datasourceLayer?.getTableSpec().map(({ columnId }) => columnId);
if (!originalOrder) {
return { groups: [] };
}
@ -312,7 +312,7 @@ export const getHeatmapVisualization = ({
const datasource = datasourceLayers[state.layerId];
const datasourceExpression = datasourceExpressionsByLayers[state.layerId];
const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId);
const originalOrder = datasource?.getTableSpec().map(({ columnId }) => columnId);
// When we add a column it could be empty, and therefore have no order
if (!originalOrder || !state.valueAccessor) {
@ -402,7 +402,7 @@ export const getHeatmapVisualization = ({
const datasource = datasourceLayers[state.layerId];
const datasourceExpression = datasourceExpressionsByLayers[state.layerId];
const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId);
const originalOrder = datasource?.getTableSpec().map(({ columnId }) => columnId);
// When we add a column it could be empty, and therefore have no order
if (!originalOrder) {
@ -513,7 +513,7 @@ export const getHeatmapVisualization = ({
const hasArrayValues = rows.some((row) => Array.isArray(row[state.valueAccessor!]));
const datasource = frame.datasourceLayers[state.layerId];
const operation = datasource.getOperationForColumnId(state.valueAccessor);
const operation = datasource?.getOperationForColumnId(state.valueAccessor);
return hasArrayValues
? [

View file

@ -78,7 +78,7 @@ const toExpression = (
const maxPossibleTiles =
// if there's a collapse function, no need to calculate since we're dealing with a single tile
state.breakdownByAccessor && !state.collapseFn
? datasource.getMaxPossibleNumValues(state.breakdownByAccessor)
? datasource?.getMaxPossibleNumValues(state.breakdownByAccessor)
: null;
const getCollapseFnArguments = () => {
@ -91,7 +91,7 @@ const toExpression = (
return state.collapseFn;
} else {
const isMaxStatic = Boolean(
datasource.getOperationForColumnId(state.maxAccessor!)?.isStaticValue
datasource?.getOperationForColumnId(state.maxAccessor!)?.isStaticValue
);
// we do this because the user expects the static value they set to be the same
// even if they define a collapse on the breakdown by

View file

@ -59,13 +59,16 @@ type GenerateLabelsAstArguments = (
layer: PieLayerState
) => [Ast];
export const getSortedGroups = (datasource: DatasourcePublicAPI, layer: PieLayerState) => {
export const getSortedGroups = (
datasource: DatasourcePublicAPI | undefined,
layer: PieLayerState
) => {
const originalOrder = datasource
.getTableSpec()
?.getTableSpec()
.map(({ columnId }: { columnId: string }) => columnId)
.filter((columnId: string) => layer.groups.includes(columnId));
// When we add a column it could be empty, and therefore have no order
return Array.from(new Set(originalOrder.concat(layer.groups)));
return Array.from(new Set(originalOrder?.concat(layer.groups)));
};
const prepareDimension = (accessor: string) => {
@ -264,7 +267,7 @@ function expressionHelper(
const operations = groups
.map((columnId) => ({
columnId,
operation: datasource.getOperationForColumnId(columnId) as Operation | null,
operation: datasource?.getOperationForColumnId(columnId) as Operation | null,
}))
.filter((o): o is { columnId: string; operation: Operation } => !!o.operation);

View file

@ -299,7 +299,7 @@ export const getPieVisualization = ({
);
}
const columnToLabel = frame.datasourceLayers[layerId].getOperationForColumnId(metric)?.label;
const columnToLabel = frame.datasourceLayers[layerId]?.getOperationForColumnId(metric)?.label;
const hasArrayValues = rows.some((row) => Array.isArray(row[metric]));
if (hasArrayValues) {
warningMessages.push(

View file

@ -65,13 +65,13 @@ export const getSeriesColor = (layer: XYLayerConfig, accessor: string) => {
export const getColumnToLabelMap = (
layer: XYDataLayerConfig | XYReferenceLineLayerConfig,
datasource: DatasourcePublicAPI
datasource?: DatasourcePublicAPI
) => {
const columnToLabel: Record<string, string> = {};
layer.accessors
.concat(isDataLayer(layer) && layer.splitAccessor ? [layer.splitAccessor] : [])
.forEach((accessor) => {
const operation = datasource.getOperationForColumnId(accessor);
const operation = datasource?.getOperationForColumnId(accessor);
if (operation?.label) {
columnToLabel[accessor] = operation.label;
}
@ -93,7 +93,7 @@ export function hasHistogramSeries(
return false;
}
const xAxisOperation = datasourceLayers[layerId].getOperationForColumnId(xAccessor);
const xAxisOperation = datasourceLayers[layerId]?.getOperationForColumnId(xAccessor);
return (
xAxisOperation &&
xAxisOperation.isBucketed &&

View file

@ -35,7 +35,7 @@ import { layerTypes } from '../../../common';
import { axisExtentConfigToExpression } from '../../shared_components';
export const getSortedAccessors = (
datasource: DatasourcePublicAPI,
datasource: DatasourcePublicAPI | undefined,
layer: XYDataLayerConfig | XYReferenceLineLayerConfig
) => {
const originalOrder = datasource
@ -66,7 +66,8 @@ export const toExpression = (
const datasource = datasourceLayers[layer.layerId];
if (datasource) {
datasource.getTableSpec().forEach((column) => {
const operation = datasourceLayers[layer.layerId].getOperationForColumnId(column.columnId);
const operation =
datasourceLayers[layer.layerId]?.getOperationForColumnId(column.columnId) ?? null;
metadata[layer.layerId][column.columnId] = operation;
});
}
@ -375,7 +376,7 @@ const yAxisConfigsToExpression = (yAxisConfigs: AxisConfig[]): Ast[] => {
const referenceLineLayerToExpression = (
layer: XYReferenceLineLayerConfig,
datasourceLayer: DatasourcePublicAPI,
datasourceLayer: DatasourcePublicAPI | undefined,
datasourceExpression: Ast
): Ast => {
return {
@ -425,7 +426,7 @@ const annotationLayerToExpression = (
const dataLayerToExpression = (
layer: ValidXYDataLayerConfig,
yAxisConfigs: AxisConfig[],
datasourceLayer: DatasourcePublicAPI,
datasourceLayer: DatasourcePublicAPI | undefined,
metadata: Record<string, Record<string, OperationMetadata | null>>,
paletteService: PaletteRegistry,
datasourceExpression: Ast

View file

@ -7,7 +7,13 @@
import { getXyVisualization } from './visualization';
import { Position } from '@elastic/charts';
import { Operation, VisualizeEditorContext, Suggestion, OperationDescriptor } from '../../types';
import {
Operation,
VisualizeEditorContext,
Suggestion,
OperationDescriptor,
DatasourcePublicAPI,
} from '../../types';
import type {
State,
XYState,
@ -269,7 +275,8 @@ describe('xy_visualization', () => {
frame.datasourceLayers = {
first: mockDatasource.publicAPIMock,
};
frame.datasourceLayers.first.getOperationForColumnId = jest.fn((accessor) => {
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.first.getOperationForColumnId = jest.fn((accessor) => {
if (accessor === 'a') {
return {
dataType: 'date',
@ -1547,7 +1554,8 @@ describe('xy_visualization', () => {
(state.layers[0] as XYDataLayerConfig).accessors = [];
(state.layers[1] as XYReferenceLineLayerConfig).yConfig = []; // empty the configuration
// set the xAccessor as date_histogram
frame.datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
if (accessor === 'b') {
return {
dataType: 'date',
@ -1576,7 +1584,8 @@ describe('xy_visualization', () => {
(state.layers[0] as XYDataLayerConfig).accessors = [];
(state.layers[1] as XYReferenceLineLayerConfig).yConfig![0].axisMode = 'bottom';
// set the xAccessor as date_histogram
frame.datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
if (accessor === 'b') {
return {
dataType: 'date',
@ -1618,8 +1627,9 @@ describe('xy_visualization', () => {
{ forAccessor: 'b', axisMode: 'right' },
{ forAccessor: 'a', axisMode: 'left' },
];
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
// set the xAccessor as number histogram
frame.datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
if (accessor === 'c') {
return {
dataType: 'number',
@ -1650,7 +1660,8 @@ describe('xy_visualization', () => {
(state.layers[0] as XYDataLayerConfig).accessors = [];
(state.layers[1] as XYReferenceLineLayerConfig).yConfig = []; // empty the configuration
// set the xAccessor as top values
frame.datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
if (accessor === 'b') {
return {
dataType: 'string',
@ -1679,7 +1690,8 @@ describe('xy_visualization', () => {
(state.layers[0] as XYDataLayerConfig).accessors = [];
(state.layers[1] as XYReferenceLineLayerConfig).yConfig![0].axisMode = 'bottom';
// set the xAccessor as date_histogram
frame.datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.referenceLine.getOperationForColumnId = jest.fn((accessor) => {
if (accessor === 'b') {
return {
dataType: 'string',
@ -1787,7 +1799,8 @@ describe('xy_visualization', () => {
frame.datasourceLayers = {
first: mockDatasource.publicAPIMock,
};
frame.datasourceLayers.first.getOperationForColumnId = jest.fn((accessor) => {
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.first.getOperationForColumnId = jest.fn((accessor) => {
if (accessor === 'a') {
return {
dataType: 'date',
@ -1935,7 +1948,8 @@ describe('xy_visualization', () => {
});
it('should pass name of current series along', () => {
(frame.datasourceLayers.first.getOperationForColumnId as jest.Mock).mockReturnValue({
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
(datasourceLayers.first.getOperationForColumnId as jest.Mock).mockReturnValue({
label: 'Overwritten label',
});
const palette = paletteServiceMock.get('default');
@ -2418,7 +2432,8 @@ describe('xy_visualization', () => {
};
});
it('should return a warning when numeric accessors contain array', () => {
(frame.datasourceLayers.first.getOperationForColumnId as jest.Mock).mockReturnValue({
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
(datasourceLayers.first.getOperationForColumnId as jest.Mock).mockReturnValue({
label: 'Label B',
});
const warningMessages = xyVisualization.getWarningMessages!(

View file

@ -104,7 +104,7 @@ export function DataDimensionEditor(
const overwriteColor = getSeriesColor(layer, accessor);
const assignedColor = useMemo(() => {
const sortedAccessors: string[] = getSortedAccessors(
props.frame.datasourceLayers[layer.layerId] ?? layer.accessors,
props.frame.datasourceLayers[layer.layerId],
layer
);
const colorAssignments = getColorAssignments(

View file

@ -213,7 +213,8 @@ export const XyToolbar = memo(function XyToolbar(
(layer) =>
!layer.xAccessor ||
getScaleType(
props.frame.datasourceLayers[layer.layerId].getOperationForColumnId(layer.xAccessor),
props.frame.datasourceLayers[layer.layerId]?.getOperationForColumnId(layer.xAccessor) ??
null,
ScaleType.Linear
) !== 'ordinal'
);
@ -223,7 +224,8 @@ export const XyToolbar = memo(function XyToolbar(
(layer) =>
layer.xAccessor &&
getScaleType(
props.frame.datasourceLayers[layer.layerId].getOperationForColumnId(layer.xAccessor),
props.frame.datasourceLayers[layer.layerId]?.getOperationForColumnId(layer.xAccessor) ??
null,
ScaleType.Linear
) === 'time'
)
@ -295,7 +297,8 @@ export const XyToolbar = memo(function XyToolbar(
if (!xAccessor) {
return false;
}
const xAccessorOp = props.frame.datasourceLayers[layerId].getOperationForColumnId(xAccessor);
const xAccessorOp =
props.frame.datasourceLayers[layerId]?.getOperationForColumnId(xAccessor) ?? null;
return (
getScaleType(xAccessorOp, ScaleType.Linear) === ScaleType.Time &&
xAccessorOp?.isBucketed &&

View file

@ -8,7 +8,7 @@
import React from 'react';
import { shallowWithIntl as shallow } from '@kbn/test-jest-helpers';
import { Position } from '@elastic/charts';
import type { FramePublicAPI } from '../../../../types';
import type { FramePublicAPI, DatasourcePublicAPI } from '../../../../types';
import { createMockDatasource, createMockFramePublicAPI } from '../../../../mocks';
import { State, XYLayerConfig } from '../../types';
import { VisualOptionsPopover } from '.';
@ -111,7 +111,8 @@ describe('Visual options popover', () => {
it('should disabled the popover if there is histogram series', () => {
// make it detect an histogram series
frame.datasourceLayers.first.getOperationForColumnId = jest.fn().mockReturnValueOnce({
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
datasourceLayers.first.getOperationForColumnId = jest.fn().mockReturnValueOnce({
isBucketed: true,
scale: 'interval',
});

View file

@ -12,7 +12,7 @@ import { createDatatableUtilitiesMock } from '@kbn/data-plugin/common/mocks';
import { XyToolbar } from '.';
import { DimensionEditor } from './dimension_editor';
import { AxisSettingsPopover } from './axis_settings_popover';
import { FramePublicAPI } from '../../../types';
import { FramePublicAPI, DatasourcePublicAPI } from '../../../types';
import { State, XYState, XYDataLayerConfig } from '../types';
import { Position } from '@elastic/charts';
import { createMockFramePublicAPI, createMockDatasource } from '../../../mocks';
@ -109,7 +109,8 @@ describe('XY Config panels', () => {
});
it('should pass in endzone visibility setter and current sate for time chart', () => {
(frame.datasourceLayers.first.getOperationForColumnId as jest.Mock).mockReturnValue({
const datasourceLayers = frame.datasourceLayers as Record<string, DatasourcePublicAPI>;
(datasourceLayers.first.getOperationForColumnId as jest.Mock).mockReturnValue({
dataType: 'date',
});
const state = testState();