Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [Rules > Shared exception lists][AXE-CORE]: Interactive controls must not be nested #178023

Merged
merged 8 commits into from
Mar 14, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import React, { memo } from 'react';
import React, { memo, useMemo } from 'react';

import {
EuiLink,
Expand All @@ -15,7 +15,8 @@ import {
EuiPanel,
EuiText,
EuiAccordion,
EuiButtonIcon,
useEuiTheme,
useEuiShadow,
} from '@elastic/eui';
import { css } from '@emotion/css';
import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
Expand Down Expand Up @@ -72,13 +73,7 @@ interface ExceptionsListCardProps {
}) => () => Promise<void>;
readOnly: boolean;
}
const buttonCss = css`
z-index: 100;
.euiAccordion__buttonContent {
cursor: pointer;
width: 100%;
}
`;

const ExceptionPanel = styled(EuiPanel)`
margin: -${euiThemeVars.euiSizeS} ${euiThemeVars.euiSizeM} 0 ${euiThemeVars.euiSizeM};
`;
Expand All @@ -98,6 +93,26 @@ export const ExceptionsListCard = memo<ExceptionsListCardProps>(
onCancelManageRules,
onRuleSelectionChange,
} = useListDetailsView(exceptionsList.list_id);
const { euiTheme } = useEuiTheme();
const panelShadow = useEuiShadow();

const euiAccordionStyles = useMemo(
() => css`
z-index: 100;
margin: ${euiTheme.size.m} 0;
.euiAccordion__buttonContent {
cursor: pointer;
width: 100%;
}
.euiAccordion__triggerWrapper {
border-radius: ${euiTheme.border.radius.medium};
padding: ${euiTheme.size.base};

${panelShadow}
}
`,
[euiTheme.border.radius.medium, euiTheme.size.base, euiTheme.size.m, panelShadow]
);

const {
listId,
Expand Down Expand Up @@ -142,101 +157,85 @@ export const ExceptionsListCard = memo<ExceptionsListCardProps>(
return (
<EuiFlexGroup gutterSize="none">
<EuiFlexItem>
<EuiPanel hasShadow={false}>
<EuiAccordion
// Note: this uses `className` instead of the `css` prop, because a plugin
// cannot be set up for styled-components and `@emotion/react` at the same time
// @see https://github.com/elastic/eui/discussions/6828#discussioncomment-6076157
buttonProps={{ className: buttonCss }}
id={openAccordionId}
arrowDisplay="none"
onToggle={() => setToggleAccordion(!toggleAccordion)}
buttonContent={
<EuiPanel>
<ListHeaderContainer gutterSize="m" alignItems="flexStart">
<EuiFlexItem grow={false}>
<EuiButtonIcon
iconType={toggleAccordion ? 'arrowDown' : 'arrowRight'}
aria-label="Next"
/>
<EuiAccordion
// Note: this uses `className` instead of the `css` prop, because a plugin
// cannot be set up for styled-components and `@emotion/react` at the same time
// @see https://github.com/elastic/eui/discussions/6828#discussioncomment-6076157
className={euiAccordionStyles}
id={openAccordionId}
buttonElement="div"
onToggle={() => setToggleAccordion(!toggleAccordion)}
buttonContent={
<ListHeaderContainer gutterSize="m" alignItems="center">
<EuiFlexItem grow={false}>
<EuiFlexGroup
direction="column"
key={listId}
alignItems="flexStart"
gutterSize="none"
>
<EuiFlexItem grow>
<EuiText size="m">
<EuiLink data-test-subj="exception-list-name" onClick={goToExceptionDetail}>
{listName}
</EuiLink>
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup
direction="column"
key={listId}
alignItems="flexStart"
gutterSize="none"
>
<EuiFlexItem grow>
<EuiText size="m">
<EuiLink
data-test-subj="exception-list-name"
onClick={goToExceptionDetail}
>
{listName}
</EuiLink>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow>
<EuiText size="xs">
<EuiTextColor color="subdued">{listDescription}</EuiTextColor>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexItem grow>
<EuiText size="xs">
<EuiTextColor color="subdued">{listDescription}</EuiTextColor>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>

<EuiFlexItem>
<EuiFlexGroup alignItems="center">
<EuiFlexItem>
<TitleBadge title={i18n.DATE_CREATED} badgeString={createdAt} />
</EuiFlexItem>
<EuiFlexItem>
<TitleBadge title={i18n.CREATED_BY} badgeString={createdBy} />
</EuiFlexItem>
<EuiFlexItem>
<TitleBadge title={i18n.EXCEPTIONS} badgeString={exceptionItemsCount} />
</EuiFlexItem>
<EuiFlexItem data-test-subj="exceptionListCardLinkedRulesBadge">
<TitleBadge
title={i18n.RULES}
badgeString={linkedRules.length.toString()}
/>
</EuiFlexItem>
<EuiFlexItem>
<HeaderMenu
disableActions={readOnly}
dataTestSubj="sharedListOverflowCard"
actions={menuActionItems}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexItem>
<EuiFlexGroup alignItems="center" justifyContent="flexEnd" wrap>
<EuiFlexItem grow={false}>
<TitleBadge title={i18n.DATE_CREATED} badgeString={createdAt} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<TitleBadge title={i18n.CREATED_BY} badgeString={createdBy} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<TitleBadge title={i18n.EXCEPTIONS} badgeString={exceptionItemsCount} />
</EuiFlexItem>
<EuiFlexItem data-test-subj="exceptionListCardLinkedRulesBadge" grow={false}>
<TitleBadge title={i18n.RULES} badgeString={linkedRules.length.toString()} />
</EuiFlexItem>
</ListHeaderContainer>
</EuiPanel>
}
data-test-subj={`exceptionsManagementListCard-${listId}`}
>
<ExceptionPanel hasBorder>
<ListExceptionItems
isReadOnly={readOnly}
exceptions={exceptions}
listType={exceptionsList.type as ExceptionListTypeEnum}
pagination={pagination}
hideUtility
viewerStatus={exceptionViewerStatus}
ruleReferences={ruleReferences}
onDeleteException={onDeleteException}
onEditExceptionItem={onEditExceptionItem}
onPaginationChange={onPaginationChange}
onCreateExceptionListItem={onAddExceptionClick}
lastUpdated={null}
emptyViewerTitle={emptyViewerTitle}
emptyViewerBody={emptyViewerBody}
emptyViewerButtonText={emptyViewerButtonText}
/>
</ExceptionPanel>
</EuiAccordion>
</EuiPanel>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<HeaderMenu
disableActions={readOnly}
dataTestSubj="sharedListOverflowCard"
actions={menuActionItems}
/>
</EuiFlexItem>
</ListHeaderContainer>
}
data-test-subj={`exceptionsManagementListCard-${listId}`}
>
<ExceptionPanel hasBorder>
<ListExceptionItems
isReadOnly={readOnly}
exceptions={exceptions}
listType={exceptionsList.type as ExceptionListTypeEnum}
pagination={pagination}
hideUtility
viewerStatus={exceptionViewerStatus}
ruleReferences={ruleReferences}
onDeleteException={onDeleteException}
onEditExceptionItem={onEditExceptionItem}
onPaginationChange={onPaginationChange}
onCreateExceptionListItem={onAddExceptionClick}
lastUpdated={null}
emptyViewerTitle={emptyViewerTitle}
emptyViewerBody={emptyViewerBody}
emptyViewerButtonText={emptyViewerButtonText}
/>
</ExceptionPanel>
</EuiAccordion>
</EuiFlexItem>
{showAddExceptionFlyout ? (
<AddExceptionFlyout
Expand Down