[Custom branding] Add custom logo to space selector (#150284)

## Summary

As part of custom branding, we need to replace all occurrences of
Elastic logo with the custom one, when it's set. This PR does that for
space selector.

Resolves: https://github.com/elastic/kibana/issues/150272

Example of how it might look like:

<img width="556" alt="Screenshot 2023-02-06 at 14 59 25"
src="https://user-images.githubusercontent.com/1937956/216990825-abb9ea07-9bf0-456d-8c58-c68e53c03273.png">

### Checklist

Delete any items that are not applicable to this PR.

- [X] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
~ - [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials~
- [X] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
~- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard
accessibility](https://webaim.org/techniques/keyboard/))~
- [X] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
~- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~
~- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))~
~- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)~


### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Maja Grubic 2023-02-10 09:27:28 +01:00 committed by GitHub
parent be045e29c0
commit 27f112650a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 114 additions and 3 deletions

View file

@ -1,5 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`it renders with custom logo 1`] = `
<_KibanaPageTemplate
className="spcSpaceSelector"
data-test-subj="kibanaSpaceSelector"
panelled={true}
>
<_EuiPageEmptyPrompt
className="spcSpaceSelector__pageContent"
>
<EuiText
size="s"
textAlign="center"
>
<EuiSpacer
size="xxl"
/>
<EuiImage
alt="Custom logo"
size={64}
src="img.jpg"
/>
<EuiSpacer
size="xxl"
/>
<h1
className="eui spcSpaceSelector__pageHeader"
tabIndex={0}
>
<FormattedMessage
defaultMessage="Select your space"
id="xpack.spaces.spaceSelector.selectSpacesTitle"
values={Object {}}
/>
</h1>
<EuiTextColor
color="subdued"
>
<p>
<FormattedMessage
defaultMessage="You can change your space at anytime."
id="xpack.spaces.spaceSelector.changeSpaceAnytimeAvailabilityText"
values={Object {}}
/>
</p>
</EuiTextColor>
</EuiText>
<EuiSpacer
size="xl"
/>
<EuiLoadingSpinner
size="xl"
/>
</_EuiPageEmptyPrompt>
</_KibanaPageTemplate>
`;
exports[`it renders without crashing 1`] = `
<_KibanaPageTemplate
className="spcSpaceSelector"

View file

@ -5,8 +5,12 @@
* 2.0.
*/
import { EuiImage } from '@elastic/eui';
import React from 'react';
import { of } from 'rxjs';
import { customBrandingServiceMock } from '@kbn/core-custom-branding-browser-mocks';
import { KibanaSolutionAvatar } from '@kbn/shared-ux-avatar-solution';
import { shallowWithIntl } from '@kbn/test-jest-helpers';
import type { Space } from '../../common';
@ -21,12 +25,32 @@ function getSpacesManager(spaces: Space[] = []) {
test('it renders without crashing', () => {
const spacesManager = getSpacesManager();
const customBranding$ = of({});
const component = shallowWithIntl(
<SpaceSelector spacesManager={spacesManager as any} serverBasePath={'/server-base-path'} />
<SpaceSelector
spacesManager={spacesManager as any}
serverBasePath={'/server-base-path'}
customBranding$={customBranding$}
/>
);
expect(component).toMatchSnapshot();
});
test('it renders with custom logo', () => {
const spacesManager = getSpacesManager();
const customBranding$ = of({ logo: 'img.jpg' });
const component = shallowWithIntl(
<SpaceSelector
spacesManager={spacesManager as any}
serverBasePath={'/server-base-path'}
customBranding$={customBranding$}
/>
);
expect(component).toMatchSnapshot();
expect(component.find(KibanaSolutionAvatar).length).toBe(0);
expect(component.find(EuiImage).length).toBe(1);
});
test('it queries for spaces when loaded', () => {
const spaces = [
{
@ -40,7 +64,11 @@ test('it queries for spaces when loaded', () => {
const spacesManager = getSpacesManager(spaces);
shallowWithIntl(
<SpaceSelector spacesManager={spacesManager as any} serverBasePath={'/server-base-path'} />
<SpaceSelector
spacesManager={spacesManager as any}
serverBasePath={'/server-base-path'}
customBranding$={customBrandingServiceMock.createStartContract().customBranding$}
/>
);
return Promise.resolve().then(() => {

View file

@ -9,6 +9,7 @@ import './space_selector.scss';
import {
EuiFieldSearch,
EuiImage,
EuiLoadingSpinner,
EuiPanel,
EuiSpacer,
@ -18,7 +19,9 @@ import {
} from '@elastic/eui';
import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
import type { Observable, Subscription } from 'rxjs';
import type { CustomBranding } from '@kbn/core-custom-branding-common';
import type { AppMountParameters, CoreStart } from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
@ -34,6 +37,7 @@ import { SpaceCards } from './components';
interface Props {
spacesManager: SpacesManager;
serverBasePath: string;
customBranding$: Observable<CustomBranding>;
}
interface State {
@ -41,10 +45,13 @@ interface State {
searchTerm: string;
spaces: Space[];
error?: Error;
customLogo?: string;
}
export class SpaceSelector extends Component<Props, State> {
private headerRef?: HTMLElement | null;
private customBrandingSubscription?: Subscription;
constructor(props: Props) {
super(props);
@ -67,6 +74,13 @@ export class SpaceSelector extends Component<Props, State> {
if (this.state.spaces.length === 0) {
this.loadSpaces();
}
this.customBrandingSubscription = this.props.customBranding$.subscribe((next) => {
this.setState({ ...this.state, customLogo: next.logo });
});
}
public componentWillUnmount() {
this.customBrandingSubscription?.unsubscribe();
}
public loadSpaces() {
@ -110,7 +124,17 @@ export class SpaceSelector extends Component<Props, State> {
<KibanaPageTemplate.Section className="spcSpaceSelector__pageContent" color="transparent">
<EuiText textAlign="center" size="s">
<EuiSpacer size="xxl" />
<KibanaSolutionAvatar name="Elastic" size="xl" />
{this.state.customLogo ? (
<EuiImage
src={this.state.customLogo}
size={64}
alt={i18n.translate('xpack.spaces.spaceSelector.customLogoAlt', {
defaultMessage: 'Custom logo',
})}
/>
) : (
<KibanaSolutionAvatar name="Elastic" size="xl" />
)}
<EuiSpacer size="xxl" />
<EuiTextColor color="subdued">
<h1

View file

@ -37,6 +37,7 @@ export const spaceSelectorApp = Object.freeze({
{
spacesManager,
serverBasePath: coreStart.http.basePath.serverBasePath,
customBranding$: coreStart.customBranding.customBranding$,
}
);
},

View file

@ -27,6 +27,8 @@
"@kbn/test",
"@kbn/utils",
"@kbn/shared-ux-page-kibana-template",
"@kbn/core-custom-branding-browser-mocks",
"@kbn/core-custom-branding-common",
],
"exclude": [
"target/**/*",