Skip to content

Commit

Permalink
Initial example: Convert RoleMappings views to new page template
Browse files Browse the repository at this point in the history
- Refactor RoleMappingsHeadings to a fn that returns a pageHeader obj to match new page template
+ remove unnecessary type union
+ fix un-i18n'ed product names
+ simplify returned JSX
  • Loading branch information
cee-chen committed Jun 15, 2021
1 parent 1415e69 commit 0c38b4a
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import React from 'react';

import { shallow } from 'enzyme';

import { Loading } from '../../../shared/loading';
import { RoleMappingsTable, RoleMappingsHeading } from '../../../shared/role_mapping';
import { EuiButton } from '@elastic/eui';

import { RoleMappingsTable } from '../../../shared/role_mapping';
import { wsRoleMapping } from '../../../shared/role_mapping/__mocks__/roles';

import { getPageHeaderActions } from '../../../test_helpers';

import { RoleMapping } from './role_mapping';
import { RoleMappings } from './role_mappings';

Expand Down Expand Up @@ -44,13 +47,6 @@ describe('RoleMappings', () => {
expect(wrapper.find(RoleMappingsTable)).toHaveLength(1);
});

it('returns Loading when loading', () => {
setMockValues({ ...mockValues, dataLoading: true });
const wrapper = shallow(<RoleMappings />);

expect(wrapper.find(Loading)).toHaveLength(1);
});

