Skip to content

Commit

Permalink
Clean up TSVB type client code to conform to the schema (#68519) (#69885
Browse files Browse the repository at this point in the history
)

* Clean up TSVB type client code to conform to the schema

Part of #57342

* Replace FieldDescriptor with IFieldType, add UIRestrictions interface

* Replace expect from chai with @kbn/expect, remove unnecessary type

* Add TimeseriesUIRestrictions type and refactor add_delete_buttons.test

* Replace some types with MetricsItemsSchema['values'] to avoid duplications

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
DianaDerevyankina and elasticmachine authored Jun 26, 2020
1 parent 40bad84 commit 9ae8ffd
Show file tree
Hide file tree
Showing 18 changed files with 369 additions and 254 deletions.
25 changes: 25 additions & 0 deletions src/plugins/vis_type_timeseries/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { TypeOf } from '@kbn/config-schema';
import { metricsItems, panel, seriesItems } from './vis_schema';

export type SeriesItemsSchema = TypeOf<typeof seriesItems>;
export type MetricsItemsSchema = TypeOf<typeof metricsItems>;
export type PanelSchema = TypeOf<typeof panel>;
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,37 @@
* @constant
* @public
*/
export const RESTRICTIONS_KEYS = {
export enum RESTRICTIONS_KEYS {
/**
* Key for getting the white listed group by fields from the UIRestrictions object.
*/
WHITE_LISTED_GROUP_BY_FIELDS: 'whiteListedGroupByFields',
WHITE_LISTED_GROUP_BY_FIELDS = 'whiteListedGroupByFields',

/**
* Key for getting the white listed metrics from the UIRestrictions object.
*/
WHITE_LISTED_METRICS: 'whiteListedMetrics',
WHITE_LISTED_METRICS = 'whiteListedMetrics',

/**
* Key for getting the white listed Time Range modes from the UIRestrictions object.
*/
WHITE_LISTED_TIMERANGE_MODES: 'whiteListedTimerangeModes',
WHITE_LISTED_TIMERANGE_MODES = 'whiteListedTimerangeModes',
}

export interface UIRestrictions {
'*': boolean;
[restriction: string]: boolean;
}

export type TimeseriesUIRestrictions = {
[key in RESTRICTIONS_KEYS]: Record<string, UIRestrictions>;
};

/**
* Default value for the UIRestriction
* @constant
* @public
*/
export const DEFAULT_UI_RESTRICTION = {
export const DEFAULT_UI_RESTRICTION: UIRestrictions = {
'*': true,
};
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const gaugeColorRulesItems = schema.object({
operator: stringOptionalNullable,
value: schema.maybe(schema.nullable(schema.number())),
});
const metricsItems = schema.object({
export const metricsItems = schema.object({
field: stringOptionalNullable,
id: stringRequired,
metric_agg: stringOptionalNullable,
Expand Down Expand Up @@ -133,7 +133,7 @@ const splitFiltersItems = schema.object({
label: stringOptionalNullable,
});

const seriesItems = schema.object({
export const seriesItems = schema.object({
aggregate_by: stringOptionalNullable,
aggregate_function: stringOptionalNullable,
axis_position: stringRequired,
Expand Down Expand Up @@ -195,66 +195,66 @@ const seriesItems = schema.object({
var_name: stringOptionalNullable,
});

export const panel = schema.object({
annotations: schema.maybe(schema.arrayOf(annotationsItems)),
axis_formatter: stringRequired,
axis_position: stringRequired,
axis_scale: stringRequired,
axis_min: stringOrNumberOptionalNullable,
axis_max: stringOrNumberOptionalNullable,
bar_color_rules: schema.maybe(arrayNullable),
background_color: stringOptionalNullable,
background_color_rules: schema.maybe(schema.arrayOf(backgroundColorRulesItems)),
default_index_pattern: stringOptionalNullable,
default_timefield: stringOptionalNullable,
drilldown_url: stringOptionalNullable,
drop_last_bucket: numberIntegerOptional,
filter: schema.nullable(
schema.oneOf([
stringOptionalNullable,
schema.object({
language: stringOptionalNullable,
query: stringOptionalNullable,
}),
])
),
gauge_color_rules: schema.maybe(schema.arrayOf(gaugeColorRulesItems)),
gauge_width: schema.nullable(schema.oneOf([stringOptionalNullable, numberOptional])),
gauge_inner_color: stringOptionalNullable,
gauge_inner_width: stringOrNumberOptionalNullable,
gauge_style: stringOptionalNullable,
gauge_max: stringOrNumberOptionalNullable,
id: stringRequired,
ignore_global_filters: numberOptional,
ignore_global_filter: numberOptional,
index_pattern: stringRequired,
interval: stringRequired,
isModelInvalid: schema.maybe(schema.boolean()),
legend_position: stringOptionalNullable,
markdown: stringOptionalNullable,
markdown_scrollbars: numberIntegerOptional,
markdown_openLinksInNewTab: numberIntegerOptional,
markdown_vertical_align: stringOptionalNullable,
markdown_less: stringOptionalNullable,
markdown_css: stringOptionalNullable,
pivot_id: stringOptionalNullable,
pivot_label: stringOptionalNullable,
pivot_type: stringOptionalNullable,
pivot_rows: stringOptionalNullable,
series: schema.arrayOf(seriesItems),
show_grid: numberIntegerRequired,
show_legend: numberIntegerRequired,
tooltip_mode: schema.maybe(
schema.oneOf([schema.literal('show_all'), schema.literal('show_focused')])
),
time_field: stringOptionalNullable,
time_range_mode: stringOptionalNullable,
type: stringRequired,
});

export const visPayloadSchema = schema.object({
filters: arrayNullable,
panels: schema.arrayOf(
schema.object({
annotations: schema.maybe(schema.arrayOf(annotationsItems)),
axis_formatter: stringRequired,
axis_position: stringRequired,
axis_scale: stringRequired,
axis_min: stringOrNumberOptionalNullable,
axis_max: stringOrNumberOptionalNullable,
bar_color_rules: schema.maybe(arrayNullable),
background_color: stringOptionalNullable,
background_color_rules: schema.maybe(schema.arrayOf(backgroundColorRulesItems)),
default_index_pattern: stringOptionalNullable,
default_timefield: stringOptionalNullable,
drilldown_url: stringOptionalNullable,
drop_last_bucket: numberIntegerOptional,
filter: schema.nullable(
schema.oneOf([
stringOptionalNullable,
schema.object({
language: stringOptionalNullable,
query: stringOptionalNullable,
}),
])
),
gauge_color_rules: schema.maybe(schema.arrayOf(gaugeColorRulesItems)),
gauge_width: schema.nullable(schema.oneOf([stringOptionalNullable, numberOptional])),
gauge_inner_color: stringOptionalNullable,
gauge_inner_width: stringOrNumberOptionalNullable,
gauge_style: stringOptionalNullable,
gauge_max: stringOrNumberOptionalNullable,
id: stringRequired,
ignore_global_filters: numberOptional,
ignore_global_filter: numberOptional,
index_pattern: stringRequired,
interval: stringRequired,
isModelInvalid: schema.maybe(schema.boolean()),
legend_position: stringOptionalNullable,
markdown: stringOptionalNullable,
markdown_scrollbars: numberIntegerOptional,
markdown_openLinksInNewTab: numberIntegerOptional,
markdown_vertical_align: stringOptionalNullable,
markdown_less: stringOptionalNullable,
markdown_css: stringOptionalNullable,
pivot_id: stringOptionalNullable,
pivot_label: stringOptionalNullable,
pivot_type: stringOptionalNullable,
pivot_rows: stringOptionalNullable,
series: schema.arrayOf(seriesItems),
show_grid: numberIntegerRequired,
show_legend: numberIntegerRequired,
tooltip_mode: schema.maybe(
schema.oneOf([schema.literal('show_all'), schema.literal('show_focused')])
),
time_field: stringOptionalNullable,
time_range_mode: stringOptionalNullable,
type: stringRequired,
})
),
panels: schema.arrayOf(panel),
// general
query: schema.nullable(schema.arrayOf(queryObject)),
state: schema.object({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,51 +18,49 @@
*/

import React from 'react';
import { expect } from 'chai';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
import sinon from 'sinon';
import { AddDeleteButtons } from './add_delete_buttons';

describe('AddDeleteButtons', () => {
it('calls onAdd={handleAdd}', () => {
const handleAdd = sinon.spy();
const handleAdd = jest.fn();
const wrapper = shallowWithIntl(<AddDeleteButtons onAdd={handleAdd} />);
wrapper.find('EuiButtonIcon').at(0).simulate('click');
expect(handleAdd.calledOnce).to.equal(true);
expect(handleAdd).toHaveBeenCalled();
});

it('calls onDelete={handleDelete}', () => {
const handleDelete = sinon.spy();
const handleDelete = jest.fn();
const wrapper = shallowWithIntl(<AddDeleteButtons onDelete={handleDelete} />);
wrapper.find('EuiButtonIcon').at(1).simulate('click');
expect(handleDelete.calledOnce).to.equal(true);
expect(handleDelete).toHaveBeenCalled();
});

it('calls onClone={handleClone}', () => {
const handleClone = sinon.spy();
const handleClone = jest.fn();
const wrapper = shallowWithIntl(<AddDeleteButtons onClone={handleClone} />);
wrapper.find('EuiButtonIcon').at(0).simulate('click');
expect(handleClone.calledOnce).to.equal(true);
expect(handleClone).toHaveBeenCalled();
});

it('disableDelete={true}', () => {
const wrapper = shallowWithIntl(<AddDeleteButtons disableDelete={true} />);
expect(wrapper.find({ text: 'Delete' })).to.have.length(0);
expect(wrapper.find({ text: 'Delete' })).toHaveLength(0);
});

it('disableAdd={true}', () => {
const wrapper = shallowWithIntl(<AddDeleteButtons disableAdd={true} />);
expect(wrapper.find({ text: 'Add' })).to.have.length(0);
expect(wrapper.find({ text: 'Add' })).toHaveLength(0);
});

it('should not display clone by default', () => {
const wrapper = shallowWithIntl(<AddDeleteButtons />);
expect(wrapper.find({ text: 'Clone' })).to.have.length(0);
expect(wrapper.find({ text: 'Clone' })).toHaveLength(0);
});

it('should not display clone when disableAdd={true}', () => {
const fn = sinon.spy();
const fn = jest.fn();
const wrapper = shallowWithIntl(<AddDeleteButtons onClone={fn} disableAdd={true} />);
expect(wrapper.find({ text: 'Clone' })).to.have.length(0);
expect(wrapper.find({ text: 'Clone' })).toHaveLength(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,29 @@
* under the License.
*/

import PropTypes from 'prop-types';
import React from 'react';
import { EuiToolTip, EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React, { MouseEvent } from 'react';
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { isBoolean } from 'lodash';

export function AddDeleteButtons(props) {
interface AddDeleteButtonsProps {
addTooltip: string;
deleteTooltip: string;
cloneTooltip: string;
activatePanelTooltip: string;
deactivatePanelTooltip: string;
isPanelActive?: boolean;
disableAdd?: boolean;
disableDelete?: boolean;
responsive?: boolean;
testSubj: string;
togglePanelActivation?: () => void;
onClone?: () => void;
onAdd?: () => void;
onDelete?: (event: MouseEvent) => void;
}

export function AddDeleteButtons(props: AddDeleteButtonsProps) {
const { testSubj } = props;
const createDelete = () => {
if (props.disableDelete) {
Expand Down Expand Up @@ -147,19 +163,3 @@ AddDeleteButtons.defaultProps = {
}
),
};

AddDeleteButtons.propTypes = {
addTooltip: PropTypes.string,
deleteTooltip: PropTypes.string,
cloneTooltip: PropTypes.string,
activatePanelTooltip: PropTypes.string,
deactivatePanelTooltip: PropTypes.string,
togglePanelActivation: PropTypes.func,
isPanelActive: PropTypes.bool,
disableAdd: PropTypes.bool,
disableDelete: PropTypes.bool,
onClone: PropTypes.func,
onAdd: PropTypes.func,
onDelete: PropTypes.func,
responsive: PropTypes.bool,
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,33 @@
* under the License.
*/

import PropTypes from 'prop-types';
import React from 'react';
import React, { HTMLAttributes } from 'react';
// @ts-ignore
import { aggToComponent } from '../lib/agg_to_component';
// @ts-ignore
import { isMetricEnabled } from '../../lib/check_ui_restrictions';
import { UnsupportedAgg } from './unsupported_agg';
import { TemporaryUnsupportedAgg } from './temporary_unsupported_agg';
import { MetricsItemsSchema, PanelSchema, SeriesItemsSchema } from '../../../../common/types';
import { DragHandleProps } from '../../../types';
import { TimeseriesUIRestrictions } from '../../../../common/ui_restrictions';
import { IFieldType } from '../../../../../data/common/index_patterns/fields';

import { isMetricEnabled } from '../../lib/check_ui_restrictions';
interface AggProps extends HTMLAttributes<HTMLElement> {
disableDelete: boolean;
fields: IFieldType[];
model: MetricsItemsSchema;
panel: PanelSchema;
series: SeriesItemsSchema;
siblings: MetricsItemsSchema[];
uiRestrictions: TimeseriesUIRestrictions;
dragHandleProps: DragHandleProps;
onAdd: () => void;
onChange: () => void;
onDelete: () => void;
}

export function Agg(props) {
export function Agg(props: AggProps) {
const { model, uiRestrictions } = props;

let Component = aggToComponent[model.type];
Expand Down Expand Up @@ -59,17 +77,3 @@ export function Agg(props) {
</div>
);
}

Agg.propTypes = {
disableDelete: PropTypes.bool,
fields: PropTypes.object,
model: PropTypes.object,
onAdd: PropTypes.func,
onChange: PropTypes.func,
onDelete: PropTypes.func,
panel: PropTypes.object,
series: PropTypes.object,
siblings: PropTypes.array,
uiRestrictions: PropTypes.object,
dragHandleProps: PropTypes.object,
};
Loading

0 comments on commit 9ae8ffd

Please sign in to comment.