Browse Source

SONAR-21380 migrate QG status in measures to new UI

tags/10.4.0.87286
Jeremy Davis 3 months ago
parent
commit
2769a5e143

+ 1
- 1
server/sonar-web/src/main/js/apps/component-measures/components/ComponentMeasuresApp.tsx View File

@@ -280,7 +280,7 @@ class ComponentMeasuresApp extends React.PureComponent<Props, State> {
<LargeCenteredLayout id="component-measures" className="sw-pt-8">
<Suggestions suggestions="component_measures" />
<Helmet defer={false} title={translate('layout.measures')} />
<PageContentFontWrapper>
<PageContentFontWrapper className="sw-body-sm">
<Spinner className="my-10 sw-flex sw-content-center" loading={this.state.loading} />

{measures.length > 0 ? (

+ 26
- 23
server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.tsx View File

@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import classNames from 'classnames';
import { Highlight, Link, MetricsLabel, MetricsRatingBadge } from 'design-system';
import { Link, MetricsLabel, MetricsRatingBadge } from 'design-system';
import * as React from 'react';
import LanguageDistribution from '../../../components/charts/LanguageDistribution';
import Tooltip from '../../../components/controls/Tooltip';
@@ -58,36 +58,39 @@ export default function MeasureHeader(props: Props) {
<div className="sw-flex sw-items-center sw-justify-between sw-gap-4">
<div className="it__measure-details-metric sw-flex sw-items-center sw-gap-1">
<strong className="sw-body-md-highlight">{getLocalizedMetricName(metric)}</strong>
<Measure
className={classNames('it__measure-details-value sw-body-md')}
metricKey={metric.key}
metricType={metric.type}
value={measureValue}
ratingComponent={
<MetricsRatingBadge
label={
measureValue
? translateWithParameters(
'metric.has_rating_X',
formatMeasure(measureValue, MetricType.Rating),
)
: translate('metric.no_rating')
}
rating={formatMeasure(measureValue, MetricType.Rating) as MetricsLabel}
/>
}
/>

<div className="sw-flex sw-items-center sw-ml-2">
<Measure
className={classNames('it__measure-details-value sw-body-md')}
metricKey={metric.key}
metricType={metric.type}
value={measureValue}
ratingComponent={
<MetricsRatingBadge
label={
measureValue
? translateWithParameters(
'metric.has_rating_X',
formatMeasure(measureValue, MetricType.Rating),
)
: translate('metric.no_rating')
}
rating={formatMeasure(measureValue, MetricType.Rating) as MetricsLabel}
/>
}
/>
</div>

{!isDiff && hasHistory && (
<Tooltip overlay={translate('component_measures.show_metric_history')}>
<Highlight>
<span className="sw-ml-4">
<Link
className="it__show-history-link sw-font-semibold sw-ml-4"
className="it__show-history-link sw-font-semibold"
to={getMeasureHistoryUrl(component.key, metric.key, branchLike)}
>
{translate('component_measures.see_metric_history')}
</Link>
</Highlight>
</span>
</Tooltip>
)}
</div>

+ 1
- 0
server/sonar-web/src/main/js/apps/component-measures/sidebar/SubnavigationMeasureValue.tsx View File

@@ -53,6 +53,7 @@ export default function SubnavigationMeasureValue({ measure }: Props) {
}
metricKey={measure.metric.key}
metricType={measure.metric.type}
small
value={value}
/>
</Note>

+ 17
- 2
server/sonar-web/src/main/js/components/measure/Measure.tsx View File

@@ -17,12 +17,14 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { QualityGateIndicator } from 'design-system';
import * as React from 'react';
import Tooltip from '../../components/controls/Tooltip';
import Level from '../../components/ui/Level';
import Rating from '../../components/ui/Rating';
import { translateWithParameters } from '../../helpers/l10n';
import { formatMeasure } from '../../helpers/measures';
import { MetricType } from '../../types/metrics';
import { Status } from '../../types/types';
import RatingTooltipContent from './RatingTooltipContent';

interface Props {
@@ -49,7 +51,20 @@ export default function Measure({
}

if (metricType === MetricType.Level) {
return <Level className={className} level={value?.toString()} small={small} />;
const formatted = formatMeasure(value, MetricType.Level);
const ariaLabel = translateWithParameters('overview.quality_gate_x', formatted);

return (
<>
<QualityGateIndicator
status={(value as Status) ?? 'NONE'}
className="sw-mr-2"
ariaLabel={ariaLabel}
size={small ? 'sm' : 'md'}
/>
<span className={small ? '' : 'sw-body-md'}>{formatted}</span>
</>
);
}

if (metricType !== MetricType.Rating) {

+ 24
- 0
server/sonar-web/src/main/js/components/measure/__tests__/MeasureIndicator-test.tsx View File

@@ -19,6 +19,7 @@
*/
import { render, screen } from '@testing-library/react';
import * as React from 'react';
import { Status } from '../../../apps/overview/utils';
import { MetricKey, MetricType } from '../../../types/metrics';
import MeasureIndicator from '../MeasureIndicator';

@@ -32,3 +33,26 @@ it('renders correctly for coverage', () => {
);
expect(screen.getByRole('img')).toMatchSnapshot();
});

it('renders correctly for failed quality gate', () => {
const wrapper = render(
<MeasureIndicator
metricKey={MetricKey.alert_status}
metricType={MetricType.Level}
small
value={Status.ERROR}
/>,
);
expect(wrapper.baseElement).toMatchSnapshot();
});

it('renders correctly for passed quality gate', () => {
const wrapper = render(
<MeasureIndicator
metricKey={MetricKey.alert_status}
metricType={MetricType.Level}
value={Status.OK}
/>,
);
expect(wrapper.baseElement).toMatchSnapshot();
});

+ 80
- 0
server/sonar-web/src/main/js/components/measure/__tests__/__snapshots__/MeasureIndicator-test.tsx.snap View File

@@ -25,3 +25,83 @@ exports[`renders correctly for coverage 1`] = `
</g>
</svg>
`;

exports[`renders correctly for failed quality gate 1`] = `
<body>
<div>
<div
aria-label="overview.quality_gate_x.ERROR"
class="sw-flex sw-justify-center sw-items-center"
>
<svg
class="sw-mr-2"
fill="none"
height="1rem"
role="status"
width="1rem"
xmlns="http://www.w3.org/2000/svg"
>
<rect
fill="rgb(254,205,202)"
height="1rem"
rx="2"
width="1rem"
/>
<path
d="m10.227 5 .871.871-5.227 5.227L5 10.227z"
fill="rgb(128,27,20)"
/>
<path
d="m11.098 10.227-.871.87L5 5.872 5.87 5z"
fill="rgb(128,27,20)"
/>
</svg>
</div>
<span
class=""
>
ERROR
</span>
</div>
</body>
`;

exports[`renders correctly for passed quality gate 1`] = `
<body>
<div>
<div
aria-label="overview.quality_gate_x.OK"
class="sw-flex sw-justify-center sw-items-center"
>
<svg
class="sw-mr-2"
fill="none"
height="1.5rem"
role="status"
width="1.5rem"
xmlns="http://www.w3.org/2000/svg"
>
<rect
fill="rgb(209,250,223)"
height="1.5rem"
rx="2"
width="1.5rem"
/>
<path
d="m16.95 7.5 1.308 1.307-7.84 7.84-1.308-1.306z"
fill="rgb(5,96,58)"
/>
<path
d="m11.79 15.34-1.307 1.307-4.484-4.483 1.307-1.306z"
fill="rgb(5,96,58)"
/>
</svg>
</div>
<span
class="sw-body-md"
>
OK
</span>
</div>
</body>
`;

Loading…
Cancel
Save