Instantly share code, notes, and snippets.
Last active
April 20, 2023 13:58
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save sebelga/5996aa64b2fc58c1984bceb687a81c42 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | |
* or more contributor license agreements. Licensed under the Elastic License | |
* 2.0 and the Server Side Public License, v 1; you may not use this file except | |
* in compliance with, at your election, the Elastic License 2.0 or the Server | |
* Side Public License, v 1. | |
*/ | |
import type { RecursiveReadonly } from '@kbn/utility-types'; | |
import { BehaviorSubject, Observable } from 'rxjs'; | |
// ------------------------------------------------------- | |
// ------------------- URL SERVICE ----------------------- | |
// ------------------------------------------------------- | |
// List of all the pages that we can navigate to | |
const KIBANA_PAGE_IDS = [ | |
'dashboard.home', | |
'dashboard.create', | |
'maps.home', | |
'management.home', | |
'management.indexManagement.dataStreams' | |
] as const; | |
// Semantic naming: <pluginName>.<page> | |
// Embedded plugin: <pluginName>.<pluginName>.<page> (e.g. "management.indexManagement.dataStreams") | |
type KibanaPageId = typeof KIBANA_PAGE_IDS[number]; | |
interface UrlPageMeta { uri?: string; label: string } | |
interface PagesMeta { | |
pages: { | |
[key in KibanaPageId]: UrlPageMeta; | |
} | |
} | |
export const PAGES_META: PagesMeta = { | |
pages: { | |
'dashboard.home': { | |
uri: '/app/dashboards', | |
label: 'Dashboards', | |
}, | |
'dashboard.create': { | |
// we don't know the URI, the dashboard app will let us know | |
label: 'Create dashboard', | |
}, | |
'maps.home': { | |
uri: '/app/maps', | |
label: 'Maps', | |
}, | |
'management.home': { | |
uri: '/app/management', | |
label: 'Stack management', | |
}, | |
'management.indexManagement.dataStreams': { | |
// We don't know the URI, the indexManagement app will let us know | |
label: 'Data streams', | |
}, | |
} | |
} | |
// Make a copy when initializing | |
// Quick and dirty code. Here we would probably add an "isActive" flag to each object item | |
const pages = new BehaviorSubject<PagesMeta>({ ...PAGES_META }); | |
// Expose a handler to update the URIs and labels | |
const updatePageMeta = (pageId: KibanaPageId, meta: UrlPageMeta) => { | |
if (pages.getValue().pages[pageId].uri !== undefined) { | |
throw new Error(`Page [${pageId}] meta cannot be overriden.`); | |
} | |
pages.next({...pages.value, [pageId]: meta}); | |
} | |
// Observable getter | |
const getPages$ = (pageId: KibanaPageId): Observable<PagesMeta> => { | |
return pages.asObservable(); | |
} | |
// ---------------------------------------------------------- | |
// ------------------- MENU / NAV SERVICE ------------------- | |
// ---------------------------------------------------------- | |
/** | |
* The Menu/Nav service subscribes to the getPages$() observable. | |
* It derives from it: | |
* - URIs for each menu item | |
* - Default label for each menu item (can be overriden in MenuDefinition) | |
* - The active page id | |
*/ | |
export interface SectionItem { | |
name: string; | |
id?: KibanaPageId; | |
helpText?: string; // For possible tooltip | |
items?: RecursiveReadonly<MenuItem[]>; | |
} | |
export interface PageItem { | |
id: KibanaPageId; | |
label?: string; // Label can be overriden, otherwise uses the UrlPageMeta['label'] | |
items?: RecursiveReadonly<MenuItem[]>; | |
} | |
type MenuItem = SectionItem | PageItem; | |
export type MenuDefinition = RecursiveReadonly<MenuItem[]>; | |
// The menu definition is a simple list of Kibana page ids and sections | |
const menu: MenuDefinition = [ | |
{ | |
// SECTION 1 | |
name: 'Section 1', | |
helpText: 'Analyse your data', | |
items: [ | |
{ | |
id: 'dashboard.home', | |
items: [ | |
{ | |
id: 'dashboard.create', | |
label: 'Create dashboard now!', // Overrides the default label from PAGES_META constant | |
}, | |
], | |
}, | |
{ | |
id: 'maps.home', | |
}, | |
], | |
}, | |
// SECTION 2 | |
{ | |
name: 'Section 2', | |
helpText: 'Some tooltip info', | |
id: 'management.home', // The section title points to management home page | |
items: [ | |
{ | |
id: 'management.indexManagement.dataStreams', | |
}, | |
], | |
}, | |
]; | |
// public/plugin.ts | |
setup() { | |
/** | |
* Calling core.application.register will throw an error if | |
* there are ids in the KIBANA_PAGE_IDS constant whose id starts with the app id (e.g. "dashboard.") | |
* and the uri is empty (""). | |
*/ | |
core.application.register({ | |
id: DASHBOARD_APP_ID, // "dashboard" | |
title: 'Dashboard', | |
order: 2500, | |
... | |
}); | |
/** | |
* To avoid that, the app must provide URIs for each of the KibanaPageId under its domain | |
*/ | |
core.application.register({ | |
id: DASHBOARD_APP_ID, | |
... | |
navItems: { | |
[`${DASHBOARD_APP_ID}.create`]: { | |
uri: '#create', // will be appened to "/app/dashboards" base path | |
label: 'Create dashboard', // Optional. Overrides the default label. Can still be overriden in the MenuDefinition | |
} | |
} | |
}) | |
} | |
// At this stage the URL service can listen to URL changes and we know which KibanaPageId is active | |
// --> set its "isActive" flag to true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment