Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SharedUx] Chrome/Navigation package #152510

Merged
merged 46 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
308b8f9
shared ux navigation package
tsullivan Mar 23, 2023
45803c2
setNavIsOpen service
tsullivan Mar 31, 2023
de11016
refactor out navigation_buckets data modeling
tsullivan Apr 1, 2023
33de083
setActiveNavitationItemId stubs
tsullivan Apr 6, 2023
80a991d
add activeNavItemId$ observable
tsullivan Apr 10, 2023
56256ab
fix home href
tsullivan Apr 11, 2023
3df721d
fix logo link
tsullivan Apr 11, 2023
30283c3
fix some mgmt links
tsullivan Apr 11, 2023
e843ca6
service to provide `getLocator`, not a wrapper
tsullivan Apr 11, 2023
6e29bf6
Add registerNavItemClick to services
tsullivan Apr 11, 2023
b8ff745
href support, default activeNavId
tsullivan Apr 11, 2023
20125e8
fill in some locator IDs
tsullivan Apr 12, 2023
9154f32
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Apr 12, 2023
a9bd56b
navigateToUrl
tsullivan Apr 12, 2023
4539f64
loadingCount
tsullivan Apr 12, 2023
5f922b6
simplify nav model methods
tsullivan Apr 13, 2023
5c7fb71
fix anchor nesting
tsullivan Apr 13, 2023
8021047
add link to cloud
tsullivan Apr 20, 2023
33512d3
create single locators package
tsullivan Apr 21, 2023
150066e
variable rename and comment
tsullivan Apr 21, 2023
24c027a
Remove locators package
tsullivan Apr 21, 2023
c32666a
Remove reference to locators
tsullivan Apr 21, 2023
817ec1f
replace configured locator objects with href strings
tsullivan Apr 21, 2023
2c7f3db
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 21, 2023
3ff81ba
simple unit tests
tsullivan Apr 22, 2023
1df05ee
Final nav items config fixes
tsullivan Apr 22, 2023
044d768
remove stale fixme comment
tsullivan Apr 25, 2023
36c17e0
remove descoped recent items integration
tsullivan Apr 25, 2023
c1168c4
Merge branch 'shared-ux/chrome/navigation' of github.com:tsullivan/ki…
tsullivan Apr 25, 2023
e1dfb32
fix commented code for investigating dark bg
tsullivan Apr 25, 2023
94a3567
Merge branch 'main' into shared-ux/chrome/navigation
tsullivan Apr 25, 2023
902759a
more recent items cleanup
tsullivan Apr 25, 2023
e45301d
more ts fix
tsullivan Apr 25, 2023
07f26d8
fix todo
tsullivan Apr 25, 2023
99af20a
add initial translatable strings
tsullivan Apr 25, 2023
ceab9d7
[CI] Auto-commit changed files from 'node scripts/lint_ts_projects --…
kibanamachine Apr 25, 2023
62f40d2
fix i18n issue
tsullivan Apr 25, 2023
1fa1f88
Merge branch 'shared-ux/chrome/navigation' of github.com:tsullivan/ki…
tsullivan Apr 25, 2023
a3acb90
fix ts
tsullivan Apr 26, 2023
8f5f601
Merge remote-tracking branch 'elastic/main' into shared-ux/chrome/nav…
tsullivan Apr 26, 2023
d1cd551
Remove services that will not be needed for future iteration
tsullivan Apr 27, 2023
f2bd9f8
Merge remote-tracking branch 'elastic/main' into shared-ux/chrome/nav…
tsullivan Apr 27, 2023
f9d53f8
Implement dark background
tsullivan Apr 27, 2023
76427ee
use light mode for now
tsullivan Apr 27, 2023
4257ba2
remove in-progress work on collapsed view
tsullivan Apr 27, 2023
5fbb3fc
fix link to dashboards app
tsullivan Apr 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,7 @@ packages/shared-ux/button_toolbar @elastic/appex-sharedux
packages/shared-ux/card/no_data/impl @elastic/appex-sharedux
packages/shared-ux/card/no_data/mocks @elastic/appex-sharedux
packages/shared-ux/card/no_data/types @elastic/appex-sharedux
packages/shared-ux/chrome/navigation @elastic/appex-sharedux
packages/shared-ux/file/context @elastic/appex-sharedux
packages/shared-ux/file/image/impl @elastic/appex-sharedux
packages/shared-ux/file/image/mocks @elastic/appex-sharedux
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@
"@kbn/shared-ux-card-no-data": "link:packages/shared-ux/card/no_data/impl",
"@kbn/shared-ux-card-no-data-mocks": "link:packages/shared-ux/card/no_data/mocks",
"@kbn/shared-ux-card-no-data-types": "link:packages/shared-ux/card/no_data/types",
"@kbn/shared-ux-chrome-navigation": "link:packages/shared-ux/chrome/navigation",
"@kbn/shared-ux-file-context": "link:packages/shared-ux/file/context",
"@kbn/shared-ux-file-image": "link:packages/shared-ux/file/image/impl",
"@kbn/shared-ux-file-image-mocks": "link:packages/shared-ux/file/image/mocks",
Expand Down
26 changes: 26 additions & 0 deletions packages/shared-ux/chrome/navigation/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
id: sharedUX/Chrome/Navigation
slug: /shared-ux/chrome/navigation
title: Kibana Chrome Navigation
description: Navigation container to render items for cross-app linking
tags: ['shared-ux', 'component', 'chrome', 'navigation']
date: 2023-02-28
---

## Description

Empty package generated by @kbn/generate
@kbn/shared-ux-chrome-navigation
Navigation container to render items for cross-app linking

## API

| Export | Description |
|---|---|
| `NavigationProvider` | Provides contextual services to `Navigation`. |
| `NavigationKibanaProvider` | Maps Kibana dependencies to provide contextual services to `Navigation`. |
| `Navigation` | Uses a `Provider` to access contextual services and render the component. |

## EUI Promotion Status

This component is not currently considered for promotion to EUI.
11 changes: 11 additions & 0 deletions packages/shared-ux/chrome/navigation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* 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 { NavigationKibanaProvider, NavigationProvider } from './src/services';
export { Navigation } from './src/ui/navigation';
export type { NavigationProps, NavigationServices, NavItemProps } from './types';
13 changes: 13 additions & 0 deletions packages/shared-ux/chrome/navigation/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../../..',
roots: ['<rootDir>/packages/shared-ux/chrome/navigation'],
};
5 changes: 5 additions & 0 deletions packages/shared-ux/chrome/navigation/kibana.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "shared-common",
"id": "@kbn/shared-ux-chrome-navigation",
"owner": "@elastic/appex-sharedux"
}
14 changes: 14 additions & 0 deletions packages/shared-ux/chrome/navigation/mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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 {
getServicesMock as getNavigationServicesMock,
getSolutionPropertiesMock,
} from './src/jest';
export { StorybookMock as NavigationStorybookMock } from './src/storybook';
export type { Params as NavigationStorybookParams } from './src/storybook';
74 changes: 74 additions & 0 deletions packages/shared-ux/chrome/navigation/mocks/src/jest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* 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 { NavigationServices, SolutionProperties } from '../../types';

export const getServicesMock = (): NavigationServices => {
const navigateToUrl = jest.fn().mockResolvedValue(undefined);
const basePath = { prepend: jest.fn((path: string) => `/base${path}`) };
const registerNavItemClick = jest.fn();
const loadingCount = 0;

return {
basePath,
loadingCount,
navIsOpen: true,
navigateToUrl,
registerNavItemClick,
};
};

export const getSolutionPropertiesMock = (): SolutionProperties => ({
id: 'example_project',
icon: 'logoObservability',
name: 'Example project',
items: [
{
id: 'root',
name: '',
items: [
{
id: 'get_started',
name: 'Get started',
href: '/app/example_project/get_started',
},
{
id: 'alerts',
name: 'Alerts',
href: '/app/example_project/alerts',
},
{
id: 'cases',
name: 'Cases',
href: '/app/example_project/cases',
},
],
},
{
id: 'example_settings',
name: 'Settings',
items: [
{
id: 'logs',
name: 'Logs',
href: '/app/management/logs',
},
{
id: 'signals',
name: 'Signals',
href: '/app/management/signals',
},
{
id: 'tracing',
name: 'Tracing',
href: '/app/management/tracing',
},
],
},
],
});
68 changes: 68 additions & 0 deletions packages/shared-ux/chrome/navigation/mocks/src/storybook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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 { AbstractStorybookMock } from '@kbn/shared-ux-storybook-mock';
import { action } from '@storybook/addon-actions';
import { BehaviorSubject } from 'rxjs';
import { NavigationProps, NavigationServices } from '../../types';

type Arguments = NavigationProps & NavigationServices;
export type Params = Pick<
Arguments,
'activeNavItemId' | 'loadingCount' | 'navIsOpen' | 'platformConfig' | 'solutions'
>;

