import React from 'react'; | import React from 'react'; | ||||
import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin'; | import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin'; | ||||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | import { translate, translateWithParameters } from '../../../helpers/l10n'; | ||||
import { getQualityProfileUrl } from '../../../helpers/urls'; | |||||
import { getQualityProfileUrl, getRulesUrl } from '../../../helpers/urls'; | |||||
import { searchRules } from '../../../api/rules'; | import { searchRules } from '../../../api/rules'; | ||||
import { getRulesUrl } from '../../../helpers/urls'; | |||||
export default class MetaQualityProfiles extends React.Component { | export default class MetaQualityProfiles extends React.Component { | ||||
state = { | state = { | ||||
return searchRules(data).then(r => r.total); | return searchRules(data).then(r => r.total); | ||||
} | } | ||||
getDeprecatedRulesCount (profile) { | |||||
const count = this.state.deprecatedByKey[profile.key]; | |||||
return count || 0; | |||||
} | |||||
renderDeprecated (profile) { | renderDeprecated (profile) { | ||||
const count = this.state.deprecatedByKey[profile.key]; | const count = this.state.deprecatedByKey[profile.key]; | ||||
if (!count) { | if (!count) { | ||||
); | ); | ||||
} | } | ||||
renderProfile (profile) { | |||||
const inner = ( | |||||
<div> | |||||
<span className="note spacer-right"> | |||||
{'(' + profile.language + ')'} | |||||
</span> | |||||
<a href={getQualityProfileUrl(profile.key)}> | |||||
{profile.name} | |||||
</a> | |||||
</div> | |||||
); | |||||
const count = this.getDeprecatedRulesCount(profile); | |||||
if (count > 0) { | |||||
const tooltip = | |||||
translateWithParameters('overview.deprecated_profile', count); | |||||
return ( | |||||
<li key={profile.key} | |||||
className="overview-deprecated-rules" | |||||
title={tooltip} | |||||
data-toggle="tooltip"> | |||||
{inner} | |||||
</li> | |||||
); | |||||
} | |||||
return ( | |||||
<li key={profile.key}> | |||||
{inner} | |||||
</li> | |||||
); | |||||
} | |||||
render () { | render () { | ||||
const { profiles } = this.props; | const { profiles } = this.props; | ||||
const deprecatedStyles = { | |||||
padding: '3px 6px', | |||||
border: '1px solid #ebccd1', | |||||
borderRadius: '3px', | |||||
backgroundColor: '#f2dede' | |||||
}; | |||||
return ( | return ( | ||||
<TooltipsContainer> | <TooltipsContainer> | ||||
<div> | <div> | ||||
</h4> | </h4> | ||||
<ul className="overview-meta-list"> | <ul className="overview-meta-list"> | ||||
{profiles.map(profile => ( | |||||
<li key={profile.key}> | |||||
{this.renderDeprecated(profile)} | |||||
<span className="note spacer-right"> | |||||
{'(' + profile.language + ')'} | |||||
</span> | |||||
<a href={getQualityProfileUrl(profile.key)}> | |||||
{profile.name} | |||||
</a> | |||||
</li> | |||||
))} | |||||
{profiles.map(profile => this.renderProfile(profile))} | |||||
</ul> | </ul> | ||||
</div> | </div> | ||||
</TooltipsContainer> | </TooltipsContainer> |
background-color: transparent !important; | background-color: transparent !important; | ||||
} | } | ||||
.overview-deprecated-rules { | |||||
margin: 4px -6px 4px; | |||||
padding: 3px 6px; | |||||
border: 1px solid #ebccd1; | |||||
border-radius: 3px; | |||||
background-color: #f2dede; | |||||
} | |||||
/* | /* | ||||
* Animations | * Animations | ||||
*/ | */ |
import keyBy from 'lodash/keyBy'; | import keyBy from 'lodash/keyBy'; | ||||
import ProfileRulesRow from './ProfileRulesRow'; | import ProfileRulesRow from './ProfileRulesRow'; | ||||
import { ProfileType } from '../propTypes'; | import { ProfileType } from '../propTypes'; | ||||
import { TooltipsContainer } from '../../../components/mixins/tooltips-mixin'; | |||||
import { searchRules, takeFacet } from '../../../api/rules'; | import { searchRules, takeFacet } from '../../../api/rules'; | ||||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | import { translate, translateWithParameters } from '../../../helpers/l10n'; | ||||
import { formatMeasure } from '../../../helpers/measures'; | import { formatMeasure } from '../../../helpers/measures'; |
return null; | return null; | ||||
} | } | ||||
const totalRules = profilesWithDeprecations | |||||
.map(p => p.activeDeprecatedRuleCount) | |||||
.reduce((p, c) => p + c, 0); | |||||
const sortedProfiles = | const sortedProfiles = | ||||
sortBy(profilesWithDeprecations, p => -p.activeDeprecatedRuleCount); | sortBy(profilesWithDeprecations, p => -p.activeDeprecatedRuleCount); | ||||
</div> | </div> | ||||
<div className="spacer-bottom"> | <div className="spacer-bottom"> | ||||
{translateWithParameters( | {translateWithParameters( | ||||
'quality_profiles.x_deprecated_rules_are_still_activated', | |||||
totalRules, | |||||
'quality_profiles.deprecated_rules_are_still_activated', | |||||
profilesWithDeprecations.length | profilesWithDeprecations.length | ||||
)} | )} | ||||
</div> | </div> |
import { searchRules } from '../../../api/rules'; | import { searchRules } from '../../../api/rules'; | ||||
import { translateWithParameters, translate } from '../../../helpers/l10n'; | import { translateWithParameters, translate } from '../../../helpers/l10n'; | ||||
import { getRulesUrl } from '../../../helpers/urls'; | import { getRulesUrl } from '../../../helpers/urls'; | ||||
import { formatMeasure } from '../../../helpers/measures'; | |||||
const RULES_LIMIT = 3; | |||||
const RULES_LIMIT = 10; | |||||
const PERIOD_START_MOMENT = moment().subtract(1, 'month'); | |||||
const PERIOD_START_MOMENT = moment().subtract(1, 'year'); | |||||
function parseRules (r) { | function parseRules (r) { | ||||
const { rules, actives } = r; | const { rules, actives } = r; | ||||
<strong className="pull-left"> | <strong className="pull-left"> | ||||
{translate('quality_profiles.latest_new_rules')} | {translate('quality_profiles.latest_new_rules')} | ||||
</strong> | </strong> | ||||
{this.state.latestRulesTotal > RULES_LIMIT && ( | |||||
<a className="pull-right small text-muted" | |||||
href={newRulesUrl}> | |||||
{translate('see_all')} | |||||
</a> | |||||
)} | |||||
</div> | </div> | ||||
<ul> | <ul> | ||||
{this.state.latestRules.map(rule => ( | {this.state.latestRules.map(rule => ( | ||||
</li> | </li> | ||||
))} | ))} | ||||
</ul> | </ul> | ||||
{this.state.latestRulesTotal > RULES_LIMIT && ( | |||||
<div className="spacer-top"> | |||||
<a className="small" | |||||
href={newRulesUrl}> | |||||
{translate('see_all')} | |||||
{' '} | |||||
{formatMeasure(this.state.latestRulesTotal, 'SHORT_INT')} | |||||
</a> | |||||
</div> | |||||
)} | |||||
</div> | </div> | ||||
); | ); | ||||
} | } |
.quality-profile-rules-deprecated { | .quality-profile-rules-deprecated { | ||||
padding: 15px 20px; | padding: 15px 20px; | ||||
border-top: 1px solid #e6e6e6; | |||||
background-color: #fcf8e3; | |||||
background-color: #f2dede; | |||||
} | } | ||||
.quality-profile-exporters { | .quality-profile-exporters { |
quality_profiles.projects_for_default=Every project not specifically associated with a quality profile will be associated to this one by default. | quality_profiles.projects_for_default=Every project not specifically associated with a quality profile will be associated to this one by default. | ||||
quality_profiles.projects_for_default.edit=You must not select specific projects for the default quality profile. | quality_profiles.projects_for_default.edit=You must not select specific projects for the default quality profile. | ||||
quality_profiles.inherits=Inherits "{0}" | quality_profiles.inherits=Inherits "{0}" | ||||
quality_profile.x_rules={0} rules | |||||
quality_profile.x_rules={0} rule(s) | |||||
quality_profile.x_active_rules={0} active rules | quality_profile.x_active_rules={0} active rules | ||||
quality_profiles.x_overridden_rules={0} overridden rules | quality_profiles.x_overridden_rules={0} overridden rules | ||||
quality_profiles.change_parent=Change Parent | quality_profiles.change_parent=Change Parent | ||||
quality_profiles.latest_new_rules.activated={0}, activated on {1} profile(s) | 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.latest_new_rules.not_activated={0}, not yet activated | ||||
quality_profiles.deprecated_rules=Deprecated Rules | quality_profiles.deprecated_rules=Deprecated Rules | ||||
quality_profiles.x_deprecated_rules_are_still_activated={0} deprecated rule(s) are still activated on {1} quality profile(s): | |||||
quality_profiles.deprecated_rules_are_still_activated=Deprecated rules are still activated on {0} quality profile(s): | |||||
quality_profiles.stagnant_profiles=Stagnant Profiles | 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: | quality_profiles.not_updated_more_than_year=The following profiles haven't been updated for more than 1 year: | ||||
quality_profiles.exporters=Exporters | quality_profiles.exporters=Exporters |