diff options
author | Stas Vilchik <stas.vilchik@sonarsource.com> | 2018-12-10 17:47:01 +0100 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-01-08 20:21:06 +0100 |
commit | bbdfc6267f94b82a7c1c072e0e400b3bee87610e (patch) | |
tree | f22d39b3a2912108e7c593a65d891dcc76c12a9d /server/sonar-web/src/main/js | |
parent | f085494e7c0a846c4e293cd4cc07ccc87bbf9b82 (diff) | |
download | sonarqube-bbdfc6267f94b82a7c1c072e0e400b3bee87610e.tar.gz sonarqube-bbdfc6267f94b82a7c1c072e0e400b3bee87610e.zip |
SONAR-11572 limit operators of quality gate conditions in UI
Diffstat (limited to 'server/sonar-web/src/main/js')
-rw-r--r-- | server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx | 17 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx | 38 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx | 64 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/quality-gates/components/MetricSelect.tsx (renamed from server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionSelect.tsx) | 8 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/quality-gates/utils.ts | 10 |
5 files changed, 74 insertions, 63 deletions
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx index 6b775c72712..9d7762977d5 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx @@ -18,7 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import ConditionOperator from './ConditionOperator'; import ConditionModal from './ConditionModal'; import ActionsDropdown, { ActionsDropdownItem } from '../../../components/controls/ActionsDropdown'; import { translate, getLocalizedMetricName, translateWithParameters } from '../../../helpers/l10n'; @@ -77,6 +76,18 @@ export default class Condition extends React.PureComponent<Props, State> { ); }; + renderOperator() { + // TODO can operator be missing? + const { op = 'GT' } = this.props.condition; + return ( + <span className="note"> + {this.props.metric.type === 'RATING' + ? translate('quality_gates.operator', op, 'rating') + : translate('quality_gates.operator', op)} + </span> + ); + } + render() { const { condition, canEdit, metric, organization, qualityGate } = this.props; return ( @@ -88,9 +99,7 @@ export default class Condition extends React.PureComponent<Props, State> { )} </td> - <td className="thin text-middle nowrap"> - <ConditionOperator canEdit={false} metric={metric} op={condition.op} /> - </td> + <td className="thin text-middle nowrap">{this.renderOperator()}</td> <td className="thin text-middle nowrap">{formatMeasure(condition.error, metric.type)}</td> diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx index e480bd53c91..e2778fe943f 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx @@ -18,13 +18,14 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import AddConditionSelect from './AddConditionSelect'; +import MetricSelect from './MetricSelect'; import ConditionOperator from './ConditionOperator'; import ThresholdInput from './ThresholdInput'; import { translate, getLocalizedMetricName } from '../../../helpers/l10n'; import { createCondition, updateCondition } from '../../../api/quality-gates'; import ConfirmModal from '../../../components/controls/ConfirmModal'; import { Alert } from '../../../components/ui/Alert'; +import { getPossibleOperators } from '../utils'; interface Props { condition?: T.Condition; @@ -64,31 +65,29 @@ export default class ConditionModal extends React.PureComponent<Props, State> { this.mounted = false; } - getUpdatedCondition = (metric: T.Metric) => { - return { - metric: metric.key, - op: metric.type === 'RATING' ? 'GT' : this.state.op, - error: this.state.error - }; - }; + getSinglePossibleOperator(metric: T.Metric) { + const operators = getPossibleOperators(metric); + return Array.isArray(operators) ? undefined : operators; + } handleFormSubmit = () => { if (this.state.metric) { const { condition, qualityGate, organization } = this.props; - const newCondition = this.getUpdatedCondition(this.state.metric); - let submitPromise: Promise<T.Condition>; - if (condition) { - submitPromise = updateCondition({ organization, id: condition.id, ...newCondition }); - } else { - submitPromise = createCondition({ gateId: qualityGate.id, organization, ...newCondition }); - } + const newCondition: T.Omit<T.Condition, 'id'> = { + metric: this.state.metric.key, + op: this.getSinglePossibleOperator(this.state.metric) || this.state.op, + error: this.state.error + }; + const submitPromise = condition + ? updateCondition({ organization, id: condition.id, ...newCondition }) + : createCondition({ gateId: qualityGate.id, organization, ...newCondition }); return submitPromise.then(this.props.onAddCondition); } return Promise.reject(); }; - handleChooseType = (metric: T.Metric) => { - this.setState({ metric }); + handleMetricChange = (metric: T.Metric) => { + this.setState({ metric, op: undefined, error: '' }); }; handleOperatorChange = (op: string) => { @@ -112,9 +111,7 @@ export default class ConditionModal extends React.PureComponent<Props, State> { {this.state.errorMessage && <Alert variant="error">{this.state.errorMessage}</Alert>} <div className="modal-field"> <label htmlFor="create-user-login">{translate('quality_gates.conditions.metric')}</label> - {metrics && ( - <AddConditionSelect metrics={metrics} onAddCondition={this.handleChooseType} /> - )} + {metrics && <MetricSelect metrics={metrics} onMetricChange={this.handleMetricChange} />} {this.props.metric && ( <span className="note">{getLocalizedMetricName(this.props.metric)}</span> )} @@ -124,7 +121,6 @@ export default class ConditionModal extends React.PureComponent<Props, State> { <div className="modal-field"> <label>{translate('quality_gates.conditions.operator')}</label> <ConditionOperator - canEdit={true} metric={metric} onOperatorChange={this.handleOperatorChange} op={op} diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx index 13ef8d24e46..ba7b8aca6c4 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx @@ -20,52 +20,48 @@ import * as React from 'react'; import Select from '../../../components/controls/Select'; import { translate } from '../../../helpers/l10n'; +import { getPossibleOperators } from '../utils'; interface Props { op?: string; - canEdit: boolean; metric: T.Metric; - onOperatorChange?: (op: string) => void; + onOperatorChange: (op: string) => void; } export default class ConditionOperator extends React.PureComponent<Props> { handleChange = ({ value }: { label: string; value: string }) => { - if (this.props.onOperatorChange) { - this.props.onOperatorChange(value); - } + this.props.onOperatorChange(value); }; - render() { - const { canEdit, metric, op } = this.props; - if (!canEdit && op) { - return metric.type === 'RATING' ? ( - <span className="note">{translate('quality_gates.operator', op, 'rating')}</span> - ) : ( - <span className="note">{translate('quality_gates.operator', op)}</span> - ); - } + getLabel(op: string, metric: T.Metric) { + return metric.type === 'RATING' + ? translate('quality_gates.operator', op, 'rating') + : translate('quality_gates.operator', op); + } - if (metric.type === 'RATING') { - return <span className="note">{translate('quality_gates.operator.GT.rating')}</span>; - } + render() { + const operators = getPossibleOperators(this.props.metric); - const operators = ['LT', 'GT', 'EQ', 'NE']; - const operatorOptions = operators.map(op => { - const label = translate('quality_gates.operator', op); - return { label, value: op }; - }); + if (Array.isArray(operators)) { + const operatorOptions = operators.map(op => { + const label = this.getLabel(op, this.props.metric); + return { label, value: op }; + }); - return ( - <Select - autoFocus={true} - className="input-medium" - clearable={false} - name="operator" - onChange={this.handleChange} - options={operatorOptions} - searchable={false} - value={op} - /> - ); + return ( + <Select + autoFocus={true} + className="input-medium" + clearable={false} + name="operator" + onChange={this.handleChange} + options={operatorOptions} + searchable={false} + value={this.props.op} + /> + ); + } else { + return <span className="note">{this.getLabel(operators, this.props.metric)}</span>; + } } } diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionSelect.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/MetricSelect.tsx index 47c852cb378..60331a83d63 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionSelect.tsx +++ b/server/sonar-web/src/main/js/apps/quality-gates/components/MetricSelect.tsx @@ -24,7 +24,7 @@ import { translate, getLocalizedMetricName, getLocalizedMetricDomain } from '../ interface Props { metrics: T.Metric[]; - onAddCondition: (metric: T.Metric) => void; + onMetricChange: (metric: T.Metric) => void; } interface State { @@ -38,12 +38,12 @@ interface Option { value: number; } -export default class AddConditionSelect extends React.PureComponent<Props, State> { +export default class MetricSelect extends React.PureComponent<Props, State> { state = { value: -1 }; handleChange = ({ value }: Option) => { this.setState({ value }); - this.props.onAddCondition(this.props.metrics[value]); + this.props.onMetricChange(this.props.metrics[value]); }; render() { @@ -77,7 +77,7 @@ export default class AddConditionSelect extends React.PureComponent<Props, State className="text-middle input-large" onChange={this.handleChange} options={optionsWithDomains} - placeholder={translate('quality_gates.add_condition')} + placeholder={translate('search.search_for_metrics')} value={this.state.value} /> ); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/utils.ts b/server/sonar-web/src/main/js/apps/quality-gates/utils.ts index 08a3a01ff8c..8c76e632ee8 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/utils.ts +++ b/server/sonar-web/src/main/js/apps/quality-gates/utils.ts @@ -46,3 +46,13 @@ export function replaceCondition( }); return { ...qualityGate, conditions }; } + +export function getPossibleOperators(metric: T.Metric) { + if (metric.direction === 1) { + return 'LT'; + } else if (metric.direction === -1) { + return 'GT'; + } else { + return ['LT', 'GT']; + } +} |