mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* [core/public/chrome] migrate controls, theme, and visibility apis * [core/public] stop uiSettings service * [core/public/chrome] test that observables stop immedaiately after stop() * fix typos * [core/public/legacyPlatform] test globalNavState init * [ui/chrome] don't pass extra params * [core/public/chrome] test for dedupe-handling * [ui/chrome/theme] test with different values for logo and smallLogo
This commit is contained in:
parent
27b86ebb05
commit
e33cba34b7
17 changed files with 909 additions and 188 deletions
239
src/core/public/chrome/chrome_service.test.ts
Normal file
239
src/core/public/chrome/chrome_service.test.ts
Normal file
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import * as Rx from 'rxjs';
|
||||
import { toArray } from 'rxjs/operators';
|
||||
|
||||
const store = new Map();
|
||||
(window as any).localStorage = {
|
||||
setItem: (key: string, value: string) => store.set(String(key), String(value)),
|
||||
getItem: (key: string) => store.get(String(key)),
|
||||
removeItem: (key: string) => store.delete(String(key)),
|
||||
};
|
||||
|
||||
import { ChromeService } from './chrome_service';
|
||||
|
||||
beforeEach(() => {
|
||||
store.clear();
|
||||
});
|
||||
|
||||
describe('start', () => {
|
||||
describe('brand', () => {
|
||||
it('updates/emits the brand as it changes', async () => {
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
const promise = start
|
||||
.getBrand$()
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
start.setBrand({
|
||||
logo: 'big logo',
|
||||
smallLogo: 'not so big logo',
|
||||
});
|
||||
start.setBrand({
|
||||
logo: 'big logo without small logo',
|
||||
});
|
||||
service.stop();
|
||||
|
||||
await expect(promise).resolves.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {},
|
||||
Object {
|
||||
"logo": "big logo",
|
||||
"smallLogo": "not so big logo",
|
||||
},
|
||||
Object {
|
||||
"logo": "big logo without small logo",
|
||||
"smallLogo": undefined,
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('visibility', () => {
|
||||
it('updates/emits the visibility', async () => {
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
const promise = start
|
||||
.getIsVisible$()
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
start.setIsVisible(true);
|
||||
start.setIsVisible(false);
|
||||
start.setIsVisible(true);
|
||||
service.stop();
|
||||
|
||||
await expect(promise).resolves.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('always emits false if embed query string is in hash when started', async () => {
|
||||
window.history.pushState(undefined, '', '#/home?a=b&embed=true');
|
||||
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
const promise = start
|
||||
.getIsVisible$()
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
start.setIsVisible(true);
|
||||
start.setIsVisible(false);
|
||||
start.setIsVisible(true);
|
||||
service.stop();
|
||||
|
||||
await expect(promise).resolves.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('is collapsed', () => {
|
||||
it('updates/emits isCollapsed', async () => {
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
const promise = start
|
||||
.getIsCollapsed$()
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
start.setIsCollapsed(true);
|
||||
start.setIsCollapsed(false);
|
||||
start.setIsCollapsed(true);
|
||||
service.stop();
|
||||
|
||||
await expect(promise).resolves.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('only stores true in localStorage', async () => {
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
|
||||
start.setIsCollapsed(true);
|
||||
expect(store.size).toBe(1);
|
||||
|
||||
start.setIsCollapsed(false);
|
||||
expect(store.size).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('application classes', () => {
|
||||
it('updates/emits the application classes', async () => {
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
const promise = start
|
||||
.getApplicationClasses$()
|
||||
.pipe(toArray())
|
||||
.toPromise();
|
||||
|
||||
start.addApplicationClass('foo');
|
||||
start.addApplicationClass('foo');
|
||||
start.addApplicationClass('bar');
|
||||
start.addApplicationClass('bar');
|
||||
start.addApplicationClass('baz');
|
||||
start.removeApplicationClass('bar');
|
||||
start.removeApplicationClass('foo');
|
||||
service.stop();
|
||||
|
||||
await expect(promise).resolves.toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [],
|
||||
Array [
|
||||
"foo",
|
||||
],
|
||||
Array [
|
||||
"foo",
|
||||
],
|
||||
Array [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
Array [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
Array [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
],
|
||||
Array [
|
||||
"foo",
|
||||
"baz",
|
||||
],
|
||||
Array [
|
||||
"baz",
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('stop', () => {
|
||||
it('completes applicationClass$, isCollapsed$, isVisible$, and brand$ observables', async () => {
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
const promise = Rx.combineLatest(
|
||||
start.getBrand$(),
|
||||
start.getApplicationClasses$(),
|
||||
start.getIsCollapsed$(),
|
||||
start.getIsVisible$()
|
||||
).toPromise();
|
||||
|
||||
service.stop();
|
||||
await promise;
|
||||
});
|
||||
|
||||
it('completes immediately if service already stopped', async () => {
|
||||
const service = new ChromeService();
|
||||
const start = service.start();
|
||||
service.stop();
|
||||
|
||||
await expect(
|
||||
Rx.combineLatest(
|
||||
start.getBrand$(),
|
||||
start.getApplicationClasses$(),
|
||||
start.getIsCollapsed$(),
|
||||
start.getIsVisible$()
|
||||
).toPromise()
|
||||
).resolves.toBe(undefined);
|
||||
});
|
||||
});
|
146
src/core/public/chrome/chrome_service.ts
Normal file
146
src/core/public/chrome/chrome_service.ts
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import * as Url from 'url';
|
||||
|
||||
import * as Rx from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
|
||||
const IS_COLLAPSED_KEY = 'core.chrome.isCollapsed';
|
||||
|
||||
function isEmbedParamInHash() {
|
||||
const { query } = Url.parse(String(window.location.hash).slice(1), true);
|
||||
return Boolean(query.embed);
|
||||
}
|
||||
|
||||
export interface Brand {
|
||||
logo?: string;
|
||||
smallLogo?: string;
|
||||
}
|
||||
|
||||
export class ChromeService {
|
||||
private readonly stop$ = new Rx.ReplaySubject(1);
|
||||
|
||||
public start() {
|
||||
const FORCE_HIDDEN = isEmbedParamInHash();
|
||||
|
||||
const brand$ = new Rx.BehaviorSubject<Brand>({});
|
||||
const isVisible$ = new Rx.BehaviorSubject(true);
|
||||
const isCollapsed$ = new Rx.BehaviorSubject(!!localStorage.getItem(IS_COLLAPSED_KEY));
|
||||
const applicationClasses$ = new Rx.BehaviorSubject<Set<string>>(new Set());
|
||||
|
||||
return {
|
||||
/**
|
||||
* Set the brand configuration. Normally the `logo` property will be rendered as the
|
||||
* CSS background for the home link in the chrome navigation, but when the page is
|
||||
* rendered in a small window the `smallLogo` will be used and rendered at about
|
||||
* 45px wide.
|
||||
*
|
||||
* example:
|
||||
*
|
||||
* chrome.setBrand({
|
||||
* logo: 'url(/plugins/app/logo.png) center no-repeat'
|
||||
* smallLogo: 'url(/plugins/app/logo-small.png) center no-repeat'
|
||||
* })
|
||||
*
|
||||
*/
|
||||
setBrand: (brand: Brand) => {
|
||||
brand$.next(
|
||||
Object.freeze({
|
||||
logo: brand.logo,
|
||||
smallLogo: brand.smallLogo,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an observable of the current brand information.
|
||||
*/
|
||||
getBrand$: () => brand$.pipe(takeUntil(this.stop$)),
|
||||
|
||||
/**
|
||||
* Set the temporary visibility for the chrome. This does nothing if the chrome is hidden
|
||||
* by default and should be used to hide the chrome for things like full-screen modes
|
||||
* with an exit button.
|
||||
*/
|
||||
setIsVisible: (visibility: boolean) => {
|
||||
isVisible$.next(visibility);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an observable of the current visibility state of the chrome.
|
||||
*/
|
||||
getIsVisible$: () =>
|
||||
isVisible$.pipe(
|
||||
map(visibility => (FORCE_HIDDEN ? false : visibility)),
|
||||
takeUntil(this.stop$)
|
||||
),
|
||||
|
||||
/**
|
||||
* Set the collapsed state of the chrome navigation.
|
||||
*/
|
||||
setIsCollapsed: (isCollapsed: boolean) => {
|
||||
isCollapsed$.next(isCollapsed);
|
||||
if (isCollapsed) {
|
||||
localStorage.setItem(IS_COLLAPSED_KEY, 'true');
|
||||
} else {
|
||||
localStorage.removeItem(IS_COLLAPSED_KEY);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an observable of the current collapsed state of the chrome.
|
||||
*/
|
||||
getIsCollapsed$: () => isCollapsed$.pipe(takeUntil(this.stop$)),
|
||||
|
||||
/**
|
||||
* Add a className that should be set on the application container.
|
||||
*/
|
||||
addApplicationClass: (className: string) => {
|
||||
const update = new Set([...applicationClasses$.getValue()]);
|
||||
update.add(className);
|
||||
applicationClasses$.next(update);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a className added with `addApplicationClass()`. If className is unknown it is ignored.
|
||||
*/
|
||||
removeApplicationClass: (className: string) => {
|
||||
const update = new Set([...applicationClasses$.getValue()]);
|
||||
update.delete(className);
|
||||
applicationClasses$.next(update);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current set of classNames that will be set on the application container.
|
||||
*/
|
||||
getApplicationClasses$: () =>
|
||||
applicationClasses$.pipe(
|
||||
map(set => [...set]),
|
||||
takeUntil(this.stop$)
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
public stop() {
|
||||
this.stop$.next();
|
||||
}
|
||||
}
|
||||
|
||||
export type ChromeStartContract = ReturnType<ChromeService['start']>;
|
20
src/core/public/chrome/index.ts
Normal file
20
src/core/public/chrome/index.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
export { ChromeService, ChromeStartContract, Brand } from './chrome_service';
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
import { BasePathService } from './base_path';
|
||||
import { ChromeService } from './chrome';
|
||||
import { FatalErrorsService } from './fatal_errors';
|
||||
import { InjectedMetadataService } from './injected_metadata';
|
||||
import { LegacyPlatformService } from './legacy_platform';
|
||||
|
@ -92,11 +93,21 @@ const MockUiSettingsService = jest.fn<UiSettingsService>(function _MockNotificat
|
|||
this: any
|
||||
) {
|
||||
this.start = jest.fn().mockReturnValue(mockUiSettingsContract);
|
||||
this.stop = jest.fn();
|
||||
});
|
||||
jest.mock('./ui_settings', () => ({
|
||||
UiSettingsService: MockUiSettingsService,
|
||||
}));
|
||||
|
||||
const mockChromeStartContract = {};
|
||||
const MockChromeService = jest.fn<ChromeService>(function _MockNotificationsService(this: any) {
|
||||
this.start = jest.fn().mockReturnValue(mockChromeStartContract);
|
||||
this.stop = jest.fn();
|
||||
});
|
||||
jest.mock('./chrome', () => ({
|
||||
ChromeService: MockChromeService,
|
||||
}));
|
||||
|
||||
import { CoreSystem } from './core_system';
|
||||
jest.spyOn(CoreSystem.prototype, 'stop');
|
||||
|
||||
|
@ -124,6 +135,7 @@ describe('constructor', () => {
|
|||
expect(MockLoadingCountService).toHaveBeenCalledTimes(1);
|
||||
expect(MockBasePathService).toHaveBeenCalledTimes(1);
|
||||
expect(MockUiSettingsService).toHaveBeenCalledTimes(1);
|
||||
expect(MockChromeService).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('passes injectedMetadata param to InjectedMetadataService', () => {
|
||||
|
@ -231,6 +243,28 @@ describe('#stop', () => {
|
|||
expect(loadingCountService.stop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls chrome.stop()', () => {
|
||||
const coreSystem = new CoreSystem({
|
||||
...defaultCoreSystemParams,
|
||||
});
|
||||
|
||||
const [chromeService] = MockChromeService.mock.instances;
|
||||
expect(chromeService.stop).not.toHaveBeenCalled();
|
||||
coreSystem.stop();
|
||||
expect(chromeService.stop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls uiSettings.stop()', () => {
|
||||
const coreSystem = new CoreSystem({
|
||||
...defaultCoreSystemParams,
|
||||
});
|
||||
|
||||
const [uiSettings] = MockUiSettingsService.mock.instances;
|
||||
expect(uiSettings.stop).not.toHaveBeenCalled();
|
||||
coreSystem.stop();
|
||||
expect(uiSettings.stop).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('clears the rootDomElement', () => {
|
||||
const rootDomElement = document.createElement('div');
|
||||
const coreSystem = new CoreSystem({
|
||||
|
@ -312,6 +346,13 @@ describe('#start()', () => {
|
|||
expect(mockInstance.start).toHaveBeenCalledTimes(1);
|
||||
expect(mockInstance.start).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('calls chrome#start()', () => {
|
||||
startCore();
|
||||
const [mockInstance] = MockChromeService.mock.instances;
|
||||
expect(mockInstance.start).toHaveBeenCalledTimes(1);
|
||||
expect(mockInstance.start).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('LegacyPlatform targetDomElement', () => {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
import './core.css';
|
||||
|
||||
import { BasePathService } from './base_path';
|
||||
import { ChromeService } from './chrome';
|
||||
import { FatalErrorsService } from './fatal_errors';
|
||||
import { InjectedMetadataParams, InjectedMetadataService } from './injected_metadata';
|
||||
import { LegacyPlatformParams, LegacyPlatformService } from './legacy_platform';
|
||||
|
@ -48,6 +49,7 @@ export class CoreSystem {
|
|||
private readonly loadingCount: LoadingCountService;
|
||||
private readonly uiSettings: UiSettingsService;
|
||||
private readonly basePath: BasePathService;
|
||||
private readonly chrome: ChromeService;
|
||||
|
||||
private readonly rootDomElement: HTMLElement;
|
||||
private readonly notificationsTargetDomElement: HTMLDivElement;
|
||||
|
@ -78,6 +80,7 @@ export class CoreSystem {
|
|||
this.loadingCount = new LoadingCountService();
|
||||
this.basePath = new BasePathService();
|
||||
this.uiSettings = new UiSettingsService();
|
||||
this.chrome = new ChromeService();
|
||||
|
||||
this.legacyPlatformTargetDomElement = document.createElement('div');
|
||||
this.legacyPlatform = new LegacyPlatformService({
|
||||
|
@ -106,6 +109,8 @@ export class CoreSystem {
|
|||
injectedMetadata,
|
||||
basePath,
|
||||
});
|
||||
const chrome = this.chrome.start();
|
||||
|
||||
this.legacyPlatform.start({
|
||||
injectedMetadata,
|
||||
fatalErrors,
|
||||
|
@ -113,6 +118,7 @@ export class CoreSystem {
|
|||
loadingCount,
|
||||
basePath,
|
||||
uiSettings,
|
||||
chrome,
|
||||
});
|
||||
} catch (error) {
|
||||
this.fatalErrors.add(error);
|
||||
|
@ -123,6 +129,8 @@ export class CoreSystem {
|
|||
this.legacyPlatform.stop();
|
||||
this.notifications.stop();
|
||||
this.loadingCount.stop();
|
||||
this.uiSettings.stop();
|
||||
this.chrome.stop();
|
||||
this.rootDomElement.textContent = '';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ Array [
|
|||
"ui/chrome/api/base_path",
|
||||
"ui/chrome/api/ui_settings",
|
||||
"ui/chrome/api/injected_vars",
|
||||
"ui/chrome/api/controls",
|
||||
"ui/chrome/api/theme",
|
||||
"ui/chrome/services/global_nav_state",
|
||||
"ui/chrome",
|
||||
"legacy files",
|
||||
]
|
||||
|
@ -23,6 +26,9 @@ Array [
|
|||
"ui/chrome/api/base_path",
|
||||
"ui/chrome/api/ui_settings",
|
||||
"ui/chrome/api/injected_vars",
|
||||
"ui/chrome/api/controls",
|
||||
"ui/chrome/api/theme",
|
||||
"ui/chrome/services/global_nav_state",
|
||||
"ui/test_harness",
|
||||
"legacy files",
|
||||
]
|
||||
|
|
|
@ -94,6 +94,30 @@ jest.mock('ui/chrome/api/injected_vars', () => {
|
|||
};
|
||||
});
|
||||
|
||||
const mockChromeControlsInit = jest.fn();
|
||||
jest.mock('ui/chrome/api/controls', () => {
|
||||
mockLoadOrder.push('ui/chrome/api/controls');
|
||||
return {
|
||||
__newPlatformInit__: mockChromeControlsInit,
|
||||
};
|
||||
});
|
||||
|
||||
const mockChromeThemeInit = jest.fn();
|
||||
jest.mock('ui/chrome/api/theme', () => {
|
||||
mockLoadOrder.push('ui/chrome/api/theme');
|
||||
return {
|
||||
__newPlatformInit__: mockChromeThemeInit,
|
||||
};
|
||||
});
|
||||
|
||||
const mockGlobalNavStateInit = jest.fn();
|
||||
jest.mock('ui/chrome/services/global_nav_state', () => {
|
||||
mockLoadOrder.push('ui/chrome/services/global_nav_state');
|
||||
return {
|
||||
__newPlatformInit__: mockGlobalNavStateInit,
|
||||
};
|
||||
});
|
||||
|
||||
import { LegacyPlatformService } from './legacy_platform_service';
|
||||
|
||||
const fatalErrorsStartContract = {} as any;
|
||||
|
@ -118,6 +142,7 @@ const basePathStartContract = {
|
|||
};
|
||||
|
||||
const uiSettingsStartContract: any = {};
|
||||
const chromeStartContract: any = {};
|
||||
|
||||
const defaultParams = {
|
||||
targetDomElement: document.createElement('div'),
|
||||
|
@ -133,6 +158,7 @@ const defaultStartDeps = {
|
|||
loadingCount: loadingCountStartContract,
|
||||
basePath: basePathStartContract,
|
||||
uiSettings: uiSettingsStartContract,
|
||||
chrome: chromeStartContract,
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -224,6 +250,39 @@ describe('#start()', () => {
|
|||
expect(mockInjectedVarsInit).toHaveBeenCalledWith(injectedMetadataStartContract);
|
||||
});
|
||||
|
||||
it('passes chrome service to ui/chrome/api/controls', () => {
|
||||
const legacyPlatform = new LegacyPlatformService({
|
||||
...defaultParams,
|
||||
});
|
||||
|
||||
legacyPlatform.start(defaultStartDeps);
|
||||
|
||||
expect(mockChromeControlsInit).toHaveBeenCalledTimes(1);
|
||||
expect(mockChromeControlsInit).toHaveBeenCalledWith(chromeStartContract);
|
||||
});
|
||||
|
||||
it('passes chrome service to ui/chrome/api/theme', () => {
|
||||
const legacyPlatform = new LegacyPlatformService({
|
||||
...defaultParams,
|
||||
});
|
||||
|
||||
legacyPlatform.start(defaultStartDeps);
|
||||
|
||||
expect(mockChromeThemeInit).toHaveBeenCalledTimes(1);
|
||||
expect(mockChromeThemeInit).toHaveBeenCalledWith(chromeStartContract);
|
||||
});
|
||||
|
||||
it('passes chrome service to ui/chrome/api/global_nav_state', () => {
|
||||
const legacyPlatform = new LegacyPlatformService({
|
||||
...defaultParams,
|
||||
});
|
||||
|
||||
legacyPlatform.start(defaultStartDeps);
|
||||
|
||||
expect(mockGlobalNavStateInit).toHaveBeenCalledTimes(1);
|
||||
expect(mockGlobalNavStateInit).toHaveBeenCalledWith(chromeStartContract);
|
||||
});
|
||||
|
||||
describe('useLegacyTestHarness = false', () => {
|
||||
it('passes the targetDomElement to ui/chrome', () => {
|
||||
const legacyPlatform = new LegacyPlatformService({
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import angular from 'angular';
|
||||
import { BasePathStartContract } from '../base_path';
|
||||
import { ChromeStartContract } from '../chrome';
|
||||
import { FatalErrorsStartContract } from '../fatal_errors';
|
||||
import { InjectedMetadataStartContract } from '../injected_metadata';
|
||||
import { LoadingCountStartContract } from '../loading_count';
|
||||
|
@ -32,6 +33,7 @@ interface Deps {
|
|||
loadingCount: LoadingCountStartContract;
|
||||
basePath: BasePathStartContract;
|
||||
uiSettings: UiSettingsClient;
|
||||
chrome: ChromeStartContract;
|
||||
}
|
||||
|
||||
export interface LegacyPlatformParams {
|
||||
|
@ -57,6 +59,7 @@ export class LegacyPlatformService {
|
|||
loadingCount,
|
||||
basePath,
|
||||
uiSettings,
|
||||
chrome,
|
||||
}: Deps) {
|
||||
// Inject parts of the new platform into parts of the legacy platform
|
||||
// so that legacy APIs/modules can mimic their new platform counterparts
|
||||
|
@ -67,6 +70,9 @@ export class LegacyPlatformService {
|
|||
require('ui/chrome/api/base_path').__newPlatformInit__(basePath);
|
||||
require('ui/chrome/api/ui_settings').__newPlatformInit__(uiSettings);
|
||||
require('ui/chrome/api/injected_vars').__newPlatformInit__(injectedMetadata);
|
||||
require('ui/chrome/api/controls').__newPlatformInit__(chrome);
|
||||
require('ui/chrome/api/theme').__newPlatformInit__(chrome);
|
||||
require('ui/chrome/services/global_nav_state').__newPlatformInit__(chrome);
|
||||
|
||||
// Load the bootstrap module before loading the legacy platform files so that
|
||||
// the bootstrap module can modify the environment a bit first
|
||||
|
|
62
src/ui/public/chrome/api/controls.js
vendored
62
src/ui/public/chrome/api/controls.js
vendored
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
// eslint-disable-next-line @elastic/kibana-custom/no-default-export
|
||||
export default function (chrome, internals) {
|
||||
/**
|
||||
* ui/chrome Controls API
|
||||
*
|
||||
* Exposes controls for the Kibana chrome
|
||||
*
|
||||
* Visible
|
||||
* determines if the Kibana chrome should be displayed
|
||||
*/
|
||||
|
||||
let permanentlyHideChrome = false;
|
||||
internals.permanentlyHideChrome = () => {
|
||||
permanentlyHideChrome = true;
|
||||
internals.visible = false;
|
||||
};
|
||||
|
||||
chrome.getIsChromePermanentlyHidden = () => {
|
||||
return permanentlyHideChrome;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} display - should the chrome be displayed
|
||||
* @return {chrome}
|
||||
*/
|
||||
chrome.setVisible = function (display) {
|
||||
if (permanentlyHideChrome) {
|
||||
return chrome;
|
||||
}
|
||||
internals.visible = Boolean(display);
|
||||
return chrome;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {boolean} - display state of the chrome
|
||||
*/
|
||||
chrome.getVisible = function () {
|
||||
if (_.isUndefined(internals.visible)) return !permanentlyHideChrome;
|
||||
return internals.visible;
|
||||
};
|
||||
}
|
74
src/ui/public/chrome/api/controls.test.ts
Normal file
74
src/ui/public/chrome/api/controls.test.ts
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import * as Rx from 'rxjs';
|
||||
|
||||
import { __newPlatformInit__, initChromeControlsApi } from './controls';
|
||||
|
||||
const newPlatformChrome = {
|
||||
setIsVisible: jest.fn(),
|
||||
getIsVisible$: jest.fn(),
|
||||
};
|
||||
|
||||
__newPlatformInit__(newPlatformChrome as any);
|
||||
|
||||
function setup() {
|
||||
const isVisible$ = new Rx.BehaviorSubject(true);
|
||||
newPlatformChrome.getIsVisible$.mockReturnValue(isVisible$);
|
||||
|
||||
const chrome: any = {};
|
||||
initChromeControlsApi(chrome);
|
||||
return { chrome, isVisible$ };
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('setVisible', () => {
|
||||
it('passes the visibility to the newPlatform', () => {
|
||||
const { chrome } = setup();
|
||||
chrome.setVisible(true);
|
||||
chrome.setVisible(false);
|
||||
chrome.setVisible(false);
|
||||
expect(newPlatformChrome.setIsVisible.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
true,
|
||||
],
|
||||
Array [
|
||||
false,
|
||||
],
|
||||
Array [
|
||||
false,
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getVisible', () => {
|
||||
it('returns a the cached value emitted by the newPlatformChrome', () => {
|
||||
const { chrome, isVisible$ } = setup();
|
||||
isVisible$.next(true);
|
||||
expect(chrome.getVisible()).toBe(true);
|
||||
isVisible$.next(false);
|
||||
expect(chrome.getVisible()).toBe(false);
|
||||
});
|
||||
});
|
53
src/ui/public/chrome/api/controls.ts
Normal file
53
src/ui/public/chrome/api/controls.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import * as Rx from 'rxjs';
|
||||
import { ChromeStartContract } from '../../../../core/public/chrome';
|
||||
|
||||
let newPlatformChrome: ChromeStartContract;
|
||||
|
||||
export function __newPlatformInit__(instance: ChromeStartContract) {
|
||||
if (newPlatformChrome) {
|
||||
throw new Error('ui/chrome/api/controls is already initialized');
|
||||
}
|
||||
|
||||
newPlatformChrome = instance;
|
||||
}
|
||||
|
||||
export function initChromeControlsApi(chrome: { [key: string]: any }) {
|
||||
// cache of chrome visibility state
|
||||
const visible$ = new Rx.BehaviorSubject(false);
|
||||
newPlatformChrome.getIsVisible$().subscribe(visible$);
|
||||
|
||||
/**
|
||||
* Set the temporary visibility for the chrome. This does nothing if the chrome is hidden
|
||||
* by default and should be used to hide the chrome for things like full-screen modes
|
||||
* with an exit button.
|
||||
*/
|
||||
chrome.setVisible = (visibility: boolean) => {
|
||||
newPlatformChrome.setIsVisible(visibility);
|
||||
return chrome;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current visibility state of the chrome. Note that this drives the UI so it
|
||||
* might be incorrect in the moments just before the UI is updated.
|
||||
*/
|
||||
chrome.getVisible = () => visible$.getValue();
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
// eslint-disable-next-line @elastic/kibana-custom/no-default-export
|
||||
export default function (chrome, internals) {
|
||||
/**
|
||||
* ui/chrome Theme API
|
||||
*
|
||||
* Logo
|
||||
* Set the background for the logo and small logo in the navbar.
|
||||
* When the app is in the "small" category, a modified version of the
|
||||
* logo is displayed that is 45px wide.
|
||||
* e.g., 'url(/plugins/app/logo.png) center no-repeat'
|
||||
*
|
||||
* Brand
|
||||
* Similar to a logo, but is just text with styles to make it stick out.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string|object} item - brand key to set, or object to apply
|
||||
* @param {mixed} val - value to put on the brand item
|
||||
* @return {chrome}
|
||||
*/
|
||||
chrome.setBrand = function (item, val) {
|
||||
internals.brand = internals.brand || {};
|
||||
|
||||
// allow objects to be passed in
|
||||
if (_.isPlainObject(item)) {
|
||||
internals.brand = _.clone(item);
|
||||
} else {
|
||||
internals.brand[item] = val;
|
||||
}
|
||||
|
||||
return chrome;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string} - the brand text
|
||||
*/
|
||||
chrome.getBrand = function (item) {
|
||||
if (!internals.brand) return;
|
||||
return internals.brand[item];
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a class to the application node
|
||||
* @param {string} - the class name to add
|
||||
* @return {chrome}
|
||||
*/
|
||||
chrome.addApplicationClass = function (val) {
|
||||
let classes = internals.applicationClasses || [];
|
||||
classes.push(val);
|
||||
classes = _.uniq(classes);
|
||||
|
||||
internals.applicationClasses = classes;
|
||||
return chrome;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a class from the application node. Note: this only
|
||||
* removes classes that were added via the addApplicationClass method
|
||||
* @param {string|[string]} - class or classes to be removed
|
||||
* @return {chrome}
|
||||
*/
|
||||
chrome.removeApplicationClass = function (val) {
|
||||
const classesToRemove = [].concat(val || []);
|
||||
const classes = internals.applicationClasses || [];
|
||||
_.pull(classes, ...classesToRemove);
|
||||
|
||||
internals.applicationClasses = classes;
|
||||
return chrome;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {string} - a space delimited string of the classes added by the
|
||||
* addApplicationClass method
|
||||
*/
|
||||
chrome.getApplicationClasses = function () {
|
||||
return internals.applicationClasses.join(' ');
|
||||
};
|
||||
|
||||
}
|
153
src/ui/public/chrome/api/theme.test.ts
Normal file
153
src/ui/public/chrome/api/theme.test.ts
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import * as Rx from 'rxjs';
|
||||
|
||||
import { __newPlatformInit__, initChromeThemeApi } from './theme';
|
||||
|
||||
const newPlatformChrome = {
|
||||
setBrand: jest.fn(),
|
||||
getBrand$: jest.fn(),
|
||||
addApplicationClass: jest.fn(),
|
||||
removeApplicationClass: jest.fn(),
|
||||
getApplicationClasses$: jest.fn(),
|
||||
};
|
||||
|
||||
__newPlatformInit__(newPlatformChrome as any);
|
||||
|
||||
function setup() {
|
||||
const brand$ = new Rx.BehaviorSubject({ logo: 'foo', smallLogo: 'foo' });
|
||||
newPlatformChrome.getBrand$.mockReturnValue(brand$);
|
||||
|
||||
const applicationClasses$ = new Rx.BehaviorSubject([] as string[]);
|
||||
newPlatformChrome.getApplicationClasses$.mockReturnValue(applicationClasses$);
|
||||
|
||||
const chrome: any = {};
|
||||
initChromeThemeApi(chrome);
|
||||
return { chrome, brand$, applicationClasses$ };
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('setBrand', () => {
|
||||
it('proxies to newPlatformChrome', () => {
|
||||
const { chrome } = setup();
|
||||
|
||||
chrome.setBrand({
|
||||
logo: 'foo.svg',
|
||||
smallLogo: 'smallFoo.svg',
|
||||
});
|
||||
|
||||
chrome.setBrand({
|
||||
logo: 'baz',
|
||||
});
|
||||
|
||||
expect(newPlatformChrome.setBrand.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"logo": "foo.svg",
|
||||
"smallLogo": "smallFoo.svg",
|
||||
},
|
||||
],
|
||||
Array [
|
||||
Object {
|
||||
"logo": "baz",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getBrand', () => {
|
||||
it('returns named properties from cached values emitted from newPlatformChrome', () => {
|
||||
const { chrome, brand$ } = setup();
|
||||
expect(chrome.getBrand('logo')).toBe('foo');
|
||||
expect(chrome.getBrand('smallLogo')).toBe('foo');
|
||||
expect(chrome.getBrand()).toBe(undefined);
|
||||
|
||||
brand$.next({
|
||||
logo: 'bar.svg',
|
||||
smallLogo: 'smallBar.svg',
|
||||
});
|
||||
|
||||
expect(chrome.getBrand('logo')).toBe('bar.svg');
|
||||
expect(chrome.getBrand('smallLogo')).toBe('smallBar.svg');
|
||||
expect(chrome.getBrand()).toBe(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addApplicationClass', () => {
|
||||
it('proxies each class as a separate argument to newPlatformChrome', () => {
|
||||
const { chrome } = setup();
|
||||
chrome.addApplicationClass('foo');
|
||||
chrome.addApplicationClass(['bar', 'baz']);
|
||||
chrome.addApplicationClass([]);
|
||||
expect(newPlatformChrome.addApplicationClass.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"foo",
|
||||
],
|
||||
Array [
|
||||
"bar",
|
||||
],
|
||||
Array [
|
||||
"baz",
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeApplicationClass', () => {
|
||||
it('proxies each class as a separate argument to newPlatformChrome', () => {
|
||||
const { chrome } = setup();
|
||||
chrome.removeApplicationClass('foo');
|
||||
chrome.removeApplicationClass(['bar', 'baz']);
|
||||
chrome.removeApplicationClass([]);
|
||||
expect(newPlatformChrome.removeApplicationClass.mock.calls).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"foo",
|
||||
],
|
||||
Array [
|
||||
"bar",
|
||||
],
|
||||
Array [
|
||||
"baz",
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getApplicationClasses', () => {
|
||||
it('returns cached values emitted from newPlatformChrome as a single string', () => {
|
||||
const { chrome, applicationClasses$ } = setup();
|
||||
|
||||
expect(chrome.getApplicationClasses()).toBe('');
|
||||
applicationClasses$.next(['foo', 'bar']);
|
||||
expect(chrome.getApplicationClasses()).toBe('foo bar');
|
||||
applicationClasses$.next(['bar']);
|
||||
expect(chrome.getApplicationClasses()).toBe('bar');
|
||||
});
|
||||
});
|
76
src/ui/public/chrome/api/theme.ts
Normal file
76
src/ui/public/chrome/api/theme.ts
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import * as Rx from 'rxjs';
|
||||
|
||||
import { Brand, ChromeStartContract } from '../../../../core/public/chrome';
|
||||
|
||||
let newPlatformChrome: ChromeStartContract;
|
||||
|
||||
export function __newPlatformInit__(instance: ChromeStartContract) {
|
||||
if (newPlatformChrome) {
|
||||
throw new Error('ui/chrome/api/theme is already initialized');
|
||||
}
|
||||
|
||||
newPlatformChrome = instance;
|
||||
}
|
||||
|
||||
export function initChromeThemeApi(chrome: { [key: string]: any }) {
|
||||
const brandCache$ = new Rx.BehaviorSubject<Brand>({});
|
||||
newPlatformChrome.getBrand$().subscribe(brandCache$);
|
||||
|
||||
const applicationClassesCache$ = new Rx.BehaviorSubject<string[]>([]);
|
||||
newPlatformChrome.getApplicationClasses$().subscribe(applicationClassesCache$);
|
||||
|
||||
chrome.setBrand = (brand: Brand) => {
|
||||
newPlatformChrome.setBrand(brand);
|
||||
return chrome;
|
||||
};
|
||||
|
||||
chrome.getBrand = (key: keyof Brand) => {
|
||||
return brandCache$.getValue()[key];
|
||||
};
|
||||
|
||||
chrome.addApplicationClass = (classNames: string | string[] = []) => {
|
||||
if (typeof classNames === 'string') {
|
||||
classNames = [classNames];
|
||||
}
|
||||
|
||||
for (const className of classNames) {
|
||||
newPlatformChrome.addApplicationClass(className);
|
||||
}
|
||||
|
||||
return chrome;
|
||||
};
|
||||
|
||||
chrome.removeApplicationClass = (classNames: string | string[]) => {
|
||||
if (typeof classNames === 'string') {
|
||||
classNames = [classNames];
|
||||
}
|
||||
|
||||
for (const className of classNames) {
|
||||
newPlatformChrome.removeApplicationClass(className);
|
||||
}
|
||||
return chrome;
|
||||
};
|
||||
|
||||
chrome.getApplicationClasses = () => {
|
||||
return applicationClassesCache$.getValue().join(' ');
|
||||
};
|
||||
}
|
|
@ -33,10 +33,10 @@ import './services';
|
|||
|
||||
import { initAngularApi } from './api/angular';
|
||||
import appsApi from './api/apps';
|
||||
import controlsApi from './api/controls';
|
||||
import { initChromeControlsApi } from './api/controls';
|
||||
import { initChromeNavApi } from './api/nav';
|
||||
import templateApi from './api/template';
|
||||
import themeApi from './api/theme';
|
||||
import { initChromeThemeApi } from './api/theme';
|
||||
import { initChromeXsrfApi } from './api/xsrf';
|
||||
import { initUiSettingsApi } from './api/ui_settings';
|
||||
import { initLoadingCountApi } from './api/loading_count';
|
||||
|
@ -69,9 +69,9 @@ initChromeInjectedVarsApi(chrome);
|
|||
initChromeNavApi(chrome, internals);
|
||||
initLoadingCountApi(chrome, internals);
|
||||
initAngularApi(chrome, internals);
|
||||
controlsApi(chrome, internals);
|
||||
initChromeControlsApi(chrome);
|
||||
templateApi(chrome, internals);
|
||||
themeApi(chrome, internals);
|
||||
initChromeThemeApi(chrome);
|
||||
|
||||
const waitForBootstrap = new Promise(resolve => {
|
||||
chrome.bootstrap = function (targetDomElement) {
|
||||
|
|
|
@ -57,16 +57,10 @@ export function kbnChromeProvider(chrome, internals) {
|
|||
},
|
||||
|
||||
controllerAs: 'chrome',
|
||||
controller($scope, $rootScope, $location, $http, Private, config) {
|
||||
controller($scope, $rootScope, Private, config) {
|
||||
config.watch('k7design', (val) => $scope.k7design = val);
|
||||
|
||||
const getUnhashableStates = Private(getUnhashableStatesProvider);
|
||||
|
||||
// are we showing the embedded version of the chrome?
|
||||
if (Boolean($location.search().embed)) {
|
||||
internals.permanentlyHideChrome();
|
||||
}
|
||||
|
||||
const subUrlRouteFilter = Private(SubUrlRouteFilterProvider);
|
||||
|
||||
function updateSubUrls() {
|
||||
|
|
|
@ -17,25 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import { distinctUntilChanged } from 'rxjs/operators';
|
||||
import { uiModules } from '../../modules';
|
||||
|
||||
uiModules.get('kibana')
|
||||
.service('globalNavState', (localStorage, $rootScope) => {
|
||||
return {
|
||||
isOpen: () => {
|
||||
const isOpen = localStorage.get('kibana.isGlobalNavOpen');
|
||||
if (isOpen === null) {
|
||||
// The global nav should default to being open for the initial experience.
|
||||
return true;
|
||||
}
|
||||
return isOpen;
|
||||
},
|
||||
let newPlatformChrome;
|
||||
export function __newPlatformInit__(instance) {
|
||||
if (newPlatformChrome) {
|
||||
throw new Error('ui/chrome/global_nav_state is already initialized');
|
||||
}
|
||||
|
||||
setOpen: isOpen => {
|
||||
localStorage.set('kibana.isGlobalNavOpen', isOpen);
|
||||
newPlatformChrome = instance;
|
||||
}
|
||||
|
||||
uiModules.get('kibana')
|
||||
.service('globalNavState', ($rootScope) => {
|
||||
let isOpen = false;
|
||||
newPlatformChrome.getIsCollapsed$().pipe(distinctUntilChanged()).subscribe(isCollapsed => {
|
||||
$rootScope.$evalAsync(() => {
|
||||
isOpen = !isCollapsed;
|
||||
$rootScope.$broadcast('globalNavState:change');
|
||||
return isOpen;
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
isOpen: () => isOpen,
|
||||
|
||||
setOpen: newValue => {
|
||||
newPlatformChrome.setIsCollapsed(!newValue);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue