From f3b2077d4b4b11ef51adbbdc39f0f46765533a9d Mon Sep 17 00:00:00 2001 From: Paul Tavares <56442535+paul-tavares@users.noreply.github.com> Date: Fri, 24 Jul 2020 10:50:15 -0400 Subject: [PATCH 1/6] [INGEST_MANAGER] Make package config name blank for endpoint on Package Config create (#73082) (#73197) * Make package config name blank for endpoint * Added functional tests on endpoint side --- .../step_define_package_config.tsx | 14 +++++++++++--- .../apps/endpoint/policy_list.ts | 5 +++++ .../ingest_manager_create_package_config_page.ts | 7 +++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx index a04d023ebcc48..f487b4e5235e7 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_package_config_page/step_define_package_config.tsx @@ -47,9 +47,17 @@ export const StepDefinePackageConfig: React.FunctionComponent<{ .sort(); updatePackageConfig({ - name: `${packageInfo.name}-${ - dsWithMatchingNames.length ? dsWithMatchingNames[dsWithMatchingNames.length - 1] + 1 : 1 - }`, + name: + // For Endpoint packages, the user must fill in the name, thus we don't attempt to generate + // a default one here. + // FIXME: Improve package configs name uniqueness - https://github.com/elastic/kibana/issues/72948 + packageInfo.name !== 'endpoint' + ? `${packageInfo.name}-${ + dsWithMatchingNames.length + ? dsWithMatchingNames[dsWithMatchingNames.length - 1] + 1 + : 1 + }` + : '', package: { name: packageInfo.name, title: packageInfo.title, diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts index a4b3a51c49513..0c5e15ed4104c 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/policy_list.ts @@ -131,6 +131,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(endpointConfig).not.to.be(undefined); }); + it('should have empty value for package configuration name', async () => { + await pageObjects.ingestManagerCreatePackageConfig.selectAgentConfig(); + expect(await pageObjects.ingestManagerCreatePackageConfig.getPackageConfigName()).to.be(''); + }); + it('should redirect user back to Policy List after a successful save', async () => { const newPolicyName = `endpoint policy ${Date.now()}`; await pageObjects.ingestManagerCreatePackageConfig.selectAgentConfig(); diff --git a/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts b/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts index dd3fc637a3d6c..dfdb528b7362c 100644 --- a/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts +++ b/x-pack/test/security_solution_endpoint/page_objects/ingest_manager_create_package_config_page.ts @@ -62,6 +62,13 @@ export function IngestManagerCreatePackageConfig({ } }, + /** + * Returns the package config name currently populated on the input field + */ + async getPackageConfigName() { + return testSubjects.getAttribute('packageConfigNameInput', 'value'); + }, + /** * Set the name of the package config on the input field * @param name From de9de1d739fd155ed9ae8202dee1ba74e3b01522 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Fri, 24 Jul 2020 18:02:52 +0200 Subject: [PATCH 2/6] Unskip dashboard embeddable rendering tests (#71824) (#73204) --- test/functional/apps/dashboard/embeddable_rendering.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/functional/apps/dashboard/embeddable_rendering.js b/test/functional/apps/dashboard/embeddable_rendering.js index 9ba0c07c744fc..c00f01d060f4a 100644 --- a/test/functional/apps/dashboard/embeddable_rendering.js +++ b/test/functional/apps/dashboard/embeddable_rendering.js @@ -98,8 +98,7 @@ export default function ({ getService, getPageObjects }) { await dashboardExpect.vegaTextsDoNotExist(['5,000']); }; - // FLAKY: https://github.com/elastic/kibana/issues/46305 - describe.skip('dashboard embeddable rendering', function describeIndexTests() { + describe('dashboard embeddable rendering', function describeIndexTests() { before(async () => { await esArchiver.load('dashboard/current/kibana'); await kibanaServer.uiSettings.replace({ From 055d3f2f67e33ac40f4f22d742832a56185251eb Mon Sep 17 00:00:00 2001 From: Corey Robertson Date: Fri, 24 Jul 2020 13:46:53 -0400 Subject: [PATCH 3/6] Exclude variables from rendered workpad (#72970) (#73207) --- x-pack/plugins/canvas/public/state/selectors/workpad.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/public/state/selectors/workpad.ts b/x-pack/plugins/canvas/public/state/selectors/workpad.ts index 1d7ea05daaa61..a677bcaf29e61 100644 --- a/x-pack/plugins/canvas/public/state/selectors/workpad.ts +++ b/x-pack/plugins/canvas/public/state/selectors/workpad.ts @@ -497,7 +497,7 @@ export function getRenderedWorkpad(state: State) { const workpad = getWorkpad(state); // eslint-disable-next-line no-unused-vars - const { pages, ...rest } = workpad; + const { pages, variables, ...rest } = workpad; return { pages: renderedPages, From faba7fedc67e34f9178a3e70f81079445c268839 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Fri, 24 Jul 2020 14:24:35 -0400 Subject: [PATCH 4/6] [Ingest Manager] Support DEGRADED state in fleet agent event (#73104) (#73195) --- .../common/openapi/spec_oas3.json | 1 + .../ingest_manager/common/types/models/agent.ts | 1 + .../components/type_labels.tsx | 8 ++++++++ .../ingest_manager/server/types/models/agent.ts | 17 ++++++++++------- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json index 4b10dab5d1ae5..e16edac5ddb7a 100644 --- a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json +++ b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json @@ -4203,6 +4203,7 @@ "FAILED", "STOPPING", "STOPPED", + "DEGRADED", "DATA_DUMP", "ACKNOWLEDGED", "UNKNOWN" diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent.ts b/x-pack/plugins/ingest_manager/common/types/models/agent.ts index d3789c58a2c22..f31d33e73c76f 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent.ts @@ -53,6 +53,7 @@ export interface NewAgentEvent { | 'FAILED' | 'STOPPING' | 'STOPPED' + | 'DEGRADED' // Action results | 'DATA_DUMP' // Actions diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx index e9cb59be37892..43e4d696ded66 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_details_page/components/type_labels.tsx @@ -95,6 +95,14 @@ export const SUBTYPE_LABEL: { [key in AgentEvent['subtype']]: JSX.Element } = { /> ), + DEGRADED: ( + + + + ), DATA_DUMP: ( Date: Fri, 24 Jul 2020 18:00:34 -0600 Subject: [PATCH 5/6] [Security Solution][Exceptions] Prevents value list entries from co-existing with non value list entries (#72995) (#73217) ## Summary Fixes validation issue where value list exception entries could be added alongside non value list exception entries. Once a value list operator (`is in list` or `is not in list`) is selected the `nested` button will disable, and subsequent `and`/ `or`'s will only have the value list operators available to them:

If a value list is not selected in the first exception entry, all subsequent entries will no longer have the value list operators:

Adds validation for empty case to prevent network error when submitted no entries. Add modal:

Edit modal:

### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios --- .../components/autocomplete/operators.ts | 14 ++++++ .../exceptions/add_exception_modal/index.tsx | 6 +-- .../builder/builder_entry_item.test.tsx | 4 +- .../exceptions/builder/builder_entry_item.tsx | 16 ++++-- .../builder/builder_exception_item.tsx | 3 ++ .../exceptions/builder/helpers.test.tsx | 49 ++++++++++++------- .../components/exceptions/builder/helpers.tsx | 17 +++++-- .../components/exceptions/builder/index.tsx | 21 ++++++-- .../components/exceptions/builder/reducer.ts | 7 ++- .../exceptions/edit_exception_modal/index.tsx | 14 +++++- 10 files changed, 113 insertions(+), 38 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts b/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts index a81d8cde94e34..c54f58a3fd4b3 100644 --- a/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts +++ b/x-pack/plugins/security_solution/public/common/components/autocomplete/operators.ts @@ -90,3 +90,17 @@ export const EXCEPTION_OPERATORS: OperatorOption[] = [ isInListOperator, isNotInListOperator, ]; + +export const EXCEPTION_OPERATORS_SANS_LISTS: OperatorOption[] = [ + isOperator, + isNotOperator, + isOneOfOperator, + isNotOneOfOperator, + existsOperator, + doesNotExistOperator, +]; + +export const EXCEPTION_OPERATORS_ONLY_LISTS: OperatorOption[] = [ + isInListOperator, + isNotInListOperator, +]; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx index d2fec1f34755f..a4fe52eaacf4e 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.tsx @@ -276,8 +276,8 @@ export const AddExceptionModal = memo(function AddExceptionModal({ signalIndexName, ]); - const isSubmitButtonDisabled = useCallback( - () => fetchOrCreateListError || exceptionItemsToAdd.length === 0, + const isSubmitButtonDisabled = useMemo( + () => fetchOrCreateListError || exceptionItemsToAdd.every((item) => item.entries.length === 0), [fetchOrCreateListError, exceptionItemsToAdd] ); @@ -377,7 +377,7 @@ export const AddExceptionModal = memo(function AddExceptionModal({ {i18n.ADD_EXCEPTION} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx index b845848bd14d8..3dcc3eb5a8329 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.test.tsx @@ -213,7 +213,7 @@ describe('BuilderEntryItem', () => { title: 'logstash-*', fields, }} - showLabel={false} + showLabel={true} listType="detection" addNested={false} onChange={jest.fn()} @@ -245,7 +245,7 @@ describe('BuilderEntryItem', () => { title: 'logstash-*', fields, }} - showLabel={false} + showLabel={true} listType="detection" addNested={false} onChange={jest.fn()} diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx index 736e88ee9fe06..dcc8a0e4fb1ba 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/builder_entry_item.tsx @@ -27,6 +27,7 @@ import { getEntryOnMatchAnyChange, getEntryOnListChange, } from './helpers'; +import { EXCEPTION_OPERATORS_ONLY_LISTS } from '../../autocomplete/operators'; interface EntryItemProps { entry: FormattedBuilderEntry; @@ -35,6 +36,7 @@ interface EntryItemProps { listType: ExceptionListType; addNested: boolean; onChange: (arg: BuilderEntry, i: number) => void; + onlyShowListOperators?: boolean; } export const BuilderEntryItem: React.FC = ({ @@ -44,6 +46,7 @@ export const BuilderEntryItem: React.FC = ({ addNested, showLabel, onChange, + onlyShowListOperators = false, }): JSX.Element => { const handleFieldChange = useCallback( ([newField]: IFieldType[]): void => { @@ -124,11 +127,14 @@ export const BuilderEntryItem: React.FC = ({ ); const renderOperatorInput = (isFirst: boolean): JSX.Element => { - const operatorOptions = getOperatorOptions( - entry, - listType, - entry.field != null && entry.field.type === 'boolean' - ); + const operatorOptions = onlyShowListOperators + ? EXCEPTION_OPERATORS_ONLY_LISTS + : getOperatorOptions( + entry, + listType, + entry.field != null && entry.field.type === 'boolean', + isFirst + ); const comboBox = ( void; onChangeExceptionItem: (item: ExceptionsBuilderExceptionItem, index: number) => void; + onlyShowListOperators?: boolean; } export const ExceptionListItemComponent = React.memo( @@ -58,6 +59,7 @@ export const ExceptionListItemComponent = React.memo( andLogicIncluded, onDeleteExceptionItem, onChangeExceptionItem, + onlyShowListOperators = false, }) => { const handleEntryChange = useCallback( (entry: BuilderEntry, entryIndex: number): void => { @@ -169,6 +171,7 @@ export const ExceptionListItemComponent = React.memo( exceptionItemIndex === 0 && index === 0 && item.nested !== 'child' } onChange={handleEntryChange} + onlyShowListOperators={onlyShowListOperators} /> {getDeleteButton( diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx index 8b74d44f29a18..17c94adf42648 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.test.tsx @@ -14,32 +14,33 @@ import { getEntryExistsMock } from '../../../../../../lists/common/schemas/types import { getExceptionListItemSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { getListResponseMock } from '../../../../../../lists/common/schemas/response/list_schema.mock'; import { - isOperator, - isOneOfOperator, - isNotOperator, - isNotOneOfOperator, - existsOperator, doesNotExistOperator, - isInListOperator, EXCEPTION_OPERATORS, + EXCEPTION_OPERATORS_SANS_LISTS, + existsOperator, + isInListOperator, + isNotOneOfOperator, + isNotOperator, + isOneOfOperator, + isOperator, } from '../../autocomplete/operators'; -import { FormattedBuilderEntry, BuilderEntry, ExceptionsBuilderExceptionItem } from '../types'; -import { IIndexPattern, IFieldType } from '../../../../../../../../src/plugins/data/common'; -import { EntryNested, Entry } from '../../../../lists_plugin_deps'; +import { BuilderEntry, ExceptionsBuilderExceptionItem, FormattedBuilderEntry } from '../types'; +import { IFieldType, IIndexPattern } from '../../../../../../../../src/plugins/data/common'; +import { Entry, EntryNested } from '../../../../lists_plugin_deps'; import { - getFilteredIndexPatterns, - getFormattedBuilderEntry, - isEntryNested, - getFormattedBuilderEntries, - getUpdatedEntriesOnDelete, getEntryFromOperator, - getOperatorOptions, getEntryOnFieldChange, - getEntryOnOperatorChange, - getEntryOnMatchChange, - getEntryOnMatchAnyChange, getEntryOnListChange, + getEntryOnMatchAnyChange, + getEntryOnMatchChange, + getEntryOnOperatorChange, + getFilteredIndexPatterns, + getFormattedBuilderEntries, + getFormattedBuilderEntry, + getOperatorOptions, + getUpdatedEntriesOnDelete, + isEntryNested, } from './helpers'; import { OperatorOption } from '../../autocomplete/types'; @@ -672,6 +673,18 @@ describe('Exception builder helpers', () => { const expected: OperatorOption[] = [isOperator, existsOperator]; expect(output).toEqual(expected); }); + + test('it returns list operators if specified to', () => { + const payloadItem: FormattedBuilderEntry = getMockBuilderEntry(); + const output = getOperatorOptions(payloadItem, 'detection', false, true); + expect(output).toEqual(EXCEPTION_OPERATORS); + }); + + test('it does not return list operators if specified not to', () => { + const payloadItem: FormattedBuilderEntry = getMockBuilderEntry(); + const output = getOperatorOptions(payloadItem, 'detection', false, false); + expect(output).toEqual(EXCEPTION_OPERATORS_SANS_LISTS); + }); }); describe('#getEntryOnFieldChange', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx index 2fe2c68941ae6..93bae091885c1 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/helpers.tsx @@ -22,6 +22,7 @@ import { existsOperator, isOneOfOperator, EXCEPTION_OPERATORS, + EXCEPTION_OPERATORS_SANS_LISTS, } from '../../autocomplete/operators'; import { OperatorOption } from '../../autocomplete/types'; import { @@ -40,7 +41,6 @@ import { getEntryValue, getExceptionOperatorSelect } from '../helpers'; * * @param patterns IIndexPattern containing available fields on rule index * @param item exception item entry - * @param addNested boolean noting whether or not UI is currently * set to add a nested field */ export const getFilteredIndexPatterns = ( @@ -295,12 +295,14 @@ export const getEntryFromOperator = ( * * @param item * @param listType - * + * @param isBoolean + * @param includeValueListOperators whether or not to include the 'is in list' and 'is not in list' operators */ export const getOperatorOptions = ( item: FormattedBuilderEntry, listType: ExceptionListType, - isBoolean: boolean + isBoolean: boolean, + includeValueListOperators = true ): OperatorOption[] => { if (item.nested === 'parent' || item.field == null) { return [isOperator]; @@ -309,7 +311,11 @@ export const getOperatorOptions = ( } else if (item.nested != null && listType === 'detection') { return isBoolean ? [isOperator, existsOperator] : [isOperator, isOneOfOperator, existsOperator]; } else { - return isBoolean ? [isOperator, existsOperator] : EXCEPTION_OPERATORS; + return isBoolean + ? [isOperator, existsOperator] + : includeValueListOperators + ? EXCEPTION_OPERATORS + : EXCEPTION_OPERATORS_SANS_LISTS; } }; @@ -547,3 +553,6 @@ export const getDefaultNestedEmptyEntry = (): EmptyNestedEntry => ({ type: OperatorTypeEnum.NESTED, entries: [], }); + +export const containsValueListEntry = (items: ExceptionsBuilderExceptionItem[]): boolean => + items.some((item) => item.entries.some((entry) => entry.type === OperatorTypeEnum.LIST)); diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx index 141429f152790..1ec49425ce8fd 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/builder/index.tsx @@ -24,7 +24,11 @@ import { BuilderButtonOptions } from './builder_button_options'; import { getNewExceptionItem, filterExceptionItems } from '../helpers'; import { ExceptionsBuilderExceptionItem, CreateExceptionListItemBuilderSchema } from '../types'; import { State, exceptionsBuilderReducer } from './reducer'; -import { getDefaultEmptyEntry, getDefaultNestedEmptyEntry } from './helpers'; +import { + containsValueListEntry, + getDefaultEmptyEntry, + getDefaultNestedEmptyEntry, +} from './helpers'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import exceptionableFields from '../exceptionable_fields.json'; @@ -44,6 +48,7 @@ const MyButtonsContainer = styled(EuiFlexItem)` const initialState: State = { disableAnd: false, + disableNested: false, disableOr: false, andLogicIncluded: false, addNested: false, @@ -82,12 +87,21 @@ export const ExceptionBuilder = ({ onChange, }: ExceptionBuilderProps) => { const [ - { exceptions, exceptionsToDelete, andLogicIncluded, disableAnd, disableOr, addNested }, + { + exceptions, + exceptionsToDelete, + andLogicIncluded, + disableAnd, + disableNested, + disableOr, + addNested, + }, dispatch, ] = useReducer(exceptionsBuilderReducer(), { ...initialState, disableAnd: isAndDisabled, disableOr: isOrDisabled, + disableNested: isNestedDisabled, }); const setUpdateExceptions = useCallback( @@ -362,6 +376,7 @@ export const ExceptionBuilder = ({ isOnlyItem={exceptions.length === 1} onDeleteExceptionItem={handleDeleteExceptionItem} onChangeExceptionItem={handleExceptionItemChange} + onlyShowListOperators={containsValueListEntry(exceptions)} /> @@ -379,7 +394,7 @@ export const ExceptionBuilder = ({ (state: State, action: Action): St const isAndDisabled = lastEntry != null && lastEntry.type === 'nested' && lastEntry.entries.length === 0; const isOrDisabled = lastEntry != null && lastEntry.type === 'nested'; + const containsValueList = action.exceptions.some( + ({ entries }) => entries.filter(({ type }) => type === OperatorTypeEnum.LIST).length > 0 + ); return { ...state, @@ -67,6 +71,7 @@ export const exceptionsBuilderReducer = () => (state: State, action: Action): St addNested: isAddNested, disableAnd: isAndDisabled, disableOr: isOrDisabled, + disableNested: containsValueList, }; } case 'setDefault': { diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx index 4ad077edf66ff..47c3498cb6ab4 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/edit_exception_modal/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { memo, useState, useCallback, useEffect } from 'react'; +import React, { memo, useState, useCallback, useEffect, useMemo } from 'react'; import styled, { css } from 'styled-components'; import { EuiModal, @@ -146,6 +146,11 @@ export const EditExceptionModal = memo(function EditExceptionModal({ } }, [shouldDisableBulkClose]); + const isSubmitButtonDisabled = useMemo( + () => exceptionItemsToAdd.every((item) => item.entries.length === 0), + [exceptionItemsToAdd] + ); + const handleBuilderOnChange = useCallback( ({ exceptionItems, @@ -261,7 +266,12 @@ export const EditExceptionModal = memo(function EditExceptionModal({ {i18n.CANCEL} - + {i18n.EDIT_EXCEPTION_SAVE_BUTTON} From 8ea0417aa0ad3e0e18b3cd1169d5a543ca722f0d Mon Sep 17 00:00:00 2001 From: Clint Andrew Hall Date: Sat, 25 Jul 2020 11:48:42 -0400 Subject: [PATCH 6/6] [7.9] Return EUI CSS to Shareable Runtime (#72990) (#73215) Co-authored-by: Elastic Machine --- x-pack/plugins/canvas/shareable_runtime/README.md | 2 +- x-pack/plugins/canvas/shareable_runtime/webpack.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/canvas/shareable_runtime/README.md b/x-pack/plugins/canvas/shareable_runtime/README.md index 8fdeb6ca6258e..3839e7c4ecb3f 100644 --- a/x-pack/plugins/canvas/shareable_runtime/README.md +++ b/x-pack/plugins/canvas/shareable_runtime/README.md @@ -207,7 +207,7 @@ There are a number of options for the build script: ### Prerequisite -Before testing or running this PR locally, you **must** run `node scripts/runtime` from `/canvas` _after_ `yarn kbn bootstrap` and _before_ starting Kibana. It is only built automatically when Kibana is built to avoid slowing down other development activities. +Before testing or running this PR locally, you **must** run `node scripts/shareable_runtime` from `/canvas` _after_ `yarn kbn bootstrap` and _before_ starting Kibana. It is only built automatically when Kibana is built to avoid slowing down other development activities. ### Webpack Dev Server diff --git a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js index 1a5a21985ba72..93dc3dbccd549 100644 --- a/x-pack/plugins/canvas/shareable_runtime/webpack.config.js +++ b/x-pack/plugins/canvas/shareable_runtime/webpack.config.js @@ -55,7 +55,6 @@ module.exports = { options: { presets: [require.resolve('@kbn/babel-preset/webpack_preset')], }, - sideEffects: false, }, { test: /\.tsx?$/, @@ -92,6 +91,7 @@ module.exports = { }, }, ], + sideEffects: true, }, { test: /\.module\.s(a|c)ss$/,