diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.test.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.test.tsx new file mode 100644 index 00000000000..ab9901d1b5a --- /dev/null +++ b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.test.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import { PromExploreExtraField, PromExploreExtraFieldProps } from './PromExploreExtraField'; + +const setup = (propOverrides?: PromExploreExtraFieldProps) => { + const label = 'Prometheus Explore Extra Field'; + const value = '123'; + const onChangeFunc = jest.fn(); + const onKeyDownFunc = jest.fn(); + + const props: any = { + label, + value, + onChangeFunc, + onKeyDownFunc, + }; + + Object.assign(props, propOverrides); + + return shallow(); +}; + +describe('PrometheusExploreExtraField', () => { + it('should render component', () => { + const wrapper = setup(); + expect(wrapper).toMatchSnapshot(); + }); +}); diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx new file mode 100644 index 00000000000..8d67d56b31e --- /dev/null +++ b/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx @@ -0,0 +1,38 @@ +// Libraries +import React, { memo } from 'react'; + +// Types +import { FormLabel } from '@grafana/ui'; + +export interface PromExploreExtraFieldProps { + label: string; + onChangeFunc: (e: React.SyntheticEvent) => void; + onKeyDownFunc: (e: React.KeyboardEvent) => void; + value: string; + hasTooltip?: boolean; + tooltipContent?: string; +} + +export function PromExploreExtraField(props: PromExploreExtraFieldProps) { + const { label, onChangeFunc, onKeyDownFunc, value, hasTooltip, tooltipContent } = props; + + return ( +
+
+ + {label} + + +
+
+ ); +} + +export default memo(PromExploreExtraField); diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx new file mode 100644 index 00000000000..e6110541b4a --- /dev/null +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.test.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { shallow, mount } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import PromExploreQueryEditor from './PromExploreQueryEditor'; +import { PromExploreExtraField } from './PromExploreExtraField'; +import { PrometheusDatasource } from '../datasource'; +import { PromQuery } from '../types'; +import { PanelData, LoadingState, dateTime } from '@grafana/data'; + +const setup = (renderMethod: any, propOverrides?: object) => { + const datasourceMock: unknown = {}; + const datasource: PrometheusDatasource = datasourceMock as PrometheusDatasource; + const onRunQuery = jest.fn(); + const onChange = jest.fn(); + const query: PromQuery = { expr: '', refId: 'A', interval: '1s' }; + const data: PanelData = { + state: LoadingState.NotStarted, + series: [], + request: { + requestId: '1', + dashboardId: 1, + interval: '1s', + panelId: 1, + range: { + from: dateTime('2020-01-01', 'YYYY-MM-DD'), + to: dateTime('2020-01-02', 'YYYY-MM-DD'), + raw: { + from: dateTime('2020-01-01', 'YYYY-MM-DD'), + to: dateTime('2020-01-02', 'YYYY-MM-DD'), + }, + }, + scopedVars: {}, + targets: [], + timezone: 'GMT', + app: 'Grafana', + startTime: 0, + }, + timeRange: { + from: dateTime('2020-01-01', 'YYYY-MM-DD'), + to: dateTime('2020-01-02', 'YYYY-MM-DD'), + raw: { + from: dateTime('2020-01-01', 'YYYY-MM-DD'), + to: dateTime('2020-01-02', 'YYYY-MM-DD'), + }, + }, + }; + const history: any[] = []; + const exploreMode = 'Metrics'; + + const props: any = { + query, + data, + datasource, + exploreMode, + history, + onChange, + onRunQuery, + }; + + Object.assign(props, propOverrides); + + return renderMethod(); +}; + +describe('PromExploreQueryEditor', () => { + let originalGetSelection: typeof window.getSelection; + beforeAll(() => { + originalGetSelection = window.getSelection; + window.getSelection = () => null; + }); + + afterAll(() => { + window.getSelection = originalGetSelection; + }); + + it('should render component', () => { + const wrapper = setup(shallow); + expect(wrapper).toMatchSnapshot(); + }); + + it('should render PromQueryField with ExtraFieldElement', async () => { + await act(async () => { + const wrapper = setup(mount); + expect(wrapper.find(PromExploreExtraField).length).toBe(1); + }); + }); +}); diff --git a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx index 1518801248c..ed63fbc9444 100644 --- a/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromExploreQueryEditor.tsx @@ -1,85 +1,57 @@ -import React, { PureComponent } from 'react'; +import React, { memo } from 'react'; // Types import { ExploreQueryFieldProps } from '@grafana/data'; -import { FormLabel } from '@grafana/ui'; import { PrometheusDatasource } from '../datasource'; import { PromQuery, PromOptions } from '../types'; import PromQueryField from './PromQueryField'; +import { PromExploreExtraField } from './PromExploreExtraField'; + export type Props = ExploreQueryFieldProps; -interface State { - interval: string; -} +export function PromExploreQueryEditor(props: Props) { + const { query, data, datasource, history, onChange, onRunQuery } = props; -export class PromExploreQueryEditor extends PureComponent { - // Query target to be modified and used for queries - query: PromQuery; - - constructor(props: Props) { - super(props); - const { query } = props; - this.query = query; - // Query target properties that are fully controlled inputs - this.state = { - // Fully controlled text inputs - interval: query.interval, - }; + function onChangeQueryStep(value: string) { + const { query, onChange } = props; + const nextQuery = { ...query, interval: value }; + onChange(nextQuery); } - onFieldChange = (query: PromQuery, override?: any) => { - this.query.expr = query.expr; - }; - - onIntervalChange = (e: React.SyntheticEvent) => { - const interval = e.currentTarget.value; - this.query.interval = interval; - this.setState({ interval }); - }; - - onRunQuery = () => { - const { query } = this; - this.props.onChange(query); - this.props.onRunQuery(); - }; - - onReturnKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - this.onRunQuery(); + function onStepChange(e: React.SyntheticEvent) { + if (e.currentTarget.value !== query.interval) { + onChangeQueryStep(e.currentTarget.value); } - }; - - render() { - const { datasource, query, data, history } = this.props; - const { interval } = this.state; - - return ( -
- -
-
- Step - -
-
-
-
- ); } + + function onReturnKeyDown(e: React.KeyboardEvent) { + if (e.key === 'Enter') { + onRunQuery(); + } + } + + return ( + + } + /> + ); } + +export default memo(PromExploreQueryEditor); diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx index f373061feea..144b8e6c8d8 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx @@ -1,5 +1,5 @@ import _ from 'lodash'; -import React from 'react'; +import React, { ReactNode } from 'react'; import { Plugin } from 'slate'; import { @@ -110,6 +110,7 @@ export function willApplySuggestion(suggestion: string, { typeaheadContext, type interface PromQueryFieldProps extends ExploreQueryFieldProps { history: Array>; + ExtraFieldElement?: ReactNode; } interface PromQueryFieldState { @@ -291,7 +292,7 @@ class PromQueryField extends React.PureComponent - {children} + {ExtraFieldElement} {showError ? (
diff --git a/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreExtraField.test.tsx.snap b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreExtraField.test.tsx.snap new file mode 100644 index 00000000000..3f10e3ec74a --- /dev/null +++ b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreExtraField.test.tsx.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PrometheusExploreExtraField should render component 1`] = ` +
+
+ + Prometheus Explore Extra Field + + +
+
+`; diff --git a/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreQueryEditor.test.tsx.snap b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreQueryEditor.test.tsx.snap new file mode 100644 index 00000000000..a7a90d2cd84 --- /dev/null +++ b/public/app/plugins/datasource/prometheus/components/__snapshots__/PromExploreQueryEditor.test.tsx.snap @@ -0,0 +1,60 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PromExploreQueryEditor should render component 1`] = ` + + } + data={ + Object { + "request": Object { + "app": "Grafana", + "dashboardId": 1, + "interval": "1s", + "panelId": 1, + "range": Object { + "from": "2020-01-01T00:00:00.000Z", + "raw": Object { + "from": "2020-01-01T00:00:00.000Z", + "to": "2020-01-02T00:00:00.000Z", + }, + "to": "2020-01-02T00:00:00.000Z", + }, + "requestId": "1", + "scopedVars": Object {}, + "startTime": 0, + "targets": Array [], + "timezone": "GMT", + }, + "series": Array [], + "state": "NotStarted", + "timeRange": Object { + "from": "2020-01-01T00:00:00.000Z", + "raw": Object { + "from": "2020-01-01T00:00:00.000Z", + "to": "2020-01-02T00:00:00.000Z", + }, + "to": "2020-01-02T00:00:00.000Z", + }, + } + } + datasource={Object {}} + history={Array []} + onChange={[MockFunction]} + onRunQuery={[MockFunction]} + query={ + Object { + "expr": "", + "interval": "1s", + "refId": "A", + } + } +/> +`; diff --git a/public/app/plugins/datasource/prometheus/module.ts b/public/app/plugins/datasource/prometheus/module.ts index df7e67d9f97..eba42cec3f9 100644 --- a/public/app/plugins/datasource/prometheus/module.ts +++ b/public/app/plugins/datasource/prometheus/module.ts @@ -3,7 +3,7 @@ import { ANNOTATION_QUERY_STEP_DEFAULT, PrometheusDatasource } from './datasourc import { PromQueryEditor } from './components/PromQueryEditor'; import PromCheatSheet from './components/PromCheatSheet'; -import { PromExploreQueryEditor } from './components/PromExploreQueryEditor'; +import PromExploreQueryEditor from './components/PromExploreQueryEditor'; import { ConfigEditor } from './configuration/ConfigEditor';