Browse Source

SONAR-22012 Improve CaYC messages on Custom QGs and Sonar way

pull/3360/head
Revanshu Paliwal 1 month ago
parent
commit
a827904491

+ 7
- 3
server/sonar-web/src/main/js/apps/quality-gates/components/CaycCompliantBanner.tsx View File

@@ -28,13 +28,17 @@ import { FormattedMessage } from 'react-intl';
import DocumentationLink from '../../../components/common/DocumentationLink';
import { translate } from '../../../helpers/l10n';
import { OPTIMIZED_CAYC_CONDITIONS } from '../utils';
import QGRecommendedIcon from './QGRecommendedIcon';

export default function CaycCompliantBanner() {
return (
<CardWithPrimaryBackground className="sw-mb-9 sw-p-8">
<SubHeadingHighlight className="sw-mb-2">
{translate('quality_gates.cayc.banner.title')}
</SubHeadingHighlight>
<div className="sw-flex sw-items-center sw-mb-2">
<QGRecommendedIcon className="sw-mr-2" />
<SubHeadingHighlight className="sw-m-0">
{translate('quality_gates.cayc.banner.title')}
</SubHeadingHighlight>
</div>

<div>
<FormattedMessage

+ 22
- 0
server/sonar-web/src/main/js/apps/quality-gates/components/Conditions.tsx View File

@@ -23,6 +23,7 @@ import {
HeadingDark,
HelperHintIcon,
HighlightedSection,
LightLabel,
LightPrimary,
Link,
Note,
@@ -34,6 +35,7 @@ import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { useAvailableFeatures } from '../../../app/components/available-features/withAvailableFeatures';
import { useMetrics } from '../../../app/components/metrics/withMetricsContext';
import DocumentationLink from '../../../components/common/DocumentationLink';
import DocumentationTooltip from '../../../components/common/DocumentationTooltip';
import ModalButton, { ModalProps } from '../../../components/controls/ModalButton';
import { useDocUrl } from '../../../helpers/docs';
@@ -49,6 +51,7 @@ import CaycCondition from './CaycCondition';
import CaycFixOptimizeBanner from './CaycFixOptimizeBanner';
import CaycReviewUpdateConditionsModal from './ConditionReviewAndUpdateModal';
import ConditionsTable from './ConditionsTable';
import QGRecommendedIcon from './QGRecommendedIcon';

interface Props {
qualityGate: QualityGate;
@@ -145,6 +148,25 @@ export default function Conditions({ qualityGate, isFetching }: Readonly<Props>)
<div>
<CaYCConditionsSimplificationGuide qualityGate={qualityGate} />

{qualityGate.isBuiltIn && (
<div className="sw-flex sw-items-center sw-mt-2 sw-mb-9">
<QGRecommendedIcon className="sw-mr-1" />
<LightLabel>
<FormattedMessage
defaultMessage="quality_gates.is_built_in.cayc.description"
id="quality_gates.is_built_in.cayc.description"
values={{
link: (
<DocumentationLink to="/user-guide/clean-as-you-code/">
{translate('clean_as_you_code')}
</DocumentationLink>
),
}}
/>
</LightLabel>
</div>
)}

{isCompliantCustomQualityGate && !isOptimizing && <CaycCompliantBanner />}
{isCompliantCustomQualityGate && isOptimizing && canEdit && (
<CaycFixOptimizeBanner renderCaycModal={renderCaycModal} isOptimizing />

+ 0
- 43
server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx View File

@@ -22,23 +22,18 @@ import {
Badge,
ButtonSecondary,
DangerButtonPrimary,
FlagWarningIcon,
ItemButton,
ItemDangerButton,
ItemDivider,
LightLabel,
SubTitle,
} from 'design-system';
import { countBy } from 'lodash';
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import DocumentationLink from '../../../components/common/DocumentationLink';
import Tooltip from '../../../components/controls/Tooltip';
import { translate } from '../../../helpers/l10n';
import { useSetQualityGateAsDefaultMutation } from '../../../queries/quality-gates';
import { CaycStatus, QualityGate } from '../../../types/types';
import BuiltInQualityGateBadge from './BuiltInQualityGateBadge';
import CaycBadgeTooltip from './CaycBadgeTooltip';
import CopyQualityGateForm from './CopyQualityGateForm';
import DeleteQualityGateForm from './DeleteQualityGateForm';
import RenameQualityGateForm from './RenameQualityGateForm';
@@ -47,8 +42,6 @@ interface Props {
qualityGate: QualityGate;
}

const TOOLTIP_MOUSE_LEAVE_DELAY = 0.3;

export default function DetailsHeader({ qualityGate }: Readonly<Props>) {
const [isRenameFormOpen, setIsRenameFormOpen] = React.useState(false);
const [isCopyFormOpen, setIsCopyFormOpen] = React.useState(false);
@@ -60,7 +53,6 @@ export default function DetailsHeader({ qualityGate }: Readonly<Props>) {
actions.delete,
actions.setAsDefault,
])['true'];
const canEdit = Boolean(actions?.manageConditions);
const { mutateAsync: setQualityGateAsDefault } = useSetQualityGateAsDefaultMutation();

const handleSetAsDefaultClick = () => {
@@ -75,46 +67,11 @@ export default function DetailsHeader({ qualityGate }: Readonly<Props>) {
<div className="sw-flex sw-flex-col">
<div className="sw-flex sw-items-baseline">
<SubTitle className="sw-m-0">{qualityGate.name}</SubTitle>
{qualityGate.caycStatus === CaycStatus.NonCompliant && canEdit && (
<Tooltip overlay={<CaycBadgeTooltip />} mouseLeaveDelay={TOOLTIP_MOUSE_LEAVE_DELAY}>
<FlagWarningIcon className="sw-ml-2" description={<CaycBadgeTooltip />} />
</Tooltip>
)}
<div className="sw-flex sw-gap-2 sw-ml-4">
{qualityGate.isDefault && <Badge>{translate('default')}</Badge>}
{qualityGate.isBuiltIn && <BuiltInQualityGateBadge />}
</div>
</div>
{qualityGate.isBuiltIn && (
<>
<LightLabel className="sw-mt-2">
<FormattedMessage
defaultMessage="quality_gates.is_built_in.cayc.description"
id="quality_gates.is_built_in.cayc.description"
values={{
link: (
<DocumentationLink to="/user-guide/clean-as-you-code/">
{translate('clean_as_you_code')}
</DocumentationLink>
),
}}
/>
</LightLabel>
<span className="sw-mt-9">
<FormattedMessage
defaultMessage="quality_gates.is_built_in.description"
id="quality_gates.is_built_in.description"
values={{
link: (
<DocumentationLink to="/user-guide/quality-gates/#using-sonar-way-the-recommended-quality-gate">
{translate('learn_more')}
</DocumentationLink>
),
}}
/>
</span>
</>
)}
</div>
{actionsCount === 1 && (
<>

+ 9
- 13
server/sonar-web/src/main/js/apps/quality-gates/components/List.tsx View File

@@ -17,13 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import {
Badge,
BareButton,
FlagWarningIcon,
SubnavigationGroup,
SubnavigationItem,
} from 'design-system';
import { Badge, BareButton, SubnavigationGroup, SubnavigationItem } from 'design-system';
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
import Tooltip from '../../../components/controls/Tooltip';
@@ -32,6 +26,7 @@ import { translate } from '../../../helpers/l10n';
import { getQualityGateUrl } from '../../../helpers/urls';
import { CaycStatus, QualityGate } from '../../../types/types';
import BuiltInQualityGateBadge from './BuiltInQualityGateBadge';
import QGRecommendedIcon from './QGRecommendedIcon';

interface Props {
qualityGates: QualityGate[];
@@ -80,12 +75,13 @@ export default function List({ qualityGates, currentQualityGate }: Props) {
</div>
)}
</div>
{qualityGate.caycStatus === CaycStatus.NonCompliant &&
qualityGate.actions?.manageConditions && (
<Tooltip overlay={translate('quality_gates.cayc.tooltip.message')}>
<FlagWarningIcon description={translate('quality_gates.cayc.tooltip.message')} />
</Tooltip>
)}
{qualityGate.caycStatus !== CaycStatus.NonCompliant && (
<Tooltip overlay={translate('quality_gates.cayc.tooltip.message')}>
<span>
<QGRecommendedIcon />
</span>
</Tooltip>
)}
</SubnavigationItem>
);
})}

server/sonar-web/src/main/js/apps/quality-gates/components/CaycBadgeTooltip.tsx → server/sonar-web/src/main/js/apps/quality-gates/components/QGRecommendedIcon.tsx View File

@@ -17,19 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import DocumentationLink from '../../../components/common/DocumentationLink';
import { translate } from '../../../helpers/l10n';

export default function CaycBadgeTooltip() {
return (
<div>
<p className="sw-mb-2 sw-pb-2 bordered-bottom-cayc">
{translate('quality_gates.cayc.tooltip.message')}
</p>
<DocumentationLink to="/user-guide/clean-as-you-code/">
{translate('quality_gates.cayc.badge.tooltip.learn_more')}
</DocumentationLink>
</div>
);
}
import styled from '@emotion/styled';
import { IconRecommended } from '@sonarsource/echoes-react';
import { themeColor } from 'design-system';

const QGRecommendedIcon = styled(IconRecommended)`
color: ${themeColor('primary')};
`;

export default QGRecommendedIcon;

+ 0
- 4
server/sonar-web/src/main/js/apps/quality-gates/components/__tests__/QualityGate-it.tsx View File

@@ -82,7 +82,6 @@ it('should render the built-in quality gate properly', async () => {
await user.click(builtInQualityGate);

expect(await screen.findByText(/quality_gates.is_built_in.cayc.description/)).toBeInTheDocument();
expect(await screen.findByText(/quality_gates.is_built_in.description/)).toBeInTheDocument();
});

it('should be able to create a quality gate then delete it', async () => {
@@ -424,7 +423,6 @@ it('should not warn user when quality gate is not CaYC compliant and user has no
await user.click(nonCompliantQualityGate);

expect(screen.queryByRole('alert')).not.toBeInTheDocument();
expect(screen.queryByText('quality_gates.cayc.tooltip.message')).not.toBeInTheDocument();
});

it('should not show optimize banner when quality gate is compliant but non-CaYC and user has no permission to edit it', async () => {
@@ -438,7 +436,6 @@ it('should not show optimize banner when quality gate is compliant but non-CaYC
await user.click(nonCompliantQualityGate);

expect(screen.queryByRole('alert')).not.toBeInTheDocument();
expect(screen.queryByText('quality_gates.cayc.tooltip.message')).not.toBeInTheDocument();
});

it('should warn user when quality gate is not CaYC compliant and user has permission to edit it', async () => {
@@ -449,7 +446,6 @@ it('should warn user when quality gate is not CaYC compliant and user has permis
const nonCompliantQualityGate = await screen.findByRole('button', { name: /Non Cayc QG/ });

await user.click(nonCompliantQualityGate);
// expect(screen.getByTestId('conditions')).toMatchSnapshot();

expect(await screen.findByText(/quality_gates.cayc_missing.banner.title/)).toBeInTheDocument();
expect(screen.getAllByText('quality_gates.cayc.tooltip.message').length).toBeGreaterThan(0);

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

@@ -2317,7 +2317,7 @@ quality_gates.cayc.new_maintainability_rating=Technical debt ratio is greater th
quality_gates.cayc.new_reliability_rating.A=No bugs
quality_gates.cayc.new_security_rating.A=No vulnerabilities
quality_gates.cayc.unlock_edit=Unlock editing
quality_gates.cayc.tooltip.message=This quality gate does not comply with Clean as You Code.
quality_gates.cayc.tooltip.message=This quality gate is configured for Clean as You Code.
quality_gates.cayc.badge.tooltip.learn_more=Learn more: Clean as You Code
quality_gates.cayc.banner.title=This quality gate complies with Clean as You Code
quality_gates.cayc.banner.description1=This quality gate complies with the {cayc_link} methodology, so that you benefit from the most efficient approach to delivering Clean Code.

Loading…
Cancel
Save