From 37832fe4b95db7ba8489d2e47095e7249c00ffce Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Wed, 23 Jun 2021 20:39:29 -0500 Subject: [PATCH 01/10] Port #3904 to Kibana https://github.com/elastic/ent-search/pull/3904 --- .../components/role_mappings/user.test.tsx | 24 +++++- .../components/role_mappings/user.tsx | 7 ++ .../__mocks__/elasticsearch_users.ts | 1 + .../shared/role_mapping/constants.ts | 22 ++++++ .../deactivated_user_callout.test.tsx | 75 +++++++++++++++++++ .../role_mapping/deactivated_user_callout.tsx | 28 +++++++ .../applications/shared/role_mapping/index.ts | 1 + .../shared/role_mapping/users_table.test.tsx | 20 ++++- .../shared/role_mapping/users_table.tsx | 10 ++- .../public/applications/shared/types.ts | 3 +- .../views/role_mappings/user.test.tsx | 24 +++++- .../views/role_mappings/user.tsx | 7 ++ 12 files changed, 217 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.test.tsx create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.test.tsx index 88103532bd149..cec7f1541a31a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.test.tsx @@ -14,7 +14,12 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { UserFlyout, UserAddedInfo, UserInvitationCallout } from '../../../shared/role_mapping'; +import { + UserFlyout, + UserAddedInfo, + UserInvitationCallout, + DeactivatedUserCallout, +} from '../../../shared/role_mapping'; import { elasticsearchUsers } from '../../../shared/role_mapping/__mocks__/elasticsearch_users'; import { wsSingleUserRoleMapping } from '../../../shared/role_mapping/__mocks__/roles'; @@ -91,6 +96,23 @@ describe('User', () => { expect(wrapper.find(UserAddedInfo)).toHaveLength(1); }); + it('renders DeactivatedUserCallout', () => { + setMockValues({ + ...mockValues, + singleUserRoleMapping: { + ...wsSingleUserRoleMapping, + invitation: null, + elasticsearchUser: { + ...wsSingleUserRoleMapping.elasticsearchUser, + enabled: false, + }, + }, + }); + const wrapper = shallow(); + + expect(wrapper.find(DeactivatedUserCallout)).toHaveLength(1); + }); + it('disables form when username value not present', () => { setMockValues({ ...mockValues, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx index df231fac64df7..d3e9a990abbe5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx @@ -17,6 +17,7 @@ import { UserSelector, UserAddedInfo, UserInvitationCallout, + DeactivatedUserCallout, } from '../../../shared/role_mapping'; import { RoleTypes } from '../../types'; @@ -55,6 +56,11 @@ export const User: React.FC = () => { const showEngineAssignmentSelector = hasEngines && hasAdvancedRoles; const flyoutDisabled = !userFormUserIsExisting && (!elasticsearchUser.email || !elasticsearchUser.username); + const userIsDeactivated = !!( + singleUserRoleMapping && + !singleUserRoleMapping.invitation && + !singleUserRoleMapping.elasticsearchUser.enabled + ); const userAddedInfo = singleUserRoleMapping && ( { > {userCreated ? userAddedInfo : createUserForm} {userInvitationCallout} + {userIsDeactivated && } ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/__mocks__/elasticsearch_users.ts b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/__mocks__/elasticsearch_users.ts index 500f560675679..6d9365d63c320 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/__mocks__/elasticsearch_users.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/__mocks__/elasticsearch_users.ts @@ -9,5 +9,6 @@ export const elasticsearchUsers = [ { email: 'user1@user.com', username: 'user1', + enabled: true, }, ]; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/constants.ts b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/constants.ts index 215c76ffb7ef4..e36f97bee2bf3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/constants.ts @@ -373,6 +373,13 @@ export const UPDATE_USER_DESCRIPTION = i18n.translate( } ); +export const DEACTIVATED_LABEL = i18n.translate( + 'xpack.enterpriseSearch.roleMapping.deactivatedLabel', + { + defaultMessage: 'Deactivated', + } +); + export const INVITATION_PENDING_LABEL = i18n.translate( 'xpack.enterpriseSearch.roleMapping.invitationPendingLabel', { @@ -422,3 +429,18 @@ export const AUTH_PROVIDER_TOOLTIP = i18n.translate( 'Provider-specific role mapping is still applied, but configuration is now deprecated.', } ); + +export const DEACTIVATED_USER_CALLOUT_LABEL = i18n.translate( + 'xpack.enterpriseSearch.roleMapping.deactivatedUserCalloutLabel', + { + defaultMessage: 'User deactivated', + } +); + +export const DEACTIVATED_USER_CALLOUT_DESCRIPTION = i18n.translate( + 'xpack.enterpriseSearch.roleMapping.deactivatedUserCalloutDescription', + { + defaultMessage: + 'This user is not currently active, and access has been temporarily revoked. Users can be re-activated via the User Management area of the Kibana console.', + } +); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.test.tsx new file mode 100644 index 0000000000000..5bae7b00dda10 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.test.tsx @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { DeactivatedUserCallout } from './'; + +describe('DeactivatedUserCallout', () => { + it('renders with new', () => { + const wrapper = shallow(); + + expect(wrapper).toMatchInlineSnapshot(` + + + + + + User deactivated + + + + + This user is not currently active, and access has been temporarily revoked. Users can be re-activated via the User Management area of the Kibana console. + + + + `); + }); + + it('renders with existing', () => { + const wrapper = shallow(); + + expect(wrapper).toMatchInlineSnapshot(` + + + + + + + User deactivated + + + + + This user is not currently active, and access has been temporarily revoked. Users can be re-activated via the User Management area of the Kibana console. + + + + `); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.tsx new file mode 100644 index 0000000000000..5b69420d169ce --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/deactivated_user_callout.tsx @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiSpacer, EuiText, EuiIcon } from '@elastic/eui'; + +interface Props { + isNew: boolean; +} + +import { DEACTIVATED_USER_CALLOUT_LABEL, DEACTIVATED_USER_CALLOUT_DESCRIPTION } from './constants'; + +export const DeactivatedUserCallout: React.FC = ({ isNew }) => ( + <> + {!isNew && } + + {DEACTIVATED_USER_CALLOUT_LABEL} + + + {DEACTIVATED_USER_CALLOUT_DESCRIPTION} + + +); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts index 8096b86939ff3..9bd57509a99b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts @@ -6,6 +6,7 @@ */ export { AttributeSelector } from './attribute_selector'; +export { DeactivatedUserCallout } from './deactivated_user_callout'; export { RolesEmptyPrompt } from './roles_empty_prompt'; export { RoleMappingsTable } from './role_mappings_table'; export { RoleOptionLabel } from './role_option_label'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.test.tsx index dc1a2713ced12..ff386ce11b4d4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.test.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { shallow, mount } from 'enzyme'; -import { EuiInMemoryTable, EuiTextColor } from '@elastic/eui'; +import { EuiInMemoryTable, EuiTextColor, EuiBadge } from '@elastic/eui'; import { engines } from '../../app_search/__mocks__/engines.mock'; @@ -27,6 +27,7 @@ describe('UsersTable', () => { singleUserRoleMappings: [wsSingleUserRoleMapping], initializeSingleUserRoleMapping, handleDeleteMapping, + enabled: true, }; it('renders', () => { @@ -55,6 +56,7 @@ describe('UsersTable', () => { elasticsearchUser: { email: null, username: 'foo', + enabled: true, }, }; const wrapper = mount(); @@ -97,4 +99,20 @@ describe('UsersTable', () => { `${engines[0].name}, ${engines[1].name} + 1` ); }); + + it('renders deactivatedBadge', () => { + const disabledUser = { + ...wsSingleUserRoleMapping, + elasticsearchUser: { + email: 'email@user.com', + username: 'foo', + enabled: false, + }, + invitation: null, + }; + const wrapper = mount(); + const cell = wrapper.find('[data-test-subj="UsernameCell"]'); + + expect(cell.find(EuiBadge)).toHaveLength(1); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.tsx index 674796775b1d3..25a9eee38f93f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/users_table.tsx @@ -15,6 +15,7 @@ import { WSRoleMapping } from '../../workplace_search/types'; import { INVITATION_PENDING_LABEL, + DEACTIVATED_LABEL, ALL_LABEL, FILTER_USERS_LABEL, NO_USERS_LABEL, @@ -37,6 +38,7 @@ interface SharedUser extends SingleUserRoleMapping—; const invitationBadge = {INVITATION_PENDING_LABEL}; +const deactivatedBadge = {DEACTIVATED_LABEL}; export const UsersTable: React.FC = ({ accessItemKey, @@ -63,6 +66,7 @@ export const UsersTable: React.FC = ({ const users = ((singleUserRoleMappings as SharedUser[]).map((user) => ({ username: user.elasticsearchUser.username, email: user.elasticsearchUser.email, + enabled: user.elasticsearchUser.enabled, roleType: user.roleMapping.roleType, id: user.roleMapping.id, accessItems: (user.roleMapping as SharedRoleMapping)[accessItemKey], @@ -73,7 +77,11 @@ export const UsersTable: React.FC = ({ { field: 'username', name: USERNAME_LABEL, - render: (_, { username }: SharedUser) => username, + render: (_, { username, invitation, enabled }: SharedUser) => ( +
+ {username} {!invitation && !enabled && deactivatedBadge} +
+ ), }, { field: 'email', diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/types.ts b/x-pack/plugins/enterprise_search/public/applications/shared/types.ts index e6d2c67d1baf8..5a90dd2c4a6bb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/types.ts @@ -49,10 +49,11 @@ export interface Invitation { export interface ElasticsearchUser { email: string | null; username: string; + enabled: boolean; } export interface SingleUserRoleMapping { - invitation: Invitation; + invitation: Invitation | null; elasticsearchUser: ElasticsearchUser; roleMapping: T; } diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.test.tsx index 32ee1a7f22875..d8e1fc160901f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.test.tsx @@ -14,7 +14,12 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { UserFlyout, UserAddedInfo, UserInvitationCallout } from '../../../shared/role_mapping'; +import { + UserFlyout, + UserAddedInfo, + UserInvitationCallout, + DeactivatedUserCallout, +} from '../../../shared/role_mapping'; import { elasticsearchUsers } from '../../../shared/role_mapping/__mocks__/elasticsearch_users'; import { wsSingleUserRoleMapping } from '../../../shared/role_mapping/__mocks__/roles'; @@ -90,6 +95,23 @@ describe('User', () => { expect(wrapper.find(UserAddedInfo)).toHaveLength(1); }); + it('renders DeactivatedUserCallout', () => { + setMockValues({ + ...mockValues, + singleUserRoleMapping: { + ...wsSingleUserRoleMapping, + invitation: null, + elasticsearchUser: { + ...wsSingleUserRoleMapping.elasticsearchUser, + enabled: false, + }, + }, + }); + const wrapper = shallow(); + + expect(wrapper.find(DeactivatedUserCallout)).toHaveLength(1); + }); + it('disables form when username value not present', () => { setMockValues({ ...mockValues, diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx index bfb32ee31c121..c3b8064c3c25a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx @@ -17,6 +17,7 @@ import { UserSelector, UserAddedInfo, UserInvitationCallout, + DeactivatedUserCallout, } from '../../../shared/role_mapping'; import { Role } from '../../types'; @@ -52,6 +53,11 @@ export const User: React.FC = () => { const hasAvailableUsers = elasticsearchUsers.length > 0; const flyoutDisabled = (!userFormUserIsExisting || !hasAvailableUsers) && !elasticsearchUser.username; + const userIsDeactivated = !!( + singleUserRoleMapping && + !singleUserRoleMapping.invitation && + !singleUserRoleMapping.elasticsearchUser.enabled + ); const userAddedInfo = singleUserRoleMapping && ( { > {userCreated ? userAddedInfo : createUserForm} {userInvitationCallout} + {userIsDeactivated && } ); }; From f75af5324ae8bcec3ac39f52bd3fc399c7e4bd09 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Wed, 23 Jun 2021 20:48:55 -0500 Subject: [PATCH 02/10] DRY out logic interfaces Should have done this long ago --- .../role_mappings/role_mappings_logic.ts | 71 ++++--------------- .../applications/shared/role_mapping/index.ts | 1 + .../applications/shared/role_mapping/types.ts | 64 +++++++++++++++++ .../role_mappings/role_mappings_logic.ts | 69 ++++-------------- 4 files changed, 90 insertions(+), 115 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/types.ts diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts index 0b57e1d08a294..ede379e4bf54f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts @@ -7,14 +7,17 @@ import { kea, MakeLogicType } from 'kea'; -import { EuiComboBoxOptionOption } from '@elastic/eui'; - import { clearFlashMessages, flashAPIErrors, setSuccessMessage, } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; +import { + RoleMappingsBaseServerDetails, + RoleMappingsBaseActions, + RoleMappingsBaseValues, +} from '../../../shared/role_mapping'; import { ANY_AUTH_PROVIDER } from '../../../shared/role_mapping/constants'; import { AttributeName, SingleUserRoleMapping, ElasticsearchUser } from '../../../shared/types'; import { ASRoleMapping, RoleTypes } from '../../types'; @@ -29,16 +32,11 @@ import { type UserMapping = SingleUserRoleMapping; -interface RoleMappingsServerDetails { +interface RoleMappingsServerDetails extends RoleMappingsBaseServerDetails { roleMappings: ASRoleMapping[]; - attributes: string[]; - authProviders: string[]; availableEngines: Engine[]; - elasticsearchRoles: string[]; - elasticsearchUsers: ElasticsearchUser[]; - hasAdvancedRoles: boolean; - multipleAuthProvidersConfig: boolean; singleUserRoleMappings: UserMapping[]; + hasAdvancedRoles: boolean; } const getFirstAttributeName = (roleMapping: ASRoleMapping) => @@ -47,24 +45,7 @@ const getFirstAttributeValue = (roleMapping: ASRoleMapping) => Object.entries(roleMapping.rules)[0][1] as AttributeName; const emptyUser = { username: '', email: '' } as ElasticsearchUser; -interface RoleMappingsActions { - handleAccessAllEnginesChange(selected: boolean): { selected: boolean }; - handleAuthProviderChange(value: string[]): { value: string[] }; - handleAttributeSelectorChange( - value: AttributeName, - firstElasticsearchRole: string - ): { value: AttributeName; firstElasticsearchRole: string }; - handleAttributeValueChange(value: string): { value: string }; - handleDeleteMapping(roleMappingId: string): { roleMappingId: string }; - handleEngineSelectionChange(engineNames: string[]): { engineNames: string[] }; - handleRoleChange(roleType: RoleTypes): { roleType: RoleTypes }; - handleUsernameSelectChange(username: string): { username: string }; - handleSaveMapping(): void; - handleSaveUser(): void; - initializeRoleMapping(roleMappingId?: string): { roleMappingId?: string }; - initializeSingleUserRoleMapping(roleMappingId?: string): { roleMappingId?: string }; - initializeRoleMappings(): void; - resetState(): void; +interface RoleMappingsActions extends RoleMappingsBaseActions { setRoleMapping(roleMapping: ASRoleMapping): { roleMapping: ASRoleMapping }; setSingleUserRoleMapping(data?: UserMapping): { singleUserRoleMapping: UserMapping }; setRoleMappings({ @@ -73,34 +54,14 @@ interface RoleMappingsActions { roleMappings: ASRoleMapping[]; }): { roleMappings: ASRoleMapping[] }; setRoleMappingsData(data: RoleMappingsServerDetails): RoleMappingsServerDetails; - setElasticsearchUser( - elasticsearchUser?: ElasticsearchUser - ): { elasticsearchUser: ElasticsearchUser }; - openRoleMappingFlyout(): void; - openSingleUserRoleMappingFlyout(): void; - closeUsersAndRolesFlyout(): void; - setRoleMappingErrors(errors: string[]): { errors: string[] }; - enableRoleBasedAccess(): void; - setUserExistingRadioValue(userFormUserIsExisting: boolean): { userFormUserIsExisting: boolean }; - setElasticsearchUsernameValue(username: string): { username: string }; - setElasticsearchEmailValue(email: string): { email: string }; - setUserCreated(): void; - setUserFormIsNewUser(userFormIsNewUser: boolean): { userFormIsNewUser: boolean }; + handleAccessAllEnginesChange(selected: boolean): { selected: boolean }; + handleEngineSelectionChange(engineNames: string[]): { engineNames: string[] }; + handleRoleChange(roleType: RoleTypes): { roleType: RoleTypes }; } -interface RoleMappingsValues { +interface RoleMappingsValues extends RoleMappingsBaseValues { accessAllEngines: boolean; - attributeName: AttributeName; - attributeValue: string; - attributes: string[]; - availableAuthProviders: string[]; availableEngines: Engine[]; - dataLoading: boolean; - elasticsearchRoles: string[]; - elasticsearchUsers: ElasticsearchUser[]; - elasticsearchUser: ElasticsearchUser; - hasAdvancedRoles: boolean; - multipleAuthProvidersConfig: boolean; roleMapping: ASRoleMapping | null; roleMappings: ASRoleMapping[]; singleUserRoleMapping: UserMapping | null; @@ -108,13 +69,7 @@ interface RoleMappingsValues { roleType: RoleTypes; selectedAuthProviders: string[]; selectedEngines: Set; - roleMappingFlyoutOpen: boolean; - singleUserRoleMappingFlyoutOpen: boolean; - selectedOptions: EuiComboBoxOptionOption[]; - roleMappingErrors: string[]; - userFormUserIsExisting: boolean; - userCreated: boolean; - userFormIsNewUser: boolean; + hasAdvancedRoles: boolean; } export const RoleMappingsLogic = kea>({ diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts index 9bd57509a99b1..c10fc5c9d8242 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/index.ts @@ -5,6 +5,7 @@ * 2.0. */ +export * from './types'; export { AttributeSelector } from './attribute_selector'; export { DeactivatedUserCallout } from './deactivated_user_callout'; export { RolesEmptyPrompt } from './roles_empty_prompt'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/types.ts b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/types.ts new file mode 100644 index 0000000000000..9a230efcf040a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/types.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiComboBoxOptionOption } from '@elastic/eui'; + +import { AttributeName, ElasticsearchUser } from '../../shared/types'; + +export interface RoleMappingsBaseServerDetails { + attributes: string[]; + authProviders: string[]; + elasticsearchRoles: string[]; + elasticsearchUsers: ElasticsearchUser[]; + multipleAuthProvidersConfig: boolean; +} + +export interface RoleMappingsBaseActions { + handleAuthProviderChange(value: string[]): { value: string[] }; + handleAttributeSelectorChange( + value: AttributeName, + firstElasticsearchRole: string + ): { value: AttributeName; firstElasticsearchRole: string }; + handleAttributeValueChange(value: string): { value: string }; + handleDeleteMapping(roleMappingId: string): { roleMappingId: string }; + handleUsernameSelectChange(username: string): { username: string }; + handleSaveMapping(): void; + handleSaveUser(): void; + initializeRoleMapping(roleMappingId?: string): { roleMappingId?: string }; + initializeSingleUserRoleMapping(roleMappingId?: string): { roleMappingId?: string }; + initializeRoleMappings(): void; + resetState(): void; + setElasticsearchUser( + elasticsearchUser?: ElasticsearchUser + ): { elasticsearchUser: ElasticsearchUser }; + openRoleMappingFlyout(): void; + openSingleUserRoleMappingFlyout(): void; + closeUsersAndRolesFlyout(): void; + setRoleMappingErrors(errors: string[]): { errors: string[] }; + enableRoleBasedAccess(): void; + setUserExistingRadioValue(userFormUserIsExisting: boolean): { userFormUserIsExisting: boolean }; + setElasticsearchUsernameValue(username: string): { username: string }; + setElasticsearchEmailValue(email: string): { email: string }; + setUserCreated(): void; + setUserFormIsNewUser(userFormIsNewUser: boolean): { userFormIsNewUser: boolean }; +} + +export interface RoleMappingsBaseValues extends RoleMappingsBaseServerDetails { + attributeName: AttributeName; + attributeValue: string; + availableAuthProviders: string[]; + dataLoading: boolean; + elasticsearchUser: ElasticsearchUser; + roleMappingFlyoutOpen: boolean; + singleUserRoleMappingFlyoutOpen: boolean; + selectedOptions: EuiComboBoxOptionOption[]; + roleMappingErrors: string[]; + userFormUserIsExisting: boolean; + userCreated: boolean; + userFormIsNewUser: boolean; + accessAllEngines: boolean; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts index 7f26c8738786c..18b560b6053ca 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts @@ -7,14 +7,17 @@ import { kea, MakeLogicType } from 'kea'; -import { EuiComboBoxOptionOption } from '@elastic/eui'; - import { clearFlashMessages, flashAPIErrors, setSuccessMessage, } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; +import { + RoleMappingsBaseServerDetails, + RoleMappingsBaseActions, + RoleMappingsBaseValues, +} from '../../../shared/role_mapping'; import { ANY_AUTH_PROVIDER } from '../../../shared/role_mapping/constants'; import { AttributeName, SingleUserRoleMapping, ElasticsearchUser } from '../../../shared/types'; import { RoleGroup, WSRoleMapping, Role } from '../../types'; @@ -28,14 +31,9 @@ import { type UserMapping = SingleUserRoleMapping; -interface RoleMappingsServerDetails { +interface RoleMappingsServerDetails extends RoleMappingsBaseServerDetails { roleMappings: WSRoleMapping[]; - attributes: string[]; - authProviders: string[]; availableGroups: RoleGroup[]; - elasticsearchUsers: ElasticsearchUser[]; - elasticsearchRoles: string[]; - multipleAuthProvidersConfig: boolean; singleUserRoleMappings: UserMapping[]; } @@ -45,24 +43,8 @@ const getFirstAttributeValue = (roleMapping: WSRoleMapping): string => Object.entries(roleMapping.rules)[0][1] as string; const emptyUser = { username: '', email: '' } as ElasticsearchUser; -interface RoleMappingsActions { - handleAllGroupsSelectionChange(selected: boolean): { selected: boolean }; - handleAuthProviderChange(value: string[]): { value: string[] }; - handleAttributeSelectorChange( - value: AttributeName, - firstElasticsearchRole: string - ): { value: AttributeName; firstElasticsearchRole: string }; - handleAttributeValueChange(value: string): { value: string }; - handleDeleteMapping(roleMappingId: string): { roleMappingId: string }; - handleGroupSelectionChange(groupIds: string[]): { groupIds: string[] }; - handleRoleChange(roleType: Role): { roleType: Role }; - handleUsernameSelectChange(username: string): { username: string }; - handleSaveMapping(): void; - handleSaveUser(): void; - initializeRoleMapping(roleMappingId?: string): { roleMappingId?: string }; - initializeSingleUserRoleMapping(roleMappingId?: string): { roleMappingId?: string }; - initializeRoleMappings(): void; - resetState(): void; +interface RoleMappingsActions extends RoleMappingsBaseActions { + setDefaultGroup(availableGroups: RoleGroup[]): { availableGroups: RoleGroup[] }; setRoleMapping(roleMapping: WSRoleMapping): { roleMapping: WSRoleMapping }; setSingleUserRoleMapping(data?: UserMapping): { singleUserRoleMapping: UserMapping }; setRoleMappings({ @@ -71,34 +53,14 @@ interface RoleMappingsActions { roleMappings: WSRoleMapping[]; }): { roleMappings: WSRoleMapping[] }; setRoleMappingsData(data: RoleMappingsServerDetails): RoleMappingsServerDetails; - setElasticsearchUser( - elasticsearchUser?: ElasticsearchUser - ): { elasticsearchUser: ElasticsearchUser }; - setDefaultGroup(availableGroups: RoleGroup[]): { availableGroups: RoleGroup[] }; - openRoleMappingFlyout(): void; - openSingleUserRoleMappingFlyout(): void; - closeUsersAndRolesFlyout(): void; - setRoleMappingErrors(errors: string[]): { errors: string[] }; - enableRoleBasedAccess(): void; - setUserExistingRadioValue(userFormUserIsExisting: boolean): { userFormUserIsExisting: boolean }; - setElasticsearchUsernameValue(username: string): { username: string }; - setElasticsearchEmailValue(email: string): { email: string }; - setUserCreated(): void; - setUserFormIsNewUser(userFormIsNewUser: boolean): { userFormIsNewUser: boolean }; + handleAllGroupsSelectionChange(selected: boolean): { selected: boolean }; + handleGroupSelectionChange(groupIds: string[]): { groupIds: string[] }; + handleRoleChange(roleType: Role): { roleType: Role }; } -interface RoleMappingsValues { +interface RoleMappingsValues extends RoleMappingsBaseValues { includeInAllGroups: boolean; - attributeName: AttributeName; - attributeValue: string; - attributes: string[]; - availableAuthProviders: string[]; availableGroups: RoleGroup[]; - dataLoading: boolean; - elasticsearchRoles: string[]; - elasticsearchUsers: ElasticsearchUser[]; - elasticsearchUser: ElasticsearchUser; - multipleAuthProvidersConfig: boolean; roleMapping: WSRoleMapping | null; roleMappings: WSRoleMapping[]; singleUserRoleMapping: UserMapping | null; @@ -106,13 +68,6 @@ interface RoleMappingsValues { roleType: Role; selectedAuthProviders: string[]; selectedGroups: Set; - roleMappingFlyoutOpen: boolean; - singleUserRoleMappingFlyoutOpen: boolean; - selectedOptions: EuiComboBoxOptionOption[]; - roleMappingErrors: string[]; - userFormUserIsExisting: boolean; - userCreated: boolean; - userFormIsNewUser: boolean; } export const RoleMappingsLogic = kea>({ From 6da677e29699b990e311328ce93e808c6a0ec381 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Wed, 23 Jun 2021 21:52:04 -0500 Subject: [PATCH 03/10] Port #3920 to Kibana https://github.com/elastic/ent-search/pull/3920 --- .../role_mappings/role_mappings_logic.test.ts | 2 ++ .../role_mappings/role_mappings_logic.ts | 6 ++++++ .../components/role_mappings/user.tsx | 2 ++ .../shared/role_mapping/constants.ts | 11 +++++++++++ .../applications/shared/role_mapping/types.ts | 1 + .../shared/role_mapping/user_selector.tsx | 18 +++++++++++++++++- .../role_mappings/role_mappings_logic.test.ts | 2 ++ .../views/role_mappings/role_mappings_logic.ts | 6 ++++++ .../views/role_mappings/user.tsx | 2 ++ 9 files changed, 49 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts index 16b44e9ec1f11..7dbbc6f779243 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.test.ts @@ -58,6 +58,7 @@ describe('RoleMappingsLogic', () => { userCreated: false, userFormIsNewUser: true, userFormUserIsExisting: true, + smtpSettingsPresent: false, }; const mappingsServerProps = { @@ -70,6 +71,7 @@ describe('RoleMappingsLogic', () => { hasAdvancedRoles: false, singleUserRoleMappings: [asSingleUserRoleMapping], elasticsearchUsers, + smtpSettingsPresent: false, }; beforeEach(() => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts index ede379e4bf54f..0dcf2d6d0b36f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts @@ -324,6 +324,12 @@ export const RoleMappingsLogic = kea userFormIsNewUser, }, ], + smtpSettingsPresent: [ + false, + { + setRoleMappingsData: (_, { smtpSettingsPresent }) => smtpSettingsPresent, + }, + ], }, selectors: ({ selectors }) => ({ selectedOptions: [ diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx index d3e9a990abbe5..029524f040abe 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx @@ -49,6 +49,7 @@ export const User: React.FC = () => { roleMappingErrors, userCreated, userFormIsNewUser, + smtpSettingsPresent, } = useValues(RoleMappingsLogic); const roleTypes = hasAdvancedRoles ? [...standardRoles, ...advancedRoles] : standardRoles; @@ -82,6 +83,7 @@ export const User: React.FC = () => { 0} error={roleMappingErrors}> = ({ isNewUser, + smtpSettingsPresent, userFormUserIsExisting, elasticsearchUsers, elasticsearchUser, @@ -66,6 +74,14 @@ export const UserSelector: React.FC = ({ })); const hasElasticsearchUsers = elasticsearchUsers.length > 0; const showNewUserExistingUserControls = userFormUserIsExisting && hasElasticsearchUsers; + const smptHelpText = !smtpSettingsPresent && ( + <> + {SMTP_CALLOUT_LABEL}{' '} + + {SMTP_LINK_LABEL} + + + ); const roleSelect = ( @@ -80,7 +96,7 @@ export const UserSelector: React.FC = ({ ); const emailInput = ( - + { userCreated: false, userFormIsNewUser: true, userFormUserIsExisting: true, + smtpSettingsPresent: false, }; const roleGroup = { id: '123', @@ -76,6 +77,7 @@ describe('RoleMappingsLogic', () => { elasticsearchRoles: [], singleUserRoleMappings: [wsSingleUserRoleMapping], elasticsearchUsers, + smtpSettingsPresent: false, }; beforeEach(() => { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts index 18b560b6053ca..a665edf3f0fca 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts @@ -324,6 +324,12 @@ export const RoleMappingsLogic = kea userFormIsNewUser, }, ], + smtpSettingsPresent: [ + false, + { + setRoleMappingsData: (_, { smtpSettingsPresent }) => smtpSettingsPresent, + }, + ], }, selectors: ({ selectors }) => ({ selectedOptions: [ diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx index c3b8064c3c25a..1a654cd83edd7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx @@ -47,6 +47,7 @@ export const User: React.FC = () => { roleMappingErrors, userCreated, userFormIsNewUser, + smtpSettingsPresent, } = useValues(RoleMappingsLogic); const showGroupAssignmentSelector = availableGroups.length > 0; @@ -79,6 +80,7 @@ export const User: React.FC = () => { 0} error={roleMappingErrors}> Date: Thu, 24 Jun 2021 09:06:43 -0500 Subject: [PATCH 04/10] Lint fixes --- .../applications/shared/role_mapping/user_selector.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.test.tsx index 60bac97d09835..0aea55a51040c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_selector.test.tsx @@ -34,6 +34,7 @@ describe('UserSelector', () => { const props = { isNewUser: true, + smtpSettingsPresent: false, userFormUserIsExisting: true, elasticsearchUsers, elasticsearchUser: elasticsearchUsers[0], @@ -101,7 +102,7 @@ describe('UserSelector', () => { {...props} userFormUserIsExisting={false} elasticsearchUsers={[]} - elasticsearchUser={{ email: '', username: '' }} + elasticsearchUser={{ email: '', username: '', enabled: true }} /> ); From 96507ee979be90ffe3525e89dd155e90648cdc49 Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Thu, 24 Jun 2021 10:31:32 -0500 Subject: [PATCH 05/10] Remove error state from form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already did this for the users flyout. Basically changes the dirty state of the form from an error state to just showing “Required”. i18n had not been translated yet for `ATTRIBUTE_VALUE_ERROR` --- .../shared/role_mapping/attribute_selector.test.tsx | 11 +++++++++-- .../shared/role_mapping/attribute_selector.tsx | 5 ++--- .../applications/shared/role_mapping/constants.ts | 7 ------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.test.tsx index d19d090b6e706..8fed459b0a8dc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.test.tsx @@ -9,12 +9,12 @@ import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; -import { EuiComboBox, EuiFieldText } from '@elastic/eui'; +import { EuiComboBox, EuiFieldText, EuiFormRow } from '@elastic/eui'; import { AttributeName } from '../types'; import { AttributeSelector } from './attribute_selector'; -import { ANY_AUTH_PROVIDER, ANY_AUTH_PROVIDER_OPTION_LABEL } from './constants'; +import { ANY_AUTH_PROVIDER, ANY_AUTH_PROVIDER_OPTION_LABEL, REQUIRED_LABEL } from './constants'; const handleAttributeSelectorChange = jest.fn(); const handleAttributeValueChange = jest.fn(); @@ -166,5 +166,12 @@ describe('AttributeSelector', () => { baseProps.elasticsearchRoles[0] ); }); + + it('shows helpText when attributeValueInvalid', () => { + const wrapper = shallow(); + const formRow = wrapper.find(EuiFormRow).at(2); + + expect(formRow.prop('helpText')).toEqual(REQUIRED_LABEL); + }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.tsx index bedb6b3df90f2..e24bc03bea452 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/attribute_selector.tsx @@ -21,7 +21,7 @@ import { ANY_AUTH_PROVIDER, ANY_AUTH_PROVIDER_OPTION_LABEL, ATTRIBUTE_VALUE_LABEL, - ATTRIBUTE_VALUE_ERROR, + REQUIRED_LABEL, AUTH_ANY_PROVIDER_LABEL, AUTH_INDIVIDUAL_PROVIDER_LABEL, AUTH_PROVIDER_LABEL, @@ -129,8 +129,7 @@ export const AttributeSelector: React.FC = ({ {attributeName === 'role' ? ( Date: Thu, 24 Jun 2021 14:44:38 -0500 Subject: [PATCH 06/10] Add loading states --- .../app_search/components/role_mappings/role_mapping.tsx | 2 ++ .../components/role_mappings/role_mappings_logic.test.ts | 1 + .../components/role_mappings/role_mappings_logic.ts | 9 +++++++++ .../app_search/components/role_mappings/user.tsx | 2 ++ .../shared/role_mapping/role_mapping_flyout.tsx | 5 ++++- .../public/applications/shared/role_mapping/types.ts | 1 + .../applications/shared/role_mapping/user_flyout.tsx | 9 ++++++++- .../views/role_mappings/role_mapping.tsx | 2 ++ .../views/role_mappings/role_mappings_logic.test.ts | 1 + .../views/role_mappings/role_mappings_logic.ts | 9 +++++++++ .../workplace_search/views/role_mappings/user.tsx | 2 ++ 11 files changed, 41 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.tsx index dbebd8e46a219..02ff4c0ba1c3d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mapping.tsx @@ -45,6 +45,7 @@ export const RoleMapping: React.FC = () => { selectedEngines, selectedAuthProviders, roleMappingErrors, + formLoading, } = useValues(RoleMappingsLogic); const isNew = !roleMapping; @@ -67,6 +68,7 @@ export const RoleMapping: React.FC = () => { return ( { userFormIsNewUser: true, userFormUserIsExisting: true, smtpSettingsPresent: false, + formLoading: false, }; const mappingsServerProps = { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts index 0dcf2d6d0b36f..fb574a3588989 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/role_mappings_logic.ts @@ -330,6 +330,15 @@ export const RoleMappingsLogic = kea smtpSettingsPresent, }, ], + formLoading: [ + false, + { + handleSaveMapping: () => true, + handleSaveUser: () => true, + initializeRoleMappings: () => false, + setRoleMappingErrors: () => false, + }, + ], }, selectors: ({ selectors }) => ({ selectedOptions: [ diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx index 029524f040abe..018d29706b05f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/role_mappings/user.tsx @@ -50,6 +50,7 @@ export const User: React.FC = () => { userCreated, userFormIsNewUser, smtpSettingsPresent, + formLoading, } = useValues(RoleMappingsLogic); const roleTypes = hasAdvancedRoles ? [...standardRoles, ...advancedRoles] : standardRoles; @@ -102,6 +103,7 @@ export const User: React.FC = () => { return ( = ({ children, isNew, disabled, + formLoading, closeUsersAndRolesFlyout, handleSaveMapping, }) => ( @@ -77,7 +79,8 @@ export const RoleMappingFlyout: React.FC = ({ = ({ isNew, isComplete, disabled, + formLoading, closeUserFlyout, handleSaveUser, }) => { @@ -75,7 +77,12 @@ export const UserFlyout: React.FC = ({ {CANCEL_BUTTON_LABEL} - + {isNew ? ADD_USER_LABEL : UPDATE_USER_LABEL} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.tsx index 20211d40d7010..734716af9f627 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mapping.tsx @@ -59,6 +59,7 @@ export const RoleMapping: React.FC = () => { selectedAuthProviders, roleMapping, roleMappingErrors, + formLoading, } = useValues(RoleMappingsLogic); const isNew = !roleMapping; @@ -69,6 +70,7 @@ export const RoleMapping: React.FC = () => { return ( { userFormIsNewUser: true, userFormUserIsExisting: true, smtpSettingsPresent: false, + formLoading: false, }; const roleGroup = { id: '123', diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts index a665edf3f0fca..6e7104964cdb7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/role_mappings_logic.ts @@ -330,6 +330,15 @@ export const RoleMappingsLogic = kea smtpSettingsPresent, }, ], + formLoading: [ + false, + { + handleSaveMapping: () => true, + handleSaveUser: () => true, + initializeRoleMappings: () => false, + setRoleMappingErrors: () => false, + }, + ], }, selectors: ({ selectors }) => ({ selectedOptions: [ diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx index 1a654cd83edd7..6447f43e6ed4d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/role_mappings/user.tsx @@ -48,6 +48,7 @@ export const User: React.FC = () => { userCreated, userFormIsNewUser, smtpSettingsPresent, + formLoading, } = useValues(RoleMappingsLogic); const showGroupAssignmentSelector = availableGroups.length > 0; @@ -99,6 +100,7 @@ export const User: React.FC = () => { return ( Date: Thu, 24 Jun 2021 14:51:18 -0500 Subject: [PATCH 07/10] Remove manual disabling of button Co-authored-by: Constance --- .../public/applications/shared/role_mapping/user_flyout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx index b5bd3ac971fa4..a505794e3420c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx @@ -78,7 +78,7 @@ export const UserFlyout: React.FC = ({ Date: Thu, 24 Jun 2021 14:53:17 -0500 Subject: [PATCH 08/10] Remove manual disabling of other button --- .../applications/shared/role_mapping/role_mapping_flyout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.tsx index 9d781f6e7718e..bcaf26ccf2cfc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.tsx @@ -79,7 +79,7 @@ export const RoleMappingFlyout: React.FC = ({ Date: Thu, 24 Jun 2021 15:26:28 -0500 Subject: [PATCH 09/10] Lint fixes --- .../shared/role_mapping/role_mapping_flyout.test.tsx | 1 + .../public/applications/shared/role_mapping/user_flyout.test.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.test.tsx index ffcf5508233fc..651a46f5df85e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/role_mapping_flyout.test.tsx @@ -26,6 +26,7 @@ describe('RoleMappingFlyout', () => { const props = { isNew: true, disabled: false, + formLoading: false, closeUsersAndRolesFlyout, handleSaveMapping, }; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.test.tsx index 43333fe048f23..f48ed6a6c7eb9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.test.tsx @@ -30,6 +30,7 @@ describe('UserFlyout', () => { isNew: true, isComplete: false, disabled: false, + formLoading: false, closeUserFlyout, handleSaveUser, }; From 5f958eb826005436a2456b0b1c653a137a1ef2ab Mon Sep 17 00:00:00 2001 From: scottybollinger Date: Thu, 24 Jun 2021 16:42:47 -0500 Subject: [PATCH 10/10] Lint --- .../applications/shared/role_mapping/user_flyout.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx index a505794e3420c..8741a2b4517d3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/role_mapping/user_flyout.tsx @@ -77,12 +77,7 @@ export const UserFlyout: React.FC = ({ {CANCEL_BUTTON_LABEL} - + {isNew ? ADD_USER_LABEL : UPDATE_USER_LABEL}