aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Mugnier <pascal.mugnier@sonarsource.com>2018-05-09 07:27:30 +0200
committerSonarTech <sonartech@sonarsource.com>2018-05-24 20:20:46 +0200
commit562b9dacb912c64a4c048c03bdc9a7e2505a4bbe (patch)
tree68b4ca9c4179cca4504b5955f47dec28a495948e
parentfbe1259e4abbbbe7416489819b79113ab953d864 (diff)
downloadsonarqube-562b9dacb912c64a4c048c03bdc9a7e2505a4bbe.tar.gz
sonarqube-562b9dacb912c64a4c048c03bdc9a7e2505a4bbe.zip
Fix SONAR-10640
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionButton.tsx70
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionSelect.tsx14
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx97
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx63
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx4
5 files changed, 240 insertions, 8 deletions
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionButton.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionButton.tsx
new file mode 100644
index 00000000000..48943131904
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/AddConditionButton.tsx
@@ -0,0 +1,70 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import ConditionModal from './ConditionModal';
+import { Button } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+import { Metric } from '../../../app/types';
+
+interface Props {
+ metrics: Metric[];
+}
+
+interface State {
+ modal: boolean;
+}
+
+export default class AddConditionButton extends React.PureComponent<Props, State> {
+ mounted = false;
+ state: State = { modal: false };
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ handleClick = () => {
+ this.setState({ modal: true });
+ };
+
+ handleModalClose = () => {
+ if (this.mounted) {
+ this.setState({ modal: false });
+ }
+ };
+
+ render() {
+ return (
+ <>
+ <Button onClick={this.handleClick}>{translate('quality_gates.add_condition')}</Button>
+ {this.state.modal && (
+ <ConditionModal
+ header={translate('quality_gates.add_condition')}
+ metrics={this.props.metrics}
+ onClose={this.handleModalClose}
+ />
+ )}
+ </>
+ );
+ }
+}
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/AddConditionSelect.tsx
index ef67bfd1554..8539232bb3f 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/AddConditionSelect.tsx
@@ -67,14 +67,12 @@ export default class AddConditionSelect extends React.PureComponent<Props> {
});
return (
- <div className="big-spacer-top panel bg-muted">
- <Select
- className="text-middle input-large"
- onChange={this.handleChange}
- options={optionsWithDomains}
- placeholder={translate('quality_gates.add_condition')}
- />
- </div>
+ <Select
+ className="text-middle input-large"
+ onChange={this.handleChange}
+ options={optionsWithDomains}
+ placeholder={translate('quality_gates.add_condition')}
+ />
);
}
}
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
new file mode 100644
index 00000000000..f0c27021af4
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx
@@ -0,0 +1,97 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import AddConditionSelect from './AddConditionSelect';
+import ConditionOperator from './ConditionOperator';
+import Modal from '../../../components/controls/Modal';
+import { SubmitButton, ResetButtonLink } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+import { Metric } from '../../../app/types';
+
+interface Props {
+ metrics: Metric[];
+ header: string;
+ onClose: () => void;
+}
+
+interface State {
+ metric: string;
+ submitting: boolean;
+}
+
+export default class ConditionModal extends React.PureComponent<Props, State> {
+ state = { metric: '', submitting: false };
+
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
+ event.preventDefault();
+ this.setState({ submitting: true });
+ };
+
+ handleChooseType = (metric: string) => {
+ this.setState({ metric });
+ };
+
+ render() {
+ const { header, metrics, onClose } = this.props;
+ const { submitting } = this.state;
+ return (
+ <Modal contentLabel={header} onRequestClose={onClose}>
+ <form onSubmit={this.handleFormSubmit}>
+ <div className="modal-head">
+ <h2>{header}</h2>
+ </div>
+
+ <div className="modal-body">
+ <div className="modal-field">
+ <label htmlFor="create-user-login">
+ {translate('quality_gates.conditions.metric')}
+ </label>
+ <AddConditionSelect metrics={metrics} onAddCondition={this.handleChooseType} />
+ </div>
+ <div className="modal-field">
+ <label htmlFor="create-user-login">
+ {translate('quality_gates.conditions.metric')}
+ </label>
+ <ConditionOperator
+ canEdit={true}
+ condition={}
+ metric={this.state.metric}
+ onOperatorChange={() => {}}
+ />
+ </div>
+ </div>
+
+ <div className="modal-foot">
+ {submitting && <i className="spinner spacer-right" />}
+ <SubmitButton disabled={submitting} id="coding-rules-custom-rule-creation-reactivate">
+ {header}
+ </SubmitButton>
+ <ResetButtonLink
+ disabled={submitting}
+ id="coding-rules-custom-rule-creation-cancel"
+ onClick={onClose}>
+ {translate('cancel')}
+ </ResetButtonLink>
+ </div>
+ </form>
+ </Modal>
+ );
+ }
+}
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
new file mode 100644
index 00000000000..55c8d3c54d1
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionOperator.tsx
@@ -0,0 +1,63 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import Select from '../../../components/controls/Select';
+import { Condition as ICondition, Metric } from '../../../app/types';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ condition: ICondition;
+ canEdit: boolean;
+ metric: Metric;
+ onOperatorChange: ({ value }: any) => void;
+}
+
+export default function ConditionOperator({ condition, canEdit, metric, onOperatorChange }: Props) {
+ if (!canEdit && condition.op) {
+ return metric.type === 'RATING' ? (
+ <span className="note">{translate('quality_gates.operator', condition.op, 'rating')}</span>
+ ) : (
+ <span className="note">{translate('quality_gates.operator', condition.op)}</span>
+ );
+ }
+
+ if (metric.type === 'RATING') {
+ return <span className="note">{translate('quality_gates.operator.GT.rating')}</span>;
+ }
+
+ const operators = ['LT', 'GT', 'EQ', 'NE'];
+ const operatorOptions = operators.map(op => {
+ const label = translate('quality_gates.operator', op);
+ return { label, value: op };
+ });
+
+ return (
+ <Select
+ autofocus={true}
+ className="input-medium"
+ clearable={false}
+ name="operator"
+ onChange={onOperatorChange}
+ options={operatorOptions}
+ searchable={false}
+ value={condition.op}
+ />
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx
index 0df36b5110f..07a9f8cc600 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx
@@ -21,6 +21,7 @@ import * as React from 'react';
import { differenceWith, map, sortBy, uniqBy } from 'lodash';
import AddConditionSelect from './AddConditionSelect';
import Condition from './Condition';
+import AddConditionButton from './AddConditionButton';
import DocTooltip from '../../../components/docs/DocTooltip';
import { translate, getLocalizedMetricName } from '../../../helpers/l10n';
import { Condition as ICondition, Metric, QualityGate } from '../../../app/types';
@@ -103,6 +104,9 @@ export default class Conditions extends React.PureComponent<Props, State> {
return (
<div className="quality-gate-section" id="quality-gate-conditions">
+ <div className="pull-right">
+ <AddConditionButton metrics={availableMetrics} />
+ </div>
<header className="display-flex-center spacer-bottom">
<h3>{translate('quality_gates.conditions')}</h3>
<DocTooltip className="spacer-left" doc="quality-gates/quality-gate-conditions" />