Skip to content

Commit

Permalink
[navigation-next] fix: redirect to standard index pattern application…
Browse files Browse the repository at this point in the history
…s while nav group is enabled (#7346)

* [navigation-next] fix: redirect to standard index pattern applications while nav group is enabled (#7305)

* feat: fix the incorrect jumping logic for Index pattern management

Signed-off-by: SuZhou-Joe <[email protected]>

* Changeset file for PR #7305 created/updated

* feat: update

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: update with comment

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: update order and remove reset logic

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: update

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: update

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: update snapshot

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: some category change

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: update category

Signed-off-by: SuZhou-Joe <[email protected]>

---------

Signed-off-by: SuZhou-Joe <[email protected]>
Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
(cherry picked from commit 2c708e3)
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* feat: change the order

Signed-off-by: SuZhou-Joe <[email protected]>

* feat: hide left navigation when workspace enabled

Signed-off-by: SuZhou-Joe <[email protected]>

---------

Signed-off-by: SuZhou-Joe <[email protected]>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: opensearch-changeset-bot[bot] <154024398+opensearch-changeset-bot[bot]@users.noreply.github.com>
Co-authored-by: SuZhou-Joe <[email protected]>
  • Loading branch information
4 people authored Jul 22, 2024
1 parent b32eade commit d30677d
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 109 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/7305.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- [navigation-next] fix: redirect to standard index pattern applications while nav group is enabled ([#7305](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7305))
47 changes: 0 additions & 47 deletions src/core/public/chrome/nav_group/nav_group_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,53 +311,6 @@ describe('ChromeNavGroupService#start()', () => {
expect(sessionStorageMock.getItem(CURRENT_NAV_GROUP_ID)).toBeFalsy();
expect(currentNavGroup).toBeUndefined();
});

it('should reset current nav group if app not belongs to any nav group', async () => {
const uiSettings = uiSettingsServiceMock.createSetupContract();
const navGroupEnabled$ = new Rx.BehaviorSubject(true);
uiSettings.get$.mockImplementation(() => navGroupEnabled$);

const chromeNavGroupService = new ChromeNavGroupService();
const chromeNavGroupServiceSetup = chromeNavGroupService.setup({ uiSettings });

chromeNavGroupServiceSetup.addNavLinksToGroup(
{
id: 'foo',
title: 'foo title',
description: 'foo description',
},
[{ id: 'foo-app1' }]
);

const chromeNavGroupServiceStart = await chromeNavGroupService.start({
navLinks: mockedNavLinkService,
application: mockedApplicationService,
});

// set an existing nav group id
chromeNavGroupServiceStart.setCurrentNavGroup('foo');

expect(sessionStorageMock.getItem(CURRENT_NAV_GROUP_ID)).toEqual('foo');

let currentNavGroup = await chromeNavGroupServiceStart
.getCurrentNavGroup$()
.pipe(first())
.toPromise();

expect(currentNavGroup?.id).toEqual('foo');

// navigate to app don't belongs to any nav group
mockedApplicationService.navigateToApp('bar-app');

currentNavGroup = await chromeNavGroupServiceStart
.getCurrentNavGroup$()
.pipe(first())
.toPromise();

// verify current nav group been reset
expect(currentNavGroup).toBeFalsy();
expect(sessionStorageMock.getItem(CURRENT_NAV_GROUP_ID)).toBeFalsy();
});
});

describe('nav group updater', () => {
Expand Down
12 changes: 0 additions & 12 deletions src/core/public/chrome/nav_group/nav_group_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,18 +212,6 @@ export class ChromeNavGroupService {
}
};

// erase current nav group when switch app don't belongs to any nav group
application.currentAppId$.subscribe((appId) => {
const navGroupMap = this.navGroupsMap$.getValue();
const appIdsWithNavGroup = Object.values(navGroupMap).flatMap(({ navLinks: links }) =>
links.map(({ id }) => id)
);

if (appId && !appIdsWithNavGroup.includes(appId)) {
setCurrentNavGroup(undefined);
}
});

const currentNavGroupSorted$ = combineLatest([
this.getSortedNavGroupsMap$(),
this.currentNavGroup$,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
border: none !important;

.nav-link-item {
padding: $ouiSize / 4 $ouiSize;
border-radius: $ouiSize;
padding: calc($euiSize / 4) $euiSize;
border-radius: $euiSize;
box-shadow: none;
margin-bottom: 0;
margin-top: 0;
Expand Down Expand Up @@ -39,11 +39,20 @@
}

.bottom-container {
padding: 0 $ouiSize;
padding: 0 $euiSize;
display: flex;

&.bottom-container-collapsed {
flex-direction: column;
align-items: center;

> * {
margin: $euiSizeS 0;
}
}
}

.nav-controls-padding {
padding: $ouiSize;
padding: $euiSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { httpServiceMock } from '../../../mocks';
import { getLogos } from '../../../../common';
import { ALL_USE_CASE_ID, DEFAULT_NAV_GROUPS } from '../../../../public';
import { CollapsibleNavTopProps } from './collapsible_nav_group_enabled_top';
import { capabilitiesServiceMock } from '../../../application/capabilities/capabilities_service.mock';

jest.mock('./collapsible_nav_group_enabled_top', () => ({
CollapsibleNavTop: (props: CollapsibleNavTopProps) => (
Expand Down Expand Up @@ -166,6 +167,7 @@ describe('<CollapsibleNavGroupEnabled />', () => {
currentNavGroup$.next(undefined);
}
},
capabilities: { ...capabilitiesServiceMock.createStartContract().capabilities },
...props,
};
}
Expand Down Expand Up @@ -223,4 +225,28 @@ describe('<CollapsibleNavGroupEnabled />', () => {
fireEvent.click(getByTestId('back'));
expect(getAllByTestId('collapsibleNavAppLink-link-in-analytics').length).toEqual(2);
});

it('should hide left navigation when in home page when workspace is enabled', async () => {
const props = mockProps({
navGroupsMap: {
[DEFAULT_NAV_GROUPS.analytics.id]: {
...DEFAULT_NAV_GROUPS.analytics,
navLinks: [
{
id: 'link-in-analytics',
title: 'link-in-analytics',
showInAllNavGroup: true,
},
],
},
},
});
props.appId$ = new BehaviorSubject('home');
if (props.capabilities.workspaces) {
(props.capabilities.workspaces as Record<string, unknown>) = {};
(props.capabilities.workspaces as Record<string, unknown>).enabled = true;
}
const { container } = render(<CollapsibleNavGroupEnabled {...props} isNavOpen />);
expect(container).toMatchSnapshot();
});
});
80 changes: 53 additions & 27 deletions src/core/public/chrome/ui/header/collapsible_nav_group_enabled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import useObservable from 'react-use/lib/useObservable';
import * as Rx from 'rxjs';
import classNames from 'classnames';
import { ChromeNavControl, ChromeNavLink } from '../..';
import { NavGroupStatus } from '../../../../types';
import { AppCategory, NavGroupStatus } from '../../../../types';
import { InternalApplicationStart } from '../../../application/types';
import { HttpStart } from '../../../http';
import { OnIsLockedUpdate } from './';
Expand All @@ -36,7 +36,7 @@ import {
LinkItem,
LinkItemType,
} from '../../utils';
import { ALL_USE_CASE_ID } from '../../../../../core/utils';
import { ALL_USE_CASE_ID, DEFAULT_APP_CATEGORIES } from '../../../../../core/utils';
import { CollapsibleNavTop } from './collapsible_nav_group_enabled_top';
import { HeaderNavControls } from './header_nav_controls';

Expand All @@ -58,6 +58,7 @@ export interface CollapsibleNavGroupEnabledProps {
navControlsLeftBottom$: Rx.Observable<readonly ChromeNavControl[]>;
currentNavGroup$: Rx.Observable<NavGroupItemInMap | undefined>;
setCurrentNavGroup: ChromeNavGroupServiceStartContract['setCurrentNavGroup'];
capabilities: InternalApplicationStart['capabilities'];
}

interface NavGroupsProps {
Expand Down Expand Up @@ -164,6 +165,14 @@ export function NavGroups({
);
}

// Custom category is used for those features not belong to any of use cases in all use case.
// and the custom category should always sit before manage category
const customCategory: AppCategory = {
id: 'custom',
label: i18n.translate('core.ui.customNavList.label', { defaultMessage: 'Custom' }),
order: (DEFAULT_APP_CATEGORIES.manage.order || 0) - 500,
};

export function CollapsibleNavGroupEnabled({
basePath,
id,
Expand All @@ -176,36 +185,14 @@ export function CollapsibleNavGroupEnabled({
navigateToUrl,
logos,
setCurrentNavGroup,
capabilities,
...observables
}: CollapsibleNavGroupEnabledProps) {
const navLinks = useObservable(observables.navLinks$, []).filter((link) => !link.hidden);
const appId = useObservable(observables.appId$, '');
const navGroupsMap = useObservable(observables.navGroupsMap$, {});
const currentNavGroup = useObservable(observables.currentNavGroup$, undefined);

const onGroupClick = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
group: NavGroupItemInMap
) => {
const fulfilledLinks = fulfillRegistrationLinksToChromeNavLinks(
navGroupsMap[group.id]?.navLinks,
navLinks
);
setCurrentNavGroup(group.id);

// the `navGroupsMap[group.id]?.navLinks` has already been sorted
const firstLink = fulfilledLinks[0];
if (firstLink) {
const propsForEui = createEuiListItem({
link: firstLink,
appId,
dataTestSubj: 'collapsibleNavAppLink',
navigateToApp,
});
propsForEui.onClick(e);
}
};

const navLinksForRender: ChromeNavLink[] = useMemo(() => {
if (currentNavGroup) {
return fulfillRegistrationLinksToChromeNavLinks(
Expand Down Expand Up @@ -234,7 +221,10 @@ export function CollapsibleNavGroupEnabled({
navLinks
.filter((link) => !linkIdsWithUseGroupInfo.includes(link.id))
.forEach((navLink) => {
navLinksForAll.push(navLink);
navLinksForAll.push({
...navLink,
category: customCategory,
});
});

// Append all the links registered to all use case
Expand Down Expand Up @@ -281,6 +271,37 @@ export function CollapsibleNavGroupEnabled({
return 270;
}, [isNavOpen]);

// For now, only home page need to hide left navigation
// when workspace is enabled.
// If there are more pages need to hide left navigation in the future
// need to come up with a mechanism to register.
if (capabilities.workspaces.enabled && appId === 'home') {
return null;
}

const onGroupClick = (
e: React.MouseEvent<HTMLButtonElement, MouseEvent>,
group: NavGroupItemInMap
) => {
const fulfilledLinks = fulfillRegistrationLinksToChromeNavLinks(
navGroupsMap[group.id]?.navLinks,
navLinks
);
setCurrentNavGroup(group.id);

// the `navGroupsMap[group.id]?.navLinks` has already been sorted
const firstLink = fulfilledLinks[0];
if (firstLink) {
const propsForEui = createEuiListItem({
link: firstLink,
appId,
dataTestSubj: 'collapsibleNavAppLink',
navigateToApp,
});
propsForEui.onClick(e);
}
};

return (
<EuiFlyout
data-test-subj="collapsibleNav"
Expand Down Expand Up @@ -335,7 +356,12 @@ export function CollapsibleNavGroupEnabled({
</EuiPanel>
</div>
<EuiHorizontalRule margin="none" />
<div className="bottom-container" style={{ flexDirection: isNavOpen ? 'row' : 'column' }}>
<div
className={classNames({
'bottom-container': true,
'bottom-container-collapsed': !isNavOpen,
})}
>
<HeaderNavControls
navControls$={observables.navControlsLeftBottom$}
className={classNames({ 'nav-controls-padding': isNavOpen })}
Expand Down
1 change: 1 addition & 0 deletions src/core/public/chrome/ui/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ export function Header({
navControlsLeftBottom$={observables.navControlsLeftBottom$}
currentNavGroup$={observables.currentNavGroup$}
setCurrentNavGroup={setCurrentNavGroup}
capabilities={application.capabilities}
/>
) : (
<CollapsibleNav
Expand Down
9 changes: 8 additions & 1 deletion src/core/utils/default_app_categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ export const DEFAULT_APP_CATEGORIES: Record<string, AppCategory> = Object.freeze
label: i18n.translate('core.ui.manageNav.label', {
defaultMessage: 'Manage',
}),
order: 7000,
order: 8000,
},
manageData: {
id: 'manageData',
label: i18n.translate('core.ui.manageDataNav.label', {
defaultMessage: 'Manage data',
}),
order: 1000,
},
});
4 changes: 2 additions & 2 deletions src/plugins/dashboard/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -456,14 +456,14 @@ export class DashboardPlugin
core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS.observability, [
{
id: app.id,
order: 300,
order: 400,
category: undefined,
},
]);
core.chrome.navGroup.addNavLinksToGroup(DEFAULT_NAV_GROUPS['security-analytics'], [
{
id: app.id,
order: 300,
order: 400,
category: undefined,
},
]);
Expand Down
Loading

0 comments on commit d30677d

Please sign in to comment.