From 0788fe0aeee44b8847a7dcd66eeaa245f4e8643a Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 19 Dec 2018 17:32:39 +0100 Subject: [PATCH] SONAR-11409 Enable rule activation from the Compare page --- .../src/main/js/api/quality-profiles.ts | 15 ++- .../components/ActivationButton.tsx | 11 -- .../components/ActivationFormModal.tsx | 1 - .../compare/ComparisonContainer.tsx | 85 ++++++-------- .../compare/ComparisonForm.tsx | 6 +- .../compare/ComparisonResultActivation.tsx | 108 ++++++++++++++++++ .../compare/ComparisonResults.tsx | 49 +++++--- .../ComparisonResultActivation-test.tsx | 45 ++++++++ .../__tests__/ComparisonResults-test.tsx | 16 ++- .../ComparisonResultActivation-test.tsx.snap | 64 +++++++++++ 10 files changed, 316 insertions(+), 84 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonResultActivation.tsx create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/ComparisonResultActivation-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/quality-profiles/compare/__tests__/__snapshots__/ComparisonResultActivation-test.tsx.snap diff --git a/server/sonar-web/src/main/js/api/quality-profiles.ts b/server/sonar-web/src/main/js/api/quality-profiles.ts index cbdabad47dd..b236bfa4910 100644 --- a/server/sonar-web/src/main/js/api/quality-profiles.ts +++ b/server/sonar-web/src/main/js/api/quality-profiles.ts @@ -161,7 +161,20 @@ export function getProfileChangelog(data: RequestData): Promise { return getJSON('/api/qualityprofiles/changelog', data); } -export function compareProfiles(leftKey: string, rightKey: string): Promise { +export interface CompareResponse { + left: { name: string }; + right: { name: string }; + inLeft: Array<{ key: string; name: string; severity: string }>; + inRight: Array<{ key: string; name: string; severity: string }>; + modified: Array<{ + key: string; + name: string; + left: { params: { [p: string]: string }; severity: string }; + right: { params: { [p: string]: string }; severity: string }; + }>; +} + +export function compareProfiles(leftKey: string, rightKey: string): Promise { return getJSON('/api/qualityprofiles/compare', { leftKey, rightKey }); } diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationButton.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationButton.tsx index be5294254e7..65daf3aff73 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationButton.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationButton.tsx @@ -31,7 +31,6 @@ interface Props { organization: string | undefined; profiles: BaseProfile[]; rule: T.Rule | T.RuleDetails; - updateMode?: boolean; } interface State { @@ -39,17 +38,8 @@ interface State { } export default class ActivationButton extends React.PureComponent { - mounted = false; state: State = { modal: false }; - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - handleButtonClick = () => { this.setState({ modal: true }); }; @@ -77,7 +67,6 @@ export default class ActivationButton extends React.PureComponent organization={this.props.organization} profiles={this.props.profiles} rule={this.props.rule} - updateMode={this.props.updateMode} /> )} diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx index b60724a2a60..8da4d9176ad 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/ActivationFormModal.tsx @@ -36,7 +36,6 @@ interface Props { organization: string | undefined; profiles: BaseProfile[]; rule: T.Rule | T.RuleDetails; - updateMode?: boolean; } interface State { diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx index 9e28e800200..9c7171535d4 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonContainer.tsx @@ -21,31 +21,18 @@ import * as React from 'react'; import { withRouter, WithRouterProps } from 'react-router'; import ComparisonForm from './ComparisonForm'; import ComparisonResults from './ComparisonResults'; -import { compareProfiles } from '../../../api/quality-profiles'; +import { compareProfiles, CompareResponse } from '../../../api/quality-profiles'; import { getProfileComparePath } from '../utils'; import { Profile } from '../types'; interface Props extends WithRouterProps { - organization: string | null; + organization?: string; profile: Profile; profiles: Profile[]; } -type Params = { [p: string]: string }; - -interface State { - loading: boolean; - left?: { name: string }; - right?: { name: string }; - inLeft?: Array<{ key: string; name: string; severity: string }>; - inRight?: Array<{ key: string; name: string; severity: string }>; - modified?: Array<{ - key: string; - name: string; - left: { params: Params; severity: string }; - right: { params: Params; severity: string }; - }>; -} +type State = { loading: boolean } & Partial; +type StateWithResults = { loading: boolean } & CompareResponse; class ComparisonContainer extends React.PureComponent { mounted = false; @@ -66,27 +53,27 @@ class ComparisonContainer extends React.PureComponent { this.mounted = false; } - loadResults() { + loadResults = () => { const { withKey } = this.props.location.query; if (!withKey) { this.setState({ left: undefined, loading: false }); - return; + return Promise.resolve(); } this.setState({ loading: true }); - compareProfiles(this.props.profile.key, withKey).then((r: any) => { - if (this.mounted) { - this.setState({ - left: r.left, - right: r.right, - inLeft: r.inLeft, - inRight: r.inRight, - modified: r.modified, - loading: false - }); + return compareProfiles(this.props.profile.key, withKey).then( + ({ left, right, inLeft, inRight, modified }) => { + if (this.mounted) { + this.setState({ left, right, inLeft, inRight, modified, loading: false }); + } + }, + () => { + if (this.mounted) { + this.setState({ loading: false }); + } } - }); - } + ); + }; handleCompare = (withKey: string) => { const path = getProfileComparePath( @@ -98,10 +85,13 @@ class ComparisonContainer extends React.PureComponent { this.props.router.push(path); }; + hasResults(state: State): state is StateWithResults { + return state.left !== undefined; + } + render() { const { profile, profiles, location } = this.props; const { withKey } = location.query; - const { left, right, inLeft, inRight, modified } = this.state; return (
@@ -116,22 +106,21 @@ class ComparisonContainer extends React.PureComponent { {this.state.loading && } - {left != null && - inLeft != null && - right != null && - inRight != null && - modified != null && ( -
- -
- )} + {this.hasResults(this.state) && ( +
+ p.key === withKey)} + /> +
+ )}
); } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx index 5cbba2b10cc..0681f741ffa 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx +++ b/server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx @@ -30,9 +30,9 @@ interface Props { } export default class ComparisonForm extends React.PureComponent { - handleChange(option: { value: string }) { + handleChange = (option: { value: string }) => { this.props.onCompare(option.value); - } + }; render() { const { profile, profiles, withKey } = this.props; @@ -46,7 +46,7 @@ export default class ComparisonForm extends React.PureComponent {