Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,25 @@ export const ExceptionsListCard = memo<ExceptionsListCardProps>(
onCancelManageRules,
onRuleSelectionChange,
} = useListDetailsView(exceptionsList.list_id);
const { euiTheme } = useEuiTheme();
const panelShadow = useEuiShadow();

const euiAccordionStyles = useMemo(
() => css`
.euiAccordion__buttonContent {
flex: 1 1 auto;
cursor: pointer;
}
.euiAccordion__triggerWrapper {
z-index: 100;
position: relative;
border-radius: ${euiTheme.border.radius.medium};
padding: ${euiTheme.size.base};
${panelShadow}
}
`,
[euiTheme.border.radius.medium, euiTheme.size.base, panelShadow]
);

const {
listId,
Expand Down Expand Up @@ -140,104 +154,86 @@ 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"
/>
</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>
<>
<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" justifyContent="spaceBetween">
<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 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>
</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}
<EuiFlexItem>
<EuiFlexGroup alignItems="center" justifyContent="flexEnd" wrap responsive>
<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>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<HeaderMenu
disableActions={readOnly}
dataTestSubj="sharedListOverflowCard"
actions={menuActionItems}
/>
</ExceptionPanel>
</EuiAccordion>
</EuiPanel>
</EuiFlexItem>
</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>
{showAddExceptionFlyout ? (
<AddExceptionFlyout
rules={null}
Expand Down Expand Up @@ -278,7 +274,7 @@ export const ExceptionsListCard = memo<ExceptionsListCardProps>(
action={showIncludeExpiredExceptionsModal}
/>
) : null}
</EuiFlexGroup>
</>
);
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
import { useApi, useExceptionLists } from '@kbn/securitysolution-list-hooks';
import { EmptyViewerState, ViewerStatus } from '@kbn/securitysolution-exception-list-components';

import styled from 'styled-components';
import { euiThemeVars } from '@kbn/ui-theme';
import { AutoDownload } from '../../../common/components/auto_download/auto_download';
import { useKibana } from '../../../common/lib/kibana';
import { useAppToasts } from '../../../common/hooks/use_app_toasts';
Expand Down Expand Up @@ -79,6 +81,10 @@ const SORT_FIELDS: Array<{ field: string; label: string; defaultOrder: 'asc' | '
},
];

const ExceptionsTable = styled(EuiFlexGroup)`
padding: ${euiThemeVars.euiSizeL} 0;
`;

export const SharedLists = React.memo(() => {
const [{ loading: userInfoLoading, canUserCRUD, canUserREAD }] = useUserData();

Expand Down Expand Up @@ -587,19 +593,20 @@ export const SharedLists = React.memo(() => {
sortFields={SORT_FIELDS}
/>
{exceptionListsWithRuleRefs.length > 0 && (
<div data-test-subj="exceptionsTable">
<ExceptionsTable data-test-subj="exceptionsTable" direction="column">
{exceptionListsWithRuleRefs.map((excList) => (
<ExceptionsListCard
key={excList.list_id}
data-test-subj="exceptionsListCard"
readOnly={isReadOnly}
exceptionsList={excList}
handleDelete={handleDelete}
handleExport={handleExport}
handleDuplicate={handleDuplicate}
/>
<EuiFlexItem key={excList.list_id}>
<ExceptionsListCard
data-test-subj="exceptionsListCard"
readOnly={isReadOnly}
exceptionsList={excList}
handleDelete={handleDelete}
handleExport={handleExport}
handleDuplicate={handleDuplicate}
/>
</EuiFlexItem>
))}
</div>
</ExceptionsTable>
)}
</>
)}
Expand Down