From 2a65dfb36bfabd4ca624388e595bedb4833408c8 Mon Sep 17 00:00:00 2001 From: Josh Romero Date: Mon, 16 May 2022 23:28:34 +0000 Subject: [PATCH] [UX] Consolidate menu bars - update branding mark unit tests - fix header spacing at smallest breakpoint - update custom branding functional test - update line chart functional test ticks to account for more ticks visisble with larger height of viz area - update release notes Signed-off-by: Josh Romero --- Dockerfile | 2 +- ...ensearch-dashboards.release-notes-2.0.0.md | 3 + src/core/public/_variables.scss | 2 +- .../header/__snapshots__/header.test.tsx.snap | 2980 ++++++----------- ..._logo.test.tsx.snap => mark.test.tsx.snap} | 269 +- .../chrome/ui/header/branding/mark.test.tsx | 126 + .../public/chrome/ui/header/branding/mark.tsx | 43 + ...opensearch_dashboards_custom_logo.test.tsx | 102 - .../opensearch_dashboards_custom_logo.tsx | 71 - src/core/public/chrome/ui/header/header.scss | 3 + src/core/public/chrome/ui/header/header.tsx | 92 +- .../public/chrome/ui/header/header_logo.scss | 19 +- .../public/chrome/ui/header/header_logo.tsx | 28 +- .../apps/visualize/_custom_branding.js | 8 +- test/functional/apps/visualize/_line_chart.js | 52 +- 15 files changed, 1495 insertions(+), 2305 deletions(-) rename src/core/public/chrome/ui/header/branding/__snapshots__/{opensearch_dashboards_custom_logo.test.tsx.snap => mark.test.tsx.snap} (84%) create mode 100644 src/core/public/chrome/ui/header/branding/mark.test.tsx create mode 100644 src/core/public/chrome/ui/header/branding/mark.tsx delete mode 100644 src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.test.tsx delete mode 100644 src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.tsx create mode 100644 src/core/public/chrome/ui/header/header.scss diff --git a/Dockerfile b/Dockerfile index a66671fbb654..5c65d3cdaf8a 100755 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* # Specify the version of Chrome that matches the version of chromedriver in the package.json. -# A list of Chrome versions can be found here: +# A list of Chrome versions can be found here: # https://www.ubuntuupdates.org/package/google_chrome/stable/main/base/google-chrome-stable ARG CHROME_VERSION=91.0.4472.114-1 RUN curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \ diff --git a/release-notes/opensearch-dashboards.release-notes-2.0.0.md b/release-notes/opensearch-dashboards.release-notes-2.0.0.md index e5831d8a826e..8f8a0fc23a26 100644 --- a/release-notes/opensearch-dashboards.release-notes-2.0.0.md +++ b/release-notes/opensearch-dashboards.release-notes-2.0.0.md @@ -13,6 +13,9 @@ #### Disable telemetry by default * Fixes search usage telemetry ([#1427](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1427)) +#### Redesign global header +* [UX] Consolidate menu bars ([#1586])(https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1586)) + #### Deprecations * Deprecates non-inclusive config names ([#1467](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1467)) * Removes UI Framework KUI doc site ([#1379](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1379)) diff --git a/src/core/public/_variables.scss b/src/core/public/_variables.scss index bb8baa3462f1..9d8077b50ad4 100644 --- a/src/core/public/_variables.scss +++ b/src/core/public/_variables.scss @@ -1,3 +1,3 @@ @import "@elastic/eui/src/global_styling/variables/header"; -$osdHeaderOffset: $euiHeaderHeightCompensation * 2; +$osdHeaderOffset: $euiHeaderHeightCompensation; diff --git a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index 640cea65f50e..4caeedc996e7 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap @@ -1359,6 +1359,43 @@ exports[`Header renders 1`] = ` "syncErrorThrown": false, "syncErrorValue": null, }, + Subscriber { + "_parentOrParents": null, + "_subscriptions": Array [ + SubjectSubscription { + "_parentOrParents": [Circular], + "_subscriptions": null, + "closed": false, + "subject": [Circular], + "subscriber": [Circular], + }, + ], + "closed": false, + "destination": SafeSubscriber { + "_complete": undefined, + "_context": [Circular], + "_error": undefined, + "_next": [Function], + "_parentOrParents": null, + "_parentSubscriber": [Circular], + "_subscriptions": null, + "closed": false, + "destination": Object { + "closed": true, + "complete": [Function], + "error": [Function], + "next": [Function], + }, + "isStopped": false, + "syncErrorThrowable": false, + "syncErrorThrown": false, + "syncErrorValue": null, + }, + "isStopped": false, + "syncErrorThrowable": true, + "syncErrorThrown": false, + "syncErrorValue": null, + }, ], "thrownError": null, } @@ -1671,240 +1708,201 @@ exports[`Header renders 1`] = ` > +
+ +
+ +
+ + + + + + + + + + , + } + } + className="euiHeaderSectionItemButton" + color="text" + data-test-subj="toggleNavButton" + onClick={[Function]} + > + + + +
+
+ +
+ , - +
+
+ +
+ , - ], - }, - Object { - "borders": "none", - "items": Array [ - - - , - ], - }, - Object { - "borders": "none", - "items": Array [ - - - , - + + + + + +
+ +
+
+
+
+
+
+ , + } + } + className="euiHeaderSectionItemButton header__logoNavButton" + color="text" + data-test-subj="logo" + href="/" + onClick={[Function]} + > + + + + + +
+ + + + + +
+
+ + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + +
+ +
+
+ +
+ +
+ , - , - ], - }, - ] - } - theme="dark" - > -
- -
+ > +
+ +
+
- +
+
+ + - - -
- - - - - -
-
-
-
- -
- -
- - - -
-
-
-
- -
- -
- -
-
- -
- - - - - } - closePopover={[Function]} - data-test-subj="helpMenuButton" - display="inlineBlock" - hasArrow={true} - id="headerHelpMenu" - isOpen={false} - ownFocus={true} - panelPaddingSize="m" - repositionOnScroll={true} - > -
-
- - - - - - - - - - , - } - } - className="euiHeaderSectionItemButton" - color="text" - onClick={[Function]} - > - - - -
-
-
- -
-
-
- -
- -
-
-
-
-
- - -
- -
- -
- - - - - - - - - - , - } - } - className="euiHeaderSectionItemButton" - color="text" - data-test-subj="toggleNavButton" - onClick={[Function]} - > - - - -
-
- -
-
- - - - - - - - - -
+ + + + } + closePopover={[Function]} + data-test-subj="helpMenuButton" + display="inlineBlock" + hasArrow={true} + id="headerHelpMenu" + isOpen={false} + ownFocus={true} + panelPaddingSize="m" + repositionOnScroll={true} + > +
+
+ + + + + + + + + + , + } + } + className="euiHeaderSectionItemButton" + color="text" + onClick={[Function]} + > + + + +
+
+
+ + +
+
- -
- + />
diff --git a/src/core/public/chrome/ui/header/branding/__snapshots__/opensearch_dashboards_custom_logo.test.tsx.snap b/src/core/public/chrome/ui/header/branding/__snapshots__/mark.test.tsx.snap similarity index 84% rename from src/core/public/chrome/ui/header/branding/__snapshots__/opensearch_dashboards_custom_logo.test.tsx.snap rename to src/core/public/chrome/ui/header/branding/__snapshots__/mark.test.tsx.snap index 80b66e95bd41..a375b510f143 100644 --- a/src/core/public/chrome/ui/header/branding/__snapshots__/opensearch_dashboards_custom_logo.test.tsx.snap +++ b/src/core/public/chrome/ui/header/branding/__snapshots__/mark.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Header logo in dark mode rendered using logo dark mode URL 1`] = ` - -
- custom title logo -
-
+ + `; -exports[`Header logo in dark mode rendered using logo default mode URL 1`] = ` - -
- custom title logo -
-
+ + `; -exports[`Header logo in dark mode rendered using mark dark mode URL 1`] = ` - -
- custom title logo -
-
+ + `; -exports[`Header logo in dark mode rendered using mark default mode URL 1`] = ` - -
- custom title logo -
-
+ + `; -exports[`Header logo in dark mode rendered using original opensearch logo 1`] = ` - - custom title logo - + + + + `; -exports[`Header logo in default mode rendered using logo default mode URL 1`] = ` - -
- custom title logo -
-
+ + `; -exports[`Header logo in default mode rendered using mark default mode URL 1`] = ` - -
- custom title logo -
-
+ + `; -exports[`Header logo in default mode rendered using the original opensearch logo 1`] = ` - - custom title logo - + + + + `; diff --git a/src/core/public/chrome/ui/header/branding/mark.test.tsx b/src/core/public/chrome/ui/header/branding/mark.test.tsx new file mode 100644 index 000000000000..2f36ae680803 --- /dev/null +++ b/src/core/public/chrome/ui/header/branding/mark.test.tsx @@ -0,0 +1,126 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { Mark } from './mark'; + +const defaultOpensearchMarkUrl = '/opensearch_mark_default_mode.svg'; +const darkOpensearchMarkUrl = '/opensearch_mark_dark_mode.svg'; + +describe('Header logo ', () => { + describe('in default mode ', () => { + it('uses opensearch logo if no branding', () => { + const branding = {}; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(defaultOpensearchMarkUrl); + expect(icon.prop('title')).toEqual(`opensearch dashboards logo`); + expect(component).toMatchSnapshot(); + }); + + it('uses opensearch logo if no mark provided', () => { + const branding = { + darkMode: false, + logo: {}, + mark: {}, + applicationTitle: 'custom title', + assetFolderUrl: 'ui/assets', + }; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(`${branding.assetFolderUrl}${defaultOpensearchMarkUrl}`); + expect(icon.prop('title')).toEqual(`${branding.applicationTitle} logo`); + expect(component).toMatchSnapshot(); + }); + + it('uses opensearch logo if custom logo provided without mark', () => { + const branding = { + darkMode: false, + logo: { defaultUrl: '/defaultModeLogo' }, + mark: {}, + applicationTitle: 'custom title', + }; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(defaultOpensearchMarkUrl); + expect(icon.prop('title')).toEqual(`${branding.applicationTitle} logo`); + expect(component).toMatchSnapshot(); + }); + + it('uses custom mark default mode URL', () => { + const branding = { + darkMode: false, + logo: {}, + mark: { defaultUrl: '/defaultModeMark' }, + applicationTitle: 'custom title', + }; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(branding.mark.defaultUrl); + expect(icon.prop('title')).toEqual(`${branding.applicationTitle} logo`); + expect(component).toMatchSnapshot(); + }); + }); + + describe('in dark mode ', () => { + it('uses opensearch logo if no mark provided', () => { + const branding = { + darkMode: true, + logo: {}, + mark: {}, + assetFolderUrl: 'ui/assets', + applicationTitle: 'custom title', + }; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(`${branding.assetFolderUrl}${darkOpensearchMarkUrl}`); + expect(icon.prop('title')).toEqual(`${branding.applicationTitle} logo`); + expect(component).toMatchSnapshot(); + }); + + it('uses opensearch logo if custom logo provided without mark', () => { + const branding = { + darkMode: true, + logo: { defaultUrl: '/defaultModeLogo' }, + mark: {}, + applicationTitle: 'custom title', + }; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(darkOpensearchMarkUrl); + expect(icon.prop('title')).toEqual(`${branding.applicationTitle} logo`); + expect(component).toMatchSnapshot(); + }); + + it('uses custom mark default mode URL if no dark mode mark', () => { + const branding = { + darkMode: true, + logo: {}, + mark: { defaultUrl: '/defaultModeMark' }, + applicationTitle: 'custom title', + }; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(branding.mark.defaultUrl); + expect(icon.prop('title')).toEqual(`${branding.applicationTitle} logo`); + expect(component).toMatchSnapshot(); + }); + + it('uses custom mark dark mode URL', () => { + const branding = { + darkMode: true, + logo: {}, + mark: { defaultUrl: '/defaultModeMark', darkModeUrl: '/darkModeMark' }, + applicationTitle: 'custom title', + }; + const component = mountWithIntl(); + const icon = component.find('EuiIcon'); + expect(icon.prop('type')).toEqual(branding.mark.darkModeUrl); + expect(icon.prop('title')).toEqual(`${branding.applicationTitle} logo`); + expect(component).toMatchSnapshot(); + }); + }); +}); diff --git a/src/core/public/chrome/ui/header/branding/mark.tsx b/src/core/public/chrome/ui/header/branding/mark.tsx new file mode 100644 index 000000000000..68f26e91f1a5 --- /dev/null +++ b/src/core/public/chrome/ui/header/branding/mark.tsx @@ -0,0 +1,43 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { EuiIcon } from '@elastic/eui'; +import { ChromeBranding } from '../../../chrome_service'; + +/** + * Use branding configurations to render the header mark on the nav bar. + * + * @param {ChromeBranding} - branding object consist of mark, darkmode selection, asset path and title + * @returns Mark component which is going to be rendered on the main page header bar. + */ +export const Mark = ({ + darkMode, + assetFolderUrl = '', + mark, + applicationTitle = 'opensearch dashboards', +}: ChromeBranding) => { + const { defaultUrl: markUrl, darkModeUrl: darkMarkUrl } = mark ?? {}; + + const customMark = darkMode ? darkMarkUrl ?? markUrl : markUrl; + const defaultMark = darkMode + ? 'opensearch_mark_dark_mode.svg' + : 'opensearch_mark_default_mode.svg'; + const altText = `${applicationTitle} logo`; + + const iconType = customMark ? customMark : `${assetFolderUrl}/${defaultMark}`; + const testSubj = customMark ? 'customLogo' : 'defaultLogo'; + + return ( + + ); +}; diff --git a/src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.test.tsx b/src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.test.tsx deleted file mode 100644 index f04679aea6c6..000000000000 --- a/src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.test.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React from 'react'; -import { mountWithIntl } from 'test_utils/enzyme_helpers'; -import { CustomLogo } from './opensearch_dashboards_custom_logo'; - -describe('Header logo ', () => { - describe('in default mode ', () => { - it('rendered using logo default mode URL', () => { - const branding = { - darkMode: false, - logo: { defaultUrl: '/defaultModeLogo' }, - mark: {}, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - - it('rendered using mark default mode URL', () => { - const branding = { - darkMode: false, - logo: {}, - mark: { defaultUrl: '/defaultModeMark' }, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - - it('rendered using the original opensearch logo', () => { - const branding = { - darkMode: false, - logo: {}, - mark: {}, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - }); - - describe('in dark mode ', () => { - it('rendered using logo dark mode URL', () => { - const branding = { - darkMode: true, - logo: { defaultUrl: '/defaultModeLogo', darkModeUrl: '/darkModeLogo' }, - mark: { defaultUrl: '/defaultModeMark', darkModeUrl: '/darkModeMark' }, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - - it('rendered using logo default mode URL', () => { - const branding = { - darkMode: true, - logo: { defaultUrl: '/defaultModeLogo' }, - mark: { defaultUrl: '/defaultModeMark', darkModeUrl: '/darkModeMark' }, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - - it('rendered using mark dark mode URL', () => { - const branding = { - darkMode: true, - logo: {}, - mark: { defaultUrl: '/defaultModeMark', darkModeUrl: '/darkModeMark' }, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - - it('rendered using mark default mode URL', () => { - const branding = { - darkMode: true, - logo: {}, - mark: { defaultUrl: '/defaultModeMark' }, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - - it('rendered using original opensearch logo', () => { - const branding = { - darkMode: true, - logo: {}, - mark: {}, - applicationTitle: 'custom title', - }; - const component = mountWithIntl(); - expect(component).toMatchSnapshot(); - }); - }); -}); diff --git a/src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.tsx b/src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.tsx deleted file mode 100644 index 734b2dd3a1cc..000000000000 --- a/src/core/public/chrome/ui/header/branding/opensearch_dashboards_custom_logo.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React from 'react'; -import '../header_logo.scss'; -import { ChromeBranding } from '../../../chrome_service'; - -/** - * Use branding configurations to render the header logo on the nav bar. - * - * @param {ChromeBranding} - branding object consist of logo, mark and title - * @returns Custom branding logo component which is going to be rendered on the main page header bar. - * If logo default is valid, the full logo by logo default config will be rendered; - * if not, the logo icon by mark default config will be rendered; if both are not found, - * the default OpenSearch Dashboards logo will be rendered. - */ -export const CustomLogo = ({ ...branding }: ChromeBranding) => { - const darkMode = branding.darkMode; - const assetFolderUrl = branding.assetFolderUrl; - const logoDefault = branding.logo?.defaultUrl; - const logoDarkMode = branding.logo?.darkModeUrl; - const markDefault = branding.mark?.defaultUrl; - const markDarkMode = branding.mark?.darkModeUrl; - const applicationTitle = branding.applicationTitle; - - /** - * Use branding configurations to check which URL to use for rendering - * header logo in nav bar in default mode - * - * @returns a valid custom URL or undefined if no valid URL is provided - */ - const customHeaderLogoDefaultMode = () => { - return logoDefault ?? markDefault ?? undefined; - }; - - /** - * Use branding configurations to check which URL to use for rendering - * header logo in nav bar in dark mode - * - * @returns a valid custom URL or undefined if no valid URL is provided - */ - const customHeaderLogoDarkMode = () => { - return logoDarkMode ?? logoDefault ?? markDarkMode ?? markDefault ?? undefined; - }; - - /** - * Render custom header logo for both default mode and dark mode - * - * @returns a valid custom header logo URL, or undefined - */ - const customHeaderLogo = () => { - return darkMode ? customHeaderLogoDarkMode() : customHeaderLogoDefaultMode(); - }; - - return customHeaderLogo() ? ( -
- {applicationTitle -
- ) : ( - {applicationTitle - ); -}; diff --git a/src/core/public/chrome/ui/header/header.scss b/src/core/public/chrome/ui/header/header.scss new file mode 100644 index 000000000000..1bda14bd79a7 --- /dev/null +++ b/src/core/public/chrome/ui/header/header.scss @@ -0,0 +1,3 @@ +.headerGlobalNav .euiHeaderSectionItem:empty { + min-width: 0; +} diff --git a/src/core/public/chrome/ui/header/header.tsx b/src/core/public/chrome/ui/header/header.tsx index 15a78c7350c8..56c0ff0c3489 100644 --- a/src/core/public/chrome/ui/header/header.tsx +++ b/src/core/public/chrome/ui/header/header.tsx @@ -28,14 +28,13 @@ * under the License. */ +import './header.scss'; import { EuiHeader, EuiHeaderSection, EuiHeaderSectionItem, EuiHeaderSectionItemButton, - EuiHideFor, EuiIcon, - EuiShowFor, htmlIdGenerator, } from '@elastic/eui'; import { i18n } from '@osd/i18n'; @@ -114,51 +113,6 @@ export function Header({ <>
- , - , - ], - borders: 'none', - }, - { - ...(observables.navControlsCenter$ && { - items: [ - - - , - ], - }), - borders: 'none', - }, - { - items: [ - - - , - , - , - ], - borders: 'none', - }, - ]} - /> - @@ -177,7 +131,22 @@ export function Header({ - + {observables.navControlsLeft$ && ( + + + + )} + + + + - + {observables.badge$ && ( + + + + )} + + {observables.navControlsCenter$ && ( + + + + )} + + + + + + {observables.navControlsRight$ && ( + + + + )}
diff --git a/src/core/public/chrome/ui/header/header_logo.scss b/src/core/public/chrome/ui/header/header_logo.scss index 7835863e60c0..5b814ffd3351 100644 --- a/src/core/public/chrome/ui/header/header_logo.scss +++ b/src/core/public/chrome/ui/header/header_logo.scss @@ -1,9 +1,14 @@ -.logoContainer { - height: 30px; - padding: 3px 3px 3px 10px; -} +.header__logoNavButton .euiHeaderSectionItemButton__content { + // avoid layout shift on smallest breakpoint if logo and loading indicator are different sizes + min-width: 24px; + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 1fr; -.logoImage { - height: 100%; - max-width: 100%; + & .loaderContainer, + & .logoContainer { + grid-area: 1 / 1; + align-self: center; + justify-self: center; + } } diff --git a/src/core/public/chrome/ui/header/header_logo.tsx b/src/core/public/chrome/ui/header/header_logo.tsx index bbbd173c7bbd..dbb349454f72 100644 --- a/src/core/public/chrome/ui/header/header_logo.tsx +++ b/src/core/public/chrome/ui/header/header_logo.tsx @@ -28,15 +28,18 @@ * under the License. */ +import './header_logo.scss'; + import { i18n } from '@osd/i18n'; import React from 'react'; import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; import Url from 'url'; +import { EuiHeaderSectionItemButton } from '@elastic/eui'; import { ChromeNavLink } from '../..'; -import { CustomLogo } from './branding/opensearch_dashboards_custom_logo'; import { ChromeBranding } from '../../chrome_service'; -import './header_logo.scss'; +import { LoadingIndicator } from '../loading_indicator'; +import { Mark } from './branding/mark'; function findClosestAnchor(element: HTMLElement): HTMLAnchorElement | void { let current = element; @@ -102,6 +105,7 @@ interface Props { href: string; navLinks$: Observable; forceNavigation$: Observable; + loadingCount$: Observable; navigateToApp: (appId: string) => void; branding: ChromeBranding; } @@ -109,18 +113,28 @@ interface Props { export function HeaderLogo({ href, navigateToApp, branding, ...observables }: Props) { const forceNavigation = useObservable(observables.forceNavigation$, false); const navLinks = useObservable(observables.navLinks$, []); + const loadingCount = useObservable(observables.loadingCount$, 0); return ( - onClick(e, forceNavigation, navLinks, navigateToApp)} + onClick={(e: React.MouseEvent) => + onClick(e, forceNavigation, navLinks, navigateToApp) + } href={href} aria-label={i18n.translate('core.ui.chrome.headerGlobalNav.goHomePageIconAriaLabel', { defaultMessage: 'Go to home page', })} - className="logoContainer" > - - + {!(loadingCount > 0) && ( +
+ +
+ )} +
+ +
+ ); } diff --git a/test/functional/apps/visualize/_custom_branding.js b/test/functional/apps/visualize/_custom_branding.js index fe22524db4bb..4f14f8079d6d 100644 --- a/test/functional/apps/visualize/_custom_branding.js +++ b/test/functional/apps/visualize/_custom_branding.js @@ -15,10 +15,6 @@ export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['common', 'home', 'header', 'settings']); const testSubjects = getService('testSubjects'); - const expectedFullLogo = - 'https://opensearch.org/assets/brand/SVG/Logo/opensearch_logo_default.svg'; - const expectedFullLogoDarkMode = - 'https://opensearch.org/assets/brand/SVG/Logo/opensearch_logo_darkmode.svg'; const expectedMarkLogo = 'https://opensearch.org/assets/brand/SVG/Mark/opensearch_mark_default.svg'; const expectedMarkLogoDarkMode = @@ -125,7 +121,7 @@ export default function ({ getService, getPageObjects }) { }); it('with customized logo in header bar', async () => { - await globalNav.logoExistsOrFail(expectedFullLogo); + await globalNav.logoExistsOrFail(expectedMarkLogo); }); it('with customized logo that can take back to home page', async () => { @@ -168,7 +164,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.common.navigateToApp('management/opensearch-dashboards/settings'); await PageObjects.settings.toggleAdvancedSettingCheckbox('theme:darkMode'); await PageObjects.common.navigateToApp('home'); - await globalNav.logoExistsOrFail(expectedFullLogoDarkMode); + await globalNav.logoExistsOrFail(expectedMarkLogoDarkMode); }); it('with customized logo that can take back to home page in dark mode', async () => { diff --git a/test/functional/apps/visualize/_line_chart.js b/test/functional/apps/visualize/_line_chart.js index dadc860147c8..932bd192916a 100644 --- a/test/functional/apps/visualize/_line_chart.js +++ b/test/functional/apps/visualize/_line_chart.js @@ -221,7 +221,19 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, false); await PageObjects.visEditor.clickGo(); const labels = await PageObjects.visChart.getYAxisLabels(); - const expectedLabels = ['0', '2,000', '4,000', '6,000', '8,000', '10,000']; + const expectedLabels = [ + '0', + '1,000', + '2,000', + '3,000', + '4,000', + '5,000', + '6,000', + '7,000', + '8,000', + '9,000', + '10,000', + ]; expect(labels).to.eql(expectedLabels); }); @@ -229,7 +241,17 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true); await PageObjects.visEditor.clickGo(); const labels = await PageObjects.visChart.getYAxisLabels(); - const expectedLabels = ['2,000', '4,000', '6,000', '8,000']; + const expectedLabels = [ + '1,000', + '2,000', + '3,000', + '4,000', + '5,000', + '6,000', + '7,000', + '8,000', + '9,000', + ]; expect(labels).to.eql(expectedLabels); }); @@ -239,7 +261,19 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visEditor.clickGo(); const labels = await PageObjects.visChart.getYAxisLabels(); log.debug(labels); - const expectedLabels = ['0', '2,000', '4,000', '6,000', '8,000', '10,000']; + const expectedLabels = [ + '0', + '1,000', + '2,000', + '3,000', + '4,000', + '5,000', + '6,000', + '7,000', + '8,000', + '9,000', + '10,000', + ]; expect(labels).to.eql(expectedLabels); }); @@ -247,7 +281,17 @@ export default function ({ getService, getPageObjects }) { await PageObjects.visEditor.changeYAxisFilterLabelsCheckbox(axisId, true); await PageObjects.visEditor.clickGo(); const labels = await PageObjects.visChart.getYAxisLabels(); - const expectedLabels = ['2,000', '4,000', '6,000', '8,000']; + const expectedLabels = [ + '1,000', + '2,000', + '3,000', + '4,000', + '5,000', + '6,000', + '7,000', + '8,000', + '9,000', + ]; expect(labels).to.eql(expectedLabels); }); });