Skip to content

Commit

Permalink
Merge branch 'main' into bfilar.ml-refactor-2
Browse files Browse the repository at this point in the history
  • Loading branch information
randomuserid authored May 17, 2022
2 parents 702e642 + af3c090 commit 4974858
Show file tree
Hide file tree
Showing 155 changed files with 4,072 additions and 1,558 deletions.
1 change: 1 addition & 0 deletions .buildkite/ftr_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ disabled:
- x-pack/test/security_solution_cypress/upgrade_config.ts
- x-pack/test/security_solution_cypress/visual_config.ts
- x-pack/test/functional_enterprise_search/with_host_configured.config.ts
- x-pack/plugins/apm/ftr_e2e/ftr_config_open.ts
- x-pack/plugins/apm/ftr_e2e/ftr_config_run.ts
- x-pack/plugins/apm/ftr_e2e/ftr_config.ts

Expand Down
4 changes: 1 addition & 3 deletions packages/shared-ux/page/analytics_no_data/src/services.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ export interface AnalyticsNoDataPageKibanaDependencies {
coreStart: {
application: {
capabilities: {
navLinks: {
integrations: boolean;
};
navLinks: Record<string, boolean>;
};
currentAppId$: Observable<string | undefined>;
navigateToUrl: (url: string) => Promise<void>;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ describe('MetricVisComponent', function () {
visData,
renderComplete: jest.fn(),
fireEvent: jest.fn(),
filterable: [true],
...propOverrides,
};

Expand All @@ -88,6 +89,7 @@ describe('MetricVisComponent', function () {

it('should render correct structure for multi-value metrics', function () {
const component = getComponent({
filterable: [true, false],
visData: {
type: 'datatable',
columns: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import './metric.scss';
export interface MetricVisComponentProps {
visParams: Pick<VisParams, 'metric' | 'dimensions'>;
visData: Datatable;
filterable: boolean[];
fireEvent: (event: any) => void;
renderComplete: () => void;
}
Expand Down Expand Up @@ -127,6 +128,7 @@ class MetricVisComponent extends Component<MetricVisComponentProps> {
};

private renderMetric = (metric: MetricOptions, index: number) => {
const hasBuckets = this.props.visParams.dimensions.bucket !== undefined;
const MetricComponent = this.props.visParams.metric.autoScale
? AutoScaleMetricVisValue
: MetricVisValue;
Expand All @@ -147,7 +149,11 @@ class MetricVisComponent extends Component<MetricVisComponentProps> {
key={index}
metric={metric}
style={this.props.visParams.metric.style}
onFilter={() => this.filterColumn(metric.rowIndex, metric.colIndex)}
onFilter={
hasBuckets || this.props.filterable[index]
? () => this.filterColumn(metric.rowIndex, metric.colIndex)
: undefined
}
autoScale={this.props.visParams.metric.autoScale}
colorFullBackground={this.props.visParams.metric.colorFullBackground}
labelConfig={this.props.visParams.metric.labels}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,48 @@ import { render, unmountComponentAtNode } from 'react-dom';

import { ThemeServiceStart } from '@kbn/core/public';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
import { VisualizationContainer } from '@kbn/visualizations-plugin/public';
import { ExpressionRenderDefinition } from '@kbn/expressions-plugin/common/expression_renderers';
import { EXPRESSION_METRIC_NAME, MetricVisRenderConfig } from '../../common';
import {
ExpressionValueVisDimension,
VisualizationContainer,
} from '@kbn/visualizations-plugin/public';
import {
ExpressionRenderDefinition,
IInterpreterRenderHandlers,
} from '@kbn/expressions-plugin/common/expression_renderers';
import { getColumnByAccessor } from '@kbn/visualizations-plugin/common/utils';
import { Datatable } from '@kbn/expressions-plugin';
import { EXPRESSION_METRIC_NAME, MetricVisRenderConfig, VisParams } from '../../common';

// @ts-ignore
const MetricVisComponent = lazy(() => import('../components/metric_component'));

async function metricFilterable(
dimensions: VisParams['dimensions'],
table: Datatable,
handlers: IInterpreterRenderHandlers
) {
return Promise.all(
dimensions.metrics.map(async (metric: string | ExpressionValueVisDimension) => {
const column = getColumnByAccessor(metric, table.columns);
const colIndex = table.columns.indexOf(column!);
return Boolean(
await handlers.hasCompatibleActions?.({
name: 'filter',
data: {
data: [
{
table,
column: colIndex,
row: 0,
},
],
},
})
);
})
);
}

export const getMetricVisRenderer = (
theme: ThemeServiceStart
): (() => ExpressionRenderDefinition<MetricVisRenderConfig>) => {
Expand All @@ -30,6 +65,8 @@ export const getMetricVisRenderer = (
unmountComponentAtNode(domNode);
});

const filterable = await metricFilterable(visConfig.dimensions, visData, handlers);

render(
<KibanaThemeProvider theme$={theme.theme$}>
<VisualizationContainer
Expand All @@ -43,6 +80,7 @@ export const getMetricVisRenderer = (
visParams={visConfig}
renderComplete={handlers.done}
fireEvent={handlers.event}
filterable={filterable}
/>
</VisualizationContainer>
</KibanaThemeProvider>,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,8 @@ export const commonXYArgs: CommonXYFn['args'] = {
types: ['string'],
help: strings.getAriaLabelHelp(),
},
minTimeBarInterval: {
types: ['string'],
help: strings.getMinTimeBarIntervalHelp(),
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@
*/

import { XY_VIS_RENDERER } from '../constants';
import { appendLayerIds } from '../helpers';
import { appendLayerIds, getDataLayers } from '../helpers';
import { LayeredXyVisFn } from '../types';
import { logDatatables } from '../utils';
import { validateMinTimeBarInterval, hasBarLayer } from './validate';

export const layeredXyVisFn: LayeredXyVisFn['fn'] = async (data, args, handlers) => {
const layers = appendLayerIds(args.layers ?? [], 'layers');

logDatatables(layers, handlers);

const dataLayers = getDataLayers(layers);
const hasBar = hasBarLayer(dataLayers);
validateMinTimeBarInterval(dataLayers, hasBar, args.minTimeBarInterval);

return {
type: 'render',
as: XY_VIS_RENDERER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
*/

import { i18n } from '@kbn/i18n';
import { isValidInterval } from '@kbn/data-plugin/common';
import { AxisExtentModes, ValueLabelModes } from '../constants';
import {
AxisExtentConfigResult,
DataLayerConfigResult,
CommonXYDataLayerConfigResult,
ValueLabelMode,
CommonXYDataLayerConfig,
} from '../types';
import { isTimeChart } from '../helpers';

const errors = {
extendBoundsAreInvalidError: () =>
Expand All @@ -37,6 +40,18 @@ const errors = {
i18n.translate('expressionXY.reusable.function.xyVis.errors.dataBoundsForNotLineChartError', {
defaultMessage: 'Only line charts can be fit to the data bounds',
}),
isInvalidIntervalError: () =>
i18n.translate('expressionXY.reusable.function.xyVis.errors.isInvalidIntervalError', {
defaultMessage:
'Provided x-axis interval is invalid. The interval should include quantity and unit names. Examples: 1d, 24h, 1w.',
}),
minTimeBarIntervalNotForTimeBarChartError: () =>
i18n.translate(
'expressionXY.reusable.function.xyVis.errors.minTimeBarIntervalNotForTimeBarChartError',
{
defaultMessage: '`minTimeBarInterval` argument is applicable only for time bar charts.',
}
),
};

export const hasBarLayer = (layers: Array<DataLayerConfigResult | CommonXYDataLayerConfig>) =>
Expand Down Expand Up @@ -101,3 +116,19 @@ export const validateValueLabels = (
throw new Error(errors.valueLabelsForNotBarsOrHistogramBarsChartsError());
}
};

export const validateMinTimeBarInterval = (
dataLayers: CommonXYDataLayerConfigResult[],
hasBar: boolean,
minTimeBarInterval?: string
) => {
if (minTimeBarInterval) {
if (!isValidInterval(minTimeBarInterval)) {
throw new Error(errors.isInvalidIntervalError());
}

if (!hasBar || !isTimeChart(dataLayers)) {
throw new Error(errors.minTimeBarIntervalNotForTimeBarChartError());
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,44 @@ describe('xyVis', () => {
});
});

test('it should throw error if minTimeBarInterval is invalid', async () => {
const { data, args } = sampleArgs();
const { layers, ...rest } = args;
const { layerId, layerType, table, type, ...restLayerArgs } = sampleLayer;
expect(
xyVisFunction.fn(
data,
{
...rest,
...restLayerArgs,
minTimeBarInterval: '1q',
referenceLineLayers: [],
annotationLayers: [],
},
createMockExecutionContext()
)
).rejects.toThrowErrorMatchingSnapshot();
});

test('it should throw error if minTimeBarInterval applied for not time bar chart', async () => {
const { data, args } = sampleArgs();
const { layers, ...rest } = args;
const { layerId, layerType, table, type, ...restLayerArgs } = sampleLayer;
expect(
xyVisFunction.fn(
data,
{
...rest,
...restLayerArgs,
minTimeBarInterval: '1h',
referenceLineLayers: [],
annotationLayers: [],
},
createMockExecutionContext()
)
).rejects.toThrowErrorMatchingSnapshot();
});

test('it should throw error if splitRowAccessor is pointing to the absent column', async () => {
const { data, args } = sampleArgs();
const { layers, ...rest } = args;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
validateExtent,
validateFillOpacity,
validateValueLabels,
validateMinTimeBarInterval,
} from './validate';

const createDataLayer = (args: XYArgs, table: Datatable): DataLayerConfigResult => {
Expand Down Expand Up @@ -99,6 +100,7 @@ export const xyVisFn: XyVisFn['fn'] = async (data, args, handlers) => {
validateExtent(args.yLeftExtent, hasBar || hasArea, dataLayers);
validateExtent(args.yRightExtent, hasBar || hasArea, dataLayers);
validateFillOpacity(args.fillOpacity, hasArea);
validateMinTimeBarInterval(dataLayers, hasBar, args.minTimeBarInterval);

const hasNotHistogramBars = !hasHistogramBarLayer(dataLayers);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
* Side Public License, v 1.
*/

export { appendLayerIds, getAccessors } from './layers';
export { appendLayerIds, getDataLayers, getAccessors } from './layers';
export { isTimeChart } from './visualization';
export { normalizeTable } from './table';
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* Side Public License, v 1.
*/

import { generateLayerId, appendLayerIds } from './layers';
import { XYExtendedLayerConfigResult } from '../types';
import { generateLayerId, appendLayerIds, getDataLayers } from './layers';

describe('#generateLayerId', () => {
it('should return the combination of keyword and index', () => {
Expand Down Expand Up @@ -47,3 +48,28 @@ describe('#appendLayerIds', () => {
expect(layersWithIds).toStrictEqual(expectedLayerIds);
});
});

describe('#getDataLayers', () => {
it('should return only data layers', () => {
const layers: XYExtendedLayerConfigResult[] = [
{
type: 'extendedDataLayer',
layerType: 'data',
accessors: ['y'],
seriesType: 'bar',
xScaleType: 'time',
isHistogram: false,
table: { rows: [], columns: [], type: 'datatable' },
palette: { type: 'system_palette', name: 'system' },
},
{
type: 'extendedReferenceLineLayer',
layerType: 'referenceLine',
accessors: ['y'],
table: { rows: [], columns: [], type: 'datatable' },
},
];

expect(getDataLayers(layers)).toStrictEqual([layers[0]]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
*/

import { Datatable, PointSeriesColumnNames } from '@kbn/expressions-plugin/common';
import { WithLayerId } from '../types';
import { WithLayerId, ExtendedDataLayerConfig, XYExtendedLayerConfigResult } from '../types';
import { LayerTypes } from '../constants';

function isWithLayerId<T>(layer: T): layer is T & WithLayerId {
return (layer as T & WithLayerId).layerId ? true : false;
Expand All @@ -27,6 +28,13 @@ export function appendLayerIds<T>(
}));
}

export function getDataLayers(layers: XYExtendedLayerConfigResult[]) {
return layers.filter<ExtendedDataLayerConfig>(
(layer): layer is ExtendedDataLayerConfig =>
layer.layerType === LayerTypes.DATA || !layer.layerType
);
}

export function getAccessors<T, U extends { splitAccessor?: T; xAccessor?: T; accessors: T[] }>(
args: U,
table: Datatable
Expand Down
Loading

0 comments on commit 4974858

Please sign in to comment.