diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2016-06-29 17:15:49 +0200 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2016-06-30 09:47:50 +0200 |
commit | 769c503adc33e48f6dcec505d7646f8b53c11b8c (patch) | |
tree | 93c8da9267da09ecd1adc061e18aa94840e5ee36 | |
parent | 0a5a0541f5c924135863562130fc4976415ab6c5 (diff) | |
download | sonarqube-769c503adc33e48f6dcec505d7646f8b53c11b8c.tar.gz sonarqube-769c503adc33e48f6dcec505d7646f8b53c11b8c.zip |
apply feedback for the quality profiles page
10 files changed, 91 insertions, 108 deletions
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js index 1062f4cca72..62706071207 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileHeader.js @@ -26,6 +26,7 @@ import DeleteProfileView from '../views/DeleteProfileView'; import { ProfileType } from '../propTypes'; import { translate } from '../../../helpers/l10n'; import { setDefaultProfile } from '../../../api/quality-profiles'; +import { getRulesUrl } from '../../../helpers/urls'; export default class ProfileHeader extends React.Component { static propTypes = { @@ -84,7 +85,10 @@ export default class ProfileHeader extends React.Component { '/api/qualityprofiles/backup?profileKey=' + encodeURIComponent(profile.key); - // TODO fix inline styles + const activateMoreUrl = getRulesUrl({ + qprofile: this.props.profile.key, + activation: 'false' + }); return ( <header className="page-header quality-profile-header"> @@ -92,6 +96,12 @@ export default class ProfileHeader extends React.Component { <IndexLink to="/" className="text-muted"> {translate('quality_profiles.page')} </IndexLink> + {' / '} + <Link + to={{ pathname: '/', query: { language: profile.language } }} + className="text-muted"> + {profile.languageName} + </Link> </div> <h1 className="page-title"> @@ -100,9 +110,6 @@ export default class ProfileHeader extends React.Component { className="link-base-color"> {profile.name} </ProfileLink> - <span className="spacer-left small text-muted"> - {this.props.profile.languageName} - </span> </h1> <div className="pull-right"> @@ -110,8 +117,7 @@ export default class ProfileHeader extends React.Component { <li> <Link to={{ pathname: '/changelog', query: { key: this.props.profile.key } }} - className="small text-muted" - activeClassName="link-active"> + className="button"> {translate('changelog')} </Link> </li> @@ -132,6 +138,18 @@ export default class ProfileHeader extends React.Component { </Link> </li> <li> + <a href={activateMoreUrl}> + {translate('quality_profiles.activate_more_rules')} + </a> + </li> + <li> + <Link + to={{ pathname: '/compare', query: { key: profile.key } }} + id="quality-profile-compare"> + {translate('compare')} + </Link> + </li> + <li> <a id="quality-profile-backup" href={backupUrl}> {translate('backup_verb')} </a> diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js index 99b75fea77e..108b42c14b7 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileProjects.js @@ -19,6 +19,7 @@ */ import React from 'react'; import ChangeProjectsView from '../views/ChangeProjectsView'; +import QualifierIcon from '../../../components/shared/qualifier-icon'; import { ProfileType } from '../propTypes'; import { getProfileProjects } from '../../../api/quality-profiles'; import { translate } from '../../../helpers/l10n'; @@ -110,7 +111,7 @@ export default class ProfileProjects extends React.Component { <li key={project.uuid} className="spacer-top js-profile-project" data-key={project.key}> - <i className="icon-checkbox icon-checkbox-checked"/> + <QualifierIcon qualifier="TRK"/> {' '} {project.name} </li> diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js index 539878dec9f..dd04d7cffde 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRules.js @@ -132,6 +132,25 @@ export default class ProfileRules extends React.Component { ); } + renderActiveTotal () { + const rulesUrl = getRulesUrl({ + qprofile: this.props.profile.key, + activation: 'false' + }); + + if (this.state.total == null) { + return null; + } + + return ( + <a href={rulesUrl}> + <strong> + {formatMeasure(this.state.total, 'SHORT_INT')} + </strong> + </a> + ); + } + getTooltipForType (type) { const { count } = this.state.activatedByType[type]; const total = this.state.allByType[type].count; @@ -162,6 +181,26 @@ export default class ProfileRules extends React.Component { ); } + renderTotalForType (type) { + const rulesUrl = getRulesUrl({ + qprofile: this.props.profile.key, + activation: 'false', + types: type + }); + + const { count } = this.state.allByType[type]; + + if (count == null) { + return null; + } + + return ( + <a href={rulesUrl}> + {formatMeasure(count, 'SHORT_INT')} + </a> + ); + } + renderDeprecated () { const { profile } = this.props; @@ -186,8 +225,6 @@ export default class ProfileRules extends React.Component { } render () { - const { total, activatedTotal, allByType, activatedByType } = this.state; - const activateMoreUrl = getRulesUrl({ qprofile: this.props.profile.key, activation: 'false' @@ -212,21 +249,17 @@ export default class ProfileRules extends React.Component { <ul className="quality-profile-rules-distribution"> <li key="all" className="big-spacer-bottom"> <ProfileRulesRow - count={activatedTotal} - total={total} - tooltip={this.getTooltip(activatedTotal, total)} renderTitle={this.renderActiveTitle.bind(this)} - renderCount={this.renderActiveCount.bind(this)}/> + renderCount={this.renderActiveCount.bind(this)} + renderTotal={this.renderActiveTotal.bind(this)}/> </li> {TYPES.map(type => ( <li key={type} className="spacer-top"> <ProfileRulesRow - count={activatedByType[type].count} - total={allByType[type].count} - tooltip={this.getTooltipForType(type)} renderTitle={this.renderTitleForType.bind(this, type)} - renderCount={this.renderCountForType.bind(this, type)}/> + renderCount={this.renderCountForType.bind(this, type)} + renderTotal={this.renderTotalForType.bind(this, type)}/> </li> ))} </ul> diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js index 6baf9ca811e..e945ed924ad 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesRow.js @@ -18,35 +18,26 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; -import ProgressBar from './ProgressBar'; export default class ProfileRulesRow extends React.Component { static propTypes = { - count: React.PropTypes.number, - total: React.PropTypes.number, - tooltip: React.PropTypes.string, renderTitle: React.PropTypes.func.isRequired, - renderCount: React.PropTypes.func.isRequired + renderCount: React.PropTypes.func.isRequired, + renderTotal: React.PropTypes.func.isRequired }; render () { - const { total, count, tooltip, renderTitle, renderCount } = this.props; + const { renderTitle, renderCount, renderTotal } = this.props; return ( - <div title={tooltip} data-toggle="tooltip"> - <div className="clearfix"> - <div className="pull-left"> - {renderTitle()} - </div> - <div className="pull-right"> - {renderCount()} - </div> + <div className="clearfix"> + <div className="pull-left"> + {renderTitle()} </div> - <div className="little-spacer-top" style={{ height: 2 }}> - <ProgressBar - count={count || 0} - total={total || 0} - width={300}/> + <div className="pull-right"> + {renderCount()} + {' / '} + {renderTotal()} </div> </div> ); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProgressBar.js b/server/sonar-web/src/main/js/apps/quality-profiles/details/ProgressBar.js deleted file mode 100644 index 5efc85f7907..00000000000 --- a/server/sonar-web/src/main/js/apps/quality-profiles/details/ProgressBar.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact 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 React from 'react'; - -export default class ProgressBar extends React.Component { - static propTypes = { - width: React.PropTypes.number.isRequired, - height: React.PropTypes.number, - count: React.PropTypes.number.isRequired, - total: React.PropTypes.number.isRequired - }; - - static defaultProps = { - height: 2 - }; - - render () { - const { width, height } = this.props; - const p = this.props.total > 0 ? this.props.count / this.props.total : 0; - const fillWidth = this.props.width * p; - - const commonProps = { x: 0, y: 0, rx: 2, height }; - - return ( - <svg width={width} height={height}> - <rect - {...commonProps} - width={width} - fill="#e6e6e6"/> - <rect - {...commonProps} - width={fillWidth} - className="bar-chart-bar quality-profile-progress-bar"/> - </svg> - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js index b4b10f4e4ae..e153d03a216 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesList.js @@ -21,6 +21,7 @@ import React from 'react'; import { PropTypes as RouterPropTypes } from 'react-router'; import groupBy from 'lodash/groupBy'; import pick from 'lodash/pick'; +import sortBy from 'lodash/sortBy'; import ProfilesListRow from './ProfilesListRow'; import ProfilesListHeader from './ProfilesListHeader'; import RestoreBuiltInProfilesView from '../views/RestoreBuiltInProfilesView'; @@ -64,7 +65,7 @@ export default class ProfilesList extends React.Component { {')'} {this.props.canAdmin && ( <button - className="spacer-left js-restore-built-in" + className="huge-spacer-left js-restore-built-in" data-language={languageKey} onClick={this.handleRestoreBuiltIn.bind(this, languageKey)}> {translate('quality_profiles.restore_built_in_profiles')} @@ -97,6 +98,8 @@ export default class ProfilesList extends React.Component { pick(profilesIndex, language) : profilesIndex; + const languagesToShow = sortBy(Object.keys(profilesToShow)); + return ( <div> <ProfilesListHeader @@ -109,7 +112,7 @@ export default class ProfilesList extends React.Component { </div> )} - {Object.keys(profilesToShow).map(languageKey => ( + {languagesToShow.map(languageKey => ( <table key={languageKey} data-language={languageKey} diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js index 532d76e5295..010321937ce 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListHeader.js @@ -35,7 +35,7 @@ export default class ProfilesListHeader extends React.Component { const label = currentFilter ? translateWithParameters( - 'quality_profiles.x_profiles', + 'quality_profiles.x_Profiles', currentLanguage.name) : translate('quality_profiles.all_profiles'); diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/styles.css b/server/sonar-web/src/main/js/apps/quality-profiles/styles.css index c71d00c68a7..9cd46314b19 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/styles.css +++ b/server/sonar-web/src/main/js/apps/quality-profiles/styles.css @@ -103,16 +103,6 @@ .quality-profile-inheritance { } -.quality-profile-progress-bar { - transition: width 0.5s ease; - animation: appear 0.5s forwards; -} - -@keyframes appear { - 0% { transform: translateX(-100%); } - 100% { transform: translateX(0); } -} - .quality-profile-not-found { padding-top: 100px; text-align: center; diff --git a/server/sonar-web/src/main/less/init/links.less b/server/sonar-web/src/main/less/init/links.less index 1c0b097155d..4f47e67b8bf 100644 --- a/server/sonar-web/src/main/less/init/links.less +++ b/server/sonar-web/src/main/less/init/links.less @@ -59,7 +59,7 @@ a { a.active-link, .link-active { .link-no-underline; - font-weight: 500; + cursor: default; } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index c4854f06fe3..ac158bc19fe 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -1759,8 +1759,8 @@ quality_profile.total_active_rules=Total Active Rules quality_profiles.x_overridden_rules={0} overridden rules quality_profiles.change_parent=Change Parent quality_profiles.all_profiles=All Profiles -quality_profiles.x_profiles={0} Profiles -quality_profiles._quality_profiles=quality profiles +quality_profiles.x_profiles={0} profile(s) +quality_profiles.x_Profiles={0} Profiles quality_profiles.x_projects={0} projects quality_profiles.no_results=No profiles found. Try installing a language plugin. quality_profiles.projects.select_hint=Click to associate this project with the quality profile @@ -1768,6 +1768,7 @@ quality_profiles.projects.deselect_hint=Click to remove association between this quality_profiles.no_profiles_for_comparison=There are no profiles for comparison quality_profile.empty_comparison=The quality profiles are equal. quality_profiles.activate_more=Activate More +quality_profiles.activate_more_rules=Activate More Rules quality_profiles.intro1=Quality Profiles are collections of rules to apply during an analysis. quality_profiles.intro2=For each language there is a default profile. All projects not explicitly assigned to some other profile will be analyzed with the default. quality_profiles.list.profile=Profile @@ -1780,10 +1781,10 @@ quality_profiles.x_activated_out_of_y={0} rules activated out of {1} available quality_profiles.change_projects=Change Projects quality_profiles.not_found=The requested quality profile was not found. quality_profiles.latest_new_rules=Latest New Rules -quality_profiles.latest_new_rules.activated={0}, activated on {1} profiles +quality_profiles.latest_new_rules.activated={0}, activated on {1} profile(s) quality_profiles.latest_new_rules.not_activated={0}, not yet activated quality_profiles.deprecated_rules=Deprecated Rules -quality_profiles.x_deprecated_rules_are_still_activated={0} deprecated rules are still activated on {1} quality profiles: +quality_profiles.x_deprecated_rules_are_still_activated={0} deprecated rule(s) are still activated on {1} quality profile(s): quality_profiles.stagnant_profiles=Stagnant Profiles quality_profiles.not_updated_more_than_year=The following profiles haven't been updated for more than 1 year: |