export type Variant = 'error' | 'warning' | 'success' | 'info';
interface Props {
- ariaLabel: string;
variant: Variant;
}
-interface VariantInformation {
- backGroundColor: ThemeColors;
- borderColor: ThemeColors;
- icon: JSX.Element;
- role: string;
-}
-
-function getVariantInfo(variant: Variant): VariantInformation {
- const variantList: Record<Variant, VariantInformation> = {
+function getVariantInfo(variant: Variant) {
+ const variantList = {
error: {
icon: <FlagErrorIcon />,
borderColor: 'errorBorder',
backGroundColor: 'errorBackground',
- role: 'alert',
},
warning: {
icon: <FlagWarningIcon />,
borderColor: 'warningBorder',
backGroundColor: 'warningBackground',
- role: 'alert',
},
success: {
icon: <FlagSuccessIcon />,
borderColor: 'successBorder',
backGroundColor: 'successBackground',
- role: 'status',
},
info: {
icon: <FlagInfoIcon />,
borderColor: 'infoBorder',
backGroundColor: 'infoBackground',
- role: 'status',
},
- };
+ } as const;
return variantList[variant];
}
export function FlagMessage(props: Props & React.HTMLAttributes<HTMLDivElement>) {
- const { ariaLabel, className, variant, ...domProps } = props;
+ const { className, variant, ...domProps } = props;
const variantInfo = getVariantInfo(variant);
return (
<StyledFlag
- aria-label={ariaLabel}
+ backGroundColor={variantInfo.backGroundColor}
+ borderColor={variantInfo.borderColor}
className={classNames('alert', className)}
- role={variantInfo.role}
- variantInfo={variantInfo}
{...domProps}
>
- <StyledFlagInner>
- <StyledFlagIcon variantInfo={variantInfo}>{variantInfo.icon}</StyledFlagIcon>
- <StyledFlagContent>{props.children}</StyledFlagContent>
- </StyledFlagInner>
+ <div className="flag-inner">
+ <div className="flag-icon">{variantInfo.icon}</div>
+ <div className="flag-content">{props.children}</div>
+ </div>
</StyledFlag>
);
}
FlagMessage.displayName = 'FlagMessage'; // so that tests don't see the obfuscated production name
export const StyledFlag = styled.div<{
- variantInfo: VariantInformation;
+ backGroundColor: ThemeColors;
+ borderColor: ThemeColors;
}>`
${tw`sw-inline-flex`}
${tw`sw-min-h-10`}
${tw`sw-rounded-1`}
- border: ${({ variantInfo }) => themeBorder('default', variantInfo.borderColor)};
+ border: ${({ borderColor }) => themeBorder('default', borderColor)};
background-color: ${themeColor('flagMessageBackground')};
-`;
-const StyledFlagInner = styled.div`
- ${tw`sw-flex sw-items-stretch`}
- ${tw`sw-box-border`}
-`;
+ & > .flag-inner {
+ ${tw`sw-flex sw-items-stretch`}
+ ${tw`sw-box-border`}
+ }
-const StyledFlagIcon = styled.div<{ variantInfo: VariantInformation }>`
- ${tw`sw-flex sw-justify-center sw-items-center`}
- ${tw`sw-rounded-l-1`}
- ${tw`sw-px-3`}
- background-color: ${({ variantInfo }) => themeColor(variantInfo.backGroundColor)};
-`;
+ & .flag-icon {
+ ${tw`sw-flex sw-justify-center sw-items-center`}
+ ${tw`sw-rounded-l-1`}
+ ${tw`sw-px-3`}
+ background-color: ${({ backGroundColor }) => themeColor(backGroundColor)};
+ }
-const StyledFlagContent = styled.div`
- ${tw`sw-flex sw-flex-auto sw-items-center`}
- ${tw`sw-overflow-auto`}
- ${tw`sw-text-left`}
- ${tw`sw-mx-3 sw-my-2`}
- ${tw`sw-body-sm`}
- color: ${themeContrast('flagMessageBackground')};
+ & .flag-content {
+ ${tw`sw-flex sw-flex-auto sw-items-center`}
+ ${tw`sw-overflow-auto`}
+ ${tw`sw-text-left`}
+ ${tw`sw-mx-3 sw-my-2`}
+ ${tw`sw-body-sm`}
+ color: ${themeContrast('flagMessageBackground')};
+ }
`;
import { FlagMessage, Variant } from '../FlagMessage';
it.each([
- ['error', 'alert', '1px solid rgb(249,112,102)'],
- ['warning', 'alert', '1px solid rgb(248,205,92)'],
- ['success', 'status', '1px solid rgb(50,213,131)'],
- ['info', 'status', '1px solid rgb(110,185,228)'],
-])('should render properly for "%s" variant', (variant: Variant, expectedRole, color) => {
+ ['error', '1px solid rgb(249,112,102)'],
+ ['warning', '1px solid rgb(248,205,92)'],
+ ['success', '1px solid rgb(50,213,131)'],
+ ['info', '1px solid rgb(110,185,228)'],
+])('should render properly for "%s" variant', (variant: Variant, color) => {
renderFlagMessage({ variant });
- const item = screen.getByRole(expectedRole);
+ const item = screen.getByRole('status');
expect(item).toBeInTheDocument();
expect(item).toHaveStyle({ border: color });
});
function renderFlagMessage(props: Partial<FCProps<typeof FlagMessage>> = {}) {
return render(
- <FlagMessage ariaLabel="label" variant="error" {...props}>
+ <FlagMessage role="status" variant="error" {...props}>
This is an error!
</FlagMessage>
);
if (currentTask?.status === TaskStatuses.Failed) {
return (
<>
- <FlagMessage ariaLabel={translate('alert.tooltip.error')} variant="error">
+ <FlagMessage variant="error">
<span>{translate('project_navigation.analysis_status.failed')}</span>
<Link className="sw-ml-1" blurAfterClick onClick={openModal} preventDefault to={{}}>
{translate('project_navigation.analysis_status.details_link')}
if (warnings.length > 0) {
return (
<>
- <FlagMessage ariaLabel={translate('alert.tooltip.warning')} variant="warning">
+ <FlagMessage variant="warning">
<span>{translate('project_navigation.analysis_status.warnings')}</span>
<Link className="sw-ml-1" blurAfterClick onClick={openModal} preventDefault to={{}}>
{translate('project_navigation.analysis_status.details_link')}
<A11ySkipTarget anchor="code_main" />
{!canBrowseAllChildProjects && isPortfolio && (
- <FlagMessage
- ariaLabel={translate('code_viewer.not_all_measures_are_shown')}
- variant="warning"
- className="it__portfolio_warning sw-mb-4"
- >
+ <FlagMessage variant="warning" className="it__portfolio_warning sw-mb-4">
{translate('code_viewer.not_all_measures_are_shown')}
<HelpTooltip
className="sw-ml-2"
viewSelect: byLabelText('component_measures.view_as'),
emptyText: byText('component_measures.empty'),
detailsUnavailableText: byText('component_measures.details_are_not_available'),
- noAccessWarning: byRole('alert'),
+ noAccessWarning: byText('component_measures.not_all_measures_are_shown'),
showingOutOfTxt: (x: string, y: string) => byText(`x_of_y_shown.${x}.${y}`),
showAllBtn: byRole('button', {
name: 'component_measures.hidden_best_score_metrics_show_label',
view={this.props.view}
/>
{hidingBestMeasures && this.props.paging && (
- <FlagMessage
- ariaLabel={translateWithParameters(
- 'component_measures.hidden_best_score_metrics',
- formatMeasure(
- this.props.paging.total - filteredComponents.length,
- MetricType.Integer
- ),
- formatMeasure(this.props.metric.bestValue, this.props.metric.type)
- )}
- variant="info"
- className="sw-mt-4"
- >
+ <FlagMessage variant="info" className="sw-mt-4">
{translateWithParameters(
'component_measures.hidden_best_score_metrics',
formatMeasure(
}}
>
{!canBrowseAllChildProjects && isPortfolioLike(qualifier) && (
- <FlagMessage
- ariaLabel={translate('component_measures.not_all_measures_are_shown')}
- className="sw-mt-4 it__portfolio_warning"
- variant="warning"
- >
+ <FlagMessage className="sw-mt-4 it__portfolio_warning" variant="warning">
{translate('component_measures.not_all_measures_are_shown')}
<HelpTooltip
className="spacer-left"
<DeferredSpinner loading={loading}>
<form id="bulk-change-form" onSubmit={this.handleSubmit}>
{limitReached && (
- <FlagMessage
- ariaLabel={translate('alert.tooltip.warning')}
- className="sw-mb-4"
- variant="warning"
- >
+ <FlagMessage className="sw-mb-4" variant="warning">
<span>
<FormattedMessage
defaultMessage={translate('issue_bulk_change.max_issues_reached')}
{this.renderCommentField()}
{issues.length > 0 && this.renderNotificationsField()}
{issues.length === 0 && (
- <FlagMessage ariaLabel={translate('alert.tooltip.warning')} variant="warning">
- {translate('issue_bulk_change.no_match')}
- </FlagMessage>
+ <FlagMessage variant="warning">{translate('issue_bulk_change.no_match')}</FlagMessage>
)}
</form>
</DeferredSpinner>
const warning = !canBrowseAllChildProjects && isPortfolioLike(qualifier) && (
<FlagMessage
- ariaLabel={translate('issues.not_all_issue_show')}
className="it__portfolio_warning sw-flex"
title={translate('issues.not_all_issue_show_why')}
variant="warning"
) : (
<DeferredSpinner loading={loading} ariaLabel={translate('issues.loading_issues')}>
{checkAll && paging && paging.total > MAX_PAGE_SIZE && (
- <FlagMessage
- ariaLabel={translate('issue_bulk_change.max_issues_reached')}
- variant="warning"
- >
+ <FlagMessage variant="warning">
<span>
<FormattedMessage
defaultMessage={translate('issue_bulk_change.max_issues_reached')}
)}
{cannotShowOpenIssue && (!paging || paging.total > 0) && (
- <FlagMessage
- ariaLabel={translateWithParameters(
- 'issues.cannot_open_issue_max_initial_X_fetched',
- MAX_INITAL_FETCH
- )}
- className="sw-mb-4"
- variant="warning"
- >
+ <FlagMessage className="sw-mb-4" variant="warning">
{translateWithParameters(
'issues.cannot_open_issue_max_initial_X_fetched',
MAX_INITAL_FETCH
return (
<>
{issueIsClosed && (
- <FlagMessage
- className="sw-mb-2 sw-flex"
- variant="success"
- ariaLabel={translate(closedIssueMessageKey)}
- >
+ <FlagMessage className="sw-mb-2 sw-flex" variant="success">
<div className="sw-block">
<FormattedMessage
id={closedIssueMessageKey}
/>
{mightHaveMoreResults && this.state.showFullList && (
- <FlagMessage
- ariaLabel={translate('facet_might_have_more_results')}
- className="sw-flex sw-my-4"
- variant="warning"
- >
+ <FlagMessage className="sw-flex sw-my-4" variant="warning">
{translate('facet_might_have_more_results')}
</FlagMessage>
)}
</FacetItemsList>
{searchMaxResults && (
- <FlagMessage
- ariaLabel={translate('facet_might_have_more_results')}
- className="sw-flex sw-my-4"
- variant="warning"
- >
+ <FlagMessage className="sw-flex sw-my-4" variant="warning">
{translate('facet_might_have_more_results')}
</FlagMessage>
)}
return (
<Card className="sw-mt-4 sw-body-sm">
{caycStatus === CaycStatus.NonCompliant ? (
- <FlagMessage
- ariaLabel={translateWithParameters(
- 'overview.quality_gate.application.non_cayc.projects_x',
- projects.length
- )}
- variant="warning"
- >
+ <FlagMessage variant="warning">
{translateWithParameters(
'overview.quality_gate.application.non_cayc.projects_x',
projects.length
return (
<>
- <FlagMessage
- ariaLabel={translate('overview.quality_gate.conditions.cayc.warning')}
- variant="warning"
- >
+ <FlagMessage variant="warning">
{translate('overview.quality_gate.conditions.cayc.warning')}
</FlagMessage>
{component.qualityGate ? (
}
/* eslint-enable no-lonely-if */
- return (
- <FlagMessage ariaLabel={title} variant="warning">
- {title}
- </FlagMessage>
- );
+ return <FlagMessage variant="warning">{title}</FlagMessage>;
}
export default React.memo(NoCodeWarning);
export default function IgnoredConditionWarning() {
return (
- <FlagMessage
- ariaLabel={translate('overview.quality_gate.ignored_conditions')}
- className="sw-mb-4"
- variant="info"
- >
+ <FlagMessage className="sw-mb-4" variant="info">
<span>{translate('overview.quality_gate.ignored_conditions')}</span>
<HelpTooltip
className="sw-ml-2"
return (
<div className="sw-w-abs-400">
{inRemovedComponent && (
- <FlagMessage
- ariaLabel={translate('duplications.dups_found_on_deleted_resource')}
- variant="warning"
- >
+ <FlagMessage variant="warning">
{translate('duplications.dups_found_on_deleted_resource')}
</FlagMessage>
)}
{translate('coding_rules.description_context.title')}
</h2>
{defaultContext && (
- <FlagMessage
- variant="info"
- className="sw-mb-4"
- ariaLabel={translateWithParameters(
- 'coding_rules.description_context.default_information',
- defaultContext.displayName
- )}
- >
+ <FlagMessage variant="info" className="sw-mb-4">
{translateWithParameters(
'coding_rules.description_context.default_information',
defaultContext.displayName