From 762ed740328cab541c17af9a64ae933be407c65f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Thu, 30 Nov 2017 17:22:26 +0100 Subject: [PATCH] SONAR-10151 Pass organization parameter in all quality gates ws --- .../src/main/js/api/quality-gates.ts | 98 +++++++----- .../main/js/apps/overview/components/App.js | 3 +- .../qualityGate/ApplicationQualityGate.js | 8 +- .../src/main/js/apps/overview/types.js | 3 +- .../main/js/apps/projectQualityGate/App.tsx | 21 ++- .../main/js/apps/projectQualityGate/Form.tsx | 2 +- .../projectQualityGate/__tests__/App-test.tsx | 36 +++-- .../components/BuiltInQualityGateBadge.tsx | 6 +- .../{Condition.js => Condition.tsx} | 144 ++++++++++-------- .../quality-gates/components/Conditions.js | 4 +- .../components/DeleteConditionForm.tsx | 100 ++++++++++++ .../components/DeleteQualityGateForm.tsx | 2 +- .../apps/quality-gates/components/Details.js | 11 +- .../components/DetailsContent.js | 9 +- .../components/DetailsHeader.tsx | 8 +- .../apps/quality-gates/components/Projects.js | 5 +- .../components/QualityGatesApp.js | 23 +-- .../{ThresholdInput.js => ThresholdInput.tsx} | 33 ++-- ...dInput-test.js => ThresholdInput-test.tsx} | 18 ++- .../js/apps/quality-gates/store/actions.js | 2 +- .../apps/quality-gates/store/rootReducer.js | 2 +- .../quality-gates-condition-delete.hbs | 13 -- .../views/gate-conditions-delete-view.js | 54 ------- .../quality-gates/views/gate-projects-view.js | 14 +- 24 files changed, 372 insertions(+), 247 deletions(-) rename server/sonar-web/src/main/js/apps/quality-gates/components/{Condition.js => Condition.tsx} (68%) create mode 100644 server/sonar-web/src/main/js/apps/quality-gates/components/DeleteConditionForm.tsx rename server/sonar-web/src/main/js/apps/quality-gates/components/{ThresholdInput.js => ThresholdInput.tsx} (78%) rename server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/{ThresholdInput-test.js => ThresholdInput-test.tsx} (73%) delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/templates/quality-gates-condition-delete.hbs delete mode 100644 server/sonar-web/src/main/js/apps/quality-gates/views/gate-conditions-delete-view.js 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 { - return getJSON('/api/qualitygates/show', { id }).catch(throwGlobalError); +export function fetchQualityGate(data: { + id: number; + organization?: string; +}): Promise { + 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 { - return post('/api/qualitygates/destroy', { id }); +export function deleteQualityGate(data: { + id: number; + organization?: string; +}): Promise { + 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 { - return post('/api/qualitygates/set_as_default', { id }).catch(throwGlobalError); +export function setQualityGateAsDefault(data: { + id: number; + organization?: string; +}): Promise { + return post('/api/qualitygates/set_as_default', data).catch(throwGlobalError); } -export function createCondition(gateId: number, condition: RequestData): Promise { - return postJSON('/api/qualitygates/create_condition', { ...condition, gateId }); +export function createCondition( + data: { + gateId: number; + organization?: string; + } & ConditionBase +): Promise { + return postJSON('/api/qualitygates/create_condition', data); } -export function updateCondition(condition: RequestData): Promise { - return postJSON('/api/qualitygates/update_condition', condition); +export function updateCondition(data: { organization?: string } & Condition): Promise { + return postJSON('/api/qualitygates/update_condition', data); } -export function deleteCondition(id: number): Promise { - return post('/api/qualitygates/delete_condition', { id }); +export function deleteCondition(data: { id: number; organization?: string }): Promise { + return post('/api/qualitygates/delete_condition', data); } -export function getGateForProject(project: string): Promise { - return getJSON('/api/qualitygates/get_by_project', { project }).then( +export function getGateForProject(data: { + organization?: string; + project: string; +}): Promise { + return getJSON('/api/qualitygates/get_by_project', data).then( ({ qualityGate }) => qualityGate && { ...qualityGate, isDefault: qualityGate.default - } + }, + throwGlobalError ); } -export function associateGateWithProject( - gateId: number, - projectKey: string -): Promise { - return post('/api/qualitygates/select', { gateId, projectKey }).catch(throwGlobalError); +export function associateGateWithProject(data: { + gateId: number; + organization?: string; + projectKey: string; +}): Promise { + return post('/api/qualitygates/select', data).catch(throwGlobalError); } -export function dissociateGateWithProject( - gateId: number, - projectKey: string -): Promise { - return post('/api/qualitygates/deselect', { gateId, projectKey }).catch(throwGlobalError); +export function dissociateGateWithProject(data: { + gateId: number; + organization?: string; + projectKey: string; +}): Promise { + return post('/api/qualitygates/deselect', data).catch(throwGlobalError); } -export function getApplicationQualityGate(application: string): Promise { - return getJSON('/api/qualitygates/application_status', { application }); +export function getApplicationQualityGate(data: { + application: string; + organization?: string; +}): Promise { + 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 + tags: Array, + 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 { } 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 { ); } - 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 { 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; + onChange: (oldGate?: number, newGate?: number) => Promise; } 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(); + mount( + + ); expect(handleRequiredAuthorization).toBeCalled(); }); it('fetches quality gates', () => { fetchQualityGates.mockClear(); getGateForProject.mockClear(); - mount(); - expect(fetchQualityGates).toBeCalledWith(); - expect(getGateForProject).toBeCalledWith('component'); + mount(); + 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('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('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('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('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(); + const wrapper = mount(); 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 = (
-

{translate('quality_gates.built_in.description.1')}

-

{translate('quality_gates.built_in.description.2')}

+ {translate('quality_gates.built_in.description.1')} + + {translate('quality_gates.built_in.description.2')} +
); 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 similarity index 68% rename from server/sonar-web/src/main/js/apps/quality-gates/components/Condition.js rename to 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 { + 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) => { 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 ( ); } @@ -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 similarity index 73% rename from server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/ThresholdInput-test.js rename to 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( - + ).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( - + ).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( - + ).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( - + ).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( - + ).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 @@ -
- - - -
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, -- 2.39.5