Skip to content

Commit

Permalink
Organize code files
Browse files Browse the repository at this point in the history
  • Loading branch information
tsullivan committed May 1, 2023
1 parent 1e0aaf8 commit b43f859
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 108 deletions.
58 changes: 58 additions & 0 deletions packages/shared-ux/chrome/navigation/src/ui/components/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { EuiHeaderLogo, EuiLoadingSpinner } from '@elastic/eui';
import React from 'react';
import useObservable from 'react-use/lib/useObservable';
import { NavigationProps, NavigationServices } from '../../../types';
import { getI18nStrings } from '../../i18n_strings';
import { ElasticMark } from './elastic_mark';
import './header_logo.scss';

type Props = Pick<NavigationProps, 'homeHref'>;
type Services = Pick<
NavigationServices,
'basePath' | 'navIsOpen' | 'navigateToUrl' | 'loadingCount$'
>;

export const NavHeader = (props: Props & Services) => {
const strings = getI18nStrings();
const { basePath, navIsOpen, navigateToUrl, loadingCount$, homeHref } = props;

const loadingCount = useObservable(loadingCount$, 0);
const homeUrl = basePath.prepend(homeHref);
const navigateHome = (event: React.MouseEvent) => {
event.preventDefault();
navigateToUrl(homeUrl);
};
const logo =
loadingCount === 0 ? (
<EuiHeaderLogo
iconType="logoElastic"
aria-label={strings.headerLogoAriaLabel}
onClick={navigateHome}
data-test-subj="nav-header-logo"
/>
) : (
<a href={homeUrl} onClick={navigateHome}>
<EuiLoadingSpinner
size="l"
aria-hidden={false}
onClick={navigateHome}
data-test-subj="nav-header-loading-spinner"
/>
</a>
);

return (
<>
{logo}
{navIsOpen ? <ElasticMark className="chrHeaderLogo__mark" aria-hidden={true} /> : null}
</>
);
};
12 changes: 12 additions & 0 deletions packages/shared-ux/chrome/navigation/src/ui/components/index.tsx
Original file line number Diff line number Diff line change
@@ -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
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export { NavHeader } from './header';
export { LinkToCloud } from './link_to_cloud';
export { NavigationBucket } from './navigation_bucket';
export { RecentlyAccessed } from './recently_accessed';
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { EuiCollapsibleNavGroup, EuiLink } from '@elastic/eui';
import React from 'react';
import { NavigationProps } from '../../../types';
import { getI18nStrings } from '../../i18n_strings';

interface Props {
linkToCloud?: NavigationProps['homeHref'];
}

