Bladeren bron

SONAR-9608 SONAR-9615 Add inline documentation on project measures page

tags/6.6-RC1
Grégoire Aubert 6 jaren geleden
bovenliggende
commit
ee4605dde9

+ 1
- 0
server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.css Bestand weergeven

@@ -29,6 +29,7 @@
.navbar-help {
line-height: 16px !important;
padding: 7px !important;
color: #fff !important;
}

.global-navbar-menu {

+ 14
- 0
server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js Bestand weergeven

@@ -175,6 +175,19 @@ export default class BubbleChart extends React.PureComponent {
);
}

renderChartFooter(domain: string) {
const description = `component_measures.overview.${domain}.description`;
const translatedDescription = translate(description);
if (description === translatedDescription) {
return null;
}
return (
<div className="measure-overview-bubble-chart-footer">
{translatedDescription}
</div>
);
}

render() {
if (this.props.components.length <= 0) {
return <EmptyResult />;
@@ -197,6 +210,7 @@ export default class BubbleChart extends React.PureComponent {
<div className="measure-overview-bubble-chart-axis y">
{getLocalizedMetricName(yMetric)}
</div>
{this.renderChartFooter(domain)}
</div>
);
}

+ 15
- 1
server/sonar-web/src/main/js/apps/component-measures/sidebar/DomainFacet.js Bestand weergeven

@@ -31,6 +31,7 @@ import { filterMeasures, hasBubbleChart, sortMeasures } from '../utils';
import {
getLocalizedMetricDomain,
getLocalizedMetricName,
translate,
translateWithParameters
} from '../../../helpers/l10n';
import type { MeasureEnhanced } from '../../../components/measure/types';
@@ -48,6 +49,16 @@ export default class DomainFacet extends React.PureComponent {

handleHeaderClick = () => this.props.onToggle(this.props.domain.name);

hasFacetSelected = (
domain: { name: string },
measures: Array<MeasureEnhanced>,
selected: string
) => {
const measureSelected = measures.find(measure => measure.metric.key === selected);
const overviewSelected = domain.name === selected && hasBubbleChart(domain.name);
return measureSelected || overviewSelected;
};

renderOverviewFacet = () => {
const { domain, selected } = this.props;
if (!hasBubbleChart(domain.name)) {
@@ -79,13 +90,16 @@ export default class DomainFacet extends React.PureComponent {
render() {
const { domain, selected } = this.props;
const measures = sortMeasures(domain.name, filterMeasures(domain.measures));
const helper = `component_measures.domain_facets.${domain.name}.help`;
const translatedHelper = translate(helper);
return (
<FacetBox>
<FacetHeader
helper={helper !== translatedHelper ? translatedHelper : undefined}
name={getLocalizedMetricDomain(domain.name)}
onClick={this.handleHeaderClick}
open={this.props.open}
values={measures.find(measure => measure.metric.key === selected) ? 1 : 0}
values={this.hasFacetSelected(domain, measures, selected) ? 1 : 0}
/>

{this.props.open &&

+ 24
- 14
server/sonar-web/src/main/js/apps/component-measures/style.css Bestand weergeven

@@ -90,47 +90,57 @@
vertical-align: middle;
}

.measure-details-bubble-chart {
.measure-overview-bubble-chart {
position: relative;
padding: 0 0 30px 60px;
border: 1px solid #e6e6e6;
background-color: #fff;
}

.measure-details-bubble-chart-header {
.measure-overview-bubble-chart-content {
padding: 0;
padding-left: 60px;
}

.measure-overview-bubble-chart-header {
display: flex;
align-items: center;
padding: 16px;
margin-left: -60px;
border-bottom: 1px solid #e6e6e6;
}

.measure-details-bubble-chart-title {
.measure-overview-bubble-chart-title {
position: absolute;
}

.measure-details-bubble-chart-legend {
.measure-overview-bubble-chart-legend {
display: flex;
flex-direction: column;
text-align: center;
flex-grow: 1;
}

.measure-details-bubble-chart-axis {
position: absolute;
.measure-overview-bubble-chart-footer {
padding: 15px 60px;
border-top: 1px solid #e6e6e6;
text-align: center;
font-size: 12px;
line-height: 1.4;
}

.measure-overview-bubble-chart-axis {
color: #777;
font-size: 12px;
}

.measure-details-bubble-chart-axis.x {
left: 50%;
bottom: 10px;
width: 500px;
margin-left: -250px;
.measure-overview-bubble-chart-axis.x {
position: relative;
top: -8px;
padding-bottom: 8px;
text-align: center;
}

.measure-details-bubble-chart-axis.y {
.measure-overview-bubble-chart-axis.y {
position: absolute;
top: 50%;
left: -20px;
transform: rotate(-90deg);

+ 27
- 2
server/sonar-web/src/main/js/components/facet/FacetHeader.js Bestand weergeven

@@ -20,9 +20,12 @@
// @flow
/* eslint-disable max-len */
import React from 'react';
import Tooltip from '../controls/Tooltip';
import HelpIcon from '../icons-components/HelpIcon';
import { translate } from '../../helpers/l10n';

type Props = {|
helper?: string,
name: string,
onClear?: () => void,
onClick?: () => void,
@@ -55,7 +58,12 @@ export default class FacetHeader extends React.PureComponent {

renderCheckbox() {
return (
<svg viewBox="0 0 1792 1792" width="10" height="10" style={{ paddingTop: 3 }}>
<svg
className="little-spacer-right"
viewBox="0 0 1792 1792"
width="10"
height="10"
style={{ paddingTop: 3 }}>
{this.props.open
? <path
style={{ fill: 'currentColor ' }}
@@ -69,6 +77,19 @@ export default class FacetHeader extends React.PureComponent {
);
}

renderHelper() {
if (!this.props.helper) {
return null;
}
return (
<Tooltip overlay={this.props.helper} placement="right">
<span>
<HelpIcon className="spacer-left text-info" />
</span>
</Tooltip>
);
}

renderValueIndicator() {
if (this.props.open || !this.props.values) {
return null;
@@ -94,10 +115,14 @@ export default class FacetHeader extends React.PureComponent {

{this.props.onClick
? <a className="search-navigator-facet-header" href="#" onClick={this.handleClick}>
{this.renderCheckbox()} {this.props.name} {this.renderValueIndicator()}
{this.renderCheckbox()}
{this.props.name}
{this.renderHelper()}
{this.renderValueIndicator()}
</a>
: <span className="search-navigator-facet-header">
{this.props.name}
{this.renderHelper()}
</span>}
</div>
);

+ 5
- 10
server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetHeader-test.js.snap Bestand weergeven

@@ -14,6 +14,7 @@ exports[`should clear 1`] = `
onClick={[Function]}
>
<svg
className="little-spacer-right"
height="10"
style={
Object {
@@ -32,9 +33,7 @@ exports[`should clear 1`] = `
}
/>
</svg>
foo
<span
className="spacer-left badge is-rounded"
>
@@ -52,6 +51,7 @@ exports[`should render closed facet with value 1`] = `
onClick={[Function]}
>
<svg
className="little-spacer-right"
height="10"
style={
Object {
@@ -70,9 +70,7 @@ exports[`should render closed facet with value 1`] = `
}
/>
</svg>
foo
<span
className="spacer-left badge is-rounded"
>
@@ -90,6 +88,7 @@ exports[`should render closed facet without value 1`] = `
onClick={[Function]}
>
<svg
className="little-spacer-right"
height="10"
style={
Object {
@@ -108,9 +107,7 @@ exports[`should render closed facet without value 1`] = `
}
/>
</svg>
foo
</a>
</div>
`;
@@ -123,6 +120,7 @@ exports[`should render open facet with value 1`] = `
onClick={[Function]}
>
<svg
className="little-spacer-right"
height="10"
style={
Object {
@@ -141,9 +139,7 @@ exports[`should render open facet with value 1`] = `
}
/>
</svg>
foo
</a>
</div>
`;
@@ -156,6 +152,7 @@ exports[`should render open facet without value 1`] = `
onClick={[Function]}
>
<svg
className="little-spacer-right"
height="10"
style={
Object {
@@ -174,9 +171,7 @@ exports[`should render open facet without value 1`] = `
}
/>
</svg>
foo
</a>
</div>
`;

+ 1
- 1
server/sonar-web/src/main/js/components/icons-components/HelpIcon.js Bestand weergeven

@@ -28,7 +28,7 @@ export default function HelpIcon({ className, size = 16 }: Props) {
<svg className={className} viewBox="0 0 16 16" width={size} height={size}>
<g transform="matrix(0.0364583,0,0,0.0364583,1,-0.166667)">
<path
fill="#fff"
fill="currentColor"
d="M224,344L224,296C224,293.667 223.25,291.75 221.75,290.25C220.25,288.75 218.333,288 216,288L168,288C165.667,288 163.75,288.75 162.25,290.25C160.75,291.75 160,293.667 160,296L160,344C160,346.333 160.75,348.25 162.25,349.75C163.75,351.25 165.667,352 168,352L216,352C218.333,352 220.25,351.25 221.75,349.75C223.25,348.25 224,346.333 224,344ZM288,176C288,161.333 283.375,147.75 274.125,135.25C264.875,122.75 253.333,113.083 239.5,106.25C225.667,99.417 211.5,96 197,96C156.5,96 125.583,113.75 104.25,149.25C101.75,153.25 102.417,156.75 106.25,159.75L139.25,184.75C140.417,185.75 142,186.25 144,186.25C146.667,186.25 148.75,185.25 150.25,183.25C159.083,171.917 166.25,164.25 171.75,160.25C177.417,156.25 184.583,154.25 193.25,154.25C201.25,154.25 208.375,156.417 214.625,160.75C220.875,165.083 224,170 224,175.5C224,181.833 222.333,186.917 219,190.75C215.667,194.583 210,198.333 202,202C191.5,206.667 181.875,213.875 173.125,223.625C164.375,233.375 160,243.833 160,255L160,264C160,266.333 160.75,268.25 162.25,269.75C163.75,271.25 165.667,272 168,272L216,272C218.333,272 220.25,271.25 221.75,269.75C223.25,268.25 224,266.333 224,264C224,260.833 225.792,256.708 229.375,251.625C232.958,246.542 237.5,242.417 243,239.25C248.333,236.25 252.417,233.875 255.25,232.125C258.083,230.375 261.917,227.458 266.75,223.375C271.583,219.292 275.292,215.292 277.875,211.375C280.458,207.458 282.792,202.417 284.875,196.25C286.958,190.083 288,183.333 288,176ZM384,224C384,258.833 375.417,290.958 358.25,320.375C341.083,349.792 317.792,373.083 288.375,390.25C258.958,407.417 226.833,416 192,416C157.167,416 125.042,407.417 95.625,390.25C66.208,373.083 42.917,349.792 25.75,320.375C8.583,290.958 0,258.833 0,224C0,189.167 8.583,157.042 25.75,127.625C42.917,98.208 66.208,74.917 95.625,57.75C125.042,40.583 157.167,32 192,32C226.833,32 258.958,40.583 288.375,57.75C317.792,74.917 341.083,98.208 358.25,127.625C375.417,157.042 384,189.167 384,224Z"
/>
</g>

+ 11
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties Bestand weergeven

@@ -2904,6 +2904,17 @@ component_measures.to_navigate_back=to navigate back

component_measures.overview.project_overview.facet=Project Overview
component_measures.overview.project_overview.title=Risk
component_measures.overview.project_overview.description=Get quick insights into the operational risks. Any color but green indicates immediate risks: Bugs or Vulnerabilities that should be examined. A position at the top or right of the graph means that the longer-term health may be at risk. Green bubbles at the bottom-left are best.
component_measures.overview.Reliability.description=See bugs' operational risks. The closer a bubble's color is to red, the more severe the worse bugs are. Bubble size indicates bug volume, and each bubble's vertical position reflects the estimated time to address the bugs. Small green bubbles on the bottom edge are best.
component_measures.overview.Security.description=See vulnerabilities' operational risks. The closer a bubble's color is to red, the more severe the worst vulnerabilities are. Bubble size indicates vulnerability volume, and each bubble's vertical position reflects the estimated time to address the vulnerabilities. Small green bubbles on the bottom edge are best.
component_measures.overview.Maintainability.description=See code smells' long-term risks. The closer a bubble's color is to red, the higher the ratio of technical debt is. Bubble size indicates code smell volume, and each bubble's vertical position reflects the estimated time to address the code smells. Small green bubbles on the bottom edge are best.
component_measures.overview.Coverage.description=See missing test coverage's long-term risks. Bubble size indicates the volume of uncovered lines, and each bubble's vertical position reflects the volume of missing coverage. Small bubbles on the bottom edge are best.
component_measures.overview.Duplications.description=See duplications' long-term risks. Bubble size indicates the volume of duplicated blocks, and each bubble's vertical position reflects the volume of lines in those blocks. Small bubbles on the bottom edge are best.

component_measures.domain_facets.Reliability.help=Issues in this domain mark code where you will get behavior other than what was expected.
component_measures.domain_facets.Maintainability.help=Issues in this domain mark code that will be more difficult to update competently than it should.
component_measures.domain_facets.Security.help=Issues in this domain mark potential weaknesses to hackers.
component_measures.domain_facets.Complexity.help=How simple or complicated the control flow of the application is. Cyclomatic Complexity measures the minimum number of test cases requiref for full test coverage. Cognitive Complexity is a measure of how difficult the application is to Understand

#------------------------------------------------------------------------------
#

Laden…
Annuleren
Opslaan