filteredRules = filteredRules.filter((r) => matchingRules.includes(r.key));
}
if (q && q.length > 2) {
- filteredRules = filteredRules.filter((r) => r.name.includes(q));
+ filteredRules = filteredRules.filter((r) => r.name.includes(q) || r.key.includes(q));
}
if (tags) {
filteredRules = filteredRules.filter((r) => r.tags && r.tags.some((t) => tags.includes(t)));
languageName: 'Java',
actions: { edit: true },
}),
- mockQualityProfile({ key: QP_2, name: 'QP Bar', language: 'py', languageName: 'Python' }),
+ mockQualityProfile({
+ key: QP_2,
+ name: 'QP Bar',
+ language: 'py',
+ languageName: 'Python',
+ parentKey: 'sonar_way',
+ parentName: 'Sonar Way',
+ }),
mockQualityProfile({ key: QP_3, name: 'QP FooBar', language: 'java', languageName: 'Java' }),
mockQualityProfile({
key: QP_4,
import selectEvent from 'react-select-event';
import CodingRulesServiceMock, { RULE_TAGS_MOCK } from '../../../api/mocks/CodingRulesServiceMock';
import SettingsServiceMock from '../../../api/mocks/SettingsServiceMock';
-import { QP_2, RULE_1 } from '../../../api/mocks/data/ids';
+import { QP_2, RULE_1, RULE_10 } from '../../../api/mocks/data/ids';
import { CLEAN_CODE_CATEGORIES, SOFTWARE_QUALITIES } from '../../../helpers/constants';
import { mockCurrentUser, mockLoggedInUser } from '../../../helpers/testMocks';
import {
});
});
- it('can activate/deactivate specific rule for quality profile', async () => {
+ it('can activate/change/deactivate specific rule for quality profile', async () => {
const { ui, user } = getPageObjects();
rulesHandler.setIsAdmin();
renderCodingRulesApp(mockLoggedInUser());
await user.click(ui.qpInactiveRadio.get(ui.facetItem('QP Bar Python').get()));
expect(ui.getAllRuleListItems()).toHaveLength(2);
expect(ui.activateButton.getAll()).toHaveLength(2);
+ expect(ui.changeButton(QP_2).query()).not.toBeInTheDocument();
// Activate Rule for qp
await user.click(ui.activateButton.getAll()[0]);
+ expect(ui.selectValue.get(ui.activateQPDialog.get())).toHaveTextContent('severity.MAJOR');
await selectEvent.select(ui.oldSeveritySelect.get(), 'severity.MINOR');
await user.click(ui.activateButton.get(ui.activateQPDialog.get()));
expect(ui.activateButton.getAll()).toHaveLength(1);
+ expect(ui.changeButton('QP Bar').get()).toBeInTheDocument();
expect(ui.deactivateButton.getAll()).toHaveLength(1);
+ // Change Rule for qp
+ await user.click(ui.changeButton('QP Bar').get());
+ expect(ui.selectValue.get(ui.changeQPDialog.get())).toHaveTextContent('severity.MINOR');
+ await selectEvent.select(ui.oldSeveritySelect.get(), 'severity.BLOCKER');
+ await user.click(ui.saveButton.get(ui.changeQPDialog.get()));
+
+ // Check that new severity is saved
+ await user.click(ui.changeButton('QP Bar').get());
+ expect(ui.selectValue.get(ui.changeQPDialog.get())).toHaveTextContent('severity.BLOCKER');
+ await user.click(ui.cancelButton.get(ui.changeQPDialog.get()));
+
// Deactivate activated rule
await user.click(ui.deactivateButton.get());
await user.click(ui.yesButton.get());
expect(ui.activateButton.getAll()).toHaveLength(2);
});
+ it('can revert to parent definition specific rule for quality profile', async () => {
+ const { ui, user } = getPageObjects();
+ settingsHandler.set(SettingsKey.QPAdminCanDisableInheritedRules, 'false');
+ rulesHandler.setIsAdmin();
+ renderCodingRulesApp(mockLoggedInUser());
+ await ui.appLoaded();
+
+ await user.click(ui.qpFacet.get());
+ await user.click(ui.facetItem('QP Bar Python').get());
+
+ // Only 4 rules are activated in selected QP
+ expect(ui.getAllRuleListItems()).toHaveLength(4);
+
+ // 3 rules have deactivate button and 1 rule has revert to parent definition button
+ expect(ui.deactivateButton.getAll()).toHaveLength(3);
+ expect(ui.revertToParentDefinitionButton.get()).toBeInTheDocument();
+
+ await user.type(ui.searchInput.get(), RULE_10);
+
+ // Only 1 rule left after search
+ expect(ui.getAllRuleListItems()).toHaveLength(1);
+ expect(ui.revertToParentDefinitionButton.get()).toBeInTheDocument();
+ expect(ui.changeButton('QP Bar').get()).toBeInTheDocument();
+
+ // Check that severity is reflected correctly
+ await user.click(ui.changeButton('QP Bar').get());
+ expect(ui.selectValue.get(ui.changeQPDialog.get())).toHaveTextContent('severity.MAJOR');
+ await user.click(ui.cancelButton.get(ui.changeQPDialog.get()));
+
+ await user.click(ui.revertToParentDefinitionButton.get());
+ await user.click(ui.yesButton.get());
+
+ expect(ui.getAllRuleListItems()).toHaveLength(1);
+ expect(ui.revertToParentDefinitionButton.query()).not.toBeInTheDocument();
+ expect(ui.deactivateButton.get()).toBeInTheDocument();
+ expect(ui.deactivateButton.get()).toBeDisabled();
+ expect(ui.changeButton('QP Bar').get()).toBeInTheDocument();
+
+ // Check that severity is reflected correctly
+ await user.click(ui.changeButton('QP Bar').get());
+ expect(ui.selectValue.get(ui.changeQPDialog.get())).toHaveTextContent('severity.MINOR');
+ await user.click(ui.cancelButton.get(ui.changeQPDialog.get()));
+ });
+
it('can not deactivate rules for quality profile if setting is false', async () => {
const { ui } = getPageObjects();
rulesHandler.setIsAdmin();
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { DangerButtonSecondary, Tooltip } from 'design-system';
+import * as React from 'react';
+import { Profile } from '../../../api/quality-profiles';
+import ConfirmButton from '../../../components/controls/ConfirmButton';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { Rule, RuleActivation } from '../../../types/types';
+import ActivationButton from './ActivationButton';
+
+interface Props {
+ activation: RuleActivation;
+ profile: Profile;
+ ruleDetails: Rule;
+ onActivate: (severity: string) => Promise<void> | void;
+ handleRevert: (key?: string) => void;
+ handleDeactivate: (key?: string) => void;
+ showDeactivated?: boolean;
+ canDeactivateInherited?: boolean;
+}
+
+export default function ActivatedRuleActions(props: Readonly<Props>) {
+ const {
+ activation,
+ profile,
+ ruleDetails,
+ onActivate,
+ handleRevert,
+ handleDeactivate,
+ showDeactivated,
+ canDeactivateInherited,
+ } = props;
+
+ const canEdit = profile.actions?.edit && !profile.isBuiltIn;
+ const hasParent = activation.inherit !== 'NONE' && profile.parentKey !== undefined;
+
+ return (
+ <>
+ {canEdit && (
+ <>
+ {!ruleDetails.isTemplate && (
+ <ActivationButton
+ className="sw-ml-2"
+ activation={activation}
+ ariaLabel={translateWithParameters('coding_rules.change_details_x', profile.name)}
+ buttonText={translate('change_verb')}
+ modalHeader={translate('coding_rules.change_details')}
+ onDone={onActivate}
+ profiles={[profile]}
+ rule={ruleDetails}
+ />
+ )}
+
+ {hasParent && activation.inherit === 'OVERRIDES' && profile.parentName && (
+ <ConfirmButton
+ confirmButtonText={translate('yes')}
+ confirmData={profile.key}
+ isDestructive
+ modalBody={translateWithParameters(
+ 'coding_rules.revert_to_parent_definition.confirm',
+ profile.parentName,
+ )}
+ modalHeader={translate('coding_rules.revert_to_parent_definition')}
+ onConfirm={handleRevert}
+ >
+ {({ onClick }) => (
+ <DangerButtonSecondary className="sw-ml-2 sw-whitespace-nowrap" onClick={onClick}>
+ {translate('coding_rules.revert_to_parent_definition')}
+ </DangerButtonSecondary>
+ )}
+ </ConfirmButton>
+ )}
+
+ {(!hasParent || canDeactivateInherited) && (
+ <ConfirmButton
+ confirmButtonText={translate('yes')}
+ confirmData={profile.key}
+ modalBody={translate('coding_rules.deactivate.confirm')}
+ modalHeader={translate('coding_rules.deactivate')}
+ onConfirm={handleDeactivate}
+ >
+ {({ onClick }) => (
+ <DangerButtonSecondary
+ className="sw-ml-2 sw-whitespace-nowrap"
+ aria-label={translateWithParameters(
+ 'coding_rules.deactivate_in_quality_profile_x',
+ profile.name,
+ )}
+ onClick={onClick}
+ >
+ {translate('coding_rules.deactivate')}
+ </DangerButtonSecondary>
+ )}
+ </ConfirmButton>
+ )}
+
+ {showDeactivated &&
+ hasParent &&
+ !canDeactivateInherited &&
+ activation.inherit !== 'OVERRIDES' && (
+ <Tooltip overlay={translate('coding_rules.can_not_deactivate')}>
+ <DangerButtonSecondary
+ disabled
+ className="sw-ml-2"
+ aria-label={translateWithParameters(
+ 'coding_rules.deactivate_in_quality_profile_x',
+ profile.name,
+ )}
+ >
+ {translate('coding_rules.deactivate')}
+ </DangerButtonSecondary>
+ </Tooltip>
+ )}
+ </>
+ )}
+ </>
+ );
+}
shouldOpenStandardsFacet,
} from '../../issues/utils';
import {
- Activation,
Actives,
FacetKey,
Facets,
}
};
- handleRuleActivate = (profile: string, rule: string, activation: Activation) =>
+ handleRuleActivate = (profile: string, rule: string, activation: RuleActivation) =>
this.setState((state: State) => {
const { actives = {} } = state;
if (!actives[rule]) {
const actives: Actives = {};
for (const [rule, activations] of Object.entries(rawActives)) {
actives[rule] = {};
- for (const { inherit, qProfile, severity } of activations) {
- actives[rule][qProfile] = { inherit, severity };
+ for (const activation of activations) {
+ actives[rule][activation.qProfile] = { ...activation };
}
}
return actives;
useRuleDetailsQuery,
useUpdateRuleMutation,
} from '../../../queries/rules';
-import { Dict } from '../../../types/types';
-import { Activation } from '../query';
+import { Dict, RuleActivation } from '../../../types/types';
import CustomRuleButton from './CustomRuleButton';
import RuleDetailsCustomRules from './RuleDetailsCustomRules';
import RuleDetailsDescription from './RuleDetailsDescription';
allowCustomRules?: boolean;
canWrite?: boolean;
canDeactivateInherited?: boolean;
- onActivate: (profile: string, rule: string, activation: Activation) => void;
+ onActivate: (profile: string, rule: string, activation: RuleActivation) => void;
onDeactivate: (profile: string, rule: string) => void;
onDelete: (rule: string) => void;
referencedProfiles: Dict<Profile>;
ActionCell,
CellComponent,
ContentCell,
- DangerButtonSecondary,
DiscreetLink,
InheritanceIcon,
Link,
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { Profile } from '../../../api/quality-profiles';
-import ConfirmButton from '../../../components/controls/ConfirmButton';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { translate } from '../../../helpers/l10n';
import { getQualityProfileUrl } from '../../../helpers/urls';
import {
useActivateRuleMutation,
} from '../../../queries/quality-profiles';
import { Dict, RuleActivation, RuleDetails } from '../../../types/types';
import BuiltInQualityProfileBadge from '../../quality-profiles/components/BuiltInQualityProfileBadge';
+import ActivatedRuleActions from './ActivatedRuleActions';
import ActivationButton from './ActivationButton';
interface Props {
};
const renderRowActions = (activation: RuleActivation, profile: Profile) => {
- const canEdit = profile.actions?.edit && !profile.isBuiltIn;
- const hasParent = activation.inherit !== 'NONE' && profile.parentKey;
-
return (
<ActionCell>
- {canEdit && (
- <>
- {!ruleDetails.isTemplate && (
- <ActivationButton
- activation={activation}
- ariaLabel={translateWithParameters('coding_rules.change_details_x', profile.name)}
- buttonText={translate('change_verb')}
- modalHeader={translate('coding_rules.change_details')}
- onDone={props.onActivate}
- profiles={[profile]}
- rule={ruleDetails}
- />
- )}
-
- {hasParent && activation.inherit === 'OVERRIDES' && profile.parentName && (
- <ConfirmButton
- confirmButtonText={translate('yes')}
- confirmData={profile.key}
- isDestructive
- modalBody={translateWithParameters(
- 'coding_rules.revert_to_parent_definition.confirm',
- profile.parentName,
- )}
- modalHeader={translate('coding_rules.revert_to_parent_definition')}
- onConfirm={handleRevert}
- >
- {({ onClick }) => (
- <DangerButtonSecondary className="sw-ml-2 sw-whitespace-nowrap" onClick={onClick}>
- {translate('coding_rules.revert_to_parent_definition')}
- </DangerButtonSecondary>
- )}
- </ConfirmButton>
- )}
-
- {(!hasParent || canDeactivateInherited) && (
- <ConfirmButton
- confirmButtonText={translate('yes')}
- confirmData={profile.key}
- modalBody={translate('coding_rules.deactivate.confirm')}
- modalHeader={translate('coding_rules.deactivate')}
- onConfirm={handleDeactivate}
- >
- {({ onClick }) => (
- <DangerButtonSecondary
- className="sw-ml-2 sw-whitespace-nowrap"
- aria-label={translateWithParameters(
- 'coding_rules.deactivate_in_quality_profile_x',
- profile.name,
- )}
- onClick={onClick}
- >
- {translate('coding_rules.deactivate')}
- </DangerButtonSecondary>
- )}
- </ConfirmButton>
- )}
- </>
- )}
+ <ActivatedRuleActions
+ activation={activation}
+ profile={profile}
+ ruleDetails={ruleDetails}
+ onActivate={props.onActivate}
+ handleDeactivate={handleDeactivate}
+ handleRevert={handleRevert}
+ canDeactivateInherited={canDeactivateInherited}
+ />
</ActionCell>
);
};
} from 'design-system';
import * as React from 'react';
import DocHelpTooltip from '~sonar-aligned/components/controls/DocHelpTooltip';
-import { Profile, deactivateRule } from '../../../api/quality-profiles';
-import ConfirmButton from '../../../components/controls/ConfirmButton';
+import { Profile } from '../../../api/quality-profiles';
import Tooltip from '../../../components/controls/Tooltip';
import { CleanCodeAttributePill } from '../../../components/shared/CleanCodeAttributePill';
import SoftwareImpactPillList from '../../../components/shared/SoftwareImpactPillList';
import TypeHelper from '../../../components/shared/TypeHelper';
import TagsList from '../../../components/tags/TagsList';
-import { DocLink } from '../../../helpers/doc-links';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { getRuleUrl } from '../../../helpers/urls';
-import { Rule } from '../../../types/types';
-import { Activation } from '../query';
+import {
+ useActivateRuleMutation,
+ useDeactivateRuleMutation,
+} from '../../../queries/quality-profiles';
+import { Rule, RuleActivation } from '../../../types/types';
+import ActivatedRuleActions from './ActivatedRuleActions';
import ActivationButton from './ActivationButton';
interface Props {
- activation?: Activation;
+ activation?: RuleActivation;
isLoggedIn: boolean;
canDeactivateInherited?: boolean;
- onActivate: (profile: string, rule: string, activation: Activation) => void;
+ onActivate: (profile: string, rule: string, activation: RuleActivation) => void;
onDeactivate: (profile: string, rule: string) => void;
onOpen: (ruleKey: string) => void;
rule: Rule;
selectedProfile?: Profile;
}
-export default class RuleListItem extends React.PureComponent<Props> {
- handleDeactivate = () => {
- if (this.props.selectedProfile) {
+export default function RuleListItem(props: Readonly<Props>) {
+ const {
+ activation,
+ rule,
+ selectedProfile,
+ isLoggedIn,
+ selected,
+ selectRule,
+ canDeactivateInherited,
+ onDeactivate,
+ onActivate,
+ onOpen,
+ } = props;
+ const { mutate: activateRule } = useActivateRuleMutation((data) => {
+ if (data.reset && activation) {
+ onActivate(data.key, data.rule, {
+ ...activation,
+ // Actually the severity should be taken from the inherited qprofile, but we don't have this information
+ severity: rule.severity,
+ inherit: 'INHERITED',
+ });
+ }
+ });
+ const { mutate: deactivateRule } = useDeactivateRuleMutation((data) =>
+ onDeactivate(data.key, data.rule),
+ );
+ const handleDeactivate = () => {
+ if (selectedProfile) {
const data = {
- key: this.props.selectedProfile.key,
- rule: this.props.rule.key,
+ key: selectedProfile.key,
+ rule: rule.key,
};
- deactivateRule(data).then(
- () => this.props.onDeactivate(data.key, data.rule),
- () => {},
- );
+ deactivateRule(data);
}
};
- handleActivate = (severity: string) => {
- if (this.props.selectedProfile) {
- this.props.onActivate(this.props.selectedProfile.key, this.props.rule.key, {
+ const handleActivate = (severity: string) => {
+ if (selectedProfile) {
+ onActivate(selectedProfile.key, rule.key, {
+ createdAt: new Date().toISOString(),
severity,
- inherit: 'NONE',
+ params: [],
+ qProfile: selectedProfile.key,
+ inherit: activation ? 'OVERRIDES' : 'NONE',
});
}
return Promise.resolve();
};
- handleNameClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
+ const handleRevert = (key?: string) => {
+ if (key !== undefined) {
+ activateRule({
+ key,
+ rule: rule.key,
+ reset: true,
+ });
+ }
+ };
+
+ const handleNameClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
// cmd(ctrl) + click should open a rule permalink in a new tab
const isLeftClickEvent = event.button === 0;
const isModifiedEvent = !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
event.preventDefault();
event.stopPropagation();
- this.props.onOpen(this.props.rule.key);
+ onOpen(rule.key);
};
- renderActivation = () => {
- const { activation, selectedProfile } = this.props;
- if (!activation || !selectedProfile?.parentName) {
+ const renderActivation = () => {
+ if (!activation || selectedProfile?.parentName === undefined) {
return null;
}
);
};
- renderActions = () => {
- const { activation, isLoggedIn, canDeactivateInherited, rule, selectedProfile } = this.props;
-
+ const renderActions = () => {
if (!selectedProfile || !isLoggedIn) {
return null;
}
if (activation) {
return (
- <div className="sw-ml-4">
- {activation.inherit === 'NONE' || canDeactivateInherited ? (
- <ConfirmButton
- confirmButtonText={translate('yes')}
- modalBody={translate('coding_rules.deactivate.confirm')}
- modalHeader={translate('coding_rules.deactivate')}
- onConfirm={this.handleDeactivate}
- >
- {({ onClick }) => (
- <DangerButtonSecondary onClick={onClick}>
- {translate('coding_rules.deactivate')}
- </DangerButtonSecondary>
- )}
- </ConfirmButton>
- ) : (
- <Tooltip content={translate('coding_rules.can_not_deactivate')}>
- <DangerButtonSecondary disabled>
- {translate('coding_rules.deactivate')}
- </DangerButtonSecondary>
- </Tooltip>
- )}
- </div>
+ <ActivatedRuleActions
+ activation={activation}
+ profile={selectedProfile}
+ ruleDetails={rule}
+ onActivate={handleActivate}
+ handleDeactivate={handleDeactivate}
+ handleRevert={handleRevert}
+ showDeactivated
+ canDeactivateInherited={canDeactivateInherited}
+ />
);
}
<ActivationButton
buttonText={translate('coding_rules.activate')}
modalHeader={translate('coding_rules.activate_in_quality_profile')}
- onDone={this.handleActivate}
+ onDone={handleActivate}
profiles={[selectedProfile]}
rule={rule}
/>
);
};
- render() {
- const { rule, selected } = this.props;
- const allTags = [...(rule.tags ?? []), ...(rule.sysTags ?? [])];
- return (
- <ListItemStyled
- selected={selected}
- className="it__coding-rule sw-p-3 sw-mb-4 sw-rounded-1 sw-bg-white"
- aria-current={selected}
- data-rule={rule.key}
- onClick={() => this.props.selectRule(rule.key)}
- >
- <div className="sw-flex sw-flex-col sw-gap-3">
- <div className="sw-flex sw-justify-between sw-items-center">
- <div className="sw-flex sw-items-center">
- {this.renderActivation()}
+ const allTags = [...(rule.tags ?? []), ...(rule.sysTags ?? [])];
+ return (
+ <ListItemStyled
+ selected={selected}
+ className="it__coding-rule sw-p-3 sw-mb-4 sw-rounded-1 sw-bg-white"
+ aria-current={selected}
+ data-rule={rule.key}
+ onClick={() => selectRule(rule.key)}
+ >
+ <div className="sw-flex sw-flex-col sw-gap-3">
+ <div className="sw-flex sw-justify-between sw-items-center">
+ <div className="sw-flex sw-items-center">
+ {renderActivation()}
- <Link
- className="sw-body-sm-highlight"
- onClick={this.handleNameClick}
- to={getRuleUrl(rule.key)}
- >
- {rule.name}
- </Link>
- </div>
+ <Link
+ className="sw-body-sm-highlight"
+ onClick={handleNameClick}
+ to={getRuleUrl(rule.key)}
+ >
+ {rule.name}
+ </Link>
+ </div>
- <div>
- {rule.cleanCodeAttributeCategory !== undefined && (
- <CleanCodeAttributePill
- cleanCodeAttributeCategory={rule.cleanCodeAttributeCategory}
- type="rule"
- />
- )}
- </div>
+ <div>
+ {rule.cleanCodeAttributeCategory !== undefined && (
+ <CleanCodeAttributePill
+ cleanCodeAttributeCategory={rule.cleanCodeAttributeCategory}
+ type="rule"
+ />
+ )}
</div>
+ </div>
- <div className="sw-flex sw-items-center">
- <div className="sw-grow sw-flex sw-gap-2 sw-items-center sw-body-xs">
- {rule.impacts.length > 0 && (
- <SoftwareImpactPillList softwareImpacts={rule.impacts} type="rule" />
- )}
- </div>
+ <div className="sw-flex sw-items-center">
+ <div className="sw-grow sw-flex sw-gap-2 sw-items-center sw-body-xs">
+ {rule.impacts.length > 0 && (
+ <SoftwareImpactPillList softwareImpacts={rule.impacts} type="rule" />
+ )}
+ </div>
- <TextSubdued as="ul" className="sw-flex sw-gap-1 sw-items-center sw-body-xs">
- <li>{rule.langName}</li>
+ <TextSubdued as="ul" className="sw-flex sw-gap-1 sw-items-center sw-body-xs">
+ <li>{rule.langName}</li>
- <SeparatorCircleIcon aria-hidden as="li" />
- <li>
- <DocHelpTooltip
- content={
- <div>
- <p className="sw-mb-2">{translate('coding_rules.type.deprecation.title')}</p>
- <p>{translate('coding_rules.type.deprecation.filter_by')}</p>
- </div>
- }
- links={[
- {
- href: DocLink.CleanCodeIntroduction,
- label: translate('learn_more'),
- },
- ]}
- >
- <TypeHelper
- className="sw-flex sw-items-center"
- iconFill="iconTypeDisabled"
- type={rule.type}
- />
- </DocHelpTooltip>
- </li>
+ <SeparatorCircleIcon aria-hidden as="li" />
+ <li>
+ <DocHelpTooltip
+ content={
+ <div>
+ <p className="sw-mb-2">{translate('coding_rules.type.deprecation.title')}</p>
+ <p>{translate('coding_rules.type.deprecation.filter_by')}</p>
+ </div>
+ }
+ links={[
+ {
+ href: '/user-guide/clean-code/introduction',
+ label: translate('learn_more'),
+ },
+ ]}
+ >
+ <TypeHelper
+ className="sw-flex sw-items-center"
+ iconFill="iconTypeDisabled"
+ type={rule.type}
+ />
+ </DocHelpTooltip>
+ </li>
- {rule.isTemplate && (
- <>
- <SeparatorCircleIcon aria-hidden as="li" />
- <li>
- <Tooltip content={translate('coding_rules.rule_template.title')}>
- <span>
- <Badge>{translate('coding_rules.rule_template')}</Badge>
- </span>
- </Tooltip>
- </li>
- </>
- )}
+ {rule.isTemplate && (
+ <>
+ <SeparatorCircleIcon aria-hidden as="li" />
+ <li>
+ <Tooltip overlay={translate('coding_rules.rule_template.title')}>
+ <span>
+ <Badge>{translate('coding_rules.rule_template')}</Badge>
+ </span>
+ </Tooltip>
+ </li>
+ </>
+ )}
- {rule.status !== 'READY' && (
- <>
- <SeparatorCircleIcon aria-hidden as="li" />
- <li>
- <Badge variant="deleted">{translate('rules.status', rule.status)}</Badge>
- </li>
- </>
- )}
+ {rule.status !== 'READY' && (
+ <>
+ <SeparatorCircleIcon aria-hidden as="li" />
+ <li>
+ <Badge variant="deleted">{translate('rules.status', rule.status)}</Badge>
+ </li>
+ </>
+ )}
- {allTags.length > 0 && (
- <>
- <SeparatorCircleIcon aria-hidden as="li" />
- <li>
- <TagsList
- allowUpdate={false}
- className="sw-body-xs"
- tagsClassName="sw-body-xs"
- tags={allTags}
- />
- </li>
- </>
- )}
- </TextSubdued>
+ {allTags.length > 0 && (
+ <>
+ <SeparatorCircleIcon aria-hidden as="li" />
+ <li>
+ <TagsList
+ allowUpdate={false}
+ className="sw-body-xs"
+ tagsClassName="sw-body-xs"
+ tags={allTags}
+ />
+ </li>
+ </>
+ )}
+ </TextSubdued>
- <div className="sw-flex sw-items-center">{this.renderActions()}</div>
- </div>
+ <div className="sw-flex sw-items-center">{renderActions()}</div>
</div>
- </ListItemStyled>
- );
- }
+ </div>
+ </ListItemStyled>
+ );
}
const ListItemStyled = styled.li<{ selected: boolean }>`
SoftwareImpactSeverity,
SoftwareQuality,
} from '../../types/clean-code-taxonomy';
-import { Dict, RuleInheritance } from '../../types/types';
+import { Dict, RuleActivation, RuleInheritance } from '../../types/types';
export interface Query {
activation: boolean | undefined;
export type OpenFacets = Dict<boolean>;
-export interface Activation {
- inherit: RuleInheritance;
- severity: string;
-}
-
export interface Actives {
[rule: string]: {
- [profile: string]: Activation;
+ [profile: string]: RuleActivation;
};
}
// Rule Quality Profiles
qpLink: (name: string) => byRole('link', { name }),
activateButton: byRole('button', { name: 'coding_rules.activate' }),
- deactivateButton: byRole('button', { name: 'coding_rules.deactivate' }),
+ deactivateButton: byRole('button', { name: /coding_rules.deactivate_in_quality_profile/ }),
oldSeveritySelect: byRole('combobox', { name: 'severity' }),
qualityProfileSelect: byRole('combobox', { name: 'coding_rules.quality_profile' }),
+ selectValue: byText(/severity\./),
activateQPDialog: byRole('dialog', { name: 'coding_rules.activate_in_quality_profile' }),
changeButton: (profile: string) =>
byRole('button', { name: `coding_rules.change_details_x.${profile}` }),