mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Move client-side application
service to packages (#139502)
* deletes unused utils file * just some fix while I see it * creating empty packages * moving all the things * package build success * start fixing usages * fix the scoped history type issue * export internal utils * add default for mock * fix test import * fix external import * start fixing external usages * more usages * more usages * more usages * More usages * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * fix integration test imports * fix more test types * remove public/utils from the core bundle * trying to import from the package * updating README's * remove unused test types from mock package * cleanup test types * use import type * add author to packages * more import type * remove dead path from some config * remove src/core/utils/index.ts (and pray) * update tsdoc * fix new file usage * fix paths Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6c4c78aaea
commit
383d8fab58
128 changed files with 2317 additions and 1081 deletions
|
@ -33,7 +33,7 @@ import { catchError, map, tap } from 'rxjs/operators';
|
|||
import { lastValueFrom, of } from 'rxjs';
|
||||
|
||||
import { CoreStart } from '@kbn/core/public';
|
||||
import { mountReactNode } from '@kbn/core/public/utils';
|
||||
import { mountReactNode } from '@kbn/core-mount-utils-browser-internal';
|
||||
import type { TimeRange } from '@kbn/es-query';
|
||||
import { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public';
|
||||
|
||||
|
|
12
package.json
12
package.json
|
@ -153,12 +153,18 @@
|
|||
"@kbn/core-analytics-server": "link:bazel-bin/packages/core/analytics/core-analytics-server",
|
||||
"@kbn/core-analytics-server-internal": "link:bazel-bin/packages/core/analytics/core-analytics-server-internal",
|
||||
"@kbn/core-analytics-server-mocks": "link:bazel-bin/packages/core/analytics/core-analytics-server-mocks",
|
||||
"@kbn/core-application-browser": "link:bazel-bin/packages/core/application/core-application-browser",
|
||||
"@kbn/core-application-browser-internal": "link:bazel-bin/packages/core/application/core-application-browser-internal",
|
||||
"@kbn/core-application-browser-mocks": "link:bazel-bin/packages/core/application/core-application-browser-mocks",
|
||||
"@kbn/core-application-common": "link:bazel-bin/packages/core/application/core-application-common",
|
||||
"@kbn/core-base-browser-internal": "link:bazel-bin/packages/core/base/core-base-browser-internal",
|
||||
"@kbn/core-base-browser-mocks": "link:bazel-bin/packages/core/base/core-base-browser-mocks",
|
||||
"@kbn/core-base-common": "link:bazel-bin/packages/core/base/core-base-common",
|
||||
"@kbn/core-base-common-internal": "link:bazel-bin/packages/core/base/core-base-common-internal",
|
||||
"@kbn/core-base-server-internal": "link:bazel-bin/packages/core/base/core-base-server-internal",
|
||||
"@kbn/core-base-server-mocks": "link:bazel-bin/packages/core/base/core-base-server-mocks",
|
||||
"@kbn/core-capabilities-browser-internal": "link:bazel-bin/packages/core/capabilities/core-capabilities-browser-internal",
|
||||
"@kbn/core-capabilities-browser-mocks": "link:bazel-bin/packages/core/capabilities/core-capabilities-browser-mocks",
|
||||
"@kbn/core-capabilities-common": "link:bazel-bin/packages/core/capabilities/core-capabilities-common",
|
||||
"@kbn/core-capabilities-server": "link:bazel-bin/packages/core/capabilities/core-capabilities-server",
|
||||
"@kbn/core-capabilities-server-internal": "link:bazel-bin/packages/core/capabilities/core-capabilities-server-internal",
|
||||
|
@ -819,6 +825,10 @@
|
|||
"@types/kbn__core-analytics-server": "link:bazel-bin/packages/core/analytics/core-analytics-server/npm_module_types",
|
||||
"@types/kbn__core-analytics-server-internal": "link:bazel-bin/packages/core/analytics/core-analytics-server-internal/npm_module_types",
|
||||
"@types/kbn__core-analytics-server-mocks": "link:bazel-bin/packages/core/analytics/core-analytics-server-mocks/npm_module_types",
|
||||
"@types/kbn__core-application-browser": "link:bazel-bin/packages/core/application/core-application-browser/npm_module_types",
|
||||
"@types/kbn__core-application-browser-internal": "link:bazel-bin/packages/core/application/core-application-browser-internal/npm_module_types",
|
||||
"@types/kbn__core-application-browser-mocks": "link:bazel-bin/packages/core/application/core-application-browser-mocks/npm_module_types",
|
||||
"@types/kbn__core-application-common": "link:bazel-bin/packages/core/application/core-application-common/npm_module_types",
|
||||
"@types/kbn__core-base-browser": "link:bazel-bin/packages/core/base/core-base-browser/npm_module_types",
|
||||
"@types/kbn__core-base-browser-internal": "link:bazel-bin/packages/core/base/core-base-browser-internal/npm_module_types",
|
||||
"@types/kbn__core-base-browser-mocks": "link:bazel-bin/packages/core/base/core-base-browser-mocks/npm_module_types",
|
||||
|
@ -827,6 +837,8 @@
|
|||
"@types/kbn__core-base-server": "link:bazel-bin/packages/core/base/core-base-server/npm_module_types",
|
||||
"@types/kbn__core-base-server-internal": "link:bazel-bin/packages/core/base/core-base-server-internal/npm_module_types",
|
||||
"@types/kbn__core-base-server-mocks": "link:bazel-bin/packages/core/base/core-base-server-mocks/npm_module_types",
|
||||
"@types/kbn__core-capabilities-browser-internal": "link:bazel-bin/packages/core/capabilities/core-capabilities-browser-internal/npm_module_types",
|
||||
"@types/kbn__core-capabilities-browser-mocks": "link:bazel-bin/packages/core/capabilities/core-capabilities-browser-mocks/npm_module_types",
|
||||
"@types/kbn__core-capabilities-common": "link:bazel-bin/packages/core/capabilities/core-capabilities-common/npm_module_types",
|
||||
"@types/kbn__core-capabilities-server": "link:bazel-bin/packages/core/capabilities/core-capabilities-server/npm_module_types",
|
||||
"@types/kbn__core-capabilities-server-internal": "link:bazel-bin/packages/core/capabilities/core-capabilities-server-internal/npm_module_types",
|
||||
|
|
|
@ -20,12 +20,18 @@ filegroup(
|
|||
"//packages/core/analytics/core-analytics-server:build",
|
||||
"//packages/core/analytics/core-analytics-server-internal:build",
|
||||
"//packages/core/analytics/core-analytics-server-mocks:build",
|
||||
"//packages/core/application/core-application-browser:build",
|
||||
"//packages/core/application/core-application-browser-internal:build",
|
||||
"//packages/core/application/core-application-browser-mocks:build",
|
||||
"//packages/core/application/core-application-common:build",
|
||||
"//packages/core/base/core-base-browser-internal:build",
|
||||
"//packages/core/base/core-base-browser-mocks:build",
|
||||
"//packages/core/base/core-base-common:build",
|
||||
"//packages/core/base/core-base-common-internal:build",
|
||||
"//packages/core/base/core-base-server-internal:build",
|
||||
"//packages/core/base/core-base-server-mocks:build",
|
||||
"//packages/core/capabilities/core-capabilities-browser-internal:build",
|
||||
"//packages/core/capabilities/core-capabilities-browser-mocks:build",
|
||||
"//packages/core/capabilities/core-capabilities-common:build",
|
||||
"//packages/core/capabilities/core-capabilities-server:build",
|
||||
"//packages/core/capabilities/core-capabilities-server-internal:build",
|
||||
|
@ -307,12 +313,18 @@ filegroup(
|
|||
"//packages/core/analytics/core-analytics-server:build_types",
|
||||
"//packages/core/analytics/core-analytics-server-internal:build_types",
|
||||
"//packages/core/analytics/core-analytics-server-mocks:build_types",
|
||||
"//packages/core/application/core-application-browser:build_types",
|
||||
"//packages/core/application/core-application-browser-internal:build_types",
|
||||
"//packages/core/application/core-application-browser-mocks:build_types",
|
||||
"//packages/core/application/core-application-common:build_types",
|
||||
"//packages/core/base/core-base-browser-internal:build_types",
|
||||
"//packages/core/base/core-base-browser-mocks:build_types",
|
||||
"//packages/core/base/core-base-common:build_types",
|
||||
"//packages/core/base/core-base-common-internal:build_types",
|
||||
"//packages/core/base/core-base-server-internal:build_types",
|
||||
"//packages/core/base/core-base-server-mocks:build_types",
|
||||
"//packages/core/capabilities/core-capabilities-browser-internal:build_types",
|
||||
"//packages/core/capabilities/core-capabilities-browser-mocks:build_types",
|
||||
"//packages/core/capabilities/core-capabilities-common:build_types",
|
||||
"//packages/core/capabilities/core-capabilities-server:build_types",
|
||||
"//packages/core/capabilities/core-capabilities-server-internal:build_types",
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||
|
||||
PKG_DIRNAME = "core-application-browser-internal"
|
||||
PKG_REQUIRE_NAME = "@kbn/core-application-browser-internal"
|
||||
|
||||
SOURCE_FILES = glob(
|
||||
[
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
"**/*.scss",
|
||||
],
|
||||
exclude = [
|
||||
"**/*.config.js",
|
||||
"**/*.mock.*",
|
||||
"**/*.test.*",
|
||||
"**/*.stories.*",
|
||||
"**/__snapshots__",
|
||||
"**/integration_tests",
|
||||
"**/mocks",
|
||||
"**/scripts",
|
||||
"**/storybook",
|
||||
"**/test_fixtures",
|
||||
"**/test_helpers",
|
||||
],
|
||||
)
|
||||
|
||||
SRCS = SOURCE_FILES
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = SRCS,
|
||||
)
|
||||
|
||||
NPM_MODULE_EXTRA_FILES = [
|
||||
"package.json",
|
||||
]
|
||||
|
||||
RUNTIME_DEPS = [
|
||||
"@npm//react",
|
||||
"@npm//react-router-dom",
|
||||
"@npm//react-use",
|
||||
"@npm//enzyme",
|
||||
"@npm//rxjs",
|
||||
"@npm//history",
|
||||
"@npm//@elastic/eui",
|
||||
"//packages/kbn-std",
|
||||
"//packages/kbn-i18n",
|
||||
"//packages/kbn-i18n-react",
|
||||
"//packages/core/application/core-application-common",
|
||||
]
|
||||
|
||||
TYPES_DEPS = [
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/jest",
|
||||
"@npm//@types/enzyme",
|
||||
"@npm//@types/react",
|
||||
"@npm//@types/react-router-dom",
|
||||
"@npm//react-use",
|
||||
"@npm//@types/history",
|
||||
"@npm//rxjs",
|
||||
"@npm//@elastic/eui",
|
||||
"//packages/kbn-utility-types:npm_module_types",
|
||||
"//packages/kbn-std:npm_module_types",
|
||||
"//packages/kbn-i18n:npm_module_types",
|
||||
"//packages/kbn-i18n-react:npm_module_types",
|
||||
"//packages/core/base/core-base-common:npm_module_types",
|
||||
"//packages/core/http/core-http-browser:npm_module_types",
|
||||
"//packages/core/capabilities/core-capabilities-common:npm_module_types",
|
||||
"//packages/core/theme/core-theme-browser:npm_module_types",
|
||||
"//packages/core/overlays/core-overlays-browser:npm_module_types",
|
||||
"//packages/core/mount-utils/core-mount-utils-browser:npm_module_types",
|
||||
"//packages/core/capabilities/core-capabilities-browser-internal:npm_module_types",
|
||||
"//packages/core/application/core-application-common:npm_module_types",
|
||||
"//packages/core/application/core-application-browser:npm_module_types",
|
||||
]
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_node",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
)
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_web",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
web = True,
|
||||
additional_args = [
|
||||
"--copy-files",
|
||||
"--quiet"
|
||||
],
|
||||
)
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig.json",
|
||||
deps = [
|
||||
"//:tsconfig.base.json",
|
||||
"//:tsconfig.bazel.json",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "tsc_types",
|
||||
args = ['--pretty'],
|
||||
srcs = SRCS,
|
||||
deps = TYPES_DEPS,
|
||||
declaration = True,
|
||||
declaration_map = True,
|
||||
emit_declaration_only = True,
|
||||
out_dir = "target_types",
|
||||
root_dir = ".",
|
||||
tsconfig = ":tsconfig",
|
||||
)
|
||||
|
||||
js_library(
|
||||
name = PKG_DIRNAME,
|
||||
srcs = NPM_MODULE_EXTRA_FILES,
|
||||
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_module",
|
||||
deps = [":" + PKG_DIRNAME],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build",
|
||||
srcs = [":npm_module"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm_types(
|
||||
name = "npm_module_types",
|
||||
srcs = SRCS,
|
||||
deps = [":tsc_types"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
tsconfig = ":tsconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build_types",
|
||||
srcs = [":npm_module_types"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
# @kbn/core-application-browser-internal
|
||||
|
||||
Contains the internal implementation and types of Core's browser-side `application` service.
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { ApplicationService } from './src/application_service';
|
||||
export { CoreScopedHistory } from './src/scoped_history';
|
||||
export type {
|
||||
InternalApplicationSetup,
|
||||
InternalApplicationStart,
|
||||
Mounter,
|
||||
ParsedAppUrl,
|
||||
} from './src/types';
|
||||
export {
|
||||
appendAppPath,
|
||||
getAppInfo,
|
||||
parseAppUrl,
|
||||
relativeToAbsolute,
|
||||
removeSlashes,
|
||||
} from './src/utils';
|
|
@ -13,12 +13,12 @@ import { createMemoryHistory, MemoryHistory } from 'history';
|
|||
|
||||
import { httpServiceMock } from '@kbn/core-http-browser-mocks';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { createRenderer } from './utils';
|
||||
import { ApplicationService } from '../application_service';
|
||||
import type { MockLifecycle } from '../test_types';
|
||||
import type { AppMountParameters, AppUpdater } from '@kbn/core-application-browser';
|
||||
import { overlayServiceMock } from '@kbn/core-overlays-browser-mocks';
|
||||
import type { AppMountParameters, AppUpdater } from '../types';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import type { MockLifecycle } from '../src/test_helpers/test_types';
|
||||
import { ApplicationService } from '../src/application_service';
|
||||
import { createRenderer } from './utils';
|
||||
|
||||
const flushPromises = () => new Promise((resolve) => setImmediate(resolve));
|
||||
|
|
@ -11,10 +11,10 @@ import { BehaviorSubject } from 'rxjs';
|
|||
import { createMemoryHistory, History, createHashHistory } from 'history';
|
||||
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { AppRouter, AppNotFound } from '../ui';
|
||||
import { MockedMounterMap, MockedMounterTuple } from '../test_types';
|
||||
import { AppStatus } from '@kbn/core-application-browser';
|
||||
import { AppRouter, AppNotFound } from '../src/ui';
|
||||
import { MockedMounterMap, MockedMounterTuple } from '../src/test_helpers/test_types';
|
||||
import { createRenderer, createAppMounter, getUnmounter } from './utils';
|
||||
import { AppStatus } from '../types';
|
||||
|
||||
describe('AppRouter', () => {
|
||||
let mounters: MockedMounterMap;
|
|
@ -10,9 +10,9 @@ import React, { ReactElement } from 'react';
|
|||
import { act } from 'react-dom/test-utils';
|
||||
import { mount } from 'enzyme';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import type { AppMountParameters } from '@kbn/core-application-browser';
|
||||
|
||||
import { AppMountParameters } from '../types';
|
||||
import { MockedMounterTuple, Mountable } from '../test_types';
|
||||
import { MockedMounterTuple, Mountable } from '../src/test_helpers/test_types';
|
||||
|
||||
type Dom = ReturnType<typeof mount> | null;
|
||||
type Renderer = () => Dom | Promise<Dom>;
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/core/application/core-application-browser-internal'],
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test/jest_integration',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/core/application/core-application-browser-internal'],
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@kbn/core-application-browser-internal",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "./target_node/index.js",
|
||||
"browser": "./target_web/index.js",
|
||||
"author": "Kibana Core",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||
}
|
|
@ -6,8 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { AppLeaveActionType } from '@kbn/core-application-browser';
|
||||
import { isConfirmAction, getLeaveAction } from './application_leave';
|
||||
import { AppLeaveActionType } from './types';
|
||||
|
||||
describe('isConfirmAction', () => {
|
||||
it('returns true if action is confirm', () => {
|
|
@ -7,12 +7,12 @@
|
|||
*/
|
||||
import type { ButtonColor } from '@elastic/eui';
|
||||
import {
|
||||
AppLeaveActionFactory,
|
||||
AppLeaveActionType,
|
||||
AppLeaveAction,
|
||||
AppLeaveConfirmAction,
|
||||
AppLeaveHandler,
|
||||
} from './types';
|
||||
type AppLeaveActionFactory,
|
||||
type AppLeaveAction,
|
||||
type AppLeaveConfirmAction,
|
||||
type AppLeaveHandler,
|
||||
} from '@kbn/core-application-browser';
|
||||
|
||||
const appLeaveActionFactory: AppLeaveActionFactory = {
|
||||
confirm(
|
|
@ -6,13 +6,13 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { capabilitiesServiceMock } from './capabilities/capabilities_service.mock';
|
||||
import { capabilitiesServiceMock } from '@kbn/core-capabilities-browser-mocks';
|
||||
|
||||
export const MockCapabilitiesService = capabilitiesServiceMock.create();
|
||||
export const CapabilitiesServiceConstructor = jest
|
||||
.fn()
|
||||
.mockImplementation(() => MockCapabilitiesService);
|
||||
jest.doMock('./capabilities', () => ({
|
||||
jest.doMock('@kbn/core-capabilities-browser-internal', () => ({
|
||||
CapabilitiesService: CapabilitiesServiceConstructor,
|
||||
}));
|
||||
|
|
@ -20,9 +20,16 @@ import { mount, shallow } from 'enzyme';
|
|||
import { httpServiceMock } from '@kbn/core-http-browser-mocks';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { overlayServiceMock } from '@kbn/core-overlays-browser-mocks';
|
||||
import { MockLifecycle } from './test_types';
|
||||
import { MockLifecycle } from './test_helpers/test_types';
|
||||
import { ApplicationService } from './application_service';
|
||||
import { App, AppDeepLink, AppNavLinkStatus, AppStatus, AppUpdater, PublicAppInfo } from './types';
|
||||
import {
|
||||
App,
|
||||
AppDeepLink,
|
||||
AppNavLinkStatus,
|
||||
AppStatus,
|
||||
AppUpdater,
|
||||
PublicAppInfo,
|
||||
} from '@kbn/core-application-browser';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
const createApp = (props: Partial<App>): App => {
|
|
@ -17,8 +17,6 @@ import type { HttpSetup, HttpStart } from '@kbn/core-http-browser';
|
|||
import type { Capabilities } from '@kbn/core-capabilities-common';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import type { OverlayStart } from '@kbn/core-overlays-browser';
|
||||
import { AppRouter } from './ui';
|
||||
import { CapabilitiesService } from './capabilities';
|
||||
import type {
|
||||
App,
|
||||
AppDeepLink,
|
||||
|
@ -26,13 +24,14 @@ import type {
|
|||
AppMount,
|
||||
AppUpdatableFields,
|
||||
AppUpdater,
|
||||
InternalApplicationSetup,
|
||||
InternalApplicationStart,
|
||||
Mounter,
|
||||
NavigateToAppOptions,
|
||||
NavigateToUrlOptions,
|
||||
} from './types';
|
||||
import { AppStatus, AppNavLinkStatus } from './types';
|
||||
} from '@kbn/core-application-browser';
|
||||
import { CapabilitiesService } from '@kbn/core-capabilities-browser-internal';
|
||||
import { AppStatus, AppNavLinkStatus } from '@kbn/core-application-browser';
|
||||
import { AppRouter } from './ui';
|
||||
import type { InternalApplicationSetup, InternalApplicationStart, Mounter } from './types';
|
||||
|
||||
import { getLeaveAction, isConfirmAction } from './application_leave';
|
||||
import { getUserConfirmationHandler } from './navigation_confirm';
|
||||
import { appendAppPath, parseAppUrl, relativeToAbsolute, getAppInfo } from './utils';
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { OverlayStart } from '..';
|
||||
import type { OverlayStart } from '@kbn/core-overlays-browser';
|
||||
|
||||
export type ConfirmHandlerCallback = (result: boolean) => void;
|
||||
export type ConfirmHandler = (message: string, callback: ConfirmHandlerCallback) => void;
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { ScopedHistory } from './scoped_history';
|
||||
import { CoreScopedHistory as ScopedHistory } from './scoped_history';
|
||||
import { createMemoryHistory, History } from 'history';
|
||||
import type { ConfirmHandler } from './navigation_confirm';
|
||||
|
|
@ -17,22 +17,15 @@ import {
|
|||
Href,
|
||||
Action,
|
||||
} from 'history';
|
||||
import type { ScopedHistory } from '@kbn/core-application-browser';
|
||||
|
||||
/**
|
||||
* A wrapper around a `History` instance that is scoped to a particular base path of the history stack. Behaves
|
||||
* similarly to the `basename` option except that this wrapper hides any history stack entries from outside the scope
|
||||
* of this base path.
|
||||
* Core's internal implementation of {@link ScopedHistory}
|
||||
*
|
||||
* This wrapper also allows Core and Plugins to share a single underlying global `History` instance without exposing
|
||||
* the history of other applications.
|
||||
*
|
||||
* The {@link ScopedHistory.createSubHistory | createSubHistory} method is particularly useful for applications that
|
||||
* contain any number of "sub-apps" which should not have access to the main application's history or basePath.
|
||||
*
|
||||
* @public
|
||||
* @internal Only exposed publicly for testing purpose.
|
||||
*/
|
||||
export class ScopedHistory<HistoryLocationState = unknown>
|
||||
implements History<HistoryLocationState>
|
||||
export class CoreScopedHistory<HistoryLocationState = unknown>
|
||||
implements ScopedHistory<HistoryLocationState>
|
||||
{
|
||||
/**
|
||||
* Tracks whether or not the user has left this history's scope. All methods throw errors if called after scope has
|
||||
|
@ -79,7 +72,7 @@ export class ScopedHistory<HistoryLocationState = unknown>
|
|||
* @param basePath the URL path scope for the sub history
|
||||
*/
|
||||
public createSubHistory = (basePath: string) => {
|
||||
return new ScopedHistory<HistoryLocationState>(this, basePath);
|
||||
return new CoreScopedHistory<HistoryLocationState>(this, basePath);
|
||||
};
|
||||
|
||||
/**
|
|
@ -6,12 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||
import { AppUnmount, Mounter } from './types';
|
||||
import { ApplicationService } from './application_service';
|
||||
import { AppUnmount } from '@kbn/core-application-browser';
|
||||
import { Mounter } from '../types';
|
||||
import { ApplicationService } from '../application_service';
|
||||
|
||||
/** @internal */
|
||||
export type ApplicationServiceContract = PublicMethodsOf<ApplicationService>;
|
||||
/** @internal */
|
||||
export type MockedUnmount = jest.Mocked<AppUnmount>;
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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 { Observable } from 'rxjs';
|
||||
import type { History } from 'history';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import type { PluginOpaqueId } from '@kbn/core-base-common';
|
||||
import type {
|
||||
App,
|
||||
AppMount,
|
||||
ApplicationSetup,
|
||||
ApplicationStart,
|
||||
} from '@kbn/core-application-browser';
|
||||
|
||||
/** @internal */
|
||||
export interface Mounter {
|
||||
appRoute: string;
|
||||
appBasePath: string;
|
||||
mount: AppMount;
|
||||
exactRoute: boolean;
|
||||
unmountBeforeMounting?: boolean;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface ParsedAppUrl {
|
||||
app: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface InternalApplicationSetup extends Pick<ApplicationSetup, 'registerAppUpdater'> {
|
||||
/**
|
||||
* Register an mountable application to the system.
|
||||
* @param plugin - opaque ID of the plugin that registers this application
|
||||
* @param app
|
||||
*/
|
||||
register<HistoryLocationState = unknown>(
|
||||
plugin: PluginOpaqueId,
|
||||
app: App<HistoryLocationState>
|
||||
): void;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface InternalApplicationStart extends ApplicationStart {
|
||||
// Internal APIs
|
||||
getComponent(): JSX.Element | null;
|
||||
|
||||
/**
|
||||
* The potential action menu set by the currently mounted app.
|
||||
* Consumed by the chrome header.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
currentActionMenu$: Observable<MountPoint | undefined>;
|
||||
|
||||
/**
|
||||
* The global history instance, exposed only to Core.
|
||||
* @internal
|
||||
*/
|
||||
history: History<unknown>;
|
||||
}
|
|
@ -11,10 +11,11 @@ import { act } from 'react-dom/test-utils';
|
|||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { type AppMountParameters, AppStatus } from '@kbn/core-application-browser';
|
||||
import { AppContainer } from './app_container';
|
||||
import { Mounter, AppMountParameters, AppStatus } from '../types';
|
||||
import type { Mounter } from '../types';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { ScopedHistory } from '../scoped_history';
|
||||
import { CoreScopedHistory as ScopedHistory } from '../scoped_history';
|
||||
|
||||
describe('AppContainer', () => {
|
||||
const appId = 'someApp';
|
|
@ -5,6 +5,7 @@
|
|||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import './app_container.scss';
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
|
@ -14,10 +15,15 @@ import { EuiLoadingElastic } from '@elastic/eui';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import type { CoreTheme } from '@kbn/core-theme-browser';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import { AppLeaveHandler, AppStatus, AppUnmount, Mounter } from '../types';
|
||||
import { APP_WRAPPER_CLASS } from '@kbn/core-application-common';
|
||||
import {
|
||||
AppStatus,
|
||||
type AppLeaveHandler,
|
||||
type AppUnmount,
|
||||
type ScopedHistory,
|
||||
} from '@kbn/core-application-browser';
|
||||
import type { Mounter } from '../types';
|
||||
import { AppNotFound } from './app_not_found_screen';
|
||||
import { ScopedHistory } from '../scoped_history';
|
||||
import { APP_WRAPPER_CLASS } from '../../../utils';
|
||||
|
||||
interface Props {
|
||||
/** Path application is mounted on without the global basePath */
|
|
@ -14,9 +14,10 @@ import useObservable from 'react-use/lib/useObservable';
|
|||
|
||||
import type { CoreTheme } from '@kbn/core-theme-browser';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import { AppLeaveHandler, AppStatus, Mounter } from '../types';
|
||||
import { type AppLeaveHandler, AppStatus } from '@kbn/core-application-browser';
|
||||
import type { Mounter } from '../types';
|
||||
import { AppContainer } from './app_container';
|
||||
import { ScopedHistory } from '../scoped_history';
|
||||
import { CoreScopedHistory } from '../scoped_history';
|
||||
|
||||
interface Props {
|
||||
mounters: Map<string, Mounter>;
|
||||
|
@ -43,7 +44,7 @@ export const AppRouter: FunctionComponent<Props> = ({
|
|||
}) => {
|
||||
const appStatuses = useObservable(appStatuses$, new Map());
|
||||
const createScopedHistory = useMemo(
|
||||
() => (appPath: string) => new ScopedHistory(history, appPath),
|
||||
() => (appPath: string) => new CoreScopedHistory(history, appPath),
|
||||
[history]
|
||||
);
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import { App, AppDeepLink, AppNavLinkStatus, AppStatus } from '../types';
|
||||
import { App, AppDeepLink, AppNavLinkStatus, AppStatus } from '@kbn/core-application-browser';
|
||||
import { getAppInfo } from './get_app_info';
|
||||
|
||||
describe('getAppInfo', () => {
|
|
@ -7,13 +7,13 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
App,
|
||||
AppNavLinkStatus,
|
||||
AppStatus,
|
||||
AppDeepLink,
|
||||
PublicAppInfo,
|
||||
PublicAppDeepLinkInfo,
|
||||
} from '../types';
|
||||
type App,
|
||||
type AppDeepLink,
|
||||
type PublicAppInfo,
|
||||
type PublicAppDeepLinkInfo,
|
||||
} from '@kbn/core-application-browser';
|
||||
|
||||
export function getAppInfo(app: App): PublicAppInfo {
|
||||
const { updater$, mount, navLinkStatus = AppNavLinkStatus.default, ...infos } = app;
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { BasePath } from '@kbn/core-http-browser-internal';
|
||||
import type { App } from '../types';
|
||||
import type { App } from '@kbn/core-application-browser';
|
||||
import { parseAppUrl } from './parse_app_url';
|
||||
|
||||
describe('parseAppUrl', () => {
|
|
@ -9,7 +9,8 @@
|
|||
import { getUrlOrigin } from '@kbn/std';
|
||||
import { resolve } from 'url';
|
||||
import type { IBasePath } from '@kbn/core-http-browser';
|
||||
import type { App, ParsedAppUrl } from '../types';
|
||||
import type { App } from '@kbn/core-application-browser';
|
||||
import type { ParsedAppUrl } from '../types';
|
||||
|
||||
/**
|
||||
* Parse given URL and return the associated app id and path if any app matches, or undefined if none do.
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.bazel.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "target_types",
|
||||
"rootDir": ".",
|
||||
"stripInternal": false,
|
||||
"types": [
|
||||
"jest",
|
||||
"node",
|
||||
"react"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||
|
||||
PKG_DIRNAME = "core-application-browser-mocks"
|
||||
PKG_REQUIRE_NAME = "@kbn/core-application-browser-mocks"
|
||||
|
||||
SOURCE_FILES = glob(
|
||||
[
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
exclude = [
|
||||
"**/*.config.js",
|
||||
"**/*.test.*",
|
||||
"**/*.stories.*",
|
||||
"**/__snapshots__",
|
||||
"**/integration_tests",
|
||||
"**/mocks",
|
||||
"**/scripts",
|
||||
"**/storybook",
|
||||
"**/test_fixtures",
|
||||
"**/test_helpers",
|
||||
],
|
||||
)
|
||||
|
||||
SRCS = SOURCE_FILES
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = SRCS,
|
||||
)
|
||||
|
||||
NPM_MODULE_EXTRA_FILES = [
|
||||
"package.json",
|
||||
]
|
||||
|
||||
RUNTIME_DEPS = [
|
||||
"//packages/kbn-std",
|
||||
"//packages/core/capabilities/core-capabilities-browser-mocks"
|
||||
]
|
||||
|
||||
TYPES_DEPS = [
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/jest",
|
||||
"@npm//@types/history",
|
||||
"@npm//rxjs",
|
||||
"//packages/kbn-std:npm_module_types",
|
||||
"//packages/core/mount-utils/core-mount-utils-browser:npm_module_types",
|
||||
"//packages/core/application/core-application-browser:npm_module_types",
|
||||
"//packages/core/application/core-application-browser-internal:npm_module_types",
|
||||
"//packages/core/capabilities/core-capabilities-browser-mocks:npm_module_types",
|
||||
"//packages/core/theme/core-theme-browser-mocks:npm_module_types",
|
||||
]
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_node",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
)
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_web",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
web = True,
|
||||
)
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig.json",
|
||||
deps = [
|
||||
"//:tsconfig.base.json",
|
||||
"//:tsconfig.bazel.json",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "tsc_types",
|
||||
args = ['--pretty'],
|
||||
srcs = SRCS,
|
||||
deps = TYPES_DEPS,
|
||||
declaration = True,
|
||||
declaration_map = True,
|
||||
emit_declaration_only = True,
|
||||
out_dir = "target_types",
|
||||
root_dir = ".",
|
||||
tsconfig = ":tsconfig",
|
||||
)
|
||||
|
||||
js_library(
|
||||
name = PKG_DIRNAME,
|
||||
srcs = NPM_MODULE_EXTRA_FILES,
|
||||
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_module",
|
||||
deps = [":" + PKG_DIRNAME],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build",
|
||||
srcs = [":npm_module"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm_types(
|
||||
name = "npm_module_types",
|
||||
srcs = SRCS,
|
||||
deps = [":tsc_types"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
tsconfig = ":tsconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build_types",
|
||||
srcs = [":npm_module_types"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,5 @@
|
|||
# @kbn/core-application-browser-mocks
|
||||
|
||||
Contains the mocks for Core's browser-side `application` service.
|
||||
- `applicationServiceMock`
|
||||
- `scopedHistoryMock`
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export { applicationServiceMock } from './src/application_service.mock';
|
||||
export type { ScopedHistoryMock } from './src/scoped_history.mock';
|
||||
export { scopedHistoryMock } from './src/scoped_history.mock';
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/core/application/core-application-browser-mocks'],
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@kbn/core-application-browser-mocks",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "./target_node/index.js",
|
||||
"browser": "./target_web/index.js",
|
||||
"author": "Kibana Core",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||
}
|
|
@ -9,19 +9,24 @@
|
|||
import { History } from 'history';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
|
||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import { capabilitiesServiceMock } from './capabilities/capabilities_service.mock';
|
||||
import { capabilitiesServiceMock } from '@kbn/core-capabilities-browser-mocks';
|
||||
import { themeServiceMock } from '@kbn/core-theme-browser-mocks';
|
||||
import { scopedHistoryMock } from './scoped_history.mock';
|
||||
import {
|
||||
ApplicationSetup,
|
||||
InternalApplicationStart,
|
||||
ApplicationStart,
|
||||
InternalApplicationSetup,
|
||||
PublicAppInfo,
|
||||
AppMountParameters,
|
||||
} from './types';
|
||||
import { ApplicationServiceContract } from './test_types';
|
||||
} from '@kbn/core-application-browser';
|
||||
import type {
|
||||
ApplicationService,
|
||||
InternalApplicationStart,
|
||||
InternalApplicationSetup,
|
||||
} from '@kbn/core-application-browser-internal';
|
||||
|
||||
type ApplicationServiceContract = PublicMethodsOf<ApplicationService>;
|
||||
|
||||
const createSetupContractMock = (): jest.Mocked<ApplicationSetup> => ({
|
||||
register: jest.fn(),
|
||||
|
@ -84,7 +89,7 @@ const createInternalStartContractMock = (): jest.Mocked<InternalApplicationStart
|
|||
};
|
||||
};
|
||||
|
||||
const createAppMountParametersMock = (parts: Partial<AppMountParameters>) => {
|
||||
const createAppMountParametersMock = (parts: Partial<AppMountParameters> = {}) => {
|
||||
const mock: AppMountParameters = {
|
||||
element: document.createElement('div'),
|
||||
history: scopedHistoryMock.create(),
|
|
@ -6,8 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Location } from 'history';
|
||||
import { ScopedHistory } from './scoped_history';
|
||||
import type { Location } from 'history';
|
||||
import type { ScopedHistory } from '@kbn/core-application-browser';
|
||||
|
||||
export type ScopedHistoryMock = jest.Mocked<ScopedHistory>;
|
||||
|
||||
|
@ -18,7 +18,7 @@ const createMock = ({
|
|||
key,
|
||||
state,
|
||||
}: Partial<Location> = {}) => {
|
||||
const mock: jest.Mocked<Pick<ScopedHistory, keyof ScopedHistory>> = {
|
||||
const mock: ScopedHistoryMock = {
|
||||
block: jest.fn(),
|
||||
createHref: jest.fn(),
|
||||
createSubHistory: jest.fn(),
|
||||
|
@ -39,9 +39,7 @@ const createMock = ({
|
|||
},
|
||||
};
|
||||
|
||||
// jest.Mocked still expects private methods and properties to be present, even
|
||||
// if not part of the public contract.
|
||||
return mock as ScopedHistoryMock;
|
||||
return mock;
|
||||
};
|
||||
|
||||
export const scopedHistoryMock = {
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.bazel.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "target_types",
|
||||
"rootDir": ".",
|
||||
"stripInternal": false,
|
||||
"types": [
|
||||
"jest",
|
||||
"node",
|
||||
"react"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
]
|
||||
}
|
122
packages/core/application/core-application-browser/BUILD.bazel
Normal file
122
packages/core/application/core-application-browser/BUILD.bazel
Normal file
|
@ -0,0 +1,122 @@
|
|||
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||
|
||||
PKG_DIRNAME = "core-application-browser"
|
||||
PKG_REQUIRE_NAME = "@kbn/core-application-browser"
|
||||
|
||||
SOURCE_FILES = glob(
|
||||
[
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
exclude = [
|
||||
"**/*.config.js",
|
||||
"**/*.mock.*",
|
||||
"**/*.test.*",
|
||||
"**/*.stories.*",
|
||||
"**/__snapshots__",
|
||||
"**/integration_tests",
|
||||
"**/mocks",
|
||||
"**/scripts",
|
||||
"**/storybook",
|
||||
"**/test_fixtures",
|
||||
"**/test_helpers",
|
||||
],
|
||||
)
|
||||
|
||||
SRCS = SOURCE_FILES
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = SRCS,
|
||||
)
|
||||
|
||||
NPM_MODULE_EXTRA_FILES = [
|
||||
"package.json",
|
||||
]
|
||||
|
||||
RUNTIME_DEPS = [
|
||||
]
|
||||
|
||||
TYPES_DEPS = [
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/jest",
|
||||
"@npm//@types/history",
|
||||
"@npm//@elastic/eui",
|
||||
"@npm//rxjs",
|
||||
"//packages/kbn-utility-types:npm_module_types",
|
||||
"//packages/core/theme/core-theme-browser:npm_module_types",
|
||||
"//packages/core/mount-utils/core-mount-utils-browser:npm_module_types",
|
||||
"//packages/core/capabilities/core-capabilities-common:npm_module_types",
|
||||
"//packages/core/application/core-application-common:npm_module_types",
|
||||
]
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_node",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
)
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_web",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
web = True,
|
||||
)
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig.json",
|
||||
deps = [
|
||||
"//:tsconfig.base.json",
|
||||
"//:tsconfig.bazel.json",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "tsc_types",
|
||||
args = ['--pretty'],
|
||||
srcs = SRCS,
|
||||
deps = TYPES_DEPS,
|
||||
declaration = True,
|
||||
declaration_map = True,
|
||||
emit_declaration_only = True,
|
||||
out_dir = "target_types",
|
||||
root_dir = ".",
|
||||
tsconfig = ":tsconfig",
|
||||
)
|
||||
|
||||
js_library(
|
||||
name = PKG_DIRNAME,
|
||||
srcs = NPM_MODULE_EXTRA_FILES,
|
||||
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_module",
|
||||
deps = [":" + PKG_DIRNAME],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build",
|
||||
srcs = [":npm_module"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm_types(
|
||||
name = "npm_module_types",
|
||||
srcs = SRCS,
|
||||
deps = [":tsc_types"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
tsconfig = ":tsconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build_types",
|
||||
srcs = [":npm_module_types"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
# @kbn/core-application-browser
|
||||
|
||||
Contains the public type for Core's browser-side `application` service.
|
|
@ -6,30 +6,29 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { ApplicationService } from './application_service';
|
||||
export { ScopedHistory } from './scoped_history';
|
||||
export { AppNavLinkStatus, AppStatus } from './types';
|
||||
export { AppLeaveActionType } from './src/app_leave';
|
||||
export type {
|
||||
AppLeaveAction,
|
||||
AppLeaveActionFactory,
|
||||
AppLeaveConfirmAction,
|
||||
AppLeaveDefaultAction,
|
||||
AppLeaveHandler,
|
||||
} from './src/app_leave';
|
||||
export type { AppMount, AppMountParameters, AppUnmount } from './src/app_mount';
|
||||
export type {
|
||||
App,
|
||||
AppMount,
|
||||
AppUnmount,
|
||||
AppMountParameters,
|
||||
AppUpdatableFields,
|
||||
AppNavOptions,
|
||||
AppUpdater,
|
||||
AppDeepLink,
|
||||
PublicAppInfo,
|
||||
AppNavOptions,
|
||||
PublicAppDeepLinkInfo,
|
||||
AppUpdater,
|
||||
AppUpdatableFields,
|
||||
} from './src/application';
|
||||
export { AppNavLinkStatus, AppStatus } from './src/application';
|
||||
export type {
|
||||
ApplicationSetup,
|
||||
ApplicationStart,
|
||||
AppLeaveHandler,
|
||||
AppLeaveActionType,
|
||||
AppLeaveAction,
|
||||
AppLeaveDefaultAction,
|
||||
AppLeaveConfirmAction,
|
||||
NavigateToAppOptions,
|
||||
NavigateToUrlOptions,
|
||||
PublicAppInfo,
|
||||
PublicAppDeepLinkInfo,
|
||||
// Internal types
|
||||
InternalApplicationSetup,
|
||||
InternalApplicationStart,
|
||||
} from './types';
|
||||
} from './src/contracts';
|
||||
export type { ScopedHistory } from './src/scoped_history';
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/core/application/core-application-browser'],
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@kbn/core-application-browser",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "./target_node/index.js",
|
||||
"browser": "./target_web/index.js",
|
||||
"author": "Kibana Core",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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 { ButtonColor } from '@elastic/eui';
|
||||
|
||||
/**
|
||||
* A handler that will be executed before leaving the application, either when
|
||||
* going to another application or when closing the browser tab or manually changing
|
||||
* the url.
|
||||
* Should return `confirm` to prompt a message to the user before leaving the page, or `default`
|
||||
* to keep the default behavior (doing nothing).
|
||||
*
|
||||
* See {@link AppMountParameters} for detailed usage examples.
|
||||
*
|
||||
* @public
|
||||
* @deprecated {@link AppMountParameters.onAppLeave} has been deprecated in favor of {@link ScopedHistory.block}
|
||||
* @removeBy 8.8.0
|
||||
*/
|
||||
export type AppLeaveHandler = (
|
||||
factory: AppLeaveActionFactory,
|
||||
nextAppId?: string
|
||||
) => AppLeaveAction;
|
||||
|
||||
/**
|
||||
* Possible type of actions on application leave.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export enum AppLeaveActionType {
|
||||
confirm = 'confirm',
|
||||
default = 'default',
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to return from a {@link AppLeaveHandler} to execute the default
|
||||
* behaviour when leaving the application.
|
||||
*
|
||||
* See {@link AppLeaveActionFactory}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface AppLeaveDefaultAction {
|
||||
type: AppLeaveActionType.default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to return from a {@link AppLeaveHandler} to show a confirmation
|
||||
* message when trying to leave an application.
|
||||
*
|
||||
* See {@link AppLeaveActionFactory}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface AppLeaveConfirmAction {
|
||||
type: AppLeaveActionType.confirm;
|
||||
text: string;
|
||||
title?: string;
|
||||
confirmButtonText?: string;
|
||||
buttonColor?: ButtonColor;
|
||||
callback?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible actions to return from a {@link AppLeaveHandler}
|
||||
*
|
||||
* See {@link AppLeaveConfirmAction} and {@link AppLeaveDefaultAction}
|
||||
*
|
||||
* @public
|
||||
* */
|
||||
export type AppLeaveAction = AppLeaveDefaultAction | AppLeaveConfirmAction;
|
||||
|
||||
/**
|
||||
* Factory provided when invoking a {@link AppLeaveHandler} to retrieve the {@link AppLeaveAction} to execute.
|
||||
*/
|
||||
export interface AppLeaveActionFactory {
|
||||
/**
|
||||
* Returns a confirm action, resulting on prompting a message to the user before leaving the
|
||||
* application, allowing him to choose if he wants to stay on the app or confirm that he
|
||||
* wants to leave.
|
||||
*
|
||||
* @param text The text to display in the confirmation message
|
||||
* @param title (optional) title to display in the confirmation message
|
||||
* @param callback (optional) to know that the user want to stay on the page
|
||||
* @param confirmButtonText (optional) text for the confirmation button
|
||||
* @param buttonColor (optional) color for the confirmation button
|
||||
* so we can show to the user the right UX for him to saved his/her/their changes
|
||||
*/
|
||||
confirm(
|
||||
text: string,
|
||||
title?: string,
|
||||
callback?: () => void,
|
||||
confirmButtonText?: string,
|
||||
buttonColor?: ButtonColor
|
||||
): AppLeaveConfirmAction;
|
||||
|
||||
/**
|
||||
* Returns a default action, resulting on executing the default behavior when
|
||||
* the user tries to leave an application
|
||||
*/
|
||||
default(): AppLeaveDefaultAction;
|
||||
}
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* 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 { Observable } from 'rxjs';
|
||||
import type { CoreTheme } from '@kbn/core-theme-browser';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import type { AppLeaveHandler } from './app_leave';
|
||||
import type { ScopedHistory } from './scoped_history';
|
||||
|
||||
/**
|
||||
* A mount function called when the user navigates to this app's route.
|
||||
*
|
||||
* @param params {@link AppMountParameters}
|
||||
* @returns An unmounting function that will be called to unmount the application. See {@link AppUnmount}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type AppMount<HistoryLocationState = unknown> = (
|
||||
params: AppMountParameters<HistoryLocationState>
|
||||
) => AppUnmount | Promise<AppUnmount>;
|
||||
|
||||
/**
|
||||
* A function called when an application should be unmounted from the page. This function should be synchronous.
|
||||
* @public
|
||||
*/
|
||||
export type AppUnmount = () => void;
|
||||
|
||||
/** @public */
|
||||
export interface AppMountParameters<HistoryLocationState = unknown> {
|
||||
/**
|
||||
* The container element to render the application into.
|
||||
*/
|
||||
element: HTMLElement;
|
||||
|
||||
/**
|
||||
* A scoped history instance for your application. Should be used to wire up
|
||||
* your applications Router.
|
||||
*
|
||||
* @example
|
||||
* How to configure react-router with a base path:
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* setup({ application }) {
|
||||
* application.register({
|
||||
* id: 'my-app',
|
||||
* appRoute: '/my-app',
|
||||
* async mount(params) {
|
||||
* const { renderApp } = await import('./application');
|
||||
* return renderApp(params);
|
||||
* },
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { Router, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ element, history }: AppMountParameters) => {
|
||||
* ReactDOM.render(
|
||||
* <Router history={history}>
|
||||
* <Route path="/" exact component={HomePage} />
|
||||
* </Router>,
|
||||
* element
|
||||
* );
|
||||
*
|
||||
* return () => ReactDOM.unmountComponentAtNode(element);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
history: ScopedHistory<HistoryLocationState>;
|
||||
|
||||
/**
|
||||
* The route path for configuring navigation to the application.
|
||||
* This string should not include the base path from HTTP.
|
||||
*
|
||||
* @deprecated Use {@link AppMountParameters.history} instead.
|
||||
* @removeBy 8.8.0
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* How to configure react-router with a base path:
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* setup({ application }) {
|
||||
* application.register({
|
||||
* id: 'my-app',
|
||||
* appRoute: '/my-app',
|
||||
* async mount(params) {
|
||||
* const { renderApp } = await import('./application');
|
||||
* return renderApp(params);
|
||||
* },
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { BrowserRouter, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ appBasePath, element }: AppMountParameters) => {
|
||||
* ReactDOM.render(
|
||||
* // pass `appBasePath` to `basename`
|
||||
* <BrowserRouter basename={appBasePath}>
|
||||
* <Route path="/" exact component={HomePage} />
|
||||
* </BrowserRouter>,
|
||||
* element
|
||||
* );
|
||||
*
|
||||
* return () => ReactDOM.unmountComponentAtNode(element);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
appBasePath: string;
|
||||
|
||||
/**
|
||||
* A function that can be used to register a handler that will be called
|
||||
* when the user is leaving the current application, allowing to
|
||||
* prompt a confirmation message before actually changing the page.
|
||||
*
|
||||
* This will be called either when the user goes to another application, or when
|
||||
* trying to close the tab or manually changing the url.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { BrowserRouter, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ element, history, onAppLeave }: AppMountParameters) => {
|
||||
* const { renderApp, hasUnsavedChanges } = await import('./application');
|
||||
* onAppLeave(actions => {
|
||||
* if(hasUnsavedChanges()) {
|
||||
* return actions.confirm('Some changes were not saved. Are you sure you want to leave?');
|
||||
* }
|
||||
* return actions.default();
|
||||
* });
|
||||
* return renderApp({ element, history });
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @deprecated {@link ScopedHistory.block} should be used instead.
|
||||
* @removeBy 8.8.0
|
||||
*/
|
||||
onAppLeave: (handler: AppLeaveHandler) => void;
|
||||
|
||||
/**
|
||||
* A function that can be used to set the mount point used to populate the application action container
|
||||
* in the chrome header.
|
||||
*
|
||||
* Calling the handler multiple time will erase the current content of the action menu with the mount from the latest call.
|
||||
* Calling the handler with `undefined` will unmount the current mount point.
|
||||
* Calling the handler after the application has been unmounted will have no effect.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { BrowserRouter, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ element, history, setHeaderActionMenu }: AppMountParameters) => {
|
||||
* const { renderApp } = await import('./application');
|
||||
* const { renderActionMenu } = await import('./action_menu');
|
||||
* setHeaderActionMenu((element) => {
|
||||
* return renderActionMenu(element);
|
||||
* })
|
||||
* return renderApp({ element, history });
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
setHeaderActionMenu: (menuMount: MountPoint | undefined) => void;
|
||||
|
||||
/**
|
||||
* An observable emitting {@link CoreTheme | Core's theme}.
|
||||
* Should be used when mounting the application to include theme information.
|
||||
*
|
||||
* @example
|
||||
* When mounting a react application:
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
*
|
||||
* import { AppMountParameters } from 'src/core/public';
|
||||
* import { wrapWithTheme } from 'src/plugins/kibana_react';
|
||||
* import { MyApp } from './app';
|
||||
*
|
||||
* export renderApp = ({ element, theme$ }: AppMountParameters) => {
|
||||
* ReactDOM.render(wrapWithTheme(<MyApp/>, theme$), element);
|
||||
* return () => ReactDOM.unmountComponentAtNode(element);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
theme$: Observable<CoreTheme>;
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* 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 { Observable } from 'rxjs';
|
||||
import type { Capabilities } from '@kbn/core-capabilities-common';
|
||||
import type { AppCategory } from '@kbn/core-application-common';
|
||||
import type { AppMount } from './app_mount';
|
||||
|
||||
/**
|
||||
* Accessibility status of an application.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export enum AppStatus {
|
||||
/**
|
||||
* Application is accessible.
|
||||
*/
|
||||
accessible = 0,
|
||||
/**
|
||||
* Application is not accessible.
|
||||
*/
|
||||
inaccessible = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* Status of the application's navLink.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export enum AppNavLinkStatus {
|
||||
/**
|
||||
* The application navLink will be `visible` if the application's {@link AppStatus} is set to `accessible`
|
||||
* and `hidden` if the application status is set to `inaccessible`.
|
||||
*/
|
||||
default = 0,
|
||||
/**
|
||||
* The application navLink is visible and clickable in the navigation bar.
|
||||
*/
|
||||
visible = 1,
|
||||
/**
|
||||
* The application navLink is visible but inactive and not clickable in the navigation bar.
|
||||
*/
|
||||
disabled = 2,
|
||||
/**
|
||||
* The application navLink does not appear in the navigation bar.
|
||||
*/
|
||||
hidden = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* App navigation menu options
|
||||
* @public
|
||||
*/
|
||||
export interface AppNavOptions {
|
||||
/**
|
||||
* An ordinal used to sort nav links relative to one another for display.
|
||||
*/
|
||||
order?: number;
|
||||
|
||||
/**
|
||||
* A tooltip shown when hovering over app link.
|
||||
*/
|
||||
tooltip?: string;
|
||||
|
||||
/**
|
||||
* A EUI iconType that will be used for the app's icon. This icon
|
||||
* takes precedence over the `icon` property.
|
||||
*/
|
||||
euiIconType?: string;
|
||||
|
||||
/**
|
||||
* A URL to an image file used as an icon. Used as a fallback
|
||||
* if `euiIconType` is not provided.
|
||||
*/
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updater for applications.
|
||||
* see {@link ApplicationSetup}
|
||||
* @public
|
||||
*/
|
||||
export type AppUpdater = (app: App) => Partial<AppUpdatableFields> | undefined;
|
||||
|
||||
/**
|
||||
* Defines the list of fields that can be updated via an {@link AppUpdater}.
|
||||
* @public
|
||||
*/
|
||||
export type AppUpdatableFields = Pick<
|
||||
App,
|
||||
'status' | 'navLinkStatus' | 'searchable' | 'tooltip' | 'defaultPath' | 'deepLinks'
|
||||
>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface App<HistoryLocationState = unknown> extends AppNavOptions {
|
||||
/**
|
||||
* The unique identifier of the application.
|
||||
*
|
||||
* Can only be composed of alphanumeric characters, `-`, `:` and `_`
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The title of the application.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* The category definition of the product
|
||||
* See {@link AppCategory}
|
||||
* See DEFAULT_APP_CATEGORIES for more reference
|
||||
*/
|
||||
category?: AppCategory;
|
||||
|
||||
/**
|
||||
* The initial status of the application.
|
||||
* Defaulting to `accessible`
|
||||
*/
|
||||
status?: AppStatus;
|
||||
|
||||
/**
|
||||
* The initial status of the application's navLink.
|
||||
* Defaulting to `visible` if `status` is `accessible` and `hidden` if status is `inaccessible`
|
||||
* See {@link AppNavLinkStatus}
|
||||
*/
|
||||
navLinkStatus?: AppNavLinkStatus;
|
||||
|
||||
/**
|
||||
* The initial flag to determine if the application is searchable in the global search.
|
||||
* Defaulting to `true` if `navLinkStatus` is `visible` or omitted.
|
||||
*/
|
||||
searchable?: boolean;
|
||||
|
||||
/**
|
||||
* Allow to define the default path a user should be directed to when navigating to the app.
|
||||
* When defined, this value will be used as a default for the `path` option when calling {@link ApplicationStart.navigateToApp | navigateToApp}`,
|
||||
* and will also be appended to the {@link ChromeNavLink | application navLink} in the navigation bar.
|
||||
*/
|
||||
defaultPath?: string;
|
||||
|
||||
/**
|
||||
* An {@link AppUpdater} observable that can be used to update the application {@link AppUpdatableFields} at runtime.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* How to update an application navLink at runtime
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* private appUpdater = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
*
|
||||
* setup({ application }) {
|
||||
* application.register({
|
||||
* id: 'my-app',
|
||||
* title: 'My App',
|
||||
* updater$: this.appUpdater,
|
||||
* async mount(params) {
|
||||
* const { renderApp } = await import('./application');
|
||||
* return renderApp(params);
|
||||
* },
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* start() {
|
||||
* // later, when the navlink needs to be updated
|
||||
* appUpdater.next(() => {
|
||||
* navLinkStatus: AppNavLinkStatus.disabled,
|
||||
* })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
updater$?: Observable<AppUpdater>;
|
||||
|
||||
/**
|
||||
* Custom capabilities defined by the app.
|
||||
*/
|
||||
capabilities?: Partial<Capabilities>;
|
||||
|
||||
/**
|
||||
* Hide the UI chrome when the application is mounted. Defaults to `false`.
|
||||
* Takes precedence over chrome service visibility settings.
|
||||
*/
|
||||
chromeless?: boolean;
|
||||
|
||||
/**
|
||||
* A mount function called when the user navigates to this app's route.
|
||||
*/
|
||||
mount: AppMount<HistoryLocationState>;
|
||||
|
||||
/**
|
||||
* Override the application's routing path from `/app/${id}`.
|
||||
* Must be unique across registered applications. Should not include the
|
||||
* base path from HTTP.
|
||||
*/
|
||||
appRoute?: string;
|
||||
|
||||
/**
|
||||
* If set to true, the application's route will only be checked against an exact match. Defaults to `false`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* core.application.register({
|
||||
* id: 'my_app',
|
||||
* title: 'My App',
|
||||
* exactRoute: true,
|
||||
* mount: () => { ... },
|
||||
* })
|
||||
*
|
||||
* // '[basePath]/app/my_app' will be matched
|
||||
* // '[basePath]/app/my_app/some/path' will not be matched
|
||||
* ```
|
||||
*/
|
||||
exactRoute?: boolean;
|
||||
|
||||
/** Optional keywords to match with in deep links search. Omit if this part of the hierarchy does not have a page URL. */
|
||||
keywords?: string[];
|
||||
|
||||
/**
|
||||
* Input type for registering secondary in-app locations for an application.
|
||||
*
|
||||
* Deep links must include at least one of `path` or `deepLinks`. A deep link that does not have a `path`
|
||||
* represents a topological level in the application's hierarchy, but does not have a destination URL that is
|
||||
* user-accessible.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* core.application.register({
|
||||
* id: 'my_app',
|
||||
* title: 'Translated title',
|
||||
* keywords: ['translated keyword1', 'translated keyword2'],
|
||||
* deepLinks: [
|
||||
* {
|
||||
* id: 'sub1',
|
||||
* title: 'Sub1',
|
||||
* path: '/sub1',
|
||||
* keywords: ['subpath1'],
|
||||
* },
|
||||
* {
|
||||
* id: 'sub2',
|
||||
* title: 'Sub2',
|
||||
* deepLinks: [
|
||||
* {
|
||||
* id: 'subsub',
|
||||
* title: 'SubSub',
|
||||
* path: '/sub2/sub',
|
||||
* keywords: ['subpath2'],
|
||||
* },
|
||||
* ],
|
||||
* },
|
||||
* ],
|
||||
* mount: () => { ... }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
deepLinks?: AppDeepLink[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Public information about a registered app's {@link AppDeepLink | deepLinks}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type PublicAppDeepLinkInfo = Omit<
|
||||
AppDeepLink,
|
||||
'deepLinks' | 'keywords' | 'navLinkStatus' | 'searchable'
|
||||
> & {
|
||||
deepLinks: PublicAppDeepLinkInfo[];
|
||||
keywords: string[];
|
||||
navLinkStatus: AppNavLinkStatus;
|
||||
searchable: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Input type for registering secondary in-app locations for an application.
|
||||
*
|
||||
* Deep links must include at least one of `path` or `deepLinks`. A deep link that does not have a `path`
|
||||
* represents a topological level in the application's hierarchy, but does not have a destination URL that is
|
||||
* user-accessible.
|
||||
* @public
|
||||
*/
|
||||
export type AppDeepLink = {
|
||||
/** Identifier to represent this sublink, should be unique for this application */
|
||||
id: string;
|
||||
/** Title to label represent this deep link */
|
||||
title: string;
|
||||
/** Optional keywords to match with in deep links search. Omit if this part of the hierarchy does not have a page URL. */
|
||||
keywords?: string[];
|
||||
/** Optional status of the chrome navigation, defaults to `hidden` */
|
||||
navLinkStatus?: AppNavLinkStatus;
|
||||
/** Optional flag to determine if the link is searchable in the global search. Defaulting to `true` if `navLinkStatus` is `visible` or omitted */
|
||||
searchable?: boolean;
|
||||
} & AppNavOptions &
|
||||
(
|
||||
| {
|
||||
/** URL path to access this link, relative to the application's appRoute. */
|
||||
path: string;
|
||||
/** Optional array of links that are 'underneath' this section in the hierarchy */
|
||||
deepLinks?: AppDeepLink[];
|
||||
}
|
||||
| {
|
||||
/** Optional path to access this section. Omit if this part of the hierarchy does not have a page URL. */
|
||||
path?: string;
|
||||
/** Array links that are 'underneath' this section in this hierarchy. */
|
||||
deepLinks: AppDeepLink[];
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Public information about a registered {@link App | application}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type PublicAppInfo = Omit<
|
||||
App,
|
||||
'mount' | 'updater$' | 'keywords' | 'deepLinks' | 'searchable'
|
||||
> & {
|
||||
// remove optional on fields populated with default values
|
||||
status: AppStatus;
|
||||
navLinkStatus: AppNavLinkStatus;
|
||||
appRoute: string;
|
||||
keywords: string[];
|
||||
deepLinks: PublicAppDeepLinkInfo[];
|
||||
searchable: boolean;
|
||||
};
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* 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 { Observable } from 'rxjs';
|
||||
import type { RecursiveReadonly } from '@kbn/utility-types';
|
||||
import type { Capabilities } from '@kbn/core-capabilities-common';
|
||||
import type { App, AppUpdater, PublicAppInfo } from './application';
|
||||
|
||||
/** @public */
|
||||
export interface ApplicationSetup {
|
||||
/**
|
||||
* Register an mountable application to the system.
|
||||
* @param app - an {@link App}
|
||||
* @typeParam HistoryLocationState - shape of the `History` state on {@link AppMountParameters.history}, defaults to `unknown`.
|
||||
*/
|
||||
register<HistoryLocationState = unknown>(app: App<HistoryLocationState>): void;
|
||||
|
||||
/**
|
||||
* Register an application updater that can be used to change the {@link AppUpdatableFields} fields
|
||||
* of all applications at runtime.
|
||||
*
|
||||
* This is meant to be used by plugins that needs to updates the whole list of applications.
|
||||
* To only updates a specific application, use the `updater$` property of the registered application instead.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* How to register an application updater that disables some applications:
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* setup({ application }) {
|
||||
* application.registerAppUpdater(
|
||||
* new BehaviorSubject<AppUpdater>(app => {
|
||||
* if (myPluginApi.shouldDisable(app))
|
||||
* return {
|
||||
* status: AppStatus.inaccessible,
|
||||
* };
|
||||
* })
|
||||
* );
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
registerAppUpdater(appUpdater$: Observable<AppUpdater>): void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface ApplicationStart {
|
||||
/**
|
||||
* Gets the read-only capabilities.
|
||||
*/
|
||||
capabilities: RecursiveReadonly<Capabilities>;
|
||||
|
||||
/**
|
||||
* Observable emitting the list of currently registered apps and their associated status.
|
||||
*
|
||||
* @remarks
|
||||
* Applications disabled by {@link Capabilities} will not be present in the map. Applications manually disabled from
|
||||
* the client-side using an {@link AppUpdater | application updater} are present, with their status properly set as `inaccessible`.
|
||||
*/
|
||||
applications$: Observable<ReadonlyMap<string, PublicAppInfo>>;
|
||||
|
||||
/**
|
||||
* Navigate to a given app
|
||||
*
|
||||
* @param appId
|
||||
* @param options - navigation options
|
||||
*/
|
||||
navigateToApp(appId: string, options?: NavigateToAppOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Navigate to given URL in a SPA friendly way when possible (when the URL will redirect to a valid application
|
||||
* within the current basePath).
|
||||
*
|
||||
* The method resolves pathnames the same way browsers do when resolving a `<a href>` value. The provided `url` can be:
|
||||
* - an absolute URL
|
||||
* - an absolute path
|
||||
* - a path relative to the current URL (window.location.href)
|
||||
*
|
||||
* If all these criteria are true for the given URL:
|
||||
* - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location
|
||||
* - The resolved pathname of the provided URL/path starts with the current basePath (eg. /mybasepath/s/my-space)
|
||||
* - The pathname segment after the basePath matches any known application route (eg. /app/<id>/ or any application's `appRoute` configuration)
|
||||
*
|
||||
* Then a SPA navigation will be performed using `navigateToApp` using the corresponding application and path.
|
||||
* Otherwise, fallback to a full page reload to navigate to the url using `window.location.assign`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // current url: `https://kibana:8080/base-path/s/my-space/app/dashboard`
|
||||
*
|
||||
* // will call `application.navigateToApp('discover', { path: '/some-path?foo=bar'})`
|
||||
* application.navigateToUrl('https://kibana:8080/base-path/s/my-space/app/discover/some-path?foo=bar')
|
||||
* application.navigateToUrl('/base-path/s/my-space/app/discover/some-path?foo=bar')
|
||||
* application.navigateToUrl('./discover/some-path?foo=bar')
|
||||
*
|
||||
* // will perform a full page reload using `window.location.assign`
|
||||
* application.navigateToUrl('https://elsewhere:8080/base-path/s/my-space/app/discover/some-path') // origin does not match
|
||||
* application.navigateToUrl('/app/discover/some-path') // does not include the current basePath
|
||||
* application.navigateToUrl('/base-path/s/my-space/app/unknown-app/some-path') // unknown application
|
||||
* application.navigateToUrl('../discover') // resolve to `/base-path/s/my-space/discover` which is not a path of a known app.
|
||||
* application.navigateToUrl('../../other-space/discover') // resolve to `/base-path/s/other-space/discover` which is not within the current basePath.
|
||||
* ```
|
||||
*
|
||||
* @param url - an absolute URL, an absolute path or a relative path, to navigate to.
|
||||
* @param options - navigation options
|
||||
*/
|
||||
navigateToUrl(url: string, options?: NavigateToUrlOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns the absolute path (or URL) to a given app, including the global base path.
|
||||
*
|
||||
* By default, it returns the absolute path of the application (e.g `/basePath/app/my-app`).
|
||||
* Use the `absolute` option to generate an absolute url instead (e.g `http://host:port/basePath/app/my-app`)
|
||||
*
|
||||
* Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's current location.
|
||||
*
|
||||
* @param appId
|
||||
* @param options.path - optional path inside application to deep link to
|
||||
* @param options.absolute - if true, will returns an absolute url instead of a relative one
|
||||
*/
|
||||
getUrlForApp(
|
||||
appId: string,
|
||||
options?: { path?: string; absolute?: boolean; deepLinkId?: string }
|
||||
): string;
|
||||
|
||||
/**
|
||||
* An observable that emits the current application id and each subsequent id update.
|
||||
*/
|
||||
currentAppId$: Observable<string | undefined>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for the {@link ApplicationStart.navigateToApp | navigateToApp API}
|
||||
* @public
|
||||
*/
|
||||
export interface NavigateToAppOptions {
|
||||
/**
|
||||
* optional {@link App.deepLinks | deep link} id inside the application to navigate to.
|
||||
* If an additional {@link NavigateToAppOptions.path | path} is defined it will be appended to the deep link path.
|
||||
*/
|
||||
deepLinkId?: string;
|
||||
/**
|
||||
* optional path inside application to deep link to.
|
||||
* If undefined, will use {@link App.defaultPath | the app's default path} as default.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* optional state to forward to the application
|
||||
*/
|
||||
state?: unknown;
|
||||
/**
|
||||
* if true, will not create a new history entry when navigating (using `replace` instead of `push`)
|
||||
*/
|
||||
replace?: boolean;
|
||||
|
||||
/**
|
||||
* if true, will open the app in new tab, will share session information via window.open if base
|
||||
*/
|
||||
openInNewTab?: boolean;
|
||||
|
||||
/**
|
||||
* if true, will bypass the default onAppLeave behavior
|
||||
*/
|
||||
skipAppLeave?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for the {@link ApplicationStart.navigateToUrl | navigateToUrl API}
|
||||
* @public
|
||||
*/
|
||||
export interface NavigateToUrlOptions {
|
||||
/**
|
||||
* if true, will bypass the default onAppLeave behavior
|
||||
*/
|
||||
skipAppLeave?: boolean;
|
||||
/**
|
||||
* if true will force a full page reload/refresh/assign, overriding the outcome of other url checks against current the location (effectively using `window.location.assign` instead of `push`)
|
||||
*/
|
||||
forceRedirect?: boolean;
|
||||
/**
|
||||
* optional state to forward to the application
|
||||
*/
|
||||
state?: unknown;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 { History, LocationDescriptorObject, Href } from 'history';
|
||||
|
||||
/**
|
||||
* A wrapper around a `History` instance that is scoped to a particular base path of the history stack. Behaves
|
||||
* similarly to the `basename` option except that this wrapper hides any history stack entries from outside the scope
|
||||
* of this base path.
|
||||
*
|
||||
* This wrapper also allows Core and Plugins to share a single underlying global `History` instance without exposing
|
||||
* the history of other applications.
|
||||
*
|
||||
* The {@link ScopedHistory.createSubHistory | createSubHistory} method is particularly useful for applications that
|
||||
* contain any number of "sub-apps" which should not have access to the main application's history or basePath.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface ScopedHistory<HistoryLocationState = unknown>
|
||||
extends History<HistoryLocationState> {
|
||||
/**
|
||||
* Creates a `ScopedHistory` for a subpath of this `ScopedHistory`. Useful for applications that may have sub-apps
|
||||
* that do not need access to the containing application's history.
|
||||
*
|
||||
* @param basePath the URL path scope for the sub history
|
||||
*/
|
||||
createSubHistory(basePath: string): ScopedHistory;
|
||||
|
||||
/**
|
||||
* Creates an href (string) to the location.
|
||||
* If `prependBasePath` is true (default), it will prepend the location's path with the scoped history basePath.
|
||||
*
|
||||
* @param location
|
||||
* @param options.prependBasePath
|
||||
*/
|
||||
createHref(
|
||||
location: LocationDescriptorObject<HistoryLocationState>,
|
||||
options?: { prependBasePath?: boolean }
|
||||
): Href;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.bazel.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "target_types",
|
||||
"rootDir": ".",
|
||||
"stripInternal": false,
|
||||
"types": [
|
||||
"jest",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
]
|
||||
}
|
117
packages/core/application/core-application-common/BUILD.bazel
Normal file
117
packages/core/application/core-application-common/BUILD.bazel
Normal file
|
@ -0,0 +1,117 @@
|
|||
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||
|
||||
PKG_DIRNAME = "core-application-common"
|
||||
PKG_REQUIRE_NAME = "@kbn/core-application-common"
|
||||
|
||||
SOURCE_FILES = glob(
|
||||
[
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
exclude = [
|
||||
"**/*.config.js",
|
||||
"**/*.mock.*",
|
||||
"**/*.test.*",
|
||||
"**/*.stories.*",
|
||||
"**/__snapshots__",
|
||||
"**/integration_tests",
|
||||
"**/mocks",
|
||||
"**/scripts",
|
||||
"**/storybook",
|
||||
"**/test_fixtures",
|
||||
"**/test_helpers",
|
||||
],
|
||||
)
|
||||
|
||||
SRCS = SOURCE_FILES
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = SRCS,
|
||||
)
|
||||
|
||||
NPM_MODULE_EXTRA_FILES = [
|
||||
"package.json",
|
||||
]
|
||||
|
||||
RUNTIME_DEPS = [
|
||||
"@npm//react",
|
||||
"//packages/kbn-i18n",
|
||||
]
|
||||
|
||||
TYPES_DEPS = [
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/jest",
|
||||
"//packages/kbn-i18n:npm_module_types",
|
||||
]
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_node",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
)
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_web",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
web = True,
|
||||
)
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig.json",
|
||||
deps = [
|
||||
"//:tsconfig.base.json",
|
||||
"//:tsconfig.bazel.json",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "tsc_types",
|
||||
args = ['--pretty'],
|
||||
srcs = SRCS,
|
||||
deps = TYPES_DEPS,
|
||||
declaration = True,
|
||||
declaration_map = True,
|
||||
emit_declaration_only = True,
|
||||
out_dir = "target_types",
|
||||
root_dir = ".",
|
||||
tsconfig = ":tsconfig",
|
||||
)
|
||||
|
||||
js_library(
|
||||
name = PKG_DIRNAME,
|
||||
srcs = NPM_MODULE_EXTRA_FILES,
|
||||
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_module",
|
||||
deps = [":" + PKG_DIRNAME],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build",
|
||||
srcs = [":npm_module"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm_types(
|
||||
name = "npm_module_types",
|
||||
srcs = SRCS,
|
||||
deps = [":tsc_types"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
tsconfig = ":tsconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build_types",
|
||||
srcs = [":npm_module_types"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
# @kbn/core-application-common
|
||||
|
||||
Contains public types and constants for Core's browser-side `application` service.
|
11
packages/core/application/core-application-common/index.ts
Normal file
11
packages/core/application/core-application-common/index.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export type { AppCategory } from './src/app_category';
|
||||
export { APP_WRAPPER_CLASS } from './src/app_wrapper_class';
|
||||
export { DEFAULT_APP_CATEGORIES } from './src/default_app_categories';
|
|
@ -6,5 +6,8 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { DEFAULT_APP_CATEGORIES } from './default_app_categories';
|
||||
export { APP_WRAPPER_CLASS } from './app_wrapper_class';
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/core/application/core-application-common'],
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@kbn/core-application-common",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "./target_node/index.js",
|
||||
"browser": "./target_web/index.js",
|
||||
"author": "Kibana Core",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||
}
|
|
@ -6,8 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
/** @public */
|
||||
|
||||
/**
|
||||
* A category definition for nav links to know where to sort them in the left hand nav
|
||||
* @public
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { AppCategory } from '../types';
|
||||
import type { AppCategory } from './app_category';
|
||||
|
||||
/** @internal */
|
||||
/** @public */
|
||||
export const DEFAULT_APP_CATEGORIES: Record<string, AppCategory> = Object.freeze({
|
||||
kibana: {
|
||||
id: 'kibana',
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.bazel.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "target_types",
|
||||
"rootDir": ".",
|
||||
"stripInternal": false,
|
||||
"types": [
|
||||
"jest",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||
|
||||
PKG_DIRNAME = "core-capabilities-browser-internal"
|
||||
PKG_REQUIRE_NAME = "@kbn/core-capabilities-browser-internal"
|
||||
|
||||
SOURCE_FILES = glob(
|
||||
[
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
exclude = [
|
||||
"**/*.config.js",
|
||||
"**/*.mock.*",
|
||||
"**/*.test.*",
|
||||
"**/*.stories.*",
|
||||
"**/__snapshots__",
|
||||
"**/integration_tests",
|
||||
"**/mocks",
|
||||
"**/scripts",
|
||||
"**/storybook",
|
||||
"**/test_fixtures",
|
||||
"**/test_helpers",
|
||||
],
|
||||
)
|
||||
|
||||
SRCS = SOURCE_FILES
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = SRCS,
|
||||
)
|
||||
|
||||
NPM_MODULE_EXTRA_FILES = [
|
||||
"package.json",
|
||||
]
|
||||
|
||||
RUNTIME_DEPS = [
|
||||
"//packages/kbn-std",
|
||||
### test dependencies
|
||||
"//packages/core/http/core-http-browser-mocks"
|
||||
]
|
||||
|
||||
TYPES_DEPS = [
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/jest",
|
||||
"//packages/kbn-utility-types:npm_module_types",
|
||||
"//packages/kbn-std:npm_module_types",
|
||||
"//packages/core/http/core-http-browser:npm_module_types",
|
||||
"//packages/core/capabilities/core-capabilities-common:npm_module_types",
|
||||
]
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_node",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
)
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_web",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
web = True,
|
||||
)
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig.json",
|
||||
deps = [
|
||||
"//:tsconfig.base.json",
|
||||
"//:tsconfig.bazel.json",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "tsc_types",
|
||||
args = ['--pretty'],
|
||||
srcs = SRCS,
|
||||
deps = TYPES_DEPS,
|
||||
declaration = True,
|
||||
declaration_map = True,
|
||||
emit_declaration_only = True,
|
||||
out_dir = "target_types",
|
||||
root_dir = ".",
|
||||
tsconfig = ":tsconfig",
|
||||
)
|
||||
|
||||
js_library(
|
||||
name = PKG_DIRNAME,
|
||||
srcs = NPM_MODULE_EXTRA_FILES,
|
||||
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_module",
|
||||
deps = [":" + PKG_DIRNAME],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build",
|
||||
srcs = [":npm_module"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm_types(
|
||||
name = "npm_module_types",
|
||||
srcs = SRCS,
|
||||
deps = [":tsc_types"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
tsconfig = ":tsconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build_types",
|
||||
srcs = [":npm_module_types"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
# @kbn/core-capabilities-browser-internal
|
||||
|
||||
Contains the implementation of Core's internal `capabilities` browser-side service.
|
|
@ -6,8 +6,5 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export {
|
||||
MountWrapper,
|
||||
mountReactNode,
|
||||
KBN_LOAD_MARKS,
|
||||
} from '@kbn/core-mount-utils-browser-internal';
|
||||
export { CapabilitiesService } from './src/capabilities_service';
|
||||
export type { CapabilitiesStart } from './src/capabilities_service';
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/core/capabilities/core-capabilities-browser-internal'],
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@kbn/core-capabilities-browser-internal",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "./target_node/index.js",
|
||||
"browser": "./target_web/index.js",
|
||||
"author": "Kibana Core",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.bazel.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "target_types",
|
||||
"rootDir": ".",
|
||||
"stripInternal": false,
|
||||
"types": [
|
||||
"jest",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
load("@npm//@bazel/typescript:index.bzl", "ts_config")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
|
||||
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
|
||||
|
||||
PKG_DIRNAME = "core-capabilities-browser-mocks"
|
||||
PKG_REQUIRE_NAME = "@kbn/core-capabilities-browser-mocks"
|
||||
|
||||
SOURCE_FILES = glob(
|
||||
[
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
exclude = [
|
||||
"**/*.config.js",
|
||||
"**/*.test.*",
|
||||
"**/*.stories.*",
|
||||
"**/__snapshots__",
|
||||
"**/integration_tests",
|
||||
"**/mocks",
|
||||
"**/scripts",
|
||||
"**/storybook",
|
||||
"**/test_fixtures",
|
||||
"**/test_helpers",
|
||||
],
|
||||
)
|
||||
|
||||
SRCS = SOURCE_FILES
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = SRCS,
|
||||
)
|
||||
|
||||
NPM_MODULE_EXTRA_FILES = [
|
||||
"package.json",
|
||||
]
|
||||
|
||||
RUNTIME_DEPS = [
|
||||
"//packages/kbn-std",
|
||||
]
|
||||
|
||||
TYPES_DEPS = [
|
||||
"@npm//@types/node",
|
||||
"@npm//@types/jest",
|
||||
"//packages/kbn-std:npm_module_types",
|
||||
"//packages/kbn-utility-types:npm_module_types",
|
||||
"//packages/core/capabilities/core-capabilities-browser-internal:npm_module_types",
|
||||
]
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_node",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
)
|
||||
|
||||
jsts_transpiler(
|
||||
name = "target_web",
|
||||
srcs = SRCS,
|
||||
build_pkg_name = package_name(),
|
||||
web = True,
|
||||
)
|
||||
|
||||
ts_config(
|
||||
name = "tsconfig",
|
||||
src = "tsconfig.json",
|
||||
deps = [
|
||||
"//:tsconfig.base.json",
|
||||
"//:tsconfig.bazel.json",
|
||||
],
|
||||
)
|
||||
|
||||
ts_project(
|
||||
name = "tsc_types",
|
||||
args = ['--pretty'],
|
||||
srcs = SRCS,
|
||||
deps = TYPES_DEPS,
|
||||
declaration = True,
|
||||
declaration_map = True,
|
||||
emit_declaration_only = True,
|
||||
out_dir = "target_types",
|
||||
root_dir = ".",
|
||||
tsconfig = ":tsconfig",
|
||||
)
|
||||
|
||||
js_library(
|
||||
name = PKG_DIRNAME,
|
||||
srcs = NPM_MODULE_EXTRA_FILES,
|
||||
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm(
|
||||
name = "npm_module",
|
||||
deps = [":" + PKG_DIRNAME],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build",
|
||||
srcs = [":npm_module"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_npm_types(
|
||||
name = "npm_module_types",
|
||||
srcs = SRCS,
|
||||
deps = [":tsc_types"],
|
||||
package_name = PKG_REQUIRE_NAME,
|
||||
tsconfig = ":tsconfig",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "build_types",
|
||||
srcs = [":npm_module_types"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,4 @@
|
|||
# @kbn/core-capabilities-browser-mocks
|
||||
|
||||
Contains the mocks for Core's internal `capabilities` browser-side service:
|
||||
- `capabilitiesServiceMock`
|
|
@ -6,4 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { CapabilitiesService } from './capabilities_service';
|
||||
export { capabilitiesServiceMock } from './src/capabilities_service.mock';
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/packages/core/capabilities/core-capabilities-browser-mocks'],
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "@kbn/core-capabilities-browser-mocks",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "./target_node/index.js",
|
||||
"browser": "./target_web/index.js",
|
||||
"author": "Kibana Core",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0"
|
||||
}
|
|
@ -8,7 +8,10 @@
|
|||
|
||||
import { deepFreeze } from '@kbn/std';
|
||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||
import { CapabilitiesService, CapabilitiesStart } from './capabilities_service';
|
||||
import type {
|
||||
CapabilitiesStart,
|
||||
CapabilitiesService,
|
||||
} from '@kbn/core-capabilities-browser-internal';
|
||||
|
||||
const createStartContractMock = (): jest.Mocked<CapabilitiesStart> => ({
|
||||
capabilities: deepFreeze({
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.bazel.json",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "target_types",
|
||||
"rootDir": ".",
|
||||
"stripInternal": false,
|
||||
"types": [
|
||||
"jest",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
]
|
||||
}
|
|
@ -25,6 +25,7 @@ type MountWrapperComponent = React.FunctionComponent<MountWrapperComponentProps>
|
|||
|
||||
/**
|
||||
* MountWrapper is a react component to mount a {@link MountPoint} inside a react tree.
|
||||
* @internal
|
||||
*/
|
||||
export const MountWrapper: MountWrapperComponent = ({ mount, className = defaultWrapperClass }) => {
|
||||
const element = useRef(null);
|
||||
|
@ -36,6 +37,7 @@ export const MountWrapper: MountWrapperComponent = ({ mount, className = default
|
|||
* Mount converter for react node.
|
||||
*
|
||||
* @param node to get a mount for
|
||||
* @internal
|
||||
*/
|
||||
export const mountReactNode =
|
||||
(node: React.ReactNode): MountPoint =>
|
||||
|
|
|
@ -219,7 +219,7 @@ export class OptimizerConfig {
|
|||
new Bundle({
|
||||
type: 'entry',
|
||||
id: 'core',
|
||||
publicDirNames: ['public', 'public/utils'],
|
||||
publicDirNames: ['public'],
|
||||
sourceRoot: options.repoRoot,
|
||||
contextDir: Path.resolve(options.repoRoot, 'src/core'),
|
||||
outputDir: Path.resolve(options.outputRoot, 'src/core/target/public'),
|
||||
|
|
|
@ -22,7 +22,6 @@ const transpileKbnPaths = [
|
|||
'x-pack/examples',
|
||||
// TODO: should should probably remove this link back to the source
|
||||
'x-pack/plugins/task_manager/server/config.ts',
|
||||
'src/core/utils/default_app_categories.ts',
|
||||
'src/plugins/field_formats/common',
|
||||
].map((path) => Path.resolve(BASE_REPO_ROOT, path));
|
||||
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
*/
|
||||
|
||||
jest.mock('@elastic/apm-rum');
|
||||
import type { DeeplyMockedKeys, MockedKeys } from '@kbn/utility-types-jest';
|
||||
import { executionContextServiceMock } from '@kbn/core-execution-context-browser-mocks';
|
||||
import { init, apm } from '@elastic/apm-rum';
|
||||
import type { Transaction } from '@elastic/apm-rum';
|
||||
import { ApmSystem } from './apm_system';
|
||||
|
||||
import { Subject } from 'rxjs';
|
||||
import { InternalApplicationStart } from './application/types';
|
||||
import type { DeeplyMockedKeys, MockedKeys } from '@kbn/utility-types-jest';
|
||||
import { init, apm, type Transaction } from '@elastic/apm-rum';
|
||||
import { executionContextServiceMock } from '@kbn/core-execution-context-browser-mocks';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
import { ApmSystem } from './apm_system';
|
||||
|
||||
const initMock = init as jest.Mocked<typeof init>;
|
||||
const apmMock = apm as DeeplyMockedKeys<typeof apm>;
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
import type { ApmBase, AgentConfigOptions, Transaction } from '@elastic/apm-rum';
|
||||
import { modifyUrl } from '@kbn/std';
|
||||
import type { ExecutionContextStart } from '@kbn/core-execution-context-browser';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
import { CachedResourceObserver } from './apm_resource_counter';
|
||||
import type { InternalApplicationStart } from './application';
|
||||
|
||||
/** "GET protocol://hostname:port/pathname" */
|
||||
const HTTP_REQUEST_TRANSACTION_NAME_REGEX =
|
||||
|
|
|
@ -1,876 +0,0 @@
|
|||
/*
|
||||
* 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 { ButtonColor } from '@elastic/eui';
|
||||
import { Observable } from 'rxjs';
|
||||
import { History } from 'history';
|
||||
import { RecursiveReadonly } from '@kbn/utility-types';
|
||||
|
||||
import type { CoreTheme } from '@kbn/core-theme-browser';
|
||||
import type { Capabilities } from '@kbn/core-capabilities-common';
|
||||
import type { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import { PluginOpaqueId } from '../plugins';
|
||||
import { AppCategory } from '../../types';
|
||||
import { ScopedHistory } from './scoped_history';
|
||||
|
||||
/**
|
||||
* Accessibility status of an application.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export enum AppStatus {
|
||||
/**
|
||||
* Application is accessible.
|
||||
*/
|
||||
accessible = 0,
|
||||
/**
|
||||
* Application is not accessible.
|
||||
*/
|
||||
inaccessible = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* Status of the application's navLink.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export enum AppNavLinkStatus {
|
||||
/**
|
||||
* The application navLink will be `visible` if the application's {@link AppStatus} is set to `accessible`
|
||||
* and `hidden` if the application status is set to `inaccessible`.
|
||||
*/
|
||||
default = 0,
|
||||
/**
|
||||
* The application navLink is visible and clickable in the navigation bar.
|
||||
*/
|
||||
visible = 1,
|
||||
/**
|
||||
* The application navLink is visible but inactive and not clickable in the navigation bar.
|
||||
*/
|
||||
disabled = 2,
|
||||
/**
|
||||
* The application navLink does not appear in the navigation bar.
|
||||
*/
|
||||
hidden = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the list of fields that can be updated via an {@link AppUpdater}.
|
||||
* @public
|
||||
*/
|
||||
export type AppUpdatableFields = Pick<
|
||||
App,
|
||||
'status' | 'navLinkStatus' | 'searchable' | 'tooltip' | 'defaultPath' | 'deepLinks'
|
||||
>;
|
||||
|
||||
/**
|
||||
* App navigation menu options
|
||||
* @public
|
||||
*/
|
||||
export interface AppNavOptions {
|
||||
/**
|
||||
* An ordinal used to sort nav links relative to one another for display.
|
||||
*/
|
||||
order?: number;
|
||||
|
||||
/**
|
||||
* A tooltip shown when hovering over app link.
|
||||
*/
|
||||
tooltip?: string;
|
||||
|
||||
/**
|
||||
* A EUI iconType that will be used for the app's icon. This icon
|
||||
* takes precedence over the `icon` property.
|
||||
*/
|
||||
euiIconType?: string;
|
||||
|
||||
/**
|
||||
* A URL to an image file used as an icon. Used as a fallback
|
||||
* if `euiIconType` is not provided.
|
||||
*/
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updater for applications.
|
||||
* see {@link ApplicationSetup}
|
||||
* @public
|
||||
*/
|
||||
export type AppUpdater = (app: App) => Partial<AppUpdatableFields> | undefined;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface App<HistoryLocationState = unknown> extends AppNavOptions {
|
||||
/**
|
||||
* The unique identifier of the application.
|
||||
*
|
||||
* Can only be composed of alphanumeric characters, `-`, `:` and `_`
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The title of the application.
|
||||
*/
|
||||
title: string;
|
||||
|
||||
/**
|
||||
* The category definition of the product
|
||||
* See {@link AppCategory}
|
||||
* See DEFAULT_APP_CATEGORIES for more reference
|
||||
*/
|
||||
category?: AppCategory;
|
||||
|
||||
/**
|
||||
* The initial status of the application.
|
||||
* Defaulting to `accessible`
|
||||
*/
|
||||
status?: AppStatus;
|
||||
|
||||
/**
|
||||
* The initial status of the application's navLink.
|
||||
* Defaulting to `visible` if `status` is `accessible` and `hidden` if status is `inaccessible`
|
||||
* See {@link AppNavLinkStatus}
|
||||
*/
|
||||
navLinkStatus?: AppNavLinkStatus;
|
||||
|
||||
/**
|
||||
* The initial flag to determine if the application is searchable in the global search.
|
||||
* Defaulting to `true` if `navLinkStatus` is `visible` or omitted.
|
||||
*/
|
||||
searchable?: boolean;
|
||||
|
||||
/**
|
||||
* Allow to define the default path a user should be directed to when navigating to the app.
|
||||
* When defined, this value will be used as a default for the `path` option when calling {@link ApplicationStart.navigateToApp | navigateToApp}`,
|
||||
* and will also be appended to the {@link ChromeNavLink | application navLink} in the navigation bar.
|
||||
*/
|
||||
defaultPath?: string;
|
||||
|
||||
/**
|
||||
* An {@link AppUpdater} observable that can be used to update the application {@link AppUpdatableFields} at runtime.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* How to update an application navLink at runtime
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* private appUpdater = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
*
|
||||
* setup({ application }) {
|
||||
* application.register({
|
||||
* id: 'my-app',
|
||||
* title: 'My App',
|
||||
* updater$: this.appUpdater,
|
||||
* async mount(params) {
|
||||
* const { renderApp } = await import('./application');
|
||||
* return renderApp(params);
|
||||
* },
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* start() {
|
||||
* // later, when the navlink needs to be updated
|
||||
* appUpdater.next(() => {
|
||||
* navLinkStatus: AppNavLinkStatus.disabled,
|
||||
* })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
updater$?: Observable<AppUpdater>;
|
||||
|
||||
/**
|
||||
* Custom capabilities defined by the app.
|
||||
*/
|
||||
capabilities?: Partial<Capabilities>;
|
||||
|
||||
/**
|
||||
* Hide the UI chrome when the application is mounted. Defaults to `false`.
|
||||
* Takes precedence over chrome service visibility settings.
|
||||
*/
|
||||
chromeless?: boolean;
|
||||
|
||||
/**
|
||||
* A mount function called when the user navigates to this app's route.
|
||||
*/
|
||||
mount: AppMount<HistoryLocationState>;
|
||||
|
||||
/**
|
||||
* Override the application's routing path from `/app/${id}`.
|
||||
* Must be unique across registered applications. Should not include the
|
||||
* base path from HTTP.
|
||||
*/
|
||||
appRoute?: string;
|
||||
|
||||
/**
|
||||
* If set to true, the application's route will only be checked against an exact match. Defaults to `false`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* core.application.register({
|
||||
* id: 'my_app',
|
||||
* title: 'My App',
|
||||
* exactRoute: true,
|
||||
* mount: () => { ... },
|
||||
* })
|
||||
*
|
||||
* // '[basePath]/app/my_app' will be matched
|
||||
* // '[basePath]/app/my_app/some/path' will not be matched
|
||||
* ```
|
||||
*/
|
||||
exactRoute?: boolean;
|
||||
|
||||
/** Optional keywords to match with in deep links search. Omit if this part of the hierarchy does not have a page URL. */
|
||||
keywords?: string[];
|
||||
|
||||
/**
|
||||
* Input type for registering secondary in-app locations for an application.
|
||||
*
|
||||
* Deep links must include at least one of `path` or `deepLinks`. A deep link that does not have a `path`
|
||||
* represents a topological level in the application's hierarchy, but does not have a destination URL that is
|
||||
* user-accessible.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* core.application.register({
|
||||
* id: 'my_app',
|
||||
* title: 'Translated title',
|
||||
* keywords: ['translated keyword1', 'translated keyword2'],
|
||||
* deepLinks: [
|
||||
* {
|
||||
* id: 'sub1',
|
||||
* title: 'Sub1',
|
||||
* path: '/sub1',
|
||||
* keywords: ['subpath1'],
|
||||
* },
|
||||
* {
|
||||
* id: 'sub2',
|
||||
* title: 'Sub2',
|
||||
* deepLinks: [
|
||||
* {
|
||||
* id: 'subsub',
|
||||
* title: 'SubSub',
|
||||
* path: '/sub2/sub',
|
||||
* keywords: ['subpath2'],
|
||||
* },
|
||||
* ],
|
||||
* },
|
||||
* ],
|
||||
* mount: () => { ... }
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
deepLinks?: AppDeepLink[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Public information about a registered app's {@link AppDeepLink | deepLinks}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type PublicAppDeepLinkInfo = Omit<
|
||||
AppDeepLink,
|
||||
'deepLinks' | 'keywords' | 'navLinkStatus' | 'searchable'
|
||||
> & {
|
||||
deepLinks: PublicAppDeepLinkInfo[];
|
||||
keywords: string[];
|
||||
navLinkStatus: AppNavLinkStatus;
|
||||
searchable: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Input type for registering secondary in-app locations for an application.
|
||||
*
|
||||
* Deep links must include at least one of `path` or `deepLinks`. A deep link that does not have a `path`
|
||||
* represents a topological level in the application's hierarchy, but does not have a destination URL that is
|
||||
* user-accessible.
|
||||
* @public
|
||||
*/
|
||||
export type AppDeepLink = {
|
||||
/** Identifier to represent this sublink, should be unique for this application */
|
||||
id: string;
|
||||
/** Title to label represent this deep link */
|
||||
title: string;
|
||||
/** Optional keywords to match with in deep links search. Omit if this part of the hierarchy does not have a page URL. */
|
||||
keywords?: string[];
|
||||
/** Optional status of the chrome navigation, defaults to `hidden` */
|
||||
navLinkStatus?: AppNavLinkStatus;
|
||||
/** Optional flag to determine if the link is searchable in the global search. Defaulting to `true` if `navLinkStatus` is `visible` or omitted */
|
||||
searchable?: boolean;
|
||||
} & AppNavOptions &
|
||||
(
|
||||
| {
|
||||
/** URL path to access this link, relative to the application's appRoute. */
|
||||
path: string;
|
||||
/** Optional array of links that are 'underneath' this section in the hierarchy */
|
||||
deepLinks?: AppDeepLink[];
|
||||
}
|
||||
| {
|
||||
/** Optional path to access this section. Omit if this part of the hierarchy does not have a page URL. */
|
||||
path?: string;
|
||||
/** Array links that are 'underneath' this section in this hierarchy. */
|
||||
deepLinks: AppDeepLink[];
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Public information about a registered {@link App | application}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type PublicAppInfo = Omit<
|
||||
App,
|
||||
'mount' | 'updater$' | 'keywords' | 'deepLinks' | 'searchable'
|
||||
> & {
|
||||
// remove optional on fields populated with default values
|
||||
status: AppStatus;
|
||||
navLinkStatus: AppNavLinkStatus;
|
||||
appRoute: string;
|
||||
keywords: string[];
|
||||
deepLinks: PublicAppDeepLinkInfo[];
|
||||
searchable: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* A mount function called when the user navigates to this app's route.
|
||||
*
|
||||
* @param params {@link AppMountParameters}
|
||||
* @returns An unmounting function that will be called to unmount the application. See {@link AppUnmount}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type AppMount<HistoryLocationState = unknown> = (
|
||||
params: AppMountParameters<HistoryLocationState>
|
||||
) => AppUnmount | Promise<AppUnmount>;
|
||||
|
||||
/**
|
||||
* A function called when an application should be unmounted from the page. This function should be synchronous.
|
||||
* @public
|
||||
*/
|
||||
export type AppUnmount = () => void;
|
||||
|
||||
/** @public */
|
||||
export interface AppMountParameters<HistoryLocationState = unknown> {
|
||||
/**
|
||||
* The container element to render the application into.
|
||||
*/
|
||||
element: HTMLElement;
|
||||
|
||||
/**
|
||||
* A scoped history instance for your application. Should be used to wire up
|
||||
* your applications Router.
|
||||
*
|
||||
* @example
|
||||
* How to configure react-router with a base path:
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* setup({ application }) {
|
||||
* application.register({
|
||||
* id: 'my-app',
|
||||
* appRoute: '/my-app',
|
||||
* async mount(params) {
|
||||
* const { renderApp } = await import('./application');
|
||||
* return renderApp(params);
|
||||
* },
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { Router, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ element, history }: AppMountParameters) => {
|
||||
* ReactDOM.render(
|
||||
* <Router history={history}>
|
||||
* <Route path="/" exact component={HomePage} />
|
||||
* </Router>,
|
||||
* element
|
||||
* );
|
||||
*
|
||||
* return () => ReactDOM.unmountComponentAtNode(element);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
history: ScopedHistory<HistoryLocationState>;
|
||||
|
||||
/**
|
||||
* The route path for configuring navigation to the application.
|
||||
* This string should not include the base path from HTTP.
|
||||
*
|
||||
* @deprecated Use {@link AppMountParameters.history} instead.
|
||||
* @removeBy 8.8.0
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* How to configure react-router with a base path:
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* setup({ application }) {
|
||||
* application.register({
|
||||
* id: 'my-app',
|
||||
* appRoute: '/my-app',
|
||||
* async mount(params) {
|
||||
* const { renderApp } = await import('./application');
|
||||
* return renderApp(params);
|
||||
* },
|
||||
* });
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { BrowserRouter, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ appBasePath, element }: AppMountParameters) => {
|
||||
* ReactDOM.render(
|
||||
* // pass `appBasePath` to `basename`
|
||||
* <BrowserRouter basename={appBasePath}>
|
||||
* <Route path="/" exact component={HomePage} />
|
||||
* </BrowserRouter>,
|
||||
* element
|
||||
* );
|
||||
*
|
||||
* return () => ReactDOM.unmountComponentAtNode(element);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
appBasePath: string;
|
||||
|
||||
/**
|
||||
* A function that can be used to register a handler that will be called
|
||||
* when the user is leaving the current application, allowing to
|
||||
* prompt a confirmation message before actually changing the page.
|
||||
*
|
||||
* This will be called either when the user goes to another application, or when
|
||||
* trying to close the tab or manually changing the url.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { BrowserRouter, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ element, history, onAppLeave }: AppMountParameters) => {
|
||||
* const { renderApp, hasUnsavedChanges } = await import('./application');
|
||||
* onAppLeave(actions => {
|
||||
* if(hasUnsavedChanges()) {
|
||||
* return actions.confirm('Some changes were not saved. Are you sure you want to leave?');
|
||||
* }
|
||||
* return actions.default();
|
||||
* });
|
||||
* return renderApp({ element, history });
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @deprecated {@link ScopedHistory.block} should be used instead.
|
||||
* @removeBy 8.8.0
|
||||
*/
|
||||
onAppLeave: (handler: AppLeaveHandler) => void;
|
||||
|
||||
/**
|
||||
* A function that can be used to set the mount point used to populate the application action container
|
||||
* in the chrome header.
|
||||
*
|
||||
* Calling the handler multiple time will erase the current content of the action menu with the mount from the latest call.
|
||||
* Calling the handler with `undefined` will unmount the current mount point.
|
||||
* Calling the handler after the application has been unmounted will have no effect.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
* import { BrowserRouter, Route } from 'react-router-dom';
|
||||
*
|
||||
* import { CoreStart, AppMountParameters } from 'src/core/public';
|
||||
* import { MyPluginDepsStart } from './plugin';
|
||||
*
|
||||
* export renderApp = ({ element, history, setHeaderActionMenu }: AppMountParameters) => {
|
||||
* const { renderApp } = await import('./application');
|
||||
* const { renderActionMenu } = await import('./action_menu');
|
||||
* setHeaderActionMenu((element) => {
|
||||
* return renderActionMenu(element);
|
||||
* })
|
||||
* return renderApp({ element, history });
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
setHeaderActionMenu: (menuMount: MountPoint | undefined) => void;
|
||||
|
||||
/**
|
||||
* An observable emitting {@link CoreTheme | Core's theme}.
|
||||
* Should be used when mounting the application to include theme information.
|
||||
*
|
||||
* @example
|
||||
* When mounting a react application:
|
||||
* ```ts
|
||||
* // application.tsx
|
||||
* import React from 'react';
|
||||
* import ReactDOM from 'react-dom';
|
||||
*
|
||||
* import { AppMountParameters } from 'src/core/public';
|
||||
* import { wrapWithTheme } from 'src/plugins/kibana_react';
|
||||
* import { MyApp } from './app';
|
||||
*
|
||||
* export renderApp = ({ element, theme$ }: AppMountParameters) => {
|
||||
* ReactDOM.render(wrapWithTheme(<MyApp/>, theme$), element);
|
||||
* return () => ReactDOM.unmountComponentAtNode(element);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
theme$: Observable<CoreTheme>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A handler that will be executed before leaving the application, either when
|
||||
* going to another application or when closing the browser tab or manually changing
|
||||
* the url.
|
||||
* Should return `confirm` to prompt a message to the user before leaving the page, or `default`
|
||||
* to keep the default behavior (doing nothing).
|
||||
*
|
||||
* See {@link AppMountParameters} for detailed usage examples.
|
||||
*
|
||||
* @public
|
||||
* @deprecated {@link AppMountParameters.onAppLeave} has been deprecated in favor of {@link ScopedHistory.block}
|
||||
* @removeBy 8.8.0
|
||||
*/
|
||||
export type AppLeaveHandler = (
|
||||
factory: AppLeaveActionFactory,
|
||||
nextAppId?: string
|
||||
) => AppLeaveAction;
|
||||
|
||||
/**
|
||||
* Possible type of actions on application leave.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export enum AppLeaveActionType {
|
||||
confirm = 'confirm',
|
||||
default = 'default',
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to return from a {@link AppLeaveHandler} to execute the default
|
||||
* behaviour when leaving the application.
|
||||
*
|
||||
* See {@link AppLeaveActionFactory}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface AppLeaveDefaultAction {
|
||||
type: AppLeaveActionType.default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to return from a {@link AppLeaveHandler} to show a confirmation
|
||||
* message when trying to leave an application.
|
||||
*
|
||||
* See {@link AppLeaveActionFactory}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface AppLeaveConfirmAction {
|
||||
type: AppLeaveActionType.confirm;
|
||||
text: string;
|
||||
title?: string;
|
||||
confirmButtonText?: string;
|
||||
buttonColor?: ButtonColor;
|
||||
callback?: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible actions to return from a {@link AppLeaveHandler}
|
||||
*
|
||||
* See {@link AppLeaveConfirmAction} and {@link AppLeaveDefaultAction}
|
||||
*
|
||||
* @public
|
||||
* */
|
||||
export type AppLeaveAction = AppLeaveDefaultAction | AppLeaveConfirmAction;
|
||||
|
||||
/**
|
||||
* Factory provided when invoking a {@link AppLeaveHandler} to retrieve the {@link AppLeaveAction} to execute.
|
||||
*/
|
||||
export interface AppLeaveActionFactory {
|
||||
/**
|
||||
* Returns a confirm action, resulting on prompting a message to the user before leaving the
|
||||
* application, allowing him to choose if he wants to stay on the app or confirm that he
|
||||
* wants to leave.
|
||||
*
|
||||
* @param text The text to display in the confirmation message
|
||||
* @param title (optional) title to display in the confirmation message
|
||||
* @param callback (optional) to know that the user want to stay on the page
|
||||
* @param confirmButtonText (optional) text for the confirmation button
|
||||
* @param buttonColor (optional) color for the confirmation button
|
||||
* so we can show to the user the right UX for him to saved his/her/their changes
|
||||
*/
|
||||
confirm(
|
||||
text: string,
|
||||
title?: string,
|
||||
callback?: () => void,
|
||||
confirmButtonText?: string,
|
||||
buttonColor?: ButtonColor
|
||||
): AppLeaveConfirmAction;
|
||||
|
||||
/**
|
||||
* Returns a default action, resulting on executing the default behavior when
|
||||
* the user tries to leave an application
|
||||
*/
|
||||
default(): AppLeaveDefaultAction;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface Mounter {
|
||||
appRoute: string;
|
||||
appBasePath: string;
|
||||
mount: AppMount;
|
||||
exactRoute: boolean;
|
||||
unmountBeforeMounting?: boolean;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface ParsedAppUrl {
|
||||
app: string;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface ApplicationSetup {
|
||||
/**
|
||||
* Register an mountable application to the system.
|
||||
* @param app - an {@link App}
|
||||
* @typeParam HistoryLocationState - shape of the `History` state on {@link AppMountParameters.history}, defaults to `unknown`.
|
||||
*/
|
||||
register<HistoryLocationState = unknown>(app: App<HistoryLocationState>): void;
|
||||
|
||||
/**
|
||||
* Register an application updater that can be used to change the {@link AppUpdatableFields} fields
|
||||
* of all applications at runtime.
|
||||
*
|
||||
* This is meant to be used by plugins that needs to updates the whole list of applications.
|
||||
* To only updates a specific application, use the `updater$` property of the registered application instead.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* How to register an application updater that disables some applications:
|
||||
*
|
||||
* ```ts
|
||||
* // inside your plugin's setup function
|
||||
* export class MyPlugin implements Plugin {
|
||||
* setup({ application }) {
|
||||
* application.registerAppUpdater(
|
||||
* new BehaviorSubject<AppUpdater>(app => {
|
||||
* if (myPluginApi.shouldDisable(app))
|
||||
* return {
|
||||
* status: AppStatus.inaccessible,
|
||||
* };
|
||||
* })
|
||||
* );
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
registerAppUpdater(appUpdater$: Observable<AppUpdater>): void;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface InternalApplicationSetup extends Pick<ApplicationSetup, 'registerAppUpdater'> {
|
||||
/**
|
||||
* Register an mountable application to the system.
|
||||
* @param plugin - opaque ID of the plugin that registers this application
|
||||
* @param app
|
||||
*/
|
||||
register<HistoryLocationState = unknown>(
|
||||
plugin: PluginOpaqueId,
|
||||
app: App<HistoryLocationState>
|
||||
): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for the {@link ApplicationStart.navigateToApp | navigateToApp API}
|
||||
* @public
|
||||
*/
|
||||
export interface NavigateToAppOptions {
|
||||
/**
|
||||
* optional {@link App.deepLinks | deep link} id inside the application to navigate to.
|
||||
* If an additional {@link NavigateToAppOptions.path | path} is defined it will be appended to the deep link path.
|
||||
*/
|
||||
deepLinkId?: string;
|
||||
/**
|
||||
* optional path inside application to deep link to.
|
||||
* If undefined, will use {@link App.defaultPath | the app's default path} as default.
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* optional state to forward to the application
|
||||
*/
|
||||
state?: unknown;
|
||||
/**
|
||||
* if true, will not create a new history entry when navigating (using `replace` instead of `push`)
|
||||
*/
|
||||
replace?: boolean;
|
||||
|
||||
/**
|
||||
* if true, will open the app in new tab, will share session information via window.open if base
|
||||
*/
|
||||
openInNewTab?: boolean;
|
||||
|
||||
/**
|
||||
* if true, will bypass the default onAppLeave behavior
|
||||
*/
|
||||
skipAppLeave?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for the {@link ApplicationStart.navigateToUrl | navigateToUrl API}
|
||||
* @public
|
||||
*/
|
||||
export interface NavigateToUrlOptions {
|
||||
/**
|
||||
* if true, will bypass the default onAppLeave behavior
|
||||
*/
|
||||
skipAppLeave?: boolean;
|
||||
/**
|
||||
* if true will force a full page reload/refresh/assign, overriding the outcome of other url checks against current the location (effectively using `window.location.assign` instead of `push`)
|
||||
*/
|
||||
forceRedirect?: boolean;
|
||||
/**
|
||||
* optional state to forward to the application
|
||||
*/
|
||||
state?: unknown;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface ApplicationStart {
|
||||
/**
|
||||
* Gets the read-only capabilities.
|
||||
*/
|
||||
capabilities: RecursiveReadonly<Capabilities>;
|
||||
|
||||
/**
|
||||
* Observable emitting the list of currently registered apps and their associated status.
|
||||
*
|
||||
* @remarks
|
||||
* Applications disabled by {@link Capabilities} will not be present in the map. Applications manually disabled from
|
||||
* the client-side using an {@link AppUpdater | application updater} are present, with their status properly set as `inaccessible`.
|
||||
*/
|
||||
applications$: Observable<ReadonlyMap<string, PublicAppInfo>>;
|
||||
|
||||
/**
|
||||
* Navigate to a given app
|
||||
*
|
||||
* @param appId
|
||||
* @param options - navigation options
|
||||
*/
|
||||
navigateToApp(appId: string, options?: NavigateToAppOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Navigate to given URL in a SPA friendly way when possible (when the URL will redirect to a valid application
|
||||
* within the current basePath).
|
||||
*
|
||||
* The method resolves pathnames the same way browsers do when resolving a `<a href>` value. The provided `url` can be:
|
||||
* - an absolute URL
|
||||
* - an absolute path
|
||||
* - a path relative to the current URL (window.location.href)
|
||||
*
|
||||
* If all these criteria are true for the given URL:
|
||||
* - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location
|
||||
* - The resolved pathname of the provided URL/path starts with the current basePath (eg. /mybasepath/s/my-space)
|
||||
* - The pathname segment after the basePath matches any known application route (eg. /app/<id>/ or any application's `appRoute` configuration)
|
||||
*
|
||||
* Then a SPA navigation will be performed using `navigateToApp` using the corresponding application and path.
|
||||
* Otherwise, fallback to a full page reload to navigate to the url using `window.location.assign`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // current url: `https://kibana:8080/base-path/s/my-space/app/dashboard`
|
||||
*
|
||||
* // will call `application.navigateToApp('discover', { path: '/some-path?foo=bar'})`
|
||||
* application.navigateToUrl('https://kibana:8080/base-path/s/my-space/app/discover/some-path?foo=bar')
|
||||
* application.navigateToUrl('/base-path/s/my-space/app/discover/some-path?foo=bar')
|
||||
* application.navigateToUrl('./discover/some-path?foo=bar')
|
||||
*
|
||||
* // will perform a full page reload using `window.location.assign`
|
||||
* application.navigateToUrl('https://elsewhere:8080/base-path/s/my-space/app/discover/some-path') // origin does not match
|
||||
* application.navigateToUrl('/app/discover/some-path') // does not include the current basePath
|
||||
* application.navigateToUrl('/base-path/s/my-space/app/unknown-app/some-path') // unknown application
|
||||
* application.navigateToUrl('../discover') // resolve to `/base-path/s/my-space/discover` which is not a path of a known app.
|
||||
* application.navigateToUrl('../../other-space/discover') // resolve to `/base-path/s/other-space/discover` which is not within the current basePath.
|
||||
* ```
|
||||
*
|
||||
* @param url - an absolute URL, an absolute path or a relative path, to navigate to.
|
||||
* @param options - navigation options
|
||||
*/
|
||||
navigateToUrl(url: string, options?: NavigateToUrlOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Returns the absolute path (or URL) to a given app, including the global base path.
|
||||
*
|
||||
* By default, it returns the absolute path of the application (e.g `/basePath/app/my-app`).
|
||||
* Use the `absolute` option to generate an absolute url instead (e.g `http://host:port/basePath/app/my-app`)
|
||||
*
|
||||
* Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's current location.
|
||||
*
|
||||
* @param appId
|
||||
* @param options.path - optional path inside application to deep link to
|
||||
* @param options.absolute - if true, will returns an absolute url instead of a relative one
|
||||
*/
|
||||
getUrlForApp(
|
||||
appId: string,
|
||||
options?: { path?: string; absolute?: boolean; deepLinkId?: string }
|
||||
): string;
|
||||
|
||||
/**
|
||||
* An observable that emits the current application id and each subsequent id update.
|
||||
*/
|
||||
currentAppId$: Observable<string | undefined>;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface InternalApplicationStart extends ApplicationStart {
|
||||
// Internal APIs
|
||||
getComponent(): JSX.Element | null;
|
||||
|
||||
/**
|
||||
* The potential action menu set by the currently mounted app.
|
||||
* Consumed by the chrome header.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
currentActionMenu$: Observable<MountPoint | undefined>;
|
||||
|
||||
/**
|
||||
* The global history instance, exposed only to Core.
|
||||
* @internal
|
||||
*/
|
||||
history: History<unknown>;
|
||||
}
|
|
@ -13,12 +13,12 @@ import { toArray } from 'rxjs/operators';
|
|||
import { injectedMetadataServiceMock } from '@kbn/core-injected-metadata-browser-mocks';
|
||||
import { docLinksServiceMock } from '@kbn/core-doc-links-browser-mocks';
|
||||
import { httpServiceMock } from '@kbn/core-http-browser-mocks';
|
||||
import { App, PublicAppInfo } from '../application';
|
||||
import { applicationServiceMock } from '../application/application_service.mock';
|
||||
import type { App, PublicAppInfo } from '@kbn/core-application-browser';
|
||||
import { applicationServiceMock } from '@kbn/core-application-browser-mocks';
|
||||
import { notificationServiceMock } from '@kbn/core-notifications-browser-mocks';
|
||||
import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks';
|
||||
import { getAppInfo } from '@kbn/core-application-browser-internal';
|
||||
import { ChromeService } from './chrome_service';
|
||||
import { getAppInfo } from '../application/utils';
|
||||
|
||||
class FakeApp implements App {
|
||||
public title: string;
|
||||
|
|
|
@ -17,7 +17,7 @@ import type { DocLinksStart } from '@kbn/core-doc-links-browser';
|
|||
import type { HttpStart } from '@kbn/core-http-browser';
|
||||
import { mountReactNode } from '@kbn/core-mount-utils-browser-internal';
|
||||
import type { NotificationsStart } from '@kbn/core-notifications-browser';
|
||||
import type { InternalApplicationStart } from '../application';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
import { KIBANA_ASK_ELASTIC_LINK } from './constants';
|
||||
import { type ChromeDocTitle, DocTitleService } from './doc_title';
|
||||
import { type ChromeNavControls, NavControlsService } from './nav_controls';
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { NavLinksService } from './nav_links_service';
|
||||
import { take, map, takeLast } from 'rxjs/operators';
|
||||
import { App } from '../../application';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { take, map, takeLast } from 'rxjs/operators';
|
||||
import type { App } from '@kbn/core-application-browser';
|
||||
import { NavLinksService } from './nav_links_service';
|
||||
|
||||
const availableApps = new Map([
|
||||
['app1', { id: 'app1', order: 0, title: 'App 1', icon: 'app1' }],
|
||||
|
|
|
@ -10,12 +10,9 @@ import { sortBy } from 'lodash';
|
|||
import { BehaviorSubject, type Observable, ReplaySubject } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import type { HttpStart, IBasePath } from '@kbn/core-http-browser';
|
||||
import type { PublicAppDeepLinkInfo, PublicAppInfo } from '@kbn/core-application-browser';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
|
||||
import type {
|
||||
InternalApplicationStart,
|
||||
PublicAppDeepLinkInfo,
|
||||
PublicAppInfo,
|
||||
} from '../../application';
|
||||
import type { ChromeNavLink, NavLinkWrapper } from './nav_link';
|
||||
import { toNavLink } from './to_nav_link';
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
PublicAppInfo,
|
||||
AppNavLinkStatus,
|
||||
AppStatus,
|
||||
PublicAppDeepLinkInfo,
|
||||
} from '../../application';
|
||||
type PublicAppInfo,
|
||||
type PublicAppDeepLinkInfo,
|
||||
} from '@kbn/core-application-browser';
|
||||
import { toNavLink } from './to_nav_link';
|
||||
|
||||
import { httpServiceMock } from '../../mocks';
|
||||
|
|
|
@ -8,14 +8,13 @@
|
|||
|
||||
import type { IBasePath } from '@kbn/core-http-browser';
|
||||
import {
|
||||
type PublicAppInfo,
|
||||
AppNavLinkStatus,
|
||||
AppStatus,
|
||||
type PublicAppInfo,
|
||||
type PublicAppDeepLinkInfo,
|
||||
} from '../../application';
|
||||
|
||||
} from '@kbn/core-application-browser';
|
||||
import { appendAppPath } from '@kbn/core-application-browser-internal';
|
||||
import { NavLinkWrapper } from './nav_link';
|
||||
import { appendAppPath } from '../../application/utils';
|
||||
|
||||
export function toNavLink(
|
||||
app: PublicAppInfo,
|
||||
|
|
|
@ -23,10 +23,10 @@ import React, { Fragment, useMemo } from 'react';
|
|||
import useObservable from 'react-use/lib/useObservable';
|
||||
import * as Rx from 'rxjs';
|
||||
import type { HttpStart } from '@kbn/core-http-browser';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
import type { AppCategory } from '@kbn/core-application-common';
|
||||
|
||||
import type { ChromeNavLink, ChromeRecentlyAccessedHistoryItem } from '../..';
|
||||
import type { AppCategory } from '../../../../types';
|
||||
import type { InternalApplicationStart } from '../../../application/types';
|
||||
import type { OnIsLockedUpdate } from '.';
|
||||
import {
|
||||
createEuiListItem,
|
||||
|
|
|
@ -23,6 +23,7 @@ import React, { createRef, useState } from 'react';
|
|||
import useObservable from 'react-use/lib/useObservable';
|
||||
import type { Observable } from 'rxjs';
|
||||
import type { HttpStart } from '@kbn/core-http-browser';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
|
||||
import { LoadingIndicator } from '..';
|
||||
import type {
|
||||
|
@ -32,7 +33,6 @@ import type {
|
|||
ChromeNavLink,
|
||||
ChromeRecentlyAccessedHistoryItem,
|
||||
} from '../..';
|
||||
import type { InternalApplicationStart } from '../../../application/types';
|
||||
import type {
|
||||
ChromeBreadcrumbsAppendExtension,
|
||||
ChromeHelpExtension,
|
||||
|
|
|
@ -24,7 +24,7 @@ import {
|
|||
EuiHorizontalRule,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { InternalApplicationStart } from '../../../application';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
import { GITHUB_CREATE_ISSUE_LINK, KIBANA_FEEDBACK_LINK } from '../../constants';
|
||||
import { ChromeHelpExtension } from '../../types';
|
||||
import { HeaderExtension } from './header_extension';
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue