diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.jsx b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.jsx index 1c77022ced..0835ba7fa5 100644 --- a/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.jsx +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.jsx @@ -35,7 +35,7 @@ import { DEFAULT_OPERATION, DEFAULT_LIMIT, DEFAULT_LOOKBACK, - SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE, + CHANGE_SERVICE_ACTION_TYPE, } from '../../constants/search-form'; import { getConfigValue } from '../../utils/config/get-config'; import SearchableSelect from '../common/SearchableSelect'; @@ -302,13 +302,15 @@ export class SearchFormImpl extends React.PureComponent { }; render() { - const { invalid, searchMaxLookback, services, submitting: disabled } = this.props; + const { invalid, searchMaxLookback, services, submitting } = this.props; const { formData } = this.state; const { service: selectedService, lookback: selectedLookback } = formData; const selectedServicePayload = services.find(s => s.name === selectedService); const opsForSvc = (selectedServicePayload && selectedServicePayload.operations) || []; const noSelectedService = selectedService === '-' || !selectedService; const tz = selectedLookback === 'custom' ? new Date().toTimeString().replace(/^.*?GMT/, 'UTC') : null; + const invalidDuration = + validateDurationFields(formData.minDuration) || validateDurationFields(formData.maxDuration); return (
@@ -323,7 +325,7 @@ export class SearchFormImpl extends React.PureComponent { name="service" value={this.state.formData.service} placeholder="Select A Service" - disabled={disabled} + disabled={submitting} onChange={value => this.handleChange({ service: value })} > {services.map(service => ( @@ -343,7 +345,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ operation: value })} > @@ -429,7 +431,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ tags: e.target.value })} /> @@ -439,7 +441,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ lookback: value })} > @@ -473,7 +475,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ startDate: e.target.value })} @@ -484,7 +486,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ startDateTime: e.target.value })} /> @@ -516,7 +518,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ endDate: e.target.value })} @@ -527,7 +529,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ endDateTime: e.target.value })} /> @@ -542,7 +544,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ maxDuration: e.target.value })} @@ -555,7 +557,7 @@ export class SearchFormImpl extends React.PureComponent { this.handleChange({ minDuration: e.target.value })} @@ -568,7 +570,7 @@ export class SearchFormImpl extends React.PureComponent { Find Traces @@ -727,7 +729,7 @@ export function mapDispatchToProps(dispatch) { return { changeServiceHandler: service => dispatch({ - type: SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE, + type: CHANGE_SERVICE_ACTION_TYPE, payload: service, }), submitFormHandler: fields => submitForm(fields, searchTraces), diff --git a/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.test.js b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.test.js index 348b584cc4..307d6b1b67 100644 --- a/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.test.js +++ b/packages/jaeger-ui/src/components/SearchTracePage/SearchForm.test.js @@ -38,7 +38,7 @@ import { } from './SearchForm'; import * as markers from './SearchForm.markers'; import getConfig from '../../utils/config/get-config'; -import { SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE } from '../../constants/search-form'; +import { CHANGE_SERVICE_ACTION_TYPE } from '../../constants/search-form'; function makeDateParams(dateOffset = 0) { const date = new Date(); @@ -450,6 +450,26 @@ describe('', () => { expect(btn.prop('disabled')).toBeTruthy(); }); + it('disables the submit button when duration is invalid', () => { + wrapper = shallow(); + wrapper.instance().handleChange({ service: 'svcA' }); + wrapper.instance().handleChange({ minDuration: '1ms' }); + let btn = wrapper.find(`[data-test="${markers.SUBMIT_BTN}"]`); + let invalidDuration = + validateDurationFields(wrapper.state().formData.minDuration) || + validateDurationFields(wrapper.state().formData.maxDuration); + expect(invalidDuration).not.toBeDefined(); + expect(btn.prop('disabled')).toBeFalsy(); + + wrapper.instance().handleChange({ minDuration: '1kg' }); + btn = wrapper.find(`[data-test="${markers.SUBMIT_BTN}"]`); + invalidDuration = + validateDurationFields(wrapper.state().formData.minDuration) || + validateDurationFields(wrapper.state().formData.maxDuration); + expect(invalidDuration).toBeDefined(); + expect(btn.prop('disabled')).toBeTruthy(); + }); + it('uses config.search.maxLimit', () => { const maxLimit = 6789; getConfig.apply({}, []); @@ -702,7 +722,7 @@ describe('mapDispatchToProps()', () => { changeServiceHandler(service); expect(dispatch).toHaveBeenCalledWith({ - type: SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE, + type: CHANGE_SERVICE_ACTION_TYPE, payload: service, }); }); diff --git a/packages/jaeger-ui/src/constants/search-form.tsx b/packages/jaeger-ui/src/constants/search-form.tsx index 4cf53bc56c..a9731e0a9c 100644 --- a/packages/jaeger-ui/src/constants/search-form.tsx +++ b/packages/jaeger-ui/src/constants/search-form.tsx @@ -16,4 +16,4 @@ export const DEFAULT_OPERATION = 'all'; export const DEFAULT_LOOKBACK = '1h'; export const DEFAULT_LIMIT = 20; -export const SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE = '@@redux/searchSideBar/CHANGE_SERVICE'; +export const CHANGE_SERVICE_ACTION_TYPE = '@@redux/searchSideBar/CHANGE_SERVICE'; diff --git a/packages/jaeger-ui/src/middlewares/index.js b/packages/jaeger-ui/src/middlewares/index.js index 9c3b45f7f5..f8b5067dfa 100644 --- a/packages/jaeger-ui/src/middlewares/index.js +++ b/packages/jaeger-ui/src/middlewares/index.js @@ -17,7 +17,7 @@ import { replace } from 'redux-first-history'; import { searchTraces, fetchServiceOperations } from '../actions/jaeger-api'; import { getUrl as getSearchUrl } from '../components/SearchTracePage/url'; -import { SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE } from '../constants/search-form'; +import { CHANGE_SERVICE_ACTION_TYPE } from '../constants/search-form'; export { default as trackMiddleware } from './track'; @@ -25,7 +25,7 @@ export { default as trackMiddleware } from './track'; * Middleware to load "operations" for a particular service. */ export const loadOperationsForServiceMiddleware = store => next => action => { - if (action.type === SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE && action.payload !== '-') { + if (action.type === CHANGE_SERVICE_ACTION_TYPE && action.payload !== '-') { store.dispatch(fetchServiceOperations(action.payload)); } return next(action); diff --git a/packages/jaeger-ui/src/middlewares/index.test.js b/packages/jaeger-ui/src/middlewares/index.test.js index 1f53e8f564..9010e88a23 100644 --- a/packages/jaeger-ui/src/middlewares/index.test.js +++ b/packages/jaeger-ui/src/middlewares/index.test.js @@ -25,7 +25,7 @@ jest.mock( import * as jaegerMiddlewares from './index'; import { fetchServiceOperations } from '../actions/jaeger-api'; -import { SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE } from '../constants/search-form'; +import { CHANGE_SERVICE_ACTION_TYPE } from '../constants/search-form'; it('jaegerMiddlewares should contain the promise middleware', () => { expect(typeof jaegerMiddlewares.promise).toBe('function'); @@ -36,7 +36,7 @@ it('loadOperationsForServiceMiddleware fetches operations for services', () => { const dispatch = jest.fn(); const next = jest.fn(); const action = { - type: SEARCH_SIDEBAR_CHANGE_SERVICE_ACTION_TYPE, + type: CHANGE_SERVICE_ACTION_TYPE, payload: 'yo', }; loadOperationsForServiceMiddleware({ dispatch })(next)(action);