Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 1806114: fixes issue with editing customQueries in promQL #4426

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import * as React from 'react';
import { connect } from 'react-redux';
// FIXME upgrading redux types is causing many errors at this time
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
import { useSelector, useDispatch } from 'react-redux';
import * as fuzzy from 'fuzzysearch';
import { RootState } from '@console/internal/redux';
import { Button } from '@patternfly/react-core';
Expand All @@ -14,27 +17,7 @@ import './MetricsQueryInput.scss';
const ADD_NEW_QUERY = '#ADD_NEW_QUERY#';
const CUSTOM_QUERY = 'Custom Query';

type StateProps = {
namespace: string;
text: string;
query: string;
};

type MetricsQueryInputProps = {
patchQuery: (patch: QueryObj) => void;
runQueries: () => void;
namespace: string;
text?: string;
query?: string;
};

export const MetricsQueryInput: React.FC<MetricsQueryInputProps> = ({
patchQuery,
runQueries,
namespace,
text,
query,
}) => {
const MetricsQueryInput: React.FC = () => {
const items = metricsQuery;
const autocompleteFilter = (strText, item) => fuzzy(strText, item);
const defaultActionItem = [
Expand All @@ -44,30 +27,38 @@ export const MetricsQueryInput: React.FC<MetricsQueryInputProps> = ({
},
];

const namespace = useSelector((state: RootState) => getActiveNamespace(state));
const queries = useSelector((state: RootState) =>
state.UI.getIn(['queryBrowser', 'queries', 0]).toJS(),
);
const dispatch = useDispatch();

const [title, setTitle] = React.useState('Select Query');
const [metric, setMetric] = React.useState('');
const [showPromQl, setShowPromQl] = React.useState(false);
const [isPromQlDisabled, setIsPromQlDisabled] = React.useState(false);
React.useEffect(() => {
if (metric && metric !== ADD_NEW_QUERY) {
const runQueries = () => dispatch(queryBrowserRunQueries());
const patchQuery = (v: QueryObj) => dispatch(queryBrowserPatchQuery(0, v));
if (metric) {
const queryMetrics = getTopMetricsQueries(namespace)[metric];
patchQuery({ text: queryMetrics });
patchQuery({ text: queryMetrics || '' });
runQueries();
}
}, [metric, namespace, patchQuery, runQueries]);
}, [dispatch, metric, namespace]);

React.useEffect(() => {
const query = queries?.query;
const text = queries?.text;
if (text && text.localeCompare(query) !== 0) {
setTitle(CUSTOM_QUERY);
setIsPromQlDisabled(true);
}
}, [text, query]);
}, [queries]);

const onChange = (selectedValue: string) => {
setMetric(selectedValue);
if (selectedValue && selectedValue === ADD_NEW_QUERY) {
patchQuery({ text: '' });
runQueries();
setTitle(CUSTOM_QUERY);
setIsPromQlDisabled(true);
setShowPromQl(true);
Expand Down Expand Up @@ -113,15 +104,4 @@ export const MetricsQueryInput: React.FC<MetricsQueryInputProps> = ({
);
};

const mapStateToProps = (state: RootState): StateProps => ({
namespace: getActiveNamespace(state),
text: state.UI.getIn(['queryBrowser', 'queries', 0, 'text']),
query: state.UI.getIn(['queryBrowser', 'queries', 0, 'query']),
});

const mapDispatchToProps = (dispatch) => ({
runQueries: () => dispatch(queryBrowserRunQueries()),
patchQuery: (v: QueryObj) => dispatch(queryBrowserPatchQuery(0, v)),
});

export default connect(mapStateToProps, mapDispatchToProps)(MetricsQueryInput);
export default MetricsQueryInput;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { Helmet } from 'react-helmet';
import ConnectedMetricsQueryInput from './MetricsQueryInput';
import MetricsQueryInput from './MetricsQueryInput';
import { connect } from 'react-redux';
import { getURLSearchParams } from '@console/internal/components/utils';
import { queryBrowserRunQueries, queryBrowserPatchQuery } from '@console/internal/actions/ui';
Expand All @@ -26,7 +26,7 @@ export const MonitoringMetrics: React.FC<MonitoringMetricsProps> = ({ patchQuery
<title>Metrics</title>
</Helmet>
<div className="co-m-pane__body">
<ConnectedMetricsQueryInput />
<MetricsQueryInput />
<div className="row">
<div className="col-xs-12">
<ConnectedMetricsChart />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,44 @@
import * as React from 'react';
import * as redux from 'react-redux';
import { shallow } from 'enzyme';
import { Button } from '@patternfly/react-core';
import { Dropdown } from '@console/internal/components/utils';
import { QueryInput } from '@console/internal/components/monitoring/metrics';
import { MetricsQueryInput } from '../MetricsQueryInput';
import MetricsQueryInput from '../MetricsQueryInput';

describe('Metrics Query Input', () => {
let props: React.ComponentProps<typeof MetricsQueryInput>;
beforeEach(() => {
props = {
namespace: 'my-app',
patchQuery: jest.fn(),
runQueries: jest.fn(),
};
});

// FIXME upgrading redux types is causing many errors at this time
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
const spySelector = jest.spyOn(redux, 'useSelector');
spySelector.mockReturnValue({ queryBrowser: { queries: [] } });
// FIXME upgrading redux types is causing many errors at this time
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
const spyDispatch = jest.spyOn(redux, 'useDispatch');
spyDispatch.mockReturnValue(() => {});
it('should render Dropdown with default title', () => {
const wrapper = shallow(<MetricsQueryInput {...props} />);
const wrapper = shallow(<MetricsQueryInput />);
expect(wrapper.find(Dropdown)).toHaveLength(1);
expect(wrapper.find(Dropdown).props().title).toEqual('Select Query');
});

it('should render Button with text "Show PromQL" and not render QueryInput', () => {
const wrapper = shallow(<MetricsQueryInput {...props} />);
const wrapper = shallow(<MetricsQueryInput />);
expect(wrapper.find(Button)).toHaveLength(1);
expect(wrapper.find(Button).props().children).toEqual('Show PromQL');
expect(wrapper.find(QueryInput).exists()).toBe(false);
});

it('should update Button with text "Hide PromQL" on click and render QueryInput', () => {
const wrapper = shallow(<MetricsQueryInput {...props} />);
const wrapper = shallow(<MetricsQueryInput />);
wrapper.find(Button).simulate('click');
expect(wrapper.find(Button).props().children).toEqual('Hide PromQL');
expect(wrapper.find(QueryInput)).toHaveLength(1);
});

it('Custom Querey selection should update Dropdown title, show QueryInput and Button in disabled state', () => {
const wrapper = shallow(<MetricsQueryInput {...props} />);
const wrapper = shallow(<MetricsQueryInput />);
wrapper
.find(Dropdown)
.props()
Expand All @@ -48,7 +50,7 @@ describe('Metrics Query Input', () => {
});

it('Metric selection should update Dropdown title and show Button in enabled state', () => {
const wrapper = shallow(<MetricsQueryInput {...props} />);
const wrapper = shallow(<MetricsQueryInput />);
wrapper
.find(Dropdown)
.props()
Expand Down