[6.x] Rendering the space selector in either the header or the globalnav (#23845) (#24440)

* Rendering the space selector in either the header or the globalnav (#23845)

* Rendering the space selector in either the header or the globalnav

* Adding link title

* Doing it the React way

* Updating snapshots

* Adding withTitle prop

* Fixing Spaces nav control popover snapshot
This commit is contained in:
Brandon Kobel 2018-10-24 07:28:08 -07:00 committed by GitHub
parent 8e28de0979
commit 377688ab7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 136 additions and 46 deletions

View file

@ -2,40 +2,25 @@
exports[`NavControlPopover renders without crashing 1`] = `
<EuiPopover
anchorPosition="rightCenter"
anchorPosition="downRight"
button={
<div
className="global-nav-link"
>
<a
className="global-nav-link__anchor"
onClick={[Function]}
>
<div
className="global-nav-link__icon"
>
<Unknown
className="spaceNavGraphic"
size="s"
space={
Object {
"id": "",
"name": "foo",
}
<SpacesGlobalNavButton
linkIcon={
<Unknown
className="spaceNavGraphic"
size="s"
space={
Object {
"id": "",
"name": "foo",
}
/>
</div>
<div
className="global-nav-link__title"
>
foo
</div>
</a>
</div>
}
/>
}
linkTitle="foo"
spaceSelectorShown={false}
toggleSpaceSelector={[Function]}
/>
}
closePopover={[Function]}
data-test-subj="spacesNavSelector"
@ -45,6 +30,7 @@ exports[`NavControlPopover renders without crashing 1`] = `
ownFocus={true}
panelPaddingSize="none"
repositionOnScroll={true}
withTitle={true}
>
<Component
onManageSpacesClick={[Function]}

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React, { Component } from 'react';
import { ButtonProps } from '../types';
export class SpacesGlobalNavButton extends Component<ButtonProps> {
public render() {
return (
<div className="global-nav-link">
<a className="global-nav-link__anchor" onClick={this.props.toggleSpaceSelector}>
<div className="global-nav-link__icon"> {this.props.linkIcon} </div>
<div className="global-nav-link__title"> {this.props.linkTitle} </div>
</a>
</div>
);
}
}

View file

@ -0,0 +1,29 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import {
// @ts-ignore
EuiHeaderSectionItemButton,
} from '@elastic/eui';
import React, { Component } from 'react';
import { ButtonProps } from '../types';
export class SpacesHeaderNavButton extends Component<ButtonProps> {
public render() {
return (
<EuiHeaderSectionItemButton
aria-controls="headerSpacesMenuList"
aria-expanded={this.props.spaceSelectorShown}
aria-haspopup="true"
aria-label={this.props.linkTitle}
title={this.props.linkTitle}
onClick={this.props.toggleSpaceSelector}
>
{this.props.linkIcon}
</EuiHeaderSectionItemButton>
);
}
}

View file

@ -9,16 +9,21 @@ import { SpacesManager } from 'plugins/spaces/lib/spaces_manager';
// @ts-ignore
import template from 'plugins/spaces/views/nav_control/nav_control.html';
import 'plugins/spaces/views/nav_control/nav_control.less';
import { NavControlPopover } from 'plugins/spaces/views/nav_control/nav_control_popover';
import { UserProfileProvider } from 'plugins/xpack_main/services/user_profile';
import React from 'react';
import ReactDOM from 'react-dom';
import { render, unmountComponentAtNode } from 'react-dom';
import { NavControlSide } from 'ui/chrome/directives/header_global_nav';
// @ts-ignore
import { uiModules } from 'ui/modules';
// @ts-ignore
import { chromeHeaderNavControlsRegistry } from 'ui/registry/chrome_header_nav_controls';
// @ts-ignore
import { chromeNavControlsRegistry } from 'ui/registry/chrome_nav_controls';
import { NavControlPopover } from 'plugins/spaces/views/nav_control/nav_control_popover';
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { Space } from '../../../common/model/space';
import { SpacesGlobalNavButton } from './components/spaces_global_nav_button';
import { SpacesHeaderNavButton } from './components/spaces_header_nav_button';
chromeNavControlsRegistry.register(
constant({
@ -56,6 +61,8 @@ module.controller(
spacesManager={spacesManager}
activeSpace={activeSpace}
userProfile={userProfile}
anchorPosition={'rightCenter'}
buttonClass={SpacesGlobalNavButton}
/>,
domNode
);
@ -85,3 +92,29 @@ module.service('spacesNavState', (activeSpace: any) => {
},
} as SpacesNavState;
});
chromeHeaderNavControlsRegistry.register(
($http: any, chrome: any, Private: any, activeSpace: any) => ({
name: 'spaces',
order: 1000,
side: NavControlSide.Left,
render(el: HTMLElement) {
const userProfile = Private(UserProfileProvider);
const spaceSelectorURL = chrome.getInjected('spaceSelectorURL');
spacesManager = new SpacesManager($http, chrome, spaceSelectorURL);
ReactDOM.render(
<NavControlPopover
spacesManager={spacesManager}
activeSpace={activeSpace}
userProfile={userProfile}
anchorPosition="downLeft"
buttonClass={SpacesHeaderNavButton}
/>,
el
);
},
})
);

View file

@ -8,6 +8,7 @@ import { mount, shallow } from 'enzyme';
import React from 'react';
import { SpaceAvatar } from '../../components';
import { SpacesManager } from '../../lib/spaces_manager';
import { SpacesGlobalNavButton } from './components/spaces_global_nav_button';
import { NavControlPopover } from './nav_control_popover';
const mockChrome = {
@ -52,6 +53,8 @@ describe('NavControlPopover', () => {
activeSpace={activeSpace}
spacesManager={spacesManager}
userProfile={{ hasCapability: () => true }}
anchorPosition={'downRight'}
buttonClass={SpacesGlobalNavButton}
/>
);
expect(wrapper).toMatchSnapshot();
@ -72,6 +75,8 @@ describe('NavControlPopover', () => {
activeSpace={activeSpace}
spacesManager={spacesManager}
userProfile={{ hasCapability: () => true }}
anchorPosition={'rightCenter'}
buttonClass={SpacesGlobalNavButton}
/>
);

View file

@ -4,14 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { EuiAvatar, EuiPopover } from '@elastic/eui';
import React, { Component } from 'react';
import { EuiAvatar, EuiPopover, PopoverAnchorPosition } from '@elastic/eui';
import React, { Component, ComponentClass } from 'react';
import { UserProfile } from '../../../../xpack_main/public/services/user_profile';
import { Space } from '../../../common/model/space';
import { SpaceAvatar } from '../../components';
import { SpacesManager } from '../../lib/spaces_manager';
import { SpacesDescription } from './components/spaces_description';
import { SpacesMenu } from './components/spaces_menu';
import { ButtonProps } from './types';
interface Props {
spacesManager: SpacesManager;
@ -21,6 +22,8 @@ interface Props {
space: Space;
};
userProfile: UserProfile;
anchorPosition: PopoverAnchorPosition;
buttonClass: ComponentClass<ButtonProps>;
}
interface State {
@ -83,10 +86,11 @@ export class NavControlPopover extends Component<Props, State> {
button={button}
isOpen={this.state.showSpaceSelector}
closePopover={this.closeSpaceSelector}
anchorPosition={'rightCenter'}
anchorPosition={this.props.anchorPosition}
panelPaddingSize="none"
// @ts-ignore
repositionOnScroll={true}
withTitle
ownFocus
>
{element}
@ -134,14 +138,14 @@ export class NavControlPopover extends Component<Props, State> {
};
private getButton = (linkIcon: JSX.Element, linkTitle: string) => {
// Mimics the current angular-based navigation link
const Button = this.props.buttonClass;
return (
<div className="global-nav-link">
<a className="global-nav-link__anchor" onClick={this.toggleSpaceSelector}>
<div className="global-nav-link__icon"> {linkIcon} </div>
<div className="global-nav-link__title"> {linkTitle} </div>
</a>
</div>
<Button
linkTitle={linkTitle}
linkIcon={linkIcon}
toggleSpaceSelector={this.toggleSpaceSelector}
spaceSelectorShown={this.state.showSpaceSelector}
/>
);
};

View file

@ -0,0 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export interface ButtonProps {
toggleSpaceSelector: () => void;
linkIcon: JSX.Element;
linkTitle: string;
spaceSelectorShown: boolean;
}