[8.x] [ResponseOps] Replace SCSS with CSS-in-JS (#214092) (#216640)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponseOps] Replace SCSS with CSS-in-JS
(#214092)](https://github.com/elastic/kibana/pull/214092)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Georgiana-Andreea
Onoleață","email":"georgiana.onoleata@elastic.co"},"sourceCommit":{"committedDate":"2025-04-01T12:48:37Z","message":"[ResponseOps]
Replace SCSS with CSS-in-JS (#214092)\n\nCloses
https://github.com/elastic/kibana/issues/208303\n\n## Summary\n\n- This
PR removes SCSS (Sass) from RO plugins and replaces it
with\n`@emotion/react ` as
recommended.","sha":"67c35302e36c6a557c8138697986c171d23e81b4","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","backport:version","v9.1.0","v8.19.0","scss-removal"],"title":"[ResponseOps]
Replace SCSS with
CSS-in-JS","number":214092,"url":"https://github.com/elastic/kibana/pull/214092","mergeCommit":{"message":"[ResponseOps]
Replace SCSS with CSS-in-JS (#214092)\n\nCloses
https://github.com/elastic/kibana/issues/208303\n\n## Summary\n\n- This
PR removes SCSS (Sass) from RO plugins and replaces it
with\n`@emotion/react ` as
recommended.","sha":"67c35302e36c6a557c8138697986c171d23e81b4"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/214092","number":214092,"mergeCommit":{"message":"[ResponseOps]
Replace SCSS with CSS-in-JS (#214092)\n\nCloses
https://github.com/elastic/kibana/issues/208303\n\n## Summary\n\n- This
PR removes SCSS (Sass) from RO plugins and replaces it
with\n`@emotion/react ` as
recommended.","sha":"67c35302e36c6a557c8138697986c171d23e81b4"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
This commit is contained in:
Georgiana-Andreea Onoleață 2025-04-02 11:16:05 +03:00 committed by GitHub
parent 9c8b23ad7b
commit 8ebca65915
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
48 changed files with 416 additions and 342 deletions

View file

@ -1,6 +0,0 @@
.messageVariablesPanel {
max-height: $euiSize * 20;
max-width: $euiSize * 20;
@include euiYScrollWithShadows;
}

View file

@ -24,7 +24,6 @@ import {
EuiSelectableOption,
} from '@elastic/eui';
import type { ActionVariable } from '@kbn/alerting-types';
import './add_message_variables.scss';
import { TruncatedText } from './truncated_text';
import * as i18n from './translations';

View file

@ -25,7 +25,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import type { Subscription } from 'rxjs';
import { debounce, isEqual, isEqualWith } from 'lodash';
import type { FilterGroupProps, FilterControlConfig } from './types';
import './index.scss';
import { FilterGroupLoading } from './loading';
import { useControlGroupSyncToLocalStorage } from './hooks/use_control_group_sync_to_local_storage';
import { useViewEditMode } from './hooks/use_view_edit_mode';

View file

@ -1,11 +0,0 @@
[class*=options_list_popover_footer--OptionsListPopoverFooter] {
display: none;
}
[data-test-subj=optionsListControl__sortingOptionsButton] {
display: none
}
[id^=control-popover] .euiPopoverTitle {
display: none
}

View file

@ -1,23 +0,0 @@
.actCheckActionTypeEnabled__disabledActionWarningCard {
background-color: $euiColorLightestShade;
}
.actAccordionActionForm {
background-color: $euiColorLightestShade;
}
.actAccordionActionForm .euiCard {
box-shadow: none;
}
.actAccordionActionForm__button {
padding: $euiSizeM;
padding-left: $euiSizeL;
}
.actAccordionActionForm .euiAccordion__arrow {
transform: translateX($euiSizeM) rotate(0deg) !important;
}
.actAccordionActionForm .euiAccordion__arrow[aria-expanded='true'] {
transform: translateX($euiSizeM) rotate(90deg) !important;
}

View file

@ -9,7 +9,7 @@
import type { ActionType } from '@kbn/actions-types';
import type { ActionConnector } from '../common/types';
import './check_action_type_enabled.scss';
import { configurationCheckResult, getLicenseCheckResult } from './get_license_check_result';
export interface IsEnabledResult {

View file

@ -9,6 +9,7 @@
import { EuiFlyoutResizable, EuiLoadingElastic } from '@elastic/eui';
import React, { Suspense, lazy, useCallback } from 'react';
import { css } from '@emotion/react';
import type { RuleFormProps } from '../src/rule_form';
import type { RuleTypeMetaData } from '../src/types';
import {
@ -25,6 +26,11 @@ const RuleFormFlyoutRenderer = <MetaData extends RuleTypeMetaData>(
props: RuleFormProps<MetaData>
) => {
const { onClickClose, hideCloseButton } = useRuleFlyoutUIContext();
const inLineContainerCss = css`
container-type: inline-size;
`;
const onClose = useCallback(() => {
// If onClickClose has been initialized, call it instead of onCancel. onClickClose should be used to
// determine if the close confirmation modal should be shown. props.onCancel is passed down the component hierarchy
@ -41,11 +47,11 @@ const RuleFormFlyoutRenderer = <MetaData extends RuleTypeMetaData>(
return (
<EuiFlyoutResizable
ownFocus
css={inLineContainerCss}
onClose={onClose}
aria-labelledby="flyoutTitle"
size={620}
minWidth={500}
className="ruleFormFlyout__container"
hideCloseButton={hideCloseButton}
>
<Suspense

View file

@ -30,6 +30,7 @@ import {
EuiSelectableProps,
useCurrentEuiBreakpoint,
} from '@elastic/eui';
import { css } from '@emotion/react';
import {
ActionConnector,
type ActionTypeModel,
@ -69,6 +70,32 @@ export const RuleActionsConnectorsBody = ({
const currentBreakpoint = useCurrentEuiBreakpoint() ?? 'm';
const containerCss = css`
.showForContainer--s,
showForContainer--xs {
display: none;
}
@container (max-width: 767px) and (min-width: 575px) {
.hideForContainer--s {
display: none;
}
.showForContainer--s {
display: initial !important;
}
}
@container (max-width: 574px) {
.hideForContainer--xs {
display: none;
}
.showForContainer--xs {
display: initial !important;
}
}
`;
const {
plugins: { actionTypeRegistry },
formData: { actions },
@ -431,7 +458,11 @@ export const RuleActionsConnectorsBody = ({
return (
<>
<EuiFlexGroup direction="column" style={{ overflow: responsiveOverflow, height: '100%' }}>
<EuiFlexGroup
direction="column"
style={{ overflow: responsiveOverflow, height: '100%' }}
css={containerCss}
>
<EuiFlexItem grow={false}>
<EuiFlexGroup direction="column">
<EuiFlexGroup gutterSize="s" wrap={false} responsive={false}>

View file

@ -15,6 +15,7 @@ import {
useCurrentEuiBreakpoint,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import React, { useCallback } from 'react';
import { ACTION_TYPE_MODAL_TITLE } from '../translations';
import { RuleActionsConnectorsBody } from './rule_actions_connectors_body';
@ -24,6 +25,10 @@ export const RuleActionsConnectorsModal = () => {
const { euiTheme } = useEuiTheme();
const currentBreakpoint = useCurrentEuiBreakpoint() ?? 'm';
const isFullscreenPortrait = ['s', 'xs'].includes(currentBreakpoint);
const inLineContainerCss = css`
container-type: inline-size;
background-color: transparent;
`;
const responsiveHeight = isFullscreenPortrait ? 'initial' : '80vh';
const responsiveOverflow = isFullscreenPortrait ? 'auto' : 'hidden';
@ -48,7 +53,7 @@ export const RuleActionsConnectorsModal = () => {
<EuiModalHeader>
<EuiModalHeaderTitle size="s">{ACTION_TYPE_MODAL_TITLE}</EuiModalHeaderTitle>
</EuiModalHeader>
<EuiModalBody className="actionConnectorModal__container">
<EuiModalBody css={inLineContainerCss}>
<RuleActionsConnectorsBody
responsiveOverflow={responsiveOverflow}
onSelectConnector={onClose}

View file

@ -129,6 +129,12 @@ export const RuleActionsSystemActionsItem = (props: RuleActionsSystemActionsItem
const subdued = useEuiBackgroundColor('subdued');
const { euiTheme } = useEuiTheme();
const ruleActionsSystemActionsItemCss = css`
.actCheckActionTypeEnabled__disabledActionWarningCard {
background-color: ${subdued};
}
`;
const dispatch = useRuleFormDispatch();
const actionTypeModel = actionTypeRegistry.get(action.actionTypeId);
const actionType = connectorTypes.find(({ id }) => id === action.actionTypeId)!;
@ -230,6 +236,7 @@ export const RuleActionsSystemActionsItem = (props: RuleActionsSystemActionsItem
data-test-subj="ruleActionsSystemActionsItem"
initialIsOpen
borders="all"
css={ruleActionsSystemActionsItemCss}
style={{
backgroundColor: subdued,
borderRadius: euiTheme.border.radius.medium,

View file

@ -23,7 +23,9 @@ import {
EuiSplitPanel,
EuiText,
useEuiTheme,
useEuiFontSize,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { RuleSpecificFlappingProperties } from '@kbn/alerting-types';
import {
RuleSettingsFlappingForm,
@ -70,9 +72,32 @@ export const RuleDefinition = () => {
flappingSettings,
} = useRuleFormState();
const { colorMode } = useEuiTheme();
const { colorMode, euiTheme } = useEuiTheme();
const dispatch = useRuleFormDispatch();
const ruleDefinitionContainerCss = css`
@container (max-width: 767px) {
.euiDescribedFormGroup {
flex-direction: column;
}
.euiDescribedFormGroup > .euiFlexItem {
width: 100%;
}
.ruleDefinitionHeader {
flex-direction: column;
gap: ${euiTheme.size.m};
}
.ruleDefinitionHeaderRuleTypeName {
font-size: ${useEuiFontSize('m')}
margin-bottom: ${euiTheme.size.xs}
}
.ruleDefinitionHeaderRuleTypeDescription,
.ruleDefinitionHeaderDocsLink {
font-size: ${useEuiFontSize('s')};
}
}
`;
useEffect(() => {
// Need to do a dry run validating the params because the Missing Monitor Data rule type
// does not properly initialize the params
@ -191,7 +216,12 @@ export const RuleDefinition = () => {
);
return (
<EuiSplitPanel.Outer hasBorder hasShadow={false} data-test-subj="ruleDefinition">
<EuiSplitPanel.Outer
hasBorder
hasShadow={false}
data-test-subj="ruleDefinition"
css={ruleDefinitionContainerCss}
>
<EuiSplitPanel.Inner color="subdued">
<EuiFlexGroup gutterSize="s" className="ruleDefinitionHeader">
<EuiFlexItem grow={false} data-test-subj="ruleDefinitionHeaderRuleTypeName">

View file

@ -1,55 +0,0 @@
.ruleForm__container {
container-type: inline-size;
}
.ruleFormFlyout__container {
container-type: inline-size;
}
.actionConnectorModal__container {
container-type: inline-size;
}
@container (max-width: 767px) {
.euiDescribedFormGroup {
flex-direction: column;
}
.euiDescribedFormGroup > .euiFlexItem {
width: 100%;
}
.ruleDefinitionHeader {
flex-direction: column;
gap: $euiSizeM;
}
.ruleDefinitionHeaderRuleTypeName {
font-size: $euiFontSizeM;
margin-bottom: $euiSizeXS;
}
.ruleDefinitionHeaderRuleTypeDescription, .ruleDefinitionHeaderDocsLink {
font-size: $euiFontSizeS;
}
}
[class*='showForContainer'] {
display: none;
}
@container (max-width: 767px) and (min-width: 575px) {
.hideForContainer--s {
display: none;
}
.showForContainer--s {
display: initial !important;
}
}
@container (max-width: 574px) {
.hideForContainer--xs {
display: none;
}
.showForContainer--xs {
display: initial !important;
}
}

View file

@ -13,7 +13,6 @@ import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { type RuleCreationValidConsumer } from '@kbn/rule-data-utils';
import { CreateRuleForm } from './create_rule_form';
import { EditRuleForm } from './edit_rule_form';
import './rule_form.scss';
import { RuleFormScreenContextProvider } from './rule_form_screen_context';
import {
RULE_FORM_ROUTE_PARAMS_ERROR_TEXT,

View file

@ -15,8 +15,8 @@ import {
EuiPageTemplate,
EuiSpacer,
EuiSteps,
useEuiBackgroundColorCSS,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { checkActionFormActionTypeEnabled } from '@kbn/alerts-ui-shared';
import React, { useCallback, useMemo, useState } from 'react';
import { useRuleFormScreenContext, useRuleFormState, useRuleFormSteps } from '../hooks';
@ -46,7 +46,10 @@ export const RulePage = (props: RulePageProps) => {
const { actions } = formData;
const styles = useEuiBackgroundColorCSS().transparent;
const inLineContainerCss = css`
container-type: inline-size;
background-color: transparent;
`;
const onSaveInternal = useCallback(() => {
onSave({
@ -86,10 +89,9 @@ export const RulePage = (props: RulePageProps) => {
grow
bottomBorder
offset={0}
css={styles}
css={inLineContainerCss}
onClick={onInteraction}
onKeyDown={onInteraction}
className="ruleForm__container"
data-test-subj="ruleForm"
>
<EuiPageTemplate.Header>

View file

@ -1,9 +0,0 @@
.searchSourceAlertFilters {
.euiExpression__value {
width: 80%;
}
}
.dscExpressionParam.euiExpression {
margin-left: 0;
}

View file

@ -6,7 +6,6 @@
*/
import React, { useCallback, useEffect, useState } from 'react';
import './search_source_expression.scss';
import { EuiSpacer, EuiLoadingSpinner, EuiEmptyPrompt, EuiCallOut } from '@elastic/eui';
import { ISearchSource } from '@kbn/data-plugin/common';
import { RuleTypeParamsExpressionProps } from '@kbn/triggers-actions-ui-plugin/public';

View file

@ -1,3 +0,0 @@
.actAlertVisualization__chart {
height: $euiSize * 14;
}

View file

@ -15,7 +15,9 @@ import {
EuiText,
EuiFieldSearch,
EuiFormRow,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { HttpSetup } from '@kbn/core/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import {
@ -32,7 +34,6 @@ import {
import { COMPARATORS } from '@kbn/alerting-comparators';
import { ThresholdVisualization } from './visualization';
import { IndexThresholdRuleParams } from './types';
import './expression.scss';
import { IndexSelectPopover } from '../components/index_select_popover';
export const DEFAULT_VALUES = {
@ -97,6 +98,8 @@ export const IndexThresholdRuleTypeExpression: React.FunctionComponent<
filterKuery,
} = ruleParams;
const { euiTheme } = useEuiTheme();
const indexArray = indexParamToArray(index);
const { http } = useKibana<KibanaDeps>().services;
@ -122,6 +125,10 @@ export const IndexThresholdRuleTypeExpression: React.FunctionComponent<
}
);
const alertVizualizationChartCss = css`
height: calc(${euiTheme.size.base} * 14);
`;
const setDefaultExpressionValues = async () => {
setRuleProperty('params', {
...ruleParams,
@ -313,7 +320,7 @@ export const IndexThresholdRuleTypeExpression: React.FunctionComponent<
/>
</EuiFormRow>
<EuiSpacer />
<div className="actAlertVisualization__chart">
<div className="actAlertVisualization__chart" css={alertVizualizationChartCss}>
{cannotShowVisualization ? (
<Fragment>
<EuiEmptyPrompt

View file

@ -1,13 +0,0 @@
@mixin padBannerWith($size) {
padding-left: $size;
padding-right: $size;
}
.alertingHealthCheck__body {
@include padBannerWith(2 * $euiSize);
}
.alertingFlyoutHealthCheck__body {
@include padBannerWith(2 * $euiSize);
margin-top: $euiSize;
}

View file

@ -6,17 +6,17 @@
*/
import React, { FC, PropsWithChildren } from 'react';
import { css } from '@emotion/react';
import { Option, none, some, fold, isSome } from 'fp-ts/lib/Option';
import { pipe } from 'fp-ts/lib/pipeable';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiLink, EuiSpacer } from '@elastic/eui';
import { EuiLink, EuiSpacer, useEuiTheme, EuiThemeComputed } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { EuiEmptyPrompt } from '@elastic/eui';
import { DocLinksStart, HttpSetup } from '@kbn/core/public';
import { AlertingFrameworkHealth } from '@kbn/alerting-types';
import './health_check.scss';
import { fetchUiHealthStatus as triggersActionsUiHealth } from '@kbn/alerts-ui-shared/src/common/apis/fetch_ui_health_status';
import { fetchAlertingFrameworkHealth as alertingFrameworkHealth } from '@kbn/alerts-ui-shared/src/common/apis/fetch_alerting_framework_health';
import { useHealthContext } from '../context/health_context';
@ -34,6 +34,19 @@ interface HealthStatus {
hasPermanentEncryptionKey: boolean;
}
const alertingHealthCheckCss = (euiTheme: EuiThemeComputed) => css`
.alertingHealthCheck__body {
padding-left: calc(${euiTheme.size.base} * 2);
padding-right: calc(${euiTheme.size.base} * 2);
}
.alertingFlyoutHealthCheck__body {
padding-left: calc(${euiTheme.size.base} * 2);
padding-right: calc(${euiTheme.size.base} * 2);
margin-top: ${euiTheme.size.base};
}
`;
export const HealthCheck: FC<PropsWithChildren<Props>> = ({
children,
waitForCheck,
@ -42,6 +55,7 @@ export const HealthCheck: FC<PropsWithChildren<Props>> = ({
const { http, docLinks } = useKibana().services;
const { setLoadingHealthCheck } = useHealthContext();
const [alertingHealth, setAlertingHealth] = React.useState<Option<HealthStatus>>(none);
const { euiTheme } = useEuiTheme();
React.useEffect(() => {
(async function () {
@ -91,13 +105,17 @@ export const HealthCheck: FC<PropsWithChildren<Props>> = ({
return healthCheck?.isSufficientlySecure && healthCheck?.hasPermanentEncryptionKey ? (
<>{children}</>
) : !healthCheck.isRulesAvailable ? (
<AlertsError docLinks={docLinks} className={className} />
<AlertsError docLinks={docLinks} className={className} euiTheme={euiTheme} />
) : !healthCheck.isSufficientlySecure && !healthCheck.hasPermanentEncryptionKey ? (
<ApiKeysAndEncryptionError docLinks={docLinks} className={className} />
<ApiKeysAndEncryptionError
docLinks={docLinks}
className={className}
euiTheme={euiTheme}
/>
) : !healthCheck.hasPermanentEncryptionKey ? (
<EncryptionError docLinks={docLinks} className={className} />
<EncryptionError docLinks={docLinks} className={className} euiTheme={euiTheme} />
) : (
<ApiKeysDisabledError docLinks={docLinks} className={className} />
<ApiKeysDisabledError docLinks={docLinks} className={className} euiTheme={euiTheme} />
);
}
)
@ -120,13 +138,15 @@ async function getAlertingFrameworkHealth(
interface PromptErrorProps {
docLinks: DocLinksStart;
className?: string;
euiTheme: EuiThemeComputed;
}
const EncryptionError = ({ docLinks, className }: PromptErrorProps) => (
const EncryptionError = ({ docLinks, className, euiTheme }: PromptErrorProps) => (
<EuiEmptyPrompt
iconType="watchesApp"
data-test-subj="actionNeededEmptyPrompt"
className={className}
css={alertingHealthCheckCss(euiTheme)}
titleSize="xs"
title={
<h2>
@ -159,11 +179,12 @@ const EncryptionError = ({ docLinks, className }: PromptErrorProps) => (
/>
);
const ApiKeysDisabledError = ({ docLinks, className }: PromptErrorProps) => (
const ApiKeysDisabledError = ({ docLinks, className, euiTheme }: PromptErrorProps) => (
<EuiEmptyPrompt
iconType="watchesApp"
data-test-subj="actionNeededEmptyPrompt"
className={className}
css={alertingHealthCheckCss(euiTheme)}
titleSize="xs"
title={
<h2>
@ -197,11 +218,12 @@ const ApiKeysDisabledError = ({ docLinks, className }: PromptErrorProps) => (
/>
);
const AlertsError = ({ docLinks, className }: PromptErrorProps) => (
const AlertsError = ({ docLinks, className, euiTheme }: PromptErrorProps) => (
<EuiEmptyPrompt
iconType="watchesApp"
data-test-subj="alertsNeededEmptyPrompt"
className={className}
css={alertingHealthCheckCss(euiTheme)}
titleSize="xs"
title={
<h2>
@ -228,11 +250,12 @@ const AlertsError = ({ docLinks, className }: PromptErrorProps) => (
/>
);
const ApiKeysAndEncryptionError = ({ docLinks, className }: PromptErrorProps) => (
const ApiKeysAndEncryptionError = ({ docLinks, className, euiTheme }: PromptErrorProps) => (
<EuiEmptyPrompt
iconType="watchesApp"
data-test-subj="actionNeededEmptyPrompt"
className={className}
css={alertingHealthCheckCss(euiTheme)}
titleSize="xs"
title={
<h2>

View file

@ -1,3 +0,0 @@
.actEmptyConnectorsPrompt__logo + .actEmptyConnectorsPrompt__logo {
margin-left: $euiSize;
}

View file

@ -14,9 +14,10 @@ import {
EuiIcon,
EuiSpacer,
EuiTitle,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { DocLinksStart } from '@kbn/core-doc-links-browser';
import './empty_connectors_prompt.scss';
export const EmptyConnectorsPrompt = ({
onCTAClicked,
@ -24,62 +25,84 @@ export const EmptyConnectorsPrompt = ({
}: {
onCTAClicked: () => void;
docLinks: DocLinksStart;
}) => (
<EuiPageTemplate.EmptyPrompt
data-test-subj="createFirstConnectorEmptyPrompt"
title={
<>
<EuiIcon type="logoSlack" size="xl" className="actEmptyConnectorsPrompt__logo" />
<EuiIcon type="logoGmail" size="xl" className="actEmptyConnectorsPrompt__logo" />
<EuiIcon type="logoWebhook" size="xl" className="actEmptyConnectorsPrompt__logo" />
<EuiSpacer size="s" />
<EuiTitle size="m">
<h2>
}) => {
const { euiTheme } = useEuiTheme();
const emptyConnectorsLogoCss = css`
margin-left: ${euiTheme.size.base};
`;
return (
<EuiPageTemplate.EmptyPrompt
data-test-subj="createFirstConnectorEmptyPrompt"
title={
<>
<EuiIcon
type="logoSlack"
size="xl"
className="actEmptyConnectorsPrompt__logo"
css={emptyConnectorsLogoCss}
/>
<EuiIcon
type="logoGmail"
size="xl"
className="actEmptyConnectorsPrompt__logo"
css={emptyConnectorsLogoCss}
/>
<EuiIcon
type="logoWebhook"
size="xl"
className="actEmptyConnectorsPrompt__logo"
css={emptyConnectorsLogoCss}
/>
<EuiSpacer size="s" />
<EuiTitle size="m">
<h2>
<FormattedMessage
id="xpack.triggersActionsUI.components.emptyConnectorsPrompt.addConnectorEmptyTitle"
defaultMessage="Create your first connector"
/>
</h2>
</EuiTitle>
</>
}
body={
<p>
<FormattedMessage
id="xpack.triggersActionsUI.components.emptyConnectorsPrompt.addConnectorEmptyBody"
defaultMessage="Configure various third-party services to Kibana."
/>
</p>
}
actions={
<>
<EuiButton
data-test-subj="createFirstActionButton"
key="create-action"
fill
iconType="plusInCircle"
iconSide="left"
onClick={onCTAClicked}
>
<FormattedMessage
id="xpack.triggersActionsUI.components.emptyConnectorsPrompt.addConnectorEmptyTitle"
defaultMessage="Create your first connector"
id="xpack.triggersActionsUI.components.emptyConnectorsPrompt.addConnectorButtonLabel"
defaultMessage="Create connector"
/>
</h2>
</EuiTitle>
</>
}
body={
<p>
<FormattedMessage
id="xpack.triggersActionsUI.components.emptyConnectorsPrompt.addConnectorEmptyBody"
defaultMessage="Configure various third-party services to Kibana."
/>
</p>
}
actions={
<>
<EuiButton
data-test-subj="createFirstActionButton"
key="create-action"
fill
iconType="plusInCircle"
iconSide="left"
onClick={onCTAClicked}
>
<FormattedMessage
id="xpack.triggersActionsUI.components.emptyConnectorsPrompt.addConnectorButtonLabel"
defaultMessage="Create connector"
/>
</EuiButton>
<br />
<EuiButtonEmpty
data-test-subj="documentationButton"
key="documentation-button"
target="_blank"
href={docLinks.links.alerting.connectors}
iconType="help"
>
<FormattedMessage
id="xpack.triggersActionsUI.sections.actionsConnectorsList.documentationButtonLabel"
defaultMessage="Documentation"
/>
</EuiButtonEmpty>
</>
}
/>
);
</EuiButton>
<br />
<EuiButtonEmpty
data-test-subj="documentationButton"
key="documentation-button"
target="_blank"
href={docLinks.links.alerting.connectors}
iconType="help"
>
<FormattedMessage
id="xpack.triggersActionsUI.sections.actionsConnectorsList.documentationButtonLabel"
defaultMessage="Documentation"
/>
</EuiButtonEmpty>
</>
}
/>
);
};

View file

@ -6,6 +6,7 @@
*/
import React, { Suspense, useEffect, useState, useCallback, useMemo } from 'react';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { AlertConsumers } from '@kbn/rule-data-utils';
@ -160,6 +161,7 @@ export const ActionTypeForm = ({
unifiedSearch,
data,
} = useKibana().services;
const { euiTheme } = useEuiTheme();
const [isOpen, setIsOpen] = useState(true);
const [availableActionVariables, setAvailableActionVariables] = useState<ActionVariable[]>([]);
@ -206,6 +208,28 @@ export const ActionTypeForm = ({
[aadTemplateFields, availableActionVariables, useAadTemplateFields]
);
const actAccordionActionFormCss = css`
.actAccordionActionForm {
background-color: ${euiTheme.colors.lightestShade};
.euiCard {
box-shador: none;
}
.actAccordionActionForm__button {
padding: ${euiTheme.size.m};
padding-left: ${euiTheme.size.l};
}
.euiAccordion__arrow {
transform: translateX(${euiTheme.size.m}) rotate(0deg) !important;
}
.euiAccordion__arrow[aria-expanded='true'] {
transform: translateX(${euiTheme.size.m}) rotate(90deg) !important;
}
}
`;
let showMustacheAutocompleteSwitch;
try {
showMustacheAutocompleteSwitch =
@ -590,7 +614,7 @@ export const ActionTypeForm = ({
return (
<>
<EuiSplitPanel.Outer hasShadow={isOpen}>
<EuiSplitPanel.Outer hasShadow={isOpen} css={actAccordionActionFormCss}>
<EuiAccordion
initialIsOpen={true}
key={index}

View file

@ -1,7 +0,0 @@
.actConnectorModal {
z-index: 9000;
}
.euiComboBoxOptionsList {
z-index: 9001;
}

View file

@ -23,8 +23,8 @@ import {
EuiSpacer,
useGeneratedHtmlId,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import './connector_add_modal.scss';
import { TECH_PREVIEW_DESCRIPTION, TECH_PREVIEW_LABEL } from '../translations';
import { hasSaveActionsCapability } from '../../lib/capabilities';
import {
@ -220,6 +220,9 @@ const ConnectorAddModal = ({
return (
<EuiModal
className="actConnectorModal"
css={css`
z-index: 9000;
`}
data-test-subj="connectorAddModal"
onClose={closeModal}
style={{ width: actionTypeRegistry.get(actionType.id).modalWidth }}

View file

@ -23,7 +23,9 @@ import {
EuiSplitPanel,
EuiCallOut,
IconType,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { isEmpty, partition, some } from 'lodash';
import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common';
import { ActionGroupWithMessageVariables } from '@kbn/triggers-actions-ui-types';
@ -89,6 +91,30 @@ export const SystemActionTypeForm = ({
errors: {},
});
const { euiTheme } = useEuiTheme();
const actAccordionActionFormCss = css`
.actAccordionActionForm {
background-color: ${euiTheme.colors.lightestShade};
.euiCard {
box-shador: none;
}
.actAccordionActionForm__button {
padding: ${euiTheme.size.m};
padding-left: ${euiTheme.size.l};
}
.euiAccordion__arrow {
transform: translateX(${euiTheme.size.m}) rotate(0deg) !important;
}
.euiAccordion__arrow[aria-expanded='true'] {
transform: translateX(${euiTheme.size.m}) rotate(90deg) !important;
}
}
`;
const [warning, setWarning] = useState<string | null>(null);
const { fields: aadTemplateFields } = useRuleTypeAadTemplateFields(http, ruleTypeId, true);
@ -222,7 +248,7 @@ export const SystemActionTypeForm = ({
return (
<>
<EuiSplitPanel.Outer hasShadow={isOpen}>
<EuiSplitPanel.Outer hasShadow={isOpen} css={actAccordionActionFormCss}>
<EuiAccordion
initialIsOpen={true}
key={index}

View file

@ -1,11 +0,0 @@
.actConnectorsList__tableRowDisabled {
background-color: $euiColorLightestShade;
.actConnectorsList__tableCellDisabled {
color: $euiColorDarkShade;
}
.euiLink + .euiToolTipAnchor {
margin-left: $euiSizeXS;
}
}

View file

@ -21,8 +21,10 @@ import {
EuiButtonEmpty,
EuiBadge,
EuiPageTemplate,
useEuiTheme,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { css } from '@emotion/react';
import { useHistory, useLocation, useParams } from 'react-router-dom';
import { getConnectorCompatibility } from '@kbn/actions-plugin/common';
import { FormattedMessage } from '@kbn/i18n-react';
@ -34,7 +36,7 @@ import {
hasExecuteActionsCapability,
} from '../../../lib/capabilities';
import { DeleteModalConfirmation } from '../../../components/delete_modal_confirmation';
import './actions_connectors_list.scss';
import {
ActionConnector,
ActionConnectorTableItem,
@ -92,6 +94,7 @@ const ActionsConnectorsList = ({
docLinks,
} = useKibana().services;
const { euiTheme } = useEuiTheme();
const { connectorId } = useParams<{ connectorId?: string }>();
const history = useHistory();
const location = useLocation();
@ -105,6 +108,19 @@ const ActionsConnectorsList = ({
const [connectorsToDelete, setConnectorsToDelete] = useState<string[]>([]);
const [showWarningText, setShowWarningText] = useState<boolean>(false);
const disabledActConnectorCss = css`
.actConnectorsList__tableRowDisabled {
background-color: ${euiTheme.colors.lightestShade};
.actConnectorsList__tableCellDisabled {
color: ${euiTheme.colors.darkShade};
}
.euiLink + .euiToolTipAnchor {
margin-left: ${euiTheme.size.xs};
}
}
`;
// Set breadcrumb and page title
useEffect(() => {
setBreadcrumbs([getAlertingSectionBreadcrumb('connectors')]);
@ -364,6 +380,7 @@ const ActionsConnectorsList = ({
sorting={true}
itemId="id"
columns={actionsTableColumns}
css={disabledActConnectorCss}
rowProps={(item: ActionConnectorTableItem) => ({
className:
!item.isPreconfigured &&

View file

@ -25,6 +25,7 @@ import {
EuiIconTip,
EuiText,
} from '@elastic/eui';
import { css } from '@emotion/react';
import {
IExecutionLog,
executionLogSortableColumns,
@ -35,7 +36,6 @@ import { get } from 'lodash';
import { getIsExperimentalFeatureEnabled } from '../../../../../common/get_experimental_features';
import { EventLogListCellRenderer, ColumnId, EventLogPaginationStatus } from '.';
import { RuleActionErrorBadge } from '../../../rule_details/components/rule_action_error_badge';
import './event_log_list.scss';
export const getIsColumnSortable = (columnId: string) => {
return executionLogSortableColumns.includes(columnId as ExecutionLogSortFields);
@ -177,6 +177,10 @@ export const EventLogDataGrid = (props: EventLogDataGrid) => {
const { euiTheme } = useEuiTheme();
const selectedRowCss = css`
background-color: ${euiTheme.colors.highlight};
`;
const isRuleUsingExecutionStatus = getIsExperimentalFeatureEnabled('ruleUseExecutionStatus');
const getPaginatedRowIndex = useCallback(
@ -373,6 +377,7 @@ export const EventLogDataGrid = (props: EventLogDataGrid) => {
sorting={sortingProps}
pagination={paginationProps}
gridStyle={gridStyles}
css={selectedRowCss}
renderCellPopover={renderCellPopover}
/>
</>

View file

@ -1,3 +0,0 @@
.ruleEventLogDataGrid--rowClassSelected {
background-color: $euiColorHighlight;
}

View file

@ -1,5 +0,0 @@
.actBulkActionPopover__deleteAll {
.euiButtonEmpty__text {
padding-top: $euiSizeXS;
}
}

View file

@ -8,15 +8,16 @@
import { i18n } from '@kbn/i18n';
import { KueryNode } from '@kbn/es-query';
import React, { useMemo, useCallback, useState } from 'react';
import { css } from '@emotion/react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButtonEmpty, EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
import { EuiButtonEmpty, EuiFlexItem, EuiFlexGroup, useEuiTheme } from '@elastic/eui';
import { RuleTableItem, BulkEditActions, UpdateRulesToBulkEditProps } from '../../../../types';
import {
withBulkRuleOperations,
ComponentOpts as BulkOperationsComponentOpts,
} from './with_bulk_rule_api_operations';
import './rule_quick_edit_buttons.scss';
import { useKibana } from '../../../../common/lib/kibana';
import { UntrackAlertsModal } from './untrack_alerts_modal';
@ -53,6 +54,13 @@ export const RuleQuickEditButtons: React.FunctionComponent<ComponentOpts> = ({
notifications: { toasts },
} = useKibana().services;
const { euiTheme } = useEuiTheme();
const bulkDeleteButtonCss = css`
.euiButtonEmpty__text {
padding-top: ${euiTheme.size.xs};
}
`;
const [isUntrackAlertsModalOpen, setIsUntrackAlertsModalOpen] = useState<boolean>(false);
const isPerformingAction = isEnablingRules || isDisablingRules || isBulkEditing;
@ -359,6 +367,7 @@ export const RuleQuickEditButtons: React.FunctionComponent<ComponentOpts> = ({
color="danger"
isDisabled={isPerformingAction || hasDisabledByLicenseRuleTypes}
data-test-subj="bulkDelete"
css={bulkDeleteButtonCss}
className="actBulkActionPopover__deleteAll"
>
<FormattedMessage

View file

@ -1,16 +0,0 @@
// Add truncation to heath status
.rulesList__health {
width: 100%;
.euiFlexItem:last-of-type {
@include euiTextTruncate;
min-width: 0;
width: 85%;
}
}
.ruleDurationWarningIcon {
bottom: $euiSizeXS;
position: relative;
}

View file

@ -18,7 +18,7 @@ import {
ComponentOpts as RuleApis,
withBulkRuleOperations,
} from '../../common/components/with_bulk_rule_api_operations';
import './rule.scss';
import type { RuleEventLogListProps } from './rule_event_log_list';
import { AlertListItem, RefreshToken } from './types';
import { getIsExperimentalFeatureEnabled } from '../../../../common/get_experimental_features';

View file

@ -1,3 +0,0 @@
.ruleActionsPopover__deleteButton {
color: $euiColorDangerText;
}

View file

@ -6,8 +6,9 @@
*/
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import { EuiButtonEmpty, EuiContextMenu, EuiPopover } from '@elastic/eui';
import './rule_actions_popopver.scss';
import { EuiButtonEmpty, EuiContextMenu, EuiPopover, useEuiTheme } from '@elastic/eui';
import { css } from '@emotion/react';
import { Rule } from '../../../..';
export interface RuleActionsPopoverProps {
@ -28,6 +29,12 @@ export const RuleActionsPopover: React.FunctionComponent<RuleActionsPopoverProps
onRunRule,
}) => {
const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false);
const { euiTheme } = useEuiTheme();
const ruleActionsPopover = css`
.ruleActionsPopover__deleteButton {
color: ${euiTheme.colors.textDanger};
}
`;
return (
<EuiPopover
@ -115,6 +122,7 @@ export const RuleActionsPopover: React.FunctionComponent<RuleActionsPopoverProps
className="ruleActionsPopover"
data-test-subj="ruleActionsPopover"
data-testid="ruleActionsPopover"
css={ruleActionsPopover}
/>
</EuiPopover>
);

View file

@ -15,6 +15,7 @@ import {
EuiText,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { RuleSummary, RuleType } from '../../../../types';
import { useKibana } from '../../../../common/lib/kibana';
import { CenterJustifiedSpinner } from '../../../components/center_justified_spinner';
@ -70,6 +71,11 @@ export const RuleExecutionSummaryAndChart = (props: RuleExecutionSummaryAndChart
const isInitialized = useRef(false);
const ruleDurationWarningIconCss = css`
bottom: ${euiTheme.size.xs};
position: relative;
`;
const [internalRuleSummary, setInternalRuleSummary] = useState<RuleSummary | null>(null);
const [internalNumberOfExecutions, setInternalNumberOfExecutions] = useState(
DEFAULT_NUMBER_OF_EXECUTIONS
@ -182,6 +188,7 @@ export const RuleExecutionSummaryAndChart = (props: RuleExecutionSummaryAndChart
<EuiFlexItem grow={false} data-test-subj="ruleDurationWarning">
<EuiIconTip
anchorClassName="ruleDurationWarningIcon"
css={ruleDurationWarningIconCss}
type="warning"
color="warning"
content={ruleTypeExcessDurationMessage}

View file

@ -1,3 +0,0 @@
.collapsedItemActions__deleteButton {
color: $euiColorDangerText;
}

View file

@ -18,8 +18,10 @@ import {
EuiIcon,
EuiFlexGroup,
EuiFlexItem,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { useKibana } from '../../../../common/lib/kibana';
import { RuleTableItem, SnoozeSchedule } from '../../../../types';
import {
@ -27,7 +29,6 @@ import {
withBulkRuleOperations,
} from '../../common/components/with_bulk_rule_api_operations';
import { isRuleSnoozed } from '../../../lib';
import './collapsed_item_actions.scss';
import { futureTimeToInterval, SnoozePanel } from './rule_snooze';
import {
SNOOZE_FAILED_MESSAGE,
@ -69,10 +70,18 @@ export const CollapsedItemActions: React.FunctionComponent<ComponentOpts> = ({
notifications: { toasts },
} = useKibana().services;
const { euiTheme } = useEuiTheme();
const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false);
const [isDisabled, setIsDisabled] = useState<boolean>(!item.enabled);
const [isUntrackAlertsModalOpen, setIsUntrackAlertsModalOpen] = useState<boolean>(false);
const collapsedItemActionsCss = css`
.collapsedItemActions__deleteButton {
color: ${euiTheme.colors.textDanger};
}
`;
useEffect(() => {
setIsDisabled(!item.enabled);
}, [item.enabled]);
@ -357,6 +366,7 @@ export const CollapsedItemActions: React.FunctionComponent<ComponentOpts> = ({
className="actCollapsedItemActions"
data-test-subj="collapsedActionPanel"
data-testid="collapsedActionPanel"
css={collapsedItemActionsCss}
/>
</EuiPopover>
{isUntrackAlertsModalOpen && (

View file

@ -13,6 +13,7 @@ import {
EuiSelect,
EuiSplitPanel,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { i18n } from '@kbn/i18n';
import moment from 'moment';
import { Moment } from 'moment';
@ -37,8 +38,6 @@ import {
} from './helpers';
import { i18nNthWeekday } from './translations';
import './recurrence_scheduler.scss';
interface ComponentOpts {
startDate: Moment | null;
endDate: Moment | null;
@ -56,6 +55,16 @@ export const RecurrenceScheduler: React.FC<ComponentOpts> = ({
const [frequency, setFrequency] = useState<RRuleFrequency | 'CUSTOM'>(RRuleFrequency.DAILY);
const [recurrenceEnds, setRecurrenceEnds] = useState('never');
const ramRecurrenceSchedulerCss = css`
.euiFormRow__labelWrapper {
width: calc(20% - 8px);
}
.euiFormRow__fieldWrapper {
width: 80%;
}
`;
const [customFrequency, setCustomFrequency] = useState<CustomFrequencyState>({
freq: RRuleFrequency.WEEKLY,
interval: 1,
@ -194,7 +203,11 @@ export const RecurrenceScheduler: React.FC<ComponentOpts> = ({
return (
<EuiSplitPanel.Outer hasShadow={false} hasBorder={true}>
<EuiSplitPanel.Inner color="subdued" className="ramRecurrenceScheduler">
<EuiSplitPanel.Inner
color="subdued"
className="ramRecurrenceScheduler"
css={ramRecurrenceSchedulerCss}
>
<EuiFormRow
display="columnCompressed"
style={{ alignItems: 'center' }}

View file

@ -1,8 +0,0 @@
.ramRecurrenceScheduler {
.euiFormRow__labelWrapper {
width: calc(20% - 8px);
}
.euiFormRow__fieldWrapper {
width: 80%;
}
}

View file

@ -1,13 +0,0 @@
.RuleSnoozeScheduler__pseudofocus {
&:not(:focus) {
background-image: linear-gradient(
to top,
#07C,
#07C 2px,
transparent 2px,
transparent 100%
);
background-size: 100% 100%;
outline: none;
}
}

View file

@ -28,11 +28,10 @@ import {
EuiLink,
EuiSplitPanel,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { RecurrenceSchedule, SnoozeSchedule } from '../../../../../types';
import { RecurrenceScheduler } from './recurrence_scheduler';
import './scheduler.scss';
interface PanelOpts {
onSaveSchedule: (sched: SnoozeSchedule) => void;
onCancelSchedules: (ids: string[]) => void;
@ -56,6 +55,14 @@ const useDefaultTimzezone = () => {
return kibanaTz;
};
const ruleSnoozeSchedulerPseudoFocusCss = css`
&:not(:focus) {
background-image: linear-gradient(to top, #07c, #07c 2px, transparent 2px, transparent 100%);
background-size: 100% 100%;
outline: none;
}
`;
export const RuleSnoozeScheduler: React.FunctionComponent<ComponentOpts> = ({
onClose,
initialSchedule,
@ -313,6 +320,7 @@ const RuleSnoozeSchedulerPanel: React.FunctionComponent<PanelOpts> = ({
preventOpenOnFocus
showTimeSelect
className={selectingEndDate && !endDT ? 'RuleSnoozeScheduler__pseudofocus' : ''}
css={ruleSnoozeSchedulerPseudoFocusCss}
onFocus={onFocusEnd}
selected={endDT}
onChange={setEndDT}

View file

@ -1,44 +0,0 @@
.actRulesList__tableRowDisabled {
background-color: $euiColorLightestShade;
.actRulesList__tableCellDisabled {
color: $euiColorDarkShade;
}
}
.euiTableRow {
&:hover,
&:focus-within,
&[class*='-isActive'] {
.ruleSidebarItem__action {
opacity: 1;
}
}
}
/**
* 1. Only visually hide the action, so that it's still accessible to screen readers.
* 2. When tabbed to, this element needs to be visible for keyboard accessibility.
*/
.ruleSidebarItem__action {
opacity: 0; /* 1 */
&.ruleSidebarItem__mobile {
opacity: 1;
}
&:focus {
opacity: 1; /* 2 */
}
}
.ruleDurationWarningIcon {
margin-bottom: $euiSizeXS;
margin-left: $euiSizeS;
}
.ruleDisabledQuestionIcon {
bottom: $euiSizeXS;
margin-left: $euiSizeXS;
position: relative;
}

View file

@ -69,7 +69,6 @@ import { RulesDeleteModalConfirmation } from '../../../components/rules_delete_m
import { RulesListPrompts } from './rules_list_prompts';
import { ALERT_STATUS_LICENSE_ERROR } from '../translations';
import { useKibana } from '../../../../common/lib/kibana';
import './rules_list.scss';
import { CreateRuleButton } from './create_rule_button';
import { ManageLicenseModal } from './manage_license_modal';
import { getIsExperimentalFeatureEnabled } from '../../../../common/get_experimental_features';

View file

@ -26,6 +26,7 @@ import {
RIGHT_ALIGNMENT,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import {
RuleExecutionStatus,
formatDuration,
@ -170,6 +171,17 @@ export function convertRulesToTableItems(opts: ConvertRulesToTableItemsOpts): Ru
};
});
}
const ruleSidebarActionCss = css`
opacity: 0; /* 1 */
&.ruleSidebarItem__mobile {
opacity: 1;
}
&:focus {
opacity: 1; /* 2 */
}
`;
export const RulesListTable = (props: RulesListTableProps) => {
const {
@ -219,6 +231,25 @@ export const RulesListTable = (props: RulesListTableProps) => {
const [defaultNumberFormat] = useUiSetting$<string>(DEFAULT_NUMBER_FORMAT);
const { euiTheme } = useEuiTheme();
const ruleRowCss = css`
.actRulesList__tableRowDisabled {
background-color: ${euiTheme.colors.lightestShade};
.actRulesList__tableCellDisabled {
color: ${euiTheme.colors.darkShade};
}
}
.euiTableRow {
&:hover,
&:focus-within,
&[class*='-isActive'] {
.ruleSidebarItem__action {
opacity: 1;
}
}
}
`;
const selectedPercentile = useMemo(() => {
const selectedOption = percentileOptions.find((option) => option.checked === 'on');
if (selectedOption) {
@ -372,6 +403,13 @@ export const RulesListTable = (props: RulesListTableProps) => {
{!checkEnabledResult.isEnabled && (
<EuiIconTip
anchorClassName="ruleDisabledQuestionIcon"
css={css`
.ruleDisabledQuestionIcon {
bottom: ${euiTheme.size.xs};
margin-left: ${euiTheme.size.xs};
position: relative;
}
`}
data-test-subj="ruleDisabledByLicenseTooltip"
type="questionInCircle"
content={checkEnabledResult.message}
@ -623,6 +661,12 @@ export const RulesListTable = (props: RulesListTableProps) => {
<EuiIconTip
data-test-subj="ruleDurationWarning"
anchorClassName="ruleDurationWarningIcon"
css={css`
.ruleDurationWarningIcon {
margin-bottom: ${euiTheme.size.xs};
margin-left: ${euiTheme.size.s};
}
`}
type="warning"
color="warning"
content={i18n.translate(
@ -743,6 +787,7 @@ export const RulesListTable = (props: RulesListTableProps) => {
{ defaultMessage: 'Edit' }
)}
className="ruleSidebarItem__action"
css={ruleSidebarActionCss}
data-test-subj="editActionHoverButton"
onClick={() => onRuleEditClick(rule)}
iconType={'pencil'}
@ -763,6 +808,7 @@ export const RulesListTable = (props: RulesListTableProps) => {
{ defaultMessage: 'Delete' }
)}
className="ruleSidebarItem__action"
css={ruleSidebarActionCss}
data-test-subj="deleteActionHoverButton"
onClick={() => onRuleDeleteClick(rule)}
iconType={'trash'}
@ -816,6 +862,7 @@ export const RulesListTable = (props: RulesListTableProps) => {
selectedPercentile,
tagPopoverOpenIndex,
ruleOutcomeColumnField,
euiTheme,
]);
const allRuleColumns = useMemo(() => getRulesTableColumns(), [getRulesTableColumns]);
@ -929,6 +976,7 @@ export const RulesListTable = (props: RulesListTableProps) => {
sorting={{ sort }}
rowHeader="name"
rowProps={rowProps}
css={ruleRowCss}
cellProps={(rule: RuleTableItem) => ({
'data-test-subj': 'cell',
className: !ruleTypesState.data.get(rule.ruleTypeId)?.enabledInLicense

View file

@ -1,3 +0,0 @@
.actOf__aggFieldContainer {
width: $euiSize * 29;
}

View file

@ -15,12 +15,13 @@ import {
EuiFlexItem,
EuiFormRow,
EuiComboBox,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { builtInAggregationTypes } from '../constants';
import { AggregationType, FieldOption, ValidNormalizedTypes } from '../types';
import { IErrorObject } from '../../types';
import { ClosablePopoverTitle } from './components';
import './of.scss';
interface OfFieldOption {
label: string;
@ -62,6 +63,7 @@ export const OfExpression = ({
popupPosition,
helpText,
}: OfExpressionProps) => {
const { euiTheme } = useEuiTheme();
const [aggFieldPopoverOpen, setAggFieldPopoverOpen] = useState(false);
const firstFieldOption = {
text: i18n.translate(
@ -90,6 +92,10 @@ export const OfExpression = ({
[]
);
const aggFieldContainerCss = css`
width: calc(${euiTheme.size.base} * 29);
`;
useEffect(() => {
// if current field set doesn't contain selected field, clear selection
if (
@ -139,7 +145,7 @@ export const OfExpression = ({
/>
</ClosablePopoverTitle>
<EuiFlexGroup>
<EuiFlexItem grow={false} className="actOf__aggFieldContainer">
<EuiFlexItem grow={false} className="actOf__aggFieldContainer" css={aggFieldContainerCss}>
<EuiFormRow
id="ofField"
fullWidth