aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-11-30 17:22:26 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-12-14 17:03:35 +0100
commit762ed740328cab541c17af9a64ae933be407c65f (patch)
tree9899366667f8a5e53b95be07a9f2d49da22f0920 /server/sonar-web/src/main/js
parentc37f8a7202925bec2d9a27961ea10f125c259c91 (diff)
downloadsonarqube-762ed740328cab541c17af9a64ae933be407c65f.tar.gz
sonarqube-762ed740328cab541c17af9a64ae933be407c65f.zip
SONAR-10151 Pass organization parameter in all quality gates ws
Diffstat (limited to 'server/sonar-web/src/main/js')
-rw-r--r--server/sonar-web/src/main/js/api/quality-gates.ts98
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/App.js3
-rw-r--r--server/sonar-web/src/main/js/apps/overview/qualityGate/ApplicationQualityGate.js8
-rw-r--r--server/sonar-web/src/main/js/apps/overview/types.js3
-rw-r--r--server/sonar-web/src/main/js/apps/projectQualityGate/App.tsx21
-rw-r--r--server/sonar-web/src/main/js/apps/projectQualityGate/Form.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/App-test.tsx36
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx (renamed from server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js)144
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js4
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx100
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Details.js11
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js9
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx8
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js5
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js23
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.tsx (renamed from server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js)33
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx (renamed from server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js)18
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/store/actions.js2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js2
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/templates/quality-gates-condition-delete.hbs13
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js54
-rw-r--r--server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js14
24 files changed, 372 insertions, 247 deletions
diff --git a/server/sonar-web/src/main/js/api/quality-gates.ts b/server/sonar-web/src/main/js/api/quality-gates.ts
index 90b03cbe338..93fd2fd6e07 100644
--- a/server/sonar-web/src/main/js/api/quality-gates.ts
+++ b/server/sonar-web/src/main/js/api/quality-gates.ts
@@ -17,16 +17,19 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { getJSON, post, postJSON, RequestData } from '../helpers/request';
+import { getJSON, post, postJSON } from '../helpers/request';
import throwGlobalError from '../app/utils/throwGlobalError';
-interface Condition {
- error?: string;
- id: number;
+export interface ConditionBase {
+ error: string;
metric: string;
- op: string;
+ op?: string;
period?: number;
- warning?: string;
+ warning: string;
+}
+
+export interface Condition extends ConditionBase {
+ id: number;
}
export interface QualityGate {
@@ -45,15 +48,20 @@ export interface QualityGate {
name: string;
}
-export function fetchQualityGates(): Promise<{
+export function fetchQualityGates(data: {
+ organization?: string;
+}): Promise<{
actions: { create: boolean };
qualitygates: QualityGate[];
}> {
- return getJSON('/api/qualitygates/list').catch(throwGlobalError);
+ return getJSON('/api/qualitygates/list', data).catch(throwGlobalError);
}
-export function fetchQualityGate(id: number): Promise<QualityGate> {
- return getJSON('/api/qualitygates/show', { id }).catch(throwGlobalError);
+export function fetchQualityGate(data: {
+ id: number;
+ organization?: string;
+}): Promise<QualityGate> {
+ return getJSON('/api/qualitygates/show', data).catch(throwGlobalError);
}
export function createQualityGate(data: {
@@ -63,8 +71,11 @@ export function createQualityGate(data: {
return postJSON('/api/qualitygates/create', data).catch(throwGlobalError);
}
-export function deleteQualityGate(id: number): Promise<void> {
- return post('/api/qualitygates/destroy', { id });
+export function deleteQualityGate(data: {
+ id: number;
+ organization?: string;
+}): Promise<void | Response> {
+ return post('/api/qualitygates/destroy', data).catch(throwGlobalError);
}
export function renameQualityGate(data: {
@@ -83,46 +94,63 @@ export function copyQualityGate(data: {
return postJSON('/api/qualitygates/copy', data).catch(throwGlobalError);
}
-export function setQualityGateAsDefault(id: number): Promise<void | Response> {
- return post('/api/qualitygates/set_as_default', { id }).catch(throwGlobalError);
+export function setQualityGateAsDefault(data: {
+ id: number;
+ organization?: string;
+}): Promise<void | Response> {
+ return post('/api/qualitygates/set_as_default', data).catch(throwGlobalError);
}
-export function createCondition(gateId: number, condition: RequestData): Promise<any> {
- return postJSON('/api/qualitygates/create_condition', { ...condition, gateId });
+export function createCondition(
+ data: {
+ gateId: number;
+ organization?: string;
+ } & ConditionBase
+): Promise<Condition> {
+ return postJSON('/api/qualitygates/create_condition', data);
}
-export function updateCondition(condition: RequestData): Promise<any> {
- return postJSON('/api/qualitygates/update_condition', condition);
+export function updateCondition(data: { organization?: string } & Condition): Promise<Condition> {
+ return postJSON('/api/qualitygates/update_condition', data);
}
-export function deleteCondition(id: number): Promise<void> {
- return post('/api/qualitygates/delete_condition', { id });
+export function deleteCondition(data: { id: number; organization?: string }): Promise<void> {
+ return post('/api/qualitygates/delete_condition', data);
}
-export function getGateForProject(project: string): Promise<QualityGate | undefined> {
- return getJSON('/api/qualitygates/get_by_project', { project }).then(
+export function getGateForProject(data: {
+ organization?: string;
+ project: string;
+}): Promise<QualityGate | undefined> {
+ return getJSON('/api/qualitygates/get_by_project', data).then(
({ qualityGate }) =>
qualityGate && {
...qualityGate,
isDefault: qualityGate.default
- }
+ },
+ throwGlobalError
);
}
-export function associateGateWithProject(
- gateId: number,
- projectKey: string
-): Promise<void | Response> {
- return post('/api/qualitygates/select', { gateId, projectKey }).catch(throwGlobalError);
+export function associateGateWithProject(data: {
+ gateId: number;
+ organization?: string;
+ projectKey: string;
+}): Promise<void | Response> {
+ return post('/api/qualitygates/select', data).catch(throwGlobalError);
}
-export function dissociateGateWithProject(
- gateId: number,
- projectKey: string
-): Promise<void | Response> {
- return post('/api/qualitygates/deselect', { gateId, projectKey }).catch(throwGlobalError);
+export function dissociateGateWithProject(data: {
+ gateId: number;
+ organization?: string;
+ projectKey: string;
+}): Promise<void | Response> {
+ return post('/api/qualitygates/deselect', data).catch(throwGlobalError);
}
-export function getApplicationQualityGate(application: string): Promise<any> {
- return getJSON('/api/qualitygates/application_status', { application });
+export function getApplicationQualityGate(data: {
+ application: string;
+ organization?: string;
+}): Promise<void | Response> {
+ return getJSON('/api/qualitygates/application_status', data).catch(throwGlobalError);
}
diff --git a/server/sonar-web/src/main/js/apps/overview/components/App.js b/server/sonar-web/src/main/js/apps/overview/components/App.js
index 8ce26596388..cab5eacead8 100644
--- a/server/sonar-web/src/main/js/apps/overview/components/App.js
+++ b/server/sonar-web/src/main/js/apps/overview/components/App.js
@@ -34,7 +34,8 @@ type Props = {
id: string,
key: string,
qualifier: string,
- tags: Array<string>
+ tags: Array<string>,
+ organization?: string
},
onComponentChange: {} => void,
router: Object
diff --git a/server/sonar-web/src/main/js/apps/overview/qualityGate/ApplicationQualityGate.js b/server/sonar-web/src/main/js/apps/overview/qualityGate/ApplicationQualityGate.js
index 8149f8963f4..92a248cec4a 100644
--- a/server/sonar-web/src/main/js/apps/overview/qualityGate/ApplicationQualityGate.js
+++ b/server/sonar-web/src/main/js/apps/overview/qualityGate/ApplicationQualityGate.js
@@ -27,7 +27,7 @@ import { translate } from '../../../helpers/l10n';
/*::
type Props = {
- component: { key: string }
+ component: { key: string, organization?: string }
};
*/
@@ -68,8 +68,12 @@ export default class ApplicationQualityGate extends React.PureComponent {
}
fetchDetails = () => {
+ const { component } = this.props;
this.setState({ loading: true });
- getApplicationQualityGate(this.props.component.key).then(
+ getApplicationQualityGate({
+ application: component.key,
+ organization: component.organization
+ }).then(
({ status, projects, metrics }) => {
if (this.mounted) {
this.setState({
diff --git a/server/sonar-web/src/main/js/apps/overview/types.js b/server/sonar-web/src/main/js/apps/overview/types.js
index bc3c77aaea7..5a5cdb5df77 100644
--- a/server/sonar-web/src/main/js/apps/overview/types.js
+++ b/server/sonar-web/src/main/js/apps/overview/types.js
@@ -23,7 +23,8 @@
export type Component = {
id: string,
key: string,
- qualifier: string
+ qualifier: string,
+ organization?: string
};
*/
diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/App.tsx b/server/sonar-web/src/main/js/apps/projectQualityGate/App.tsx
index 95b899a9aa3..5297b4ecbe4 100644
--- a/server/sonar-web/src/main/js/apps/projectQualityGate/App.tsx
+++ b/server/sonar-web/src/main/js/apps/projectQualityGate/App.tsx
@@ -35,6 +35,7 @@ import { translate } from '../../helpers/l10n';
interface Props {
component: Component;
+ onComponentChange: (changes: {}) => void;
}
interface State {
@@ -67,8 +68,12 @@ export default class App extends React.PureComponent<Props> {
}
fetchQualityGates() {
+ const { component } = this.props;
this.setState({ loading: true });
- Promise.all([fetchQualityGates(), getGateForProject(this.props.component.key)]).then(
+ Promise.all([
+ fetchQualityGates({ organization: component.organization }),
+ getGateForProject({ organization: component.organization, project: component.key })
+ ]).then(
([{ qualitygates: allGates }, gate]) => {
if (this.mounted) {
this.setState({ allGates, gate, loading: false });
@@ -82,16 +87,21 @@ export default class App extends React.PureComponent<Props> {
);
}
- handleChangeGate = (oldId: number | undefined, newId: number | undefined) => {
+ handleChangeGate = (oldId?: number, newId?: number) => {
const { allGates } = this.state;
-
if ((!oldId && !newId) || !allGates) {
return Promise.resolve();
}
+ const { component } = this.props;
+ const requestData = {
+ gateId: newId ? newId : oldId!,
+ organization: component.organization,
+ projectKey: component.key
+ };
const request = newId
- ? associateGateWithProject(newId, this.props.component.key)
- : dissociateGateWithProject(oldId!, this.props.component.key);
+ ? associateGateWithProject(requestData)
+ : dissociateGateWithProject(requestData);
return request.then(() => {
if (this.mounted) {
@@ -100,6 +110,7 @@ export default class App extends React.PureComponent<Props> {
const newGate = allGates.find(gate => gate.id === newId);
if (newGate) {
this.setState({ gate: newGate });
+ this.props.onComponentChange({ qualityGate: newGate });
}
} else {
this.setState({ gate: undefined });
diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/Form.tsx b/server/sonar-web/src/main/js/apps/projectQualityGate/Form.tsx
index 909767bfed9..8b762e76f19 100644
--- a/server/sonar-web/src/main/js/apps/projectQualityGate/Form.tsx
+++ b/server/sonar-web/src/main/js/apps/projectQualityGate/Form.tsx
@@ -25,7 +25,7 @@ import { translate } from '../../helpers/l10n';
interface Props {
allGates: QualityGate[];
gate?: QualityGate;
- onChange: (oldGate: number | undefined, newGate: number) => Promise<void>;
+ onChange: (oldGate?: number, newGate?: number) => Promise<void>;
}
interface State {
diff --git a/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/App-test.tsx
index d04a0ee2f6e..2252afd252e 100644
--- a/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/App-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projectQualityGate/__tests__/App-test.tsx
@@ -72,16 +72,18 @@ beforeEach(() => {
it('checks permissions', () => {
handleRequiredAuthorization.mockClear();
- mount(<App component={{ ...component, configuration: undefined }} />);
+ mount(
+ <App component={{ ...component, configuration: undefined }} onComponentChange={jest.fn()} />
+ );
expect(handleRequiredAuthorization).toBeCalled();
});
it('fetches quality gates', () => {
fetchQualityGates.mockClear();
getGateForProject.mockClear();
- mount(<App component={component} />);
- expect(fetchQualityGates).toBeCalledWith();
- expect(getGateForProject).toBeCalledWith('component');
+ mount(<App component={component} onComponentChange={jest.fn()} />);
+ expect(fetchQualityGates).toBeCalledWith({ organization: 'org' });
+ expect(getGateForProject).toBeCalledWith({ organization: 'org', project: 'component' });
});
it('changes quality gate from custom to default', () => {
@@ -89,28 +91,44 @@ it('changes quality gate from custom to default', () => {
const allGates = [gate, randomGate('bar', true), randomGate('baz')];
const wrapper = mountRender(allGates, gate);
wrapper.find('Form').prop<Function>('onChange')('foo', 'bar');
- expect(associateGateWithProject).toBeCalledWith('bar', 'component');
+ expect(associateGateWithProject).toBeCalledWith({
+ gateId: 'bar',
+ organization: 'org',
+ projectKey: 'component'
+ });
});
it('changes quality gate from custom to custom', () => {
const allGates = [randomGate('foo'), randomGate('bar', true), randomGate('baz')];
const wrapper = mountRender(allGates, randomGate('foo'));
wrapper.find('Form').prop<Function>('onChange')('foo', 'baz');
- expect(associateGateWithProject).toBeCalledWith('baz', 'component');
+ expect(associateGateWithProject).toBeCalledWith({
+ gateId: 'baz',
+ organization: 'org',
+ projectKey: 'component'
+ });
});
it('changes quality gate from custom to none', () => {
const allGates = [randomGate('foo'), randomGate('bar'), randomGate('baz')];
const wrapper = mountRender(allGates, randomGate('foo'));
wrapper.find('Form').prop<Function>('onChange')('foo', undefined);
- expect(dissociateGateWithProject).toBeCalledWith('foo', 'component');
+ expect(dissociateGateWithProject).toBeCalledWith({
+ gateId: 'foo',
+ organization: 'org',
+ projectKey: 'component'
+ });
});
it('changes quality gate from none to custom', () => {
const allGates = [randomGate('foo'), randomGate('bar'), randomGate('baz')];
const wrapper = mountRender(allGates);
wrapper.find('Form').prop<Function>('onChange')(undefined, 'baz');
- expect(associateGateWithProject).toBeCalledWith('baz', 'component');
+ expect(associateGateWithProject).toBeCalledWith({
+ gateId: 'baz',
+ organization: 'org',
+ projectKey: 'component'
+ });
});
function randomGate(id: string, isDefault = false) {
@@ -118,7 +136,7 @@ function randomGate(id: string, isDefault = false) {
}
function mountRender(allGates: any[], gate?: any) {
- const wrapper = mount(<App component={component} />);
+ const wrapper = mount(<App component={component} onComponentChange={jest.fn()} />);
wrapper.setState({ allGates, loading: false, gate });
return wrapper;
}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx
index 5907e9d5770..7496c7cefe1 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx
@@ -36,8 +36,10 @@ export default function BuiltInQualityGateBadge({ className, tooltip = true }: P
const overlay = (
<div>
- <p>{translate('quality_gates.built_in.description.1')}</p>
- <p>{translate('quality_gates.built_in.description.2')}</p>
+ <span>{translate('quality_gates.built_in.description.1')}</span>
+ <span className="little-spacer-left">
+ {translate('quality_gates.built_in.description.2')}
+ </span>
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx
index c66890153f3..741a7b2efd0 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Condition.tsx
@@ -17,54 +17,71 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React, { Component } from 'react';
-import ThresholdInput from './ThresholdInput';
-import DeleteConditionView from '../views/gate-conditions-delete-view';
+import * as React from 'react';
import Checkbox from '../../../components/controls/Checkbox';
-import { createCondition, updateCondition } from '../../../api/quality-gates';
+import DeleteConditionForm from './DeleteConditionForm';
import Select from '../../../components/controls/Select';
+import ThresholdInput from './ThresholdInput';
+import {
+ Condition as ICondition,
+ ConditionBase,
+ createCondition,
+ QualityGate,
+ updateCondition
+} from '../../../api/quality-gates';
+import { Metric } from '../../../app/types';
import { translate, getLocalizedMetricName } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';
-export default class Condition extends Component {
- constructor(props) {
+interface Props {
+ condition: ICondition;
+ edit: boolean;
+ metric: Metric;
+ organization: string;
+ onDeleteCondition: (condition: ICondition) => void;
+ onError: (error: any) => void;
+ onResetError: () => void;
+ onSaveCondition: (condition: ICondition, newCondition: ICondition) => void;
+ qualityGate: QualityGate;
+}
+
+interface State {
+ changed: boolean;
+ period?: number;
+ op?: string;
+ openDeleteCondition: boolean;
+ warning: string;
+ error: string;
+}
+
+export default class Condition extends React.PureComponent<Props, State> {
+ constructor(props: Props) {
super(props);
this.state = {
changed: false,
period: props.condition.period,
op: props.condition.op,
+ openDeleteCondition: false,
warning: props.condition.warning || '',
error: props.condition.error || ''
};
}
- componentDidMount() {
- if (!this.props.condition.id && this.operator) {
- this.operator.focus();
- }
- }
+ handleOperatorChange = ({ value }: any) => this.setState({ changed: true, op: value });
- handleOperatorChange = ({ value }) => {
- this.setState({ changed: true, op: value });
- };
-
- handlePeriodChange = checked => {
- const period = checked ? '1' : undefined;
+ handlePeriodChange = (checked: boolean) => {
+ const period = checked ? 1 : undefined;
this.setState({ changed: true, period });
};
- handleWarningChange = value => {
- this.setState({ changed: true, warning: value });
- };
+ handleWarningChange = (warning: string) => this.setState({ changed: true, warning });
- handleErrorChange = value => {
- this.setState({ changed: true, error: value });
- };
+ handleErrorChange = (error: string) => this.setState({ changed: true, error });
- handleSaveClick = e => {
- const { qualityGate, condition, metric, onSaveCondition, onError, onResetError } = this.props;
+ handleSaveClick = () => {
+ const { qualityGate, condition, metric, organization } = this.props;
const { period } = this.state;
- const data = {
+ const data: ConditionBase = {
metric: condition.metric,
op: metric.type === 'RATING' ? 'GT' : this.state.op,
warning: this.state.warning,
@@ -76,23 +93,19 @@ export default class Condition extends Component {
}
if (metric.key.indexOf('new_') === 0) {
- data.period = '1';
+ data.period = 1;
}
- e.preventDefault();
- createCondition(qualityGate.id, data)
- .then(newCondition => {
- this.setState({ changed: false });
- onSaveCondition(condition, newCondition);
- onResetError();
- })
- .catch(onError);
+ createCondition({ gateId: qualityGate.id, organization, ...data }).then(
+ this.handleConditionResponse,
+ this.props.onError
+ );
};
- handleUpdateClick = e => {
- const { condition, onSaveCondition, metric, onError, onResetError } = this.props;
+ handleUpdateClick = () => {
+ const { condition, metric, organization } = this.props;
const { period } = this.state;
- const data = {
+ const data: ICondition = {
id: condition.id,
metric: condition.metric,
op: metric.type === 'RATING' ? 'GT' : this.state.op,
@@ -105,38 +118,30 @@ export default class Condition extends Component {
}
if (metric.key.indexOf('new_') === 0) {
- data.period = '1';
+ data.period = 1;
}
- e.preventDefault();
- updateCondition(data)
- .then(newCondition => {
- this.setState({ changed: false });
- onSaveCondition(condition, newCondition);
- onResetError();
- })
- .catch(onError);
+ updateCondition({ organization, ...data }).then(
+ this.handleConditionResponse,
+ this.props.onError
+ );
};
- handleDeleteClick = e => {
- const { qualityGate, condition, metric, onDeleteCondition } = this.props;
-
- e.preventDefault();
- new DeleteConditionView({
- qualityGate,
- condition,
- metric,
- onDelete: () => onDeleteCondition(condition)
- }).render();
+ handleConditionResponse = (newCondition: ICondition) => {
+ this.setState({ changed: false });
+ this.props.onSaveCondition(this.props.condition, newCondition);
+ this.props.onResetError();
};
- handleCancelClick = e => {
- const { condition, onDeleteCondition } = this.props;
-
+ handleCancelClick = (e: React.SyntheticEvent<HTMLAnchorElement>) => {
e.preventDefault();
- onDeleteCondition(condition);
+ e.stopPropagation();
+ this.props.onDeleteCondition(this.props.condition);
};
+ openDeleteConditionForm = () => this.setState({ openDeleteCondition: true });
+ closeDeleteConditionForm = () => this.setState({ openDeleteCondition: false });
+
renderPeriodValue() {
const { condition, metric } = this.props;
const isLeakSelected = !!this.state.period;
@@ -175,7 +180,7 @@ export default class Condition extends Component {
renderOperator() {
const { condition, edit, metric } = this.props;
- if (!edit) {
+ if (!edit && condition.op) {
return metric.type === 'RATING'
? translate('quality_gates.operator', condition.op, 'rating')
: translate('quality_gates.operator', condition.op);
@@ -193,9 +198,9 @@ export default class Condition extends Component {
return (
<Select
+ autofocus={true}
className="input-medium"
clearable={false}
- innerRef={node => (this.operator = node)}
name="operator"
onChange={this.handleOperatorChange}
options={operatorOptions}
@@ -206,7 +211,7 @@ export default class Condition extends Component {
}
render() {
- const { condition, edit, metric } = this.props;
+ const { condition, edit, metric, organization } = this.props;
return (
<tr>
<td className="text-middle">
@@ -258,9 +263,18 @@ export default class Condition extends Component {
</button>
<button
className="button-red delete-condition little-spacer-left"
- onClick={this.handleDeleteClick}>
+ onClick={this.openDeleteConditionForm}>
{translate('delete')}
</button>
+ {this.state.openDeleteCondition && (
+ <DeleteConditionForm
+ condition={condition}
+ metric={metric}
+ onClose={this.closeDeleteConditionForm}
+ onDelete={this.props.onDeleteCondition}
+ organization={organization}
+ />
+ )}
</div>
) : (
<div>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
index 7986f5a1816..547543cb215 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.js
@@ -62,7 +62,8 @@ export default class Conditions extends React.PureComponent {
edit,
onAddCondition,
onSaveCondition,
- onDeleteCondition
+ onDeleteCondition,
+ organization
} = this.props;
const existingConditions = conditions.filter(condition => metrics[condition.metric]);
@@ -130,6 +131,7 @@ export default class Conditions extends React.PureComponent {
onDeleteCondition={onDeleteCondition}
onError={this.handleError.bind(this)}
onResetError={this.handleResetError.bind(this)}
+ organization={organization}
/>
))}
</tbody>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx
new file mode 100644
index 00000000000..c4d1ea5fcfa
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx
@@ -0,0 +1,100 @@
+/*
+* SonarQube
+* Copyright (C) 2009-2017 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 Modal from '../../../components/controls/Modal';
+import { Metric } from '../../../app/types';
+import { Condition, deleteCondition } from '../../../api/quality-gates';
+import { getLocalizedMetricName, translate, translateWithParameters } from '../../../helpers/l10n';
+
+interface Props {
+ condition: Condition;
+ metric: Metric;
+ onClose: () => void;
+ onDelete: (condition: Condition) => void;
+ organization?: string;
+}
+
+interface State {
+ loading: boolean;
+}
+
+export default class DeleteConditionForm extends React.PureComponent<Props, State> {
+ mounted: boolean;
+ state: State = { loading: false };
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ handleCancelClick = (event: React.SyntheticEvent<HTMLElement>) => {
+ event.preventDefault();
+ this.props.onClose();
+ };
+
+ handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
+ event.preventDefault();
+ const { organization, condition } = this.props;
+ this.setState({ loading: true });
+ deleteCondition({ id: condition.id, organization }).then(
+ () => this.props.onDelete(condition),
+ () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ }
+ );
+ };
+
+ render() {
+ const { metric } = this.props;
+ const header = translate('quality_gates.delete_condition');
+
+ return (
+ <Modal contentLabel={header} onRequestClose={this.props.onClose}>
+ <form id="delete-profile-form" onSubmit={this.handleFormSubmit}>
+ <div className="modal-head">
+ <h2>{header}</h2>
+ </div>
+ <div className="modal-body">
+ <p>
+ {translateWithParameters(
+ 'quality_gates.delete_condition.confirm.message',
+ getLocalizedMetricName(metric)
+ )}
+ </p>
+ </div>
+ <div className="modal-foot">
+ {this.state.loading && <i className="spinner spacer-right" />}
+ <button className="js-delete button-red" disabled={this.state.loading}>
+ {translate('delete')}
+ </button>
+ <a href="#" className="js-modal-close" onClick={this.handleCancelClick}>
+ {translate('cancel')}
+ </a>
+ </div>
+ </form>
+ </Modal>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx
index ab80d7e9df9..6bb533c415c 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DeleteQualityGateForm.tsx
@@ -62,7 +62,7 @@ export default class DeleteQualityGateForm extends React.PureComponent<Props, St
event.preventDefault();
const { organization, qualityGate } = this.props;
this.setState({ loading: true });
- deleteQualityGate(qualityGate.id).then(
+ deleteQualityGate({ id: qualityGate.id, organization }).then(
() => {
this.props.onDelete(qualityGate);
this.context.router.replace(getQualityGatesUrl(organization));
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js
index b6ff64b5c87..a231079b6a2 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Details.js
@@ -20,7 +20,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import Helmet from 'react-helmet';
-import { fetchQualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
+import { fetchQualityGate } from '../../../api/quality-gates';
import DetailsHeader from './DetailsHeader';
import DetailsContent from './DetailsContent';
@@ -41,10 +41,10 @@ export default class Details extends React.PureComponent {
}
fetchDetails = () =>
- fetchQualityGate(this.props.params.id).then(
- qualityGate => this.props.onShow(qualityGate),
- () => {}
- );
+ fetchQualityGate({
+ id: this.props.params.id,
+ organization: this.props.organization && this.props.organization.key
+ }).then(qualityGate => this.props.onShow(qualityGate), () => {});
render() {
const { organization, metrics, qualityGate } = this.props;
@@ -72,6 +72,7 @@ export default class Details extends React.PureComponent {
onAddCondition={onAddCondition}
onSaveCondition={onSaveCondition}
onDeleteCondition={onDeleteCondition}
+ organization={organization && organization.key}
/>
</div>
);
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
index 0489459a58c..8a424be367e 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsContent.js
@@ -24,7 +24,7 @@ import { translate } from '../../../helpers/l10n';
export default class DetailsContent extends React.PureComponent {
render() {
- const { gate, metrics } = this.props;
+ const { gate, metrics, organization } = this.props;
const { onAddCondition, onDeleteCondition, onSaveCondition } = this.props;
const conditions = gate.conditions || [];
const actions = gate.actions || {};
@@ -43,6 +43,7 @@ export default class DetailsContent extends React.PureComponent {
onAddCondition={onAddCondition}
onSaveCondition={onSaveCondition}
onDeleteCondition={onDeleteCondition}
+ organization={organization}
/>
<div id="quality-gate-projects" className="quality-gate-section">
@@ -50,7 +51,11 @@ export default class DetailsContent extends React.PureComponent {
{gate.isDefault ? (
defaultMessage
) : (
- <Projects qualityGate={gate} edit={actions.associateProjects} />
+ <Projects
+ qualityGate={gate}
+ edit={actions.associateProjects}
+ organization={organization}
+ />
)}
</div>
</div>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
index aa3d836b237..f781cc253b8 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
@@ -22,7 +22,7 @@ import BuiltInQualityGateBadge from './BuiltInQualityGateBadge';
import RenameQualityGateForm from './RenameQualityGateForm';
import CopyQualityGateForm from './CopyQualityGateForm';
import DeleteQualityGateForm from './DeleteQualityGateForm';
-import { QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
+import { fetchQualityGate, QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
import { translate } from '../../../helpers/l10n';
interface Props {
@@ -53,9 +53,11 @@ export default class DetailsHeader extends React.PureComponent<Props, State> {
handleSetAsDefaultClick = (e: React.SyntheticEvent<HTMLButtonElement>) => {
e.preventDefault();
- const { qualityGate, onSetAsDefault } = this.props;
+ const { qualityGate, onSetAsDefault, organization } = this.props;
if (!qualityGate.isDefault) {
- setQualityGateAsDefault(qualityGate.id).then(() => onSetAsDefault(qualityGate), () => {});
+ setQualityGateAsDefault({ id: qualityGate.id, organization })
+ .then(() => fetchQualityGate({ id: qualityGate.id, organization }))
+ .then(qualityGate => onSetAsDefault(qualityGate), () => {});
}
};
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
index 33a9c447d13..344bf1e2881 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/Projects.js
@@ -44,12 +44,13 @@ export default class Projects extends React.PureComponent {
}
renderView() {
- const { qualityGate, edit } = this.props;
+ const { qualityGate, edit, organization } = this.props;
this.projectsView = new ProjectsView({
qualityGate,
edit,
- container: this.refs.container
+ container: this.refs.container,
+ organization
});
this.projectsView.render();
}
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js
index 96c3ed76f9a..0ec8d28794d 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/QualityGatesApp.js
@@ -51,15 +51,20 @@ export default class QualityGatesApp extends Component {
}
fetchQualityGates = () =>
- fetchQualityGates().then(({ actions, qualitygates: qualityGates }) => {
- const { organization, updateStore } = this.props;
- updateStore({ actions, qualityGates });
- if (qualityGates && qualityGates.length === 1 && !actions.create) {
- this.context.router.replace(
- getQualityGateUrl(String(qualityGates[0].id), organization && organization.key)
- );
- }
- });
+ fetchQualityGates({
+ organization: this.props.organization && this.props.organization.key
+ }).then(
+ ({ actions, qualitygates: qualityGates }) => {
+ const { organization, updateStore } = this.props;
+ updateStore({ actions, qualityGates });
+ if (qualityGates && qualityGates.length === 1 && !actions.create) {
+ this.context.router.replace(
+ getQualityGateUrl(String(qualityGates[0].id), organization && organization.key)
+ );
+ }
+ },
+ () => {}
+ );
render() {
const { children, qualityGates, actions, organization } = this.props;
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js b/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.tsx
index b00a7e8419f..cf60765a6f3 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/ThresholdInput.tsx
@@ -17,23 +17,23 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React from 'react';
-import PropTypes from 'prop-types';
+import * as React from 'react';
import Select from '../../../components/controls/Select';
+import { Metric } from '../../../app/types';
-export default class ThresholdInput extends React.PureComponent {
- static propTypes = {
- name: PropTypes.string.isRequired,
- value: PropTypes.any,
- metric: PropTypes.object.isRequired,
- onChange: PropTypes.func.isRequired
- };
+interface Props {
+ name: string;
+ value: string;
+ metric: Metric;
+ onChange: (value: string) => void;
+}
- handleChange = e => {
- this.props.onChange(e.target.value);
+export default class ThresholdInput extends React.PureComponent<Props> {
+ handleChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
+ this.props.onChange(e.currentTarget.value);
};
- handleSelectChange = option => {
+ handleSelectChange = (option: any) => {
if (option) {
this.props.onChange(option.value);
} else {
@@ -51,17 +51,15 @@ export default class ThresholdInput extends React.PureComponent {
{ label: 'D', value: '4' }
];
- const realValue = value === '' ? null : value;
-
return (
<Select
className="input-tiny text-middle"
name={name}
- value={realValue}
+ onChange={this.handleSelectChange}
options={options}
- searchable={false}
placeholder=""
- onChange={this.handleSelectChange}
+ searchable={false}
+ value={value}
/>
);
}
@@ -80,7 +78,6 @@ export default class ThresholdInput extends React.PureComponent {
className="input-tiny text-middle"
value={value}
data-type={metric.type}
- placeholder={metric.placeholder}
onChange={this.handleChange}
/>
);
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx
index 32727393559..42f29a6a6a8 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.tsx
@@ -17,15 +17,16 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import React from 'react';
+import * as React from 'react';
import { shallow } from 'enzyme';
import ThresholdInput from '../ThresholdInput';
import { change } from '../../../../helpers/testUtils';
describe('on strings', () => {
+ const metric = { key: 'foo', name: 'Foo', type: 'INTEGER' };
it('should render text input', () => {
const input = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'INTEGER' }} onChange={jest.fn()} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={jest.fn()} />
).find('input');
expect(input.length).toEqual(1);
expect(input.prop('name')).toEqual('foo');
@@ -35,7 +36,7 @@ describe('on strings', () => {
it('should change', () => {
const onChange = jest.fn();
const input = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'INTEGER' }} onChange={onChange} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={onChange} />
).find('input');
change(input, 'bar');
expect(onChange).toBeCalledWith('bar');
@@ -43,9 +44,10 @@ describe('on strings', () => {
});
describe('on ratings', () => {
+ const metric = { key: 'foo', name: 'Foo', type: 'RATING' };
it('should render Select', () => {
const select = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={jest.fn()} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={jest.fn()} />
).find('Select');
expect(select.length).toEqual(1);
expect(select.prop('value')).toEqual('2');
@@ -54,18 +56,18 @@ describe('on ratings', () => {
it('should set', () => {
const onChange = jest.fn();
const select = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={onChange} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={onChange} />
).find('Select');
- select.prop('onChange')({ label: 'D', value: '4' });
+ (select.prop('onChange') as Function)({ label: 'D', value: '4' });
expect(onChange).toBeCalledWith('4');
});
it('should unset', () => {
const onChange = jest.fn();
const select = shallow(
- <ThresholdInput name="foo" value="2" metric={{ type: 'RATING' }} onChange={onChange} />
+ <ThresholdInput name="foo" value="2" metric={metric} onChange={onChange} />
).find('Select');
- select.prop('onChange')(null);
+ (select.prop('onChange') as Function)(null);
expect(onChange).toBeCalledWith('');
});
});
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js b/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js
index ad94c833969..e8b688273b2 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/store/actions.js
@@ -66,7 +66,7 @@ export function copyQualityGate(qualityGate) {
};
}
-export const SET_AS_DEFAULT = 'SET_AS_DEFAULT';
+export const SET_AS_DEFAULT = 'qualityGates/SET_AS_DEFAULT';
export function setQualityGateAsDefault(qualityGate) {
return {
type: SET_AS_DEFAULT,
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js b/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js
index 56078fc6518..b63d134e2ac 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/store/rootReducer.js
@@ -70,7 +70,7 @@ export default function rootReducer(state = initialState, action = {}) {
return { ...candidate, isDefault: candidate.id === action.qualityGate.id };
}),
qualityGate: {
- ...state.qualityGate,
+ ...action.qualityGate,
isDefault: state.qualityGate.id === action.qualityGate.id
}
};
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/templates/quality-gates-condition-delete.hbs b/server/sonar-web/src/main/js/apps/quality-gates/templates/quality-gates-condition-delete.hbs
deleted file mode 100644
index 5ca1ac2944c..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-gates/templates/quality-gates-condition-delete.hbs
+++ /dev/null
@@ -1,13 +0,0 @@
-<form id="delete-condition-form">
- <div class="modal-head">
- <h2>{{t 'quality_gates.delete_condition'}}</h2>
- </div>
- <div class="modal-body">
- <div class="js-modal-messages"></div>
- {{tp 'quality_gates.delete_condition.confirm.message' localizedMetricName}}
- </div>
- <div class="modal-foot">
- <button id="delete-condition-submit">{{t 'delete'}}</button>
- <a href="#" class="js-modal-close" id="delete-condition-cancel">{{t 'cancel'}}</a>
- </div>
-</form>
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js
deleted file mode 100644
index f9f01acf285..00000000000
--- a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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 ModalForm from '../../../components/common/modal-form';
-import Template from '../templates/quality-gates-condition-delete.hbs';
-import { deleteCondition } from '../../../api/quality-gates';
-import { getLocalizedMetricName } from '../../../helpers/l10n';
-import { parseError } from '../../../helpers/request';
-
-export default ModalForm.extend({
- template: Template,
-
- onFormSubmit() {
- ModalForm.prototype.onFormSubmit.apply(this, arguments);
- this.disableForm();
- this.sendRequest();
- },
-
- sendRequest() {
- return deleteCondition(this.options.condition.id).then(
- () => {
- this.destroy();
- this.options.onDelete();
- },
- error => {
- this.enableForm();
- parseError(error).then(msg => this.showErrors([{ msg }]));
- }
- );
- },
-
- serializeData() {
- return {
- metric: this.options.metric,
- localizedMetricName: getLocalizedMetricName(this.options.metric)
- };
- }
-});
diff --git a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js
index 1b54745a857..6c648020b99 100644
--- a/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js
+++ b/server/sonar-web/src/main/js/apps/quality-gates/views/gate-projects-view.js
@@ -25,18 +25,16 @@ import { translate } from '../../../helpers/l10n';
export default Marionette.ItemView.extend({
template: () => {},
- initialize(options) {
- this.organization = options.organization;
- },
-
onRender() {
- const { qualityGate } = this.options;
+ const { qualityGate, organization } = this.options;
const extra = {
gateId: qualityGate.id
};
- if (this.organization) {
- extra.organization = this.organization.key;
+ let orgQuery = '';
+ if (organization) {
+ extra.organization = organization;
+ orgQuery = '&organization=' + organization;
}
new SelectList({
@@ -47,7 +45,7 @@ export default Marionette.ItemView.extend({
dangerouslyUnescapedHtmlFormat(item) {
return escapeHtml(item.name);
},
- searchUrl: window.baseUrl + '/api/qualitygates/search?gateId=' + qualityGate.id,
+ searchUrl: `${window.baseUrl}/api/qualitygates/search?gateId=${qualityGate.id}${orgQuery}`,
selectUrl: window.baseUrl + '/api/qualitygates/select',
deselectUrl: window.baseUrl + '/api/qualitygates/deselect',
extra,