Browse Source

SONAR-20197 Add CCT to rule list view

tags/10.2.0.77647
Wouter Admiraal 10 months ago
parent
commit
1c5b183ed5

+ 9
- 0
server/sonar-web/src/main/js/apps/coding-rules/__tests__/CodingRules-it.ts View File

@@ -24,6 +24,7 @@ import { RULE_TYPES } from '../../../helpers/constants';
import { parseDate } from '../../../helpers/dates';
import { mockCurrentUser, mockLoggedInUser } from '../../../helpers/testMocks';
import { dateInputEvent, renderAppRoutes } from '../../../helpers/testReactTestingUtils';
import { CleanCodeAttributeCategory, SoftwareQuality } from '../../../types/clean-code-taxonomy';
import { CurrentUser } from '../../../types/users';
import routes from '../routes';
import { getPageObjects } from '../utils-tests';
@@ -44,6 +45,14 @@ describe('Rules app list', () => {
.allRulesName()
.forEach((name) => expect(ui.ruleListItemLink(name).get()).toBeInTheDocument());

// Render clean code attributes.
expect(
ui.ruleCleanCodeAttributeCategory(CleanCodeAttributeCategory.Adaptable).getAll().length
).toBeGreaterThan(1);
expect(ui.ruleSoftwareQuality(SoftwareQuality.Maintainability).getAll().length).toBeGreaterThan(
1
);

// Renders type facets
RULE_TYPES.map((type) => `issue.type.${type}`).forEach((name) =>
expect(ui.facetItem(name).get()).toBeInTheDocument()

+ 19
- 9
server/sonar-web/src/main/js/apps/coding-rules/components/RuleListItem.tsx View File

@@ -24,8 +24,9 @@ import Link from '../../../components/common/Link';
import { Button } from '../../../components/controls/buttons';
import ConfirmButton from '../../../components/controls/ConfirmButton';
import Tooltip from '../../../components/controls/Tooltip';
import IssueTypeIcon from '../../../components/icons/IssueTypeIcon';
import SeverityIcon from '../../../components/icons/SeverityIcon';
import { CleanCodeAttributePill } from '../../../components/shared/CleanCodeAttributePill';
import SoftwareImpactPill from '../../../components/shared/SoftwareImpactPill';
import TagsList from '../../../components/tags/TagsList';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { getRuleUrl } from '../../../helpers/urls';
@@ -231,6 +232,13 @@ export default class RuleListItem extends React.PureComponent<Props> {

<td className="coding-rule-table-meta-cell">
<div className="display-flex-center coding-rule-meta">
{rule.cleanCodeAttributeCategory !== undefined && (
<CleanCodeAttributePill
className="spacer-left"
cleanCodeAttributeCategory={rule.cleanCodeAttributeCategory}
type="rule"
/>
)}
{rule.status !== 'READY' && (
<span className="spacer-left badge badge-error">
{translate('rules.status', rule.status)}
@@ -239,14 +247,16 @@ export default class RuleListItem extends React.PureComponent<Props> {
<span className="display-inline-flex-center spacer-left note">
{rule.langName}
</span>
<Tooltip overlay={translate('coding_rules.type.tooltip', rule.type)}>
<span className="display-inline-flex-center spacer-left note">
<IssueTypeIcon query={rule.type} />
<span className="little-spacer-left text-middle">
{translate('issue.type', rule.type)}
</span>
</span>
</Tooltip>
{rule.impacts !== undefined &&
rule.impacts.map(({ severity, softwareQuality }) => (
<SoftwareImpactPill
className="spacer-left"
key={softwareQuality}
severity={severity}
quality={softwareQuality}
type="rule"
/>
))}
{allTags.length > 0 && (
<TagsList
allowUpdate={false}

+ 10
- 0
server/sonar-web/src/main/js/apps/coding-rules/utils-tests.tsx View File

@@ -21,6 +21,11 @@ import { waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Profile } from '../../api/quality-profiles';
import { byLabelText, byPlaceholderText, byRole, byText } from '../../helpers/testSelector';
import {
CleanCodeAttribute,
CleanCodeAttributeCategory,
SoftwareQuality,
} from '../../types/clean-code-taxonomy';

const selectors = {
loading: byLabelText('loading'),
@@ -92,6 +97,11 @@ const selectors = {
saveButton: byRole('button', { name: 'save' }),
cancelButton: byRole('button', { name: 'cancel' }),
removeButton: byRole('button', { name: 'remove' }),
ruleCleanCodeAttributeCategory: (category: CleanCodeAttributeCategory) =>
byText(`rule.clean_code_attribute_category.${category}.title_short`),
ruleCleanCodeAttribute: (attribute: CleanCodeAttribute) =>
byText(new RegExp(`rule\\.clean_code_attribute\\.${attribute}$`)),
ruleSoftwareQuality: (quality: SoftwareQuality) => byText(`issue.software_quality.${quality}`),

// Rule tags
tagsDropdown: byRole('button', { name: /tags_list_x/ }),

+ 1
- 1
server/sonar-web/src/main/js/apps/issues/__tests__/IssueHeader-it.tsx View File

@@ -52,7 +52,7 @@ it('renders correctly', async () => {

// CCT attribute
const cctBadge = byText(
`issue.clean_code_attribute_category.${issue.cleanCodeAttributeCategory}.issue`
`issue.clean_code_attribute_category.${issue.cleanCodeAttributeCategory}.title_short`
).get();
expect(cctBadge).toBeInTheDocument();
await expect(cctBadge).toHaveATooltipWithContent(

+ 28
- 9
server/sonar-web/src/main/js/components/shared/CleanCodeAttributePill.tsx View File

@@ -26,23 +26,37 @@ import DocumentationTooltip from '../common/DocumentationTooltip';

export interface Props {
className?: string;
type?: 'issue' | 'rule';
cleanCodeAttributeCategory: CleanCodeAttributeCategory;
cleanCodeAttribute?: CleanCodeAttribute;
}

export function CleanCodeAttributePill(props: Props) {
const { className, cleanCodeAttributeCategory, cleanCodeAttribute } = props;

const translationKey = cleanCodeAttribute
? `issue.clean_code_attribute.${cleanCodeAttribute}`
: `issue.clean_code_attribute_category.${cleanCodeAttributeCategory}`;
const { className, cleanCodeAttributeCategory, cleanCodeAttribute, type = 'issue' } = props;
const showAdvice = type === 'issue';

return (
<DocumentationTooltip
content={
<>
<p className="sw-mb-4">{translate(translationKey, 'title')}</p>
<p>{translate(translationKey, 'advice')}</p>
<p className="sw-mb-4">
{translate(
type,
cleanCodeAttribute ? 'clean_code_attribute' : 'clean_code_attribute_category',
cleanCodeAttribute ?? cleanCodeAttributeCategory,
'title'
)}
</p>
{showAdvice && (
<p>
{translate(
type,
cleanCodeAttribute ? 'clean_code_attribute' : 'clean_code_attribute_category',
cleanCodeAttribute ?? cleanCodeAttributeCategory,
'advice'
)}
</p>
)}
</>
}
links={[
@@ -54,10 +68,15 @@ export function CleanCodeAttributePill(props: Props) {
>
<Pill variant="neutral" data-guiding-id="issue-1" className={className}>
<span className={classNames({ 'sw-font-semibold': !!cleanCodeAttribute })}>
{translate('issue.clean_code_attribute_category', cleanCodeAttributeCategory, 'issue')}
{translate(
type,
'clean_code_attribute_category',
cleanCodeAttributeCategory,
'title_short'
)}
</span>
{cleanCodeAttribute && (
<span> | {translate('issue.clean_code_attribute', cleanCodeAttribute)}</span>
<span> | {translate(type, 'clean_code_attribute', cleanCodeAttribute)}</span>
)}
</Pill>
</DocumentationTooltip>

+ 4
- 3
server/sonar-web/src/main/js/components/shared/SoftwareImpactPill.tsx View File

@@ -29,11 +29,12 @@ import SoftwareImpactSeverityIcon from '../icons/SoftwareImpactSeverityIcon';
export interface Props {
className?: string;
severity: SoftwareImpactSeverity;
type?: 'issue' | 'rule';
quality: SoftwareQuality;
}

export default function SoftwareImpactPill(props: Props) {
const { className, severity, quality } = props;
const { className, severity, quality, type = 'issue' } = props;

const variant = {
[SoftwareImpactSeverity.High]: 'danger',
@@ -45,8 +46,8 @@ export default function SoftwareImpactPill(props: Props) {
<DocumentationTooltip
content={
<FormattedMessage
id="issue.impact.severity.tooltip"
defaultMessage={translate('issue.impact.severity.tooltip')}
id={`${type}.impact.severity.tooltip`}
defaultMessage={translate(`${type}.impact.severity.tooltip`)}
values={{
severity: translate('severity', severity).toLowerCase(),
quality: translate('issue.software_quality', quality).toLowerCase(),

+ 51
- 4
sonar-core/src/main/resources/org/sonar/l10n/core.properties View File

@@ -986,19 +986,19 @@ issue.impact.severity.tooltip=This issue has a {severity} impact on the {quality
issue.clean_code_attribute_category.CONSISTENT=Consistency
issue.clean_code_attribute_category.CONSISTENT.title=This is a consistency issue.
issue.clean_code_attribute_category.CONSISTENT.advice=To be consistent, the code needs to be written in a uniform and conventional way.
issue.clean_code_attribute_category.CONSISTENT.issue=Consistency issue
issue.clean_code_attribute_category.CONSISTENT.title_short=Consistency issue
issue.clean_code_attribute_category.INTENTIONAL=Intentionality
issue.clean_code_attribute_category.INTENTIONAL.title=This is an intentionality issue.
issue.clean_code_attribute_category.INTENTIONAL.advice=To be intentional, the code content needs to be precise and purposeful.
issue.clean_code_attribute_category.INTENTIONAL.issue=Intentionality issue
issue.clean_code_attribute_category.INTENTIONAL.title_short=Intentionality issue
issue.clean_code_attribute_category.ADAPTABLE=Adaptability
issue.clean_code_attribute_category.ADAPTABLE.title=This is an adaptability issue.
issue.clean_code_attribute_category.ADAPTABLE.advice=To be adaptable, code needs to be structured to be easy to evolve with confidence.
issue.clean_code_attribute_category.ADAPTABLE.issue=Adaptability issue
issue.clean_code_attribute_category.ADAPTABLE.title_short=Adaptability issue
issue.clean_code_attribute_category.RESPONSIBLE=Responsibility
issue.clean_code_attribute_category.RESPONSIBLE.title=This is a responsibility issue.
issue.clean_code_attribute_category.RESPONSIBLE.advice=To be responsible, the code must take into account its ethical obligations on data and potential impact of societal norms.
issue.clean_code_attribute_category.RESPONSIBLE.issue=Responsibility issue
issue.clean_code_attribute_category.RESPONSIBLE.title_short=Responsibility issue

issue.clean_code_attribute=Clean Code Attribute
issue.clean_code_attribute.CLEAR=Not clear
@@ -2365,6 +2365,53 @@ coding_rules.more_info.resources.title=Resources

coding_rules.more_info.notification_message=We've added new information about Clean Code principles below to help you improve your code quality and security. Take a moment to read through them.
coding_rules.more_info.scroll_message=Scroll down to Code Quality principles

rule.impact.severity.tooltip=Issues found for this rule will have a {severity} impact on the {quality} of your software.

rule.clean_code_attribute_category.CONSISTENT=Consistency
rule.clean_code_attribute_category.CONSISTENT.title=This is a consistency rule.
rule.clean_code_attribute_category.CONSISTENT.title_short=Consistency rule
rule.clean_code_attribute_category.INTENTIONAL=Intentionality
rule.clean_code_attribute_category.INTENTIONAL.title=This is an intentionality rule.
rule.clean_code_attribute_category.INTENTIONAL.title_short=Intentionality rule
rule.clean_code_attribute_category.ADAPTABLE=Adaptability
rule.clean_code_attribute_category.ADAPTABLE.title=This is an adaptability rule.
rule.clean_code_attribute_category.ADAPTABLE.title_short=Adaptability rule
rule.clean_code_attribute_category.RESPONSIBLE=Responsibility
rule.clean_code_attribute_category.RESPONSIBLE.title=This is a responsibility rule.
rule.clean_code_attribute_category.RESPONSIBLE.title_short=Responsibility rule

rule.clean_code_attribute.CLEAR=Clear
rule.clean_code_attribute.CLEAR.title=This is an intentionality rule, the code is not clear enough.
rule.clean_code_attribute.COMPLETE=Complete
rule.clean_code_attribute.COMPLETE.title=This is a intentionality rule, the code is not complete enough.
rule.clean_code_attribute.CONVENTIONAL=Conventional
rule.clean_code_attribute.CONVENTIONAL.title=This is a consistency rule, the code is not conventional enough.
rule.clean_code_attribute.DISTINCT=Distinct
rule.clean_code_attribute.DISTINCT.title=This is an adaptability rule, the code is not distinct enough.
rule.clean_code_attribute.EFFICIENT=Efficient
rule.clean_code_attribute.EFFICIENT.title=This is an intentionality rule, the code is not efficient enough.
rule.clean_code_attribute.FOCUSED=Focused
rule.clean_code_attribute.FOCUSED.title=This is an adaptability rule, the code is not focused enough.
rule.clean_code_attribute.FORMATTED=Formatted
rule.clean_code_attribute.FORMATTED.title=This is a consistency rule, the code is not formatted enough.
rule.clean_code_attribute.IDENTIFIABLE=Identifiable
rule.clean_code_attribute.IDENTIFIABLE.title=This is a consistency rule, the code is not identifiable enough.
rule.clean_code_attribute.LAWFUL=Lawful
rule.clean_code_attribute.LAWFUL.title=This is a responsibility rule, the code is not lawful enough.
rule.clean_code_attribute.LOGICAL=Logical
rule.clean_code_attribute.LOGICAL.title=This is an intentionality rule, the code is not logical enough.
rule.clean_code_attribute.MODULAR=Modular
rule.clean_code_attribute.MODULAR.title=This is an adaptability rule, the code is not modular enough.
rule.clean_code_attribute.RESPECTFUL=Respectful
rule.clean_code_attribute.RESPECTFUL.title=This is a responsibility rule, the code is not respectful enough.
rule.clean_code_attribute.TESTED=Tested
rule.clean_code_attribute.TESTED.title=This is an adaptability rule, the code is not tested enough.
rule.clean_code_attribute.TRUSTWORTHY=Trustworthy
rule.clean_code_attribute.TRUSTWORTHY.title=This is a responsibility rule, the code is not trustworthy enough.



#------------------------------------------------------------------------------
#
# EMAIL CONFIGURATION

Loading…
Cancel
Save