export const LinkToCloud = (props: Props) => {
const strings = getI18nStrings();

switch (props.linkToCloud) {
case 'projects':
return (
<EuiLink
href="https://cloud.elastic.co/projects"
color="text"
data-test-subj="nav-header-link-to-projects"
>
<EuiCollapsibleNavGroup iconType="spaces" title={strings.linkToCloudProjects} />
</EuiLink>
);
case 'deployments':
return (
<EuiLink
href="https://cloud.elastic.co/deployments"
color="text"
data-test-subj="nav-header-link-to-deployments"
>
<EuiCollapsibleNavGroup iconType="spaces" title={strings.linkToCloudDeployments} />
</EuiLink>
);
default:
return null;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

import { EuiCollapsibleNavGroup, EuiIcon, EuiSideNav, EuiText } from '@elastic/eui';
import React from 'react';
import { NavigationBucketProps } from '../../types';
import { useNavigation } from '../services';
import { navigationStyles as styles } from '../styles';
import { NavigationBucketProps } from '../../../types';
import { useNavigation } from '../../services';
import { navigationStyles as styles } from '../../styles';

export const NavigationBucket = (opts: NavigationBucketProps) => {
const { id, items, activeNavItemId, ...props } = opts;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { EuiCollapsibleNavGroup, EuiSideNav, EuiSideNavItemType } from '@elastic/eui';
import React from 'react';
import useObservable from 'react-use/lib/useObservable';
import { NavigationProps, NavigationServices } from '../../../types';
import { getI18nStrings } from '../../i18n_strings';
import { navigationStyles as styles } from '../../styles';

interface Props {
recentlyAccessed$: Observable<RecentItem[]>;
}

export const RecentlyAccessed = (props: Props) => {
const strings = getI18nStrings();
const recentlyAccessed = useObservable(props.recentlyAccessed$, []);
if (recentlyAccessed.length > 0) {
const navItems: Array<EuiSideNavItemType<unknown>> = [
{
name: '', // no list header title
id: 'recents_root',
items: recentlyAccessed.map(({ id, label, link }) => ({
id,
name: label,
href: link,
})),
},
];

return (
<EuiCollapsibleNavGroup
title={strings.recentlyAccessed}
iconType="clock"
isCollapsible={true}
initialIsOpen={true}
data-test-subj={`nav-bucket-recentlyAccessed`}
>
<EuiSideNav items={navItems} css={styles.euiSideNavItems} />
</EuiCollapsibleNavGroup>
);
}

return null;
};
109 changes: 4 additions & 105 deletions packages/shared-ux/chrome/navigation/src/ui/navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,18 @@
* Side Public License, v 1.
*/

import useObservable from 'react-use/lib/useObservable';
import {
EuiCollapsibleNavGroup,
EuiFlexGroup,
EuiFlexItem,
EuiHeaderLogo,
EuiLink,
EuiLoadingSpinner,
EuiSideNav,
EuiSideNavItemType,
EuiSpacer,
useEuiTheme,
} from '@elastic/eui';
import React from 'react';
import { getI18nStrings } from './i18n_strings';
import { NavigationBucketProps, NavigationProps } from '../../types';
import { NavigationModel } from '../model';
import { useNavigation } from '../services';
import { navigationStyles as styles } from '../styles';
import { ElasticMark } from './elastic_mark';
import './header_logo.scss';
import { NavigationBucket } from './navigation_bucket';
import { LinkToCloud, NavHeader, NavigationBucket, RecentlyAccessed } from './components';

export const Navigation = (props: NavigationProps) => {
const { activeNavItemId, basePath, navIsOpen, navigateToUrl, ...observables } = useNavigation();
Expand All @@ -45,97 +35,6 @@ export const Navigation = (props: NavigationProps) => {
const solutions = nav.getSolutions();
const { analytics, ml, devTools, management } = nav.getPlatform();

const strings = getI18nStrings();

const NavHeader = () => {
const loadingCount = useObservable(observables.loadingCount$, 0);
const homeUrl = basePath.prepend(props.homeHref);
const navigateHome = (event: React.MouseEvent) => {
event.preventDefault();
navigateToUrl(homeUrl);
};
const logo =
loadingCount === 0 ? (
<EuiHeaderLogo
iconType="logoElastic"
aria-label={strings.headerLogoAriaLabel}
onClick={navigateHome}
data-test-subj="nav-header-logo"
/>
) : (
<a href={homeUrl} onClick={navigateHome}>
<EuiLoadingSpinner
size="l"
aria-hidden={false}
onClick={navigateHome}
data-test-subj="nav-header-loading-spinner"
/>
</a>
);

return (
<>
{logo}
{navIsOpen ? <ElasticMark className="chrHeaderLogo__mark" aria-hidden={true} /> : null}
</>
);
};

const LinkToCloud = () => {
switch (props.linkToCloud) {
case 'projects':
return (
<EuiLink
href="https://cloud.elastic.co/projects"
color="text"
data-test-subj="nav-header-link-to-projects"
>
<EuiCollapsibleNavGroup iconType="spaces" title={strings.linkToCloudProjects} />
</EuiLink>
);
case 'deployments':
return (
<EuiLink
href="https://cloud.elastic.co/deployments"
color="text"
data-test-subj="nav-header-link-to-deployments"
>
<EuiCollapsibleNavGroup iconType="spaces" title={strings.linkToCloudDeployments} />
</EuiLink>
);
default:
return null;
}
};

const RecentlyAccessed = () => {
const recentlyAccessed = useObservable(observables.recentlyAccessed$, []);

const navItems: Array<EuiSideNavItemType<unknown>> = [
{
name: '',
id: 'recents_root',
items: recentlyAccessed.map((item) => ({
...item,
name: item.label,
href: item.link,
})),
},
];

return (
<EuiCollapsibleNavGroup
title={strings.recentlyAccessed}
iconType="clock"
isCollapsible={true}
initialIsOpen={recentlyAccessed.length > 0}
data-test-subj={`nav-bucket-recentlyAccessed`}
>
<EuiSideNav items={navItems} css={styles.euiSideNavItems} />
</EuiCollapsibleNavGroup>
);
};

// higher-order-component to keep the common props DRY
const NavigationBucketHoc = (outerProps: Omit<NavigationBucketProps, 'activeNavItemId'>) => (
<NavigationBucket {...outerProps} activeNavItemId={activeNav} />
Expand All @@ -145,12 +44,12 @@ export const Navigation = (props: NavigationProps) => {
<EuiFlexGroup direction="column" gutterSize="none" style={{ overflowY: 'auto' }}>
<EuiFlexItem grow={false}>
<EuiCollapsibleNavGroup css={{ background: euiTheme.colors.darkestShade, height: '50px' }}>
<NavHeader />
<NavHeader {...observables} {...props} {...{ basePath, navIsOpen, navigateToUrl }} />
</EuiCollapsibleNavGroup>

<LinkToCloud />
<LinkToCloud {...props} />

<RecentlyAccessed />
<RecentlyAccessed {...observables} {...props} />

{solutions.map((solutionBucket, idx) => {
return <NavigationBucketHoc {...solutionBucket} key={`solution${idx}`} />;
Expand Down

0 comments on commit b43f859

Please sign in to comment.