From 7152878d5aecd486c21bf4c1edb210260b2ee6b6 Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 30 Jan 2019 09:33:04 -0800 Subject: [PATCH] [chrome/breadcrumbs] add push/filter methods (#29566) --- src/ui/public/chrome/api/breadcrumbs.ts | 128 ++++++++++++++---------- src/ui/public/chrome/index.d.ts | 6 +- 2 files changed, 79 insertions(+), 55 deletions(-) diff --git a/src/ui/public/chrome/api/breadcrumbs.ts b/src/ui/public/chrome/api/breadcrumbs.ts index c493b36960868..494989462ca89 100644 --- a/src/ui/public/chrome/api/breadcrumbs.ts +++ b/src/ui/public/chrome/api/breadcrumbs.ts @@ -18,21 +18,11 @@ */ import { IRootScopeService } from 'angular'; - -// @ts-ignore -import { uiModules } from 'ui/modules'; import { fatalError } from 'ui/notify/fatal_error'; import { Breadcrumb, ChromeStartContract } from '../../../../core/public/chrome'; export { Breadcrumb }; -export interface BreadcrumbsApi { - get$(): ReturnType; - set(newBreadcrumbs: Breadcrumb[]): void; -} - -export interface WithBreadcrumbsApi { - breadcrumbs: BreadcrumbsApi; -} +export type BreadcrumbsApi = ReturnType['breadcrumbs']; let newPlatformChrome: ChromeStartContract; export function __newPlatformInit__(instance: ChromeStartContract) { @@ -43,62 +33,94 @@ export function __newPlatformInit__(instance: ChromeStartContract) { newPlatformChrome = instance; } -export function initBreadcrumbsApi( - chrome: { [key: string]: any }, - internals: { [key: string]: any } -) { +function createBreadcrumbsApi(chrome: { [key: string]: any }) { // A flag used to determine if we should automatically // clear the breadcrumbs between angular route changes. let breadcrumbSetSinceRouteChange = false; + let currentBreadcrumbs: Breadcrumb[] = []; // reset breadcrumbSetSinceRouteChange any time the breadcrumbs change, even // if it was done directly through the new platform newPlatformChrome.getBreadcrumbs$().subscribe({ - next() { + next(nextBreadcrumbs) { breadcrumbSetSinceRouteChange = true; + currentBreadcrumbs = nextBreadcrumbs; }, }); - chrome.breadcrumbs = { - get$() { - return newPlatformChrome.getBreadcrumbs$(); + return { + breadcrumbs: { + /** + * Get an observerable that emits the current list of breadcrumbs + * and emits each update to the breadcrumbs + */ + get$() { + return newPlatformChrome.getBreadcrumbs$(); + }, + + /** + * Replace the set of breadcrumbs with a new set + */ + set(newBreadcrumbs: Breadcrumb[]) { + newPlatformChrome.setBreadcrumbs(newBreadcrumbs); + }, + + /** + * Add a breadcrumb to the end of the list of breadcrumbs + */ + push(breadcrumb: Breadcrumb) { + newPlatformChrome.setBreadcrumbs([...currentBreadcrumbs, breadcrumb]); + }, + + /** + * Filter the current set of breadcrumbs with a function. Works like Array#filter() + */ + filter(fn: (breadcrumb: Breadcrumb, i: number, all: Breadcrumb[]) => boolean) { + newPlatformChrome.setBreadcrumbs(currentBreadcrumbs.filter(fn)); + }, }, - set(newBreadcrumbs: Breadcrumb[]) { - newPlatformChrome.setBreadcrumbs(newBreadcrumbs); + /** + * internal angular run function that will be called when angular bootstraps and + * lets us integrate with the angular router so that we can automatically clear + * the breadcrumbs if we switch to a Kibana app that does not use breadcrumbs correctly + */ + $setupBreadcrumbsAutoClear: ($rootScope: IRootScopeService, $injector: any) => { + const uiSettings = chrome.getUiSettingsClient(); + const $route = $injector.has('$route') ? $injector.get('$route') : {}; + + $rootScope.$on('$routeChangeStart', () => { + breadcrumbSetSinceRouteChange = false; + }); + + $rootScope.$on('$routeChangeSuccess', () => { + const current = $route.current || {}; + + if (breadcrumbSetSinceRouteChange || (current.$$route && current.$$route.redirectTo)) { + return; + } + + const k7BreadcrumbsProvider = current.k7Breadcrumbs; + if (!k7BreadcrumbsProvider || !uiSettings.get('k7design')) { + newPlatformChrome.setBreadcrumbs([]); + return; + } + + try { + chrome.breadcrumbs.set($injector.invoke(k7BreadcrumbsProvider)); + } catch (error) { + fatalError(error); + } + }); }, }; +} - // define internal angular run function that will be called when angular - // bootstraps and lets us integrate with the angular router so that we can - // automatically clear the breadcrumbs if we switch to a Kibana app that - // does not use breadcrumbs correctly - internals.$setupBreadcrumbsAutoClear = ($rootScope: IRootScopeService, $injector: any) => { - const uiSettings = chrome.getUiSettingsClient(); - const $route = $injector.has('$route') ? $injector.get('$route') : {}; - - $rootScope.$on('$routeChangeStart', () => { - breadcrumbSetSinceRouteChange = false; - }); - - $rootScope.$on('$routeChangeSuccess', () => { - const current = $route.current || {}; - - if (breadcrumbSetSinceRouteChange || (current.$$route && current.$$route.redirectTo)) { - return; - } - - const k7BreadcrumbsProvider = current.k7Breadcrumbs; - if (!k7BreadcrumbsProvider || !uiSettings.get('k7design')) { - newPlatformChrome.setBreadcrumbs([]); - return; - } - - try { - chrome.breadcrumbs.set($injector.invoke(k7BreadcrumbsProvider)); - } catch (error) { - fatalError(error); - } - }); - }; +export function initBreadcrumbsApi( + chrome: { [key: string]: any }, + internals: { [key: string]: any } +) { + const { breadcrumbs, $setupBreadcrumbsAutoClear } = createBreadcrumbsApi(chrome); + chrome.breadcrumbs = breadcrumbs; + internals.$setupBreadcrumbsAutoClear = $setupBreadcrumbsAutoClear; } diff --git a/src/ui/public/chrome/index.d.ts b/src/ui/public/chrome/index.d.ts index 1b0fa3ca205af..5098eb54b9a5b 100644 --- a/src/ui/public/chrome/index.d.ts +++ b/src/ui/public/chrome/index.d.ts @@ -18,13 +18,14 @@ */ import { Brand } from '../../../core/public/chrome'; -import { WithBreadcrumbsApi } from './api/breadcrumbs'; +import { BreadcrumbsApi } from './api/breadcrumbs'; interface IInjector { get(injectable: string): T; } -declare interface Chrome extends WithBreadcrumbsApi { +declare interface Chrome { + breadcrumbs: BreadcrumbsApi; addBasePath(path: T): T; dangerouslyGetActiveInjector(): Promise; getBasePath(): string; @@ -44,3 +45,4 @@ declare interface Chrome extends WithBreadcrumbsApi { declare const chrome: Chrome; export default chrome; +export { Breadcrumb } from './api/breadcrumbs';