export class StorybookMock extends AbstractStorybookMock<NavigationProps, NavigationServices> {
propArguments = {};

serviceArguments = {
navIsOpen: {
control: 'boolean',
defaultValue: true,
},
loadingCount: {
control: 'number',
defaultValue: 0,
},
};

dependencies = [];

getServices(params: Params): NavigationServices {
const { navIsOpen } = params;

const navAction = action('Navigate to');
const navigateToUrl = (url: string) => {
navAction(url);
return Promise.resolve();
};

const registerNavItemClickAction = action('Register click');
const activeNavItemId$ = new BehaviorSubject<string | undefined>(undefined);
const registerNavItemClick = (id: string) => {
activeNavItemId$.next(id);
registerNavItemClickAction(id);
};

return {
...params,
basePath: { prepend: (suffix: string) => `/basepath${suffix}` },
navigateToUrl,
navIsOpen,
registerNavItemClick,
};
}

getProps(params: Params): NavigationProps {
return {
...params,
homeHref: '#',
linkToCloud: 'projects',
};
}
}
6 changes: 6 additions & 0 deletions packages/shared-ux/chrome/navigation/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@kbn/shared-ux-chrome-navigation",
"private": true,
"version": "1.0.0",
"license": "SSPL-1.0 OR Elastic License 2.0"
}
78 changes: 78 additions & 0 deletions packages/shared-ux/chrome/navigation/src/model/create_side_nav.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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 type { EuiSideNavItemType } from '@elastic/eui';
import type { NavigationModelDeps } from '.';
import type { NavItemProps, PlatformSectionConfig } from '../../types';

type MyEuiSideNavItem = EuiSideNavItemType<unknown>;
type OnClickFn = MyEuiSideNavItem['onClick'];

/**
* Factory function to return a function that processes modeled nav items into EuiSideNavItemType
* The factory puts memoized function arguments in scope for iterations of the recursive item processing.
*/
export const createSideNavDataFactory = (
deps: NavigationModelDeps,
activeNavItemId: string | undefined
) => {
const { basePath, navigateToUrl, registerNavItemClick } = deps;
const createSideNavData = (
parentIds: string | number = '',
navItems: NavItemProps[],
platformSectionConfig?: PlatformSectionConfig
): Array<EuiSideNavItemType<unknown>> =>
navItems.reduce<MyEuiSideNavItem[]>((accum, item) => {
const { id, name, items: subNav, href } = item;
const config = platformSectionConfig?.properties?.[id];
if (config?.enabled === false) {
// return accumulated set without the item that is not enabled
return accum;
}

let onClick: OnClickFn | undefined;

const fullId = [parentIds, id].filter(Boolean).join('.');

if (href) {
onClick = (event: React.MouseEvent) => {
event.preventDefault();
navigateToUrl(basePath.prepend(href));
registerNavItemClick(fullId);
};
}

let filteredSubNav: MyEuiSideNavItem[] | undefined;
if (subNav) {
// recursion
const nextConfig = platformSectionConfig?.properties?.[id];
filteredSubNav = createSideNavData(fullId, subNav, nextConfig);
}

let isSelected: boolean = false;
let subjId = fullId;
if (!subNav && fullId === activeNavItemId) {
// if there are no subnav items and ID is current, mark the item as selected
isSelected = true;
subjId += '-selected';
}

const next: MyEuiSideNavItem = {
id: fullId,
name,
isSelected,
onClick,
href,
items: filteredSubNav,
['data-test-subj']: `nav-item-${subjId}`,
};
return [...accum, next];
}, []);

return createSideNavData;
};
42 changes: 42 additions & 0 deletions packages/shared-ux/chrome/navigation/src/model/index.ts
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 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 { BasePathService, NavigateToUrlFn, NavItemClickFn } from '../../types/internal';
import { analyticsItemSet } from './platform_nav/analytics';
import { devtoolsItemSet } from './platform_nav/devtools';
import { mlItemSet } from './platform_nav/machine_learning';
import { managementItemSet } from './platform_nav/management';

export interface NavigationModelDeps {
basePath: BasePathService;
navigateToUrl: NavigateToUrlFn;
registerNavItemClick: NavItemClickFn;
}

/**
* @public
*/
export enum Platform {
Recents = 'recents',
Analytics = 'analytics',
MachineLearning = 'ml',
DevTools = 'devTools',
Management = 'management',
}

/**
* @public
*/
export const navItemSet = {
[Platform.Analytics]: analyticsItemSet,
[Platform.MachineLearning]: mlItemSet,
[Platform.DevTools]: devtoolsItemSet,
[Platform.Management]: managementItemSet,
};
Comment on lines +32 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇‍♂️


export { NavigationModel } from './model';
Loading