aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx')
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/ConditionModal.tsx190
1 files changed, 90 insertions, 100 deletions
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 e2bfb237257..91e110d823e 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
@@ -17,11 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { ButtonPrimary, FlagMessage, FormField, Modal, RadioButton } from 'design-system';
+import { ButtonPrimary, FormField, Modal, RadioButton } from 'design-system';
import * as React from 'react';
-import { createCondition, updateCondition } from '../../../api/quality-gates';
import { getLocalizedMetricName, translate } from '../../../helpers/l10n';
import { isDiffMetric } from '../../../helpers/measures';
+import {
+ useCreateConditionMutation,
+ useUpdateConditionMutation,
+} from '../../../queries/quality-gates';
import { Condition, Metric, QualityGate } from '../../../types/types';
import { getPossibleOperators } from '../utils';
import ConditionOperator from './ConditionOperator';
@@ -33,101 +36,92 @@ interface Props {
metric?: Metric;
metrics?: Metric[];
header: string;
- onAddCondition: (condition: Condition) => void;
onClose: () => void;
qualityGate: QualityGate;
}
-interface State {
- error: string;
- errorMessage?: string;
- metric?: Metric;
- op?: string;
- scope: 'new' | 'overall';
-}
-
const ADD_CONDITION_MODAL_ID = 'add-condition-modal';
-export default class ConditionModal extends React.PureComponent<Props, State> {
- constructor(props: Props) {
- super(props);
- this.state = {
- error: props.condition ? props.condition.error : '',
- scope: 'new',
- metric: props.metric ? props.metric : undefined,
- op: props.condition ? props.condition.op : undefined,
- };
- }
-
- getSinglePossibleOperator(metric: Metric) {
+export default function ConditionModal({
+ condition,
+ metric,
+ metrics,
+ header,
+ onClose,
+ qualityGate,
+}: Readonly<Props>) {
+ const [errorThreshold, setErrorThreshold] = React.useState(condition ? condition.error : '');
+ const [scope, setScope] = React.useState<'new' | 'overall'>('new');
+ const [selectedMetric, setSelectedMetric] = React.useState<Metric | undefined>(metric);
+ const [selectedOperator, setSelectedOperator] = React.useState<string | undefined>(
+ condition ? condition.op : undefined,
+ );
+ const { mutateAsync: createCondition } = useCreateConditionMutation(qualityGate.name);
+ const { mutateAsync: updateCondition } = useUpdateConditionMutation(qualityGate.name);
+
+ const getSinglePossibleOperator = (metric: Metric) => {
const operators = getPossibleOperators(metric);
return Array.isArray(operators) ? undefined : operators;
- }
+ };
- handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
+ const handleFormSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
- const { condition, qualityGate } = this.props;
- const newCondition: Omit<Condition, 'id'> = {
- metric: this.state.metric!.key,
- op: this.getSinglePossibleOperator(this.state.metric!) || this.state.op,
- error: this.state.error,
- };
- const submitPromise = condition
- ? updateCondition({ id: condition.id, ...newCondition })
- : createCondition({ gateName: qualityGate.name, ...newCondition });
- return submitPromise.then(this.props.onAddCondition).then(this.props.onClose);
+ if (selectedMetric) {
+ const newCondition: Omit<Condition, 'id'> = {
+ metric: selectedMetric.key,
+ op: getSinglePossibleOperator(selectedMetric) ?? selectedOperator,
+ error: errorThreshold,
+ };
+ const submitPromise = condition
+ ? updateCondition({ id: condition.id, ...newCondition })
+ : createCondition(newCondition);
+ await submitPromise;
+ onClose();
+ }
};
- handleScopeChange = (scope: 'new' | 'overall') => {
- this.setState(({ metric }) => {
- const { metrics } = this.props;
- let correspondingMetric;
+ const handleScopeChange = (scope: 'new' | 'overall') => {
+ let correspondingMetric;
- if (metric && metrics) {
- const correspondingMetricKey =
- scope === 'new' ? `new_${metric.key}` : metric.key.replace(/^new_/, '');
- correspondingMetric = metrics.find((m) => m.key === correspondingMetricKey);
- }
+ if (selectedMetric && metrics) {
+ const correspondingMetricKey =
+ scope === 'new' ? `new_${selectedMetric.key}` : selectedMetric.key.replace(/^new_/, '');
+ correspondingMetric = metrics.find((m) => m.key === correspondingMetricKey);
+ }
- return { scope, metric: correspondingMetric };
- });
+ setScope(scope);
+ setSelectedMetric(correspondingMetric);
};
- handleMetricChange = (metric: Metric) => {
- this.setState({ metric, op: undefined, error: '' });
+ const handleMetricChange = (metric: Metric) => {
+ setSelectedMetric(metric);
+ setSelectedOperator(undefined);
+ setErrorThreshold('');
};
- handleOperatorChange = (op: string) => {
- this.setState({ op });
+ const handleOperatorChange = (op: string) => {
+ setSelectedOperator(op);
};
- handleErrorChange = (error: string) => {
- this.setState({ error });
+ const handleErrorChange = (error: string) => {
+ setErrorThreshold(error);
};
- renderBody = () => {
- const { metrics } = this.props;
- const { op, error, scope, metric, errorMessage } = this.state;
-
+ const renderBody = () => {
return (
- <form id={ADD_CONDITION_MODAL_ID} onSubmit={this.handleFormSubmit}>
- {errorMessage && (
- <FlagMessage className="sw-mb-2" variant="error">
- {errorMessage}
- </FlagMessage>
- )}
- {this.props.metric === undefined && (
+ <form id={ADD_CONDITION_MODAL_ID} onSubmit={handleFormSubmit}>
+ {metric === undefined && (
<FormField label={translate('quality_gates.conditions.where')}>
<div className="sw-flex sw-gap-4">
- <RadioButton checked={scope === 'new'} onCheck={this.handleScopeChange} value="new">
+ <RadioButton checked={scope === 'new'} onCheck={handleScopeChange} value="new">
<span data-test="quality-gates__condition-scope-new">
{translate('quality_gates.conditions.new_code')}
</span>
</RadioButton>
<RadioButton
checked={scope === 'overall'}
- onCheck={this.handleScopeChange}
+ onCheck={handleScopeChange}
value="overall"
>
<span data-test="quality-gates__condition-scope-overall">
@@ -139,22 +133,22 @@ export default class ConditionModal extends React.PureComponent<Props, State> {
)}
<FormField
- description={this.props.metric && getLocalizedMetricName(this.props.metric)}
+ description={metric && getLocalizedMetricName(metric)}
htmlFor="condition-metric"
label={translate('quality_gates.conditions.fails_when')}
>
{metrics && (
<MetricSelect
- metric={metric}
+ metric={selectedMetric}
metricsArray={metrics.filter((m) =>
scope === 'new' ? isDiffMetric(m.key) : !isDiffMetric(m.key),
)}
- onMetricChange={this.handleMetricChange}
+ onMetricChange={handleMetricChange}
/>
)}
</FormField>
- {metric && (
+ {selectedMetric && (
<div className="sw-flex sw-gap-2">
<FormField
className="sw-mb-0"
@@ -162,9 +156,9 @@ export default class ConditionModal extends React.PureComponent<Props, State> {
label={translate('quality_gates.conditions.operator')}
>
<ConditionOperator
- metric={metric}
- onOperatorChange={this.handleOperatorChange}
- op={op}
+ metric={selectedMetric}
+ onOperatorChange={handleOperatorChange}
+ op={selectedOperator}
/>
</FormField>
<FormField
@@ -172,10 +166,10 @@ export default class ConditionModal extends React.PureComponent<Props, State> {
label={translate('quality_gates.conditions.value')}
>
<ThresholdInput
- metric={metric}
+ metric={selectedMetric}
name="error"
- onChange={this.handleErrorChange}
- value={error}
+ onChange={handleErrorChange}
+ value={errorThreshold}
/>
</FormField>
</div>
@@ -184,29 +178,25 @@ export default class ConditionModal extends React.PureComponent<Props, State> {
);
};
- render() {
- const { header } = this.props;
- const { metric } = this.state;
- return (
- <Modal
- isScrollable={false}
- isOverflowVisible
- headerTitle={header}
- onClose={this.props.onClose}
- body={this.renderBody()}
- primaryButton={
- <ButtonPrimary
- autoFocus
- disabled={metric === undefined}
- id="add-condition-button"
- form={ADD_CONDITION_MODAL_ID}
- type="submit"
- >
- {header}
- </ButtonPrimary>
- }
- secondaryButtonLabel={translate('close')}
- />
- );
- }
+ return (
+ <Modal
+ isScrollable={false}
+ isOverflowVisible
+ headerTitle={header}
+ onClose={onClose}
+ body={renderBody()}
+ primaryButton={
+ <ButtonPrimary
+ autoFocus
+ disabled={selectedMetric === undefined}
+ id="add-condition-button"
+ form={ADD_CONDITION_MODAL_ID}
+ type="submit"
+ >
+ {header}
+ </ButtonPrimary>
+ }
+ secondaryButtonLabel={translate('close')}
+ />
+ );
}