it('renders RoleMapping flyout', () => {
setMockValues({ ...mockValues, roleMappingFlyoutOpen: true });
const wrapper = shallow(<RoleMappings />);
Expand All @@ -60,8 +56,9 @@ describe('RoleMappings', () => {

it('handles onClick', () => {
const wrapper = shallow(<RoleMappings />);
wrapper.find(RoleMappingsHeading).prop('onClick')();
const actions = getPageHeaderActions(wrapper);

actions.find(EuiButton).simulate('click');
expect(initializeRoleMapping).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import React, { useEffect } from 'react';

import { useActions, useValues } from 'kea';

import { FlashMessages } from '../../../shared/flash_messages';
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { Loading } from '../../../shared/loading';
import { RoleMappingsTable, RoleMappingsHeading } from '../../../shared/role_mapping';
import { ROLE_MAPPINGS_TITLE } from '../../../shared/role_mapping/constants';
import { APP_SEARCH_PLUGIN } from '../../../../../common/constants';
import {
ROLE_MAPPINGS_TITLE,
getRoleMappingsHeader,
RoleMappingsTable,
} from '../../../shared/role_mapping';
import { AppSearchPageTemplate } from '../layout';

import { ROLE_MAPPINGS_ENGINE_ACCESS_HEADING } from './constants';
import { RoleMapping } from './role_mapping';
Expand All @@ -38,11 +40,16 @@ export const RoleMappings: React.FC = () => {
return resetState;
}, []);

if (dataLoading) return <Loading />;

const roleMappingsSection = (
<>
<RoleMappingsHeading productName="App Search" onClick={() => initializeRoleMapping()} />
return (
<AppSearchPageTemplate
pageChrome={[ROLE_MAPPINGS_TITLE]}
pageHeader={getRoleMappingsHeader({
productName: APP_SEARCH_PLUGIN.NAME,
onClick: () => initializeRoleMapping(),
})}
isLoading={dataLoading}
>
{roleMappingFlyoutOpen && <RoleMapping />}
<RoleMappingsTable
roleMappings={roleMappings}
accessItemKey="engines"
Expand All @@ -51,15 +58,6 @@ export const RoleMappings: React.FC = () => {
shouldShowAuthProvider={multipleAuthProvidersConfig}
handleDeleteMapping={handleDeleteMapping}
/>
</>
);

return (
<>
<SetPageChrome trail={[ROLE_MAPPINGS_TITLE]} />
{roleMappingFlyoutOpen && <RoleMapping />}
<FlashMessages />
{roleMappingsSection}
</>
</AppSearchPageTemplate>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ export const AppSearchConfigured: React.FC<Required<InitialAppData>> = (props) =
<Library />
</Route>
)}
{canViewRoleMappings && (
<Route path={ROLE_MAPPINGS_PATH}>
<RoleMappings />
</Route>
)}
<Route>
<Layout navigation={<AppSearchNav />} readOnlyMode={readOnlyMode}>
<Switch>
Expand All @@ -110,11 +115,6 @@ export const AppSearchConfigured: React.FC<Required<InitialAppData>> = (props) =
<Route exact path={CREDENTIALS_PATH}>
<Credentials />
</Route>
{canViewRoleMappings && (
<Route path={ROLE_MAPPINGS_PATH}>
<RoleMappings />
</Route>
)}
{canManageEngines && (
<Route exact path={ENGINE_CREATION_PATH}>
<EngineCreation />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

import { i18n } from '@kbn/i18n';

import { ProductName } from '../types';

export const ANY_AUTH_PROVIDER = '*';

export const ANY_AUTH_PROVIDER_OPTION_LABEL = i18n.translate(
Expand Down Expand Up @@ -184,7 +182,7 @@ export const ROLE_MAPPINGS_HEADING_TITLE = i18n.translate(
{ defaultMessage: 'Role mappings' }
);

export const ROLE_MAPPINGS_HEADING_DESCRIPTION = (productName: ProductName) =>
export const ROLE_MAPPINGS_HEADING_DESCRIPTION = (productName: string) =>
i18n.translate('xpack.enterpriseSearch.roleMapping.roleMappingsHeadingDescription', {
defaultMessage:
'Role mappings provide an interface to associate native or SAML-governed role attributes with {productName} permissions.',
Expand All @@ -193,7 +191,7 @@ export const ROLE_MAPPINGS_HEADING_DESCRIPTION = (productName: ProductName) =>

export const ROLE_MAPPINGS_HEADING_DOCS_LINK = i18n.translate(
'xpack.enterpriseSearch.roleMapping.roleMappingsHeadingDocsLink',
{ defaultMessage: 'Learn more about role mappings' }
{ defaultMessage: 'Learn more about role mappings.' }
);

export const ROLE_MAPPINGS_HEADING_BUTTON = i18n.translate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
* 2.0.
*/

export { ROLE_MAPPINGS_TITLE } from './constants';
export { AttributeSelector } from './attribute_selector';
export { RoleMappingsTable } from './role_mappings_table';
export { RoleOptionLabel } from './role_option_label';
export { RoleSelector } from './role_selector';
export { RoleMappingFlyout } from './role_mapping_flyout';
export { RoleMappingsHeading } from './role_mappings_heading';
export { getRoleMappingsHeader } from './role_mappings_header';
export { UsersAndRolesRowActions } from './users_and_roles_row_actions';
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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 { EuiLink, EuiButton } from '@elastic/eui';

import { getRoleMappingsHeader } from './role_mappings_header';

describe('getRoleMappingsHeader', () => {
const onClick = jest.fn();
const pageHeader = getRoleMappingsHeader({ productName: 'Workplace Search', onClick });

it('returns an EuiPageHeader object', () => {
expect(pageHeader.pageTitle).toEqual('Role mappings');
});

it('renders the passed productName in the description', () => {
const Description = () => <>{pageHeader.description}</>;
const wrapper = shallow(<Description />);

expect(wrapper.text()).toEqual(
expect.stringContaining('role attributes with Workplace Search permissions')
);
expect(wrapper.find(EuiLink)).toHaveLength(1);
});

it('renders an action button with a passed onClick', () => {
const Button = () => <>{pageHeader.rightSideItems[0]}</>;
const wrapper = shallow(<Button />);

wrapper.find(EuiButton).simulate('click');
expect(onClick).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 { EuiButton, EuiLink } from '@elastic/eui';

import {
ROLE_MAPPINGS_HEADING_TITLE,
ROLE_MAPPINGS_HEADING_DESCRIPTION,
ROLE_MAPPINGS_HEADING_DOCS_LINK,
ROLE_MAPPINGS_HEADING_BUTTON,
} from './constants';

interface Props {
productName: string;
onClick(): void;
}

// TODO: Replace EuiLink href with actual docs link when available
const ROLE_MAPPINGS_DOCS_HREF = '#TODO';

export const getRoleMappingsHeader = ({ productName, onClick }: Props) => ({
pageTitle: ROLE_MAPPINGS_HEADING_TITLE,
description: (
<>
{ROLE_MAPPINGS_HEADING_DESCRIPTION(productName)}{' '}
<EuiLink external href={ROLE_MAPPINGS_DOCS_HREF} target="_blank">
{ROLE_MAPPINGS_HEADING_DOCS_LINK}
</EuiLink>
</>
),
rightSideItems: [
<EuiButton fill onClick={onClick}>
{ROLE_MAPPINGS_HEADING_BUTTON}
</EuiButton>,
],
});

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,3 @@ export interface RoleMapping {
content: string;
};
}

export type ProductName = 'App Search' | 'Workplace Search';
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,7 @@ export const WorkplaceSearchConfigured: React.FC<InitialAppData> = (props) => {
</Layout>
</Route>
<Route path={ROLE_MAPPINGS_PATH}>
<Layout navigation={<WorkplaceSearchNav />} restrictWidth readOnlyMode={readOnlyMode}>
<RoleMappings />
</Layout>
<RoleMappings />
</Route>
<Route path={SECURITY_PATH}>
<Layout navigation={<WorkplaceSearchNav />} restrictWidth readOnlyMode={readOnlyMode}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import React from 'react';

import { shallow } from 'enzyme';

import { Loading } from '../../../shared/loading';
import { RoleMappingsTable, RoleMappingsHeading } from '../../../shared/role_mapping';
import { EuiButton } from '@elastic/eui';

import { RoleMappingsTable } from '../../../shared/role_mapping';
import { wsRoleMapping } from '../../../shared/role_mapping/__mocks__/roles';

import { getPageHeaderActions } from '../../../test_helpers';

import { RoleMapping } from './role_mapping';
import { RoleMappings } from './role_mappings';

Expand Down Expand Up @@ -44,13 +47,6 @@ describe('RoleMappings', () => {
expect(wrapper.find(RoleMappingsTable)).toHaveLength(1);
});

it('returns Loading when loading', () => {
setMockValues({ ...mockValues, dataLoading: true });
const wrapper = shallow(<RoleMappings />);

expect(wrapper.find(Loading)).toHaveLength(1);
});

it('renders RoleMapping flyout', () => {
setMockValues({ ...mockValues, roleMappingFlyoutOpen: true });
const wrapper = shallow(<RoleMappings />);
Expand All @@ -60,8 +56,9 @@ describe('RoleMappings', () => {

it('handles onClick', () => {
const wrapper = shallow(<RoleMappings />);
wrapper.find(RoleMappingsHeading).prop('onClick')();
const actions = getPageHeaderActions(wrapper);

actions.find(EuiButton).simulate('click');
expect(initializeRoleMapping).toHaveBeenCalled();
});
});
Loading

0 comments on commit 0c38b4a

Please sign in to comment.