mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
URL service docs (#125697)
* improve sharing menu docs * improve locator docs * improve locator docs * add short URL docs * add tsconfig * update plugin list * add share plugin readme to dev docs * fix linter errors * update docs list Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
cc8b949b62
commit
6ee93e9470
9 changed files with 335 additions and 26 deletions
|
@ -238,9 +238,9 @@ oss plugins.
|
||||||
|The service exposed by this plugin informs consumers whether they should optimize for non-interactivity. In this way plugins can avoid loading unnecessary code, data or other services.
|
|The service exposed by this plugin informs consumers whether they should optimize for non-interactivity. In this way plugins can avoid loading unnecessary code, data or other services.
|
||||||
|
|
||||||
|
|
||||||
|{kib-repo}blob/{branch}/src/plugins/share/README.md[share]
|
|{kib-repo}blob/{branch}/src/plugins/share/README.mdx[share]
|
||||||
|The share plugin contains various utilities for displaying sharing context menu,
|
|The share plugin contains various utilities for displaying sharing context menu,
|
||||||
generating deep links to other apps, and creating short URLs.
|
generating deep links to other apps using locators, and creating short URLs.
|
||||||
|
|
||||||
|
|
||||||
|{kib-repo}blob/{branch}/src/plugins/shared_ux/README.md[sharedUX]
|
|{kib-repo}blob/{branch}/src/plugins/shared_ux/README.md[sharedUX]
|
||||||
|
|
3
examples/share_examples/README.md
Normal file
3
examples/share_examples/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Share plugin examples
|
||||||
|
|
||||||
|
Small demos of share plugin usage.
|
14
examples/share_examples/kibana.json
Normal file
14
examples/share_examples/kibana.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"id": "shareExamples",
|
||||||
|
"kibanaVersion": "kibana",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"server": false,
|
||||||
|
"ui": true,
|
||||||
|
"owner": {
|
||||||
|
"name": "App Services",
|
||||||
|
"githubTeam": "kibana-app-services"
|
||||||
|
},
|
||||||
|
"description": "Small demos of share plugin usage",
|
||||||
|
"requiredPlugins": ["share"],
|
||||||
|
"optionalPlugins": []
|
||||||
|
}
|
11
examples/share_examples/public/index.ts
Normal file
11
examples/share_examples/public/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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ShareDemoPlugin } from './plugin';
|
||||||
|
|
||||||
|
export const plugin = () => new ShareDemoPlugin();
|
42
examples/share_examples/public/plugin.tsx
Normal file
42
examples/share_examples/public/plugin.tsx
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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 { SharePluginStart, SharePluginSetup } from '../../../src/plugins/share/public';
|
||||||
|
import { Plugin, CoreSetup, CoreStart } from '../../../src/core/public';
|
||||||
|
|
||||||
|
interface SetupDeps {
|
||||||
|
share: SharePluginSetup;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StartDeps {
|
||||||
|
share: SharePluginStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ShareDemoPlugin implements Plugin<void, void, SetupDeps, StartDeps> {
|
||||||
|
public setup(core: CoreSetup<StartDeps>, { share }: SetupDeps) {
|
||||||
|
share.register({
|
||||||
|
id: 'demo',
|
||||||
|
getShareMenuItems: (context) => [
|
||||||
|
{
|
||||||
|
panel: {
|
||||||
|
id: 'demo',
|
||||||
|
title: 'Panel title',
|
||||||
|
content: 'Panel content',
|
||||||
|
},
|
||||||
|
shareMenuItem: {
|
||||||
|
name: 'Demo list item (from share_example plugin)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public start(core: CoreStart, { share }: StartDeps) {}
|
||||||
|
|
||||||
|
public stop() {}
|
||||||
|
}
|
18
examples/share_examples/tsconfig.json
Normal file
18
examples/share_examples/tsconfig.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./target/types"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"index.ts",
|
||||||
|
"public/**/*.ts",
|
||||||
|
"public/**/*.tsx",
|
||||||
|
"server/**/*.ts",
|
||||||
|
"../../typings/**/*"
|
||||||
|
],
|
||||||
|
"exclude": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "../../src/core/tsconfig.json" },
|
||||||
|
{ "path": "../../src/plugins/share/tsconfig.json" },
|
||||||
|
]
|
||||||
|
}
|
|
@ -48,7 +48,8 @@
|
||||||
},
|
},
|
||||||
{ "id": "kibDevTutorialCI" },
|
{ "id": "kibDevTutorialCI" },
|
||||||
{ "id": "kibDevTutorialServerEndpoint" },
|
{ "id": "kibDevTutorialServerEndpoint" },
|
||||||
{ "id": "kibDevTutorialAdvancedSettings"}
|
{ "id": "kibDevTutorialAdvancedSettings"},
|
||||||
|
{ "id": "kibDevSharePluginReadme"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
# Share plugin
|
|
||||||
|
|
||||||
The `share` plugin contains various utilities for displaying sharing context menu,
|
|
||||||
generating deep links to other apps, and creating short URLs.
|
|
||||||
|
|
||||||
|
|
||||||
## Sharing context menu
|
|
||||||
|
|
||||||
You can register an item into sharing context menu (which is displayed in
|
|
||||||
Dahsboard, Discover, and Visuzlize apps).
|
|
||||||
|
|
||||||
### Example registration
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { ShareContext, ShareMenuItem } from 'src/plugins/share/public';
|
|
||||||
|
|
||||||
plugins.share.register({
|
|
||||||
id: 'MY_MENU',
|
|
||||||
getShareMenuItems: (context: ShareContext): ShareMenuItem[] => {
|
|
||||||
// ...
|
|
||||||
},
|
|
||||||
};
|
|
||||||
```
|
|
243
src/plugins/share/README.mdx
Normal file
243
src/plugins/share/README.mdx
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
---
|
||||||
|
id: kibDevSharePluginReadme
|
||||||
|
slug: /kibana-dev-docs/tutorials/share
|
||||||
|
title: Kibana share Plugin
|
||||||
|
summary: Introduction to Kibana "share" plugin services (sharing popup menu, URL locators, and short URLs).
|
||||||
|
date: 2022-02-21
|
||||||
|
tags: ['kibana', 'onboarding', 'dev', 'tutorials', 'share', 'url', 'short-url', 'locator']
|
||||||
|
---
|
||||||
|
|
||||||
|
# Share plugin
|
||||||
|
|
||||||
|
The `share` plugin contains various utilities for displaying sharing context menu,
|
||||||
|
generating deep links to other apps using *locators*, and creating short URLs.
|
||||||
|
|
||||||
|
|
||||||
|
## Sharing context menu
|
||||||
|
|
||||||
|
You can register an item into sharing context menu (which is displayed in
|
||||||
|
Dashboard, Discover, and Visualize apps).
|
||||||
|
|
||||||
|
### Example registration
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { ShareContext, ShareMenuItem } from 'src/plugins/share/public';
|
||||||
|
|
||||||
|
plugins.share.register({
|
||||||
|
id: 'demo',
|
||||||
|
getShareMenuItems: (context) => [
|
||||||
|
{
|
||||||
|
panel: {
|
||||||
|
id: 'demo',
|
||||||
|
title: 'Panel title',
|
||||||
|
content: 'Panel content',
|
||||||
|
},
|
||||||
|
shareMenuItem: {
|
||||||
|
name: 'Demo list item (from share_example plugin)',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Now the "Demo list item" will appear under the "Share" menu in Discover and
|
||||||
|
Dashboard applications.
|
||||||
|
|
||||||
|
|
||||||
|
## Locators
|
||||||
|
|
||||||
|
*Locators* are entities which given some *parameters* can navigate Kibana user
|
||||||
|
to some deep link in Kibana or return back a full formatted URL.
|
||||||
|
|
||||||
|
Kibana apps create locators and expose them from their plugin contracts. Then
|
||||||
|
other plugins can use those locators to navigate deeply into Kibana applications.
|
||||||
|
|
||||||
|
Locators work, both, on the server and browser. However, it is the responsibility
|
||||||
|
of the app, which provides the locator, to register and expose the same locator
|
||||||
|
on the server and browser.
|
||||||
|
|
||||||
|
### Creating a locator for your Kibana app
|
||||||
|
|
||||||
|
A Kibana app can create one or more *locators*, which given an object of *parameters*
|
||||||
|
knows how to specify return a *Kibana location* 3-tuple. The 3-tuple consists of:
|
||||||
|
(1) the app ID; (2) a path within the app; (3) a serializable *location state* object.
|
||||||
|
The Kibana location 3-tuple is used to navigate the Kibana app in SPA (single page app)
|
||||||
|
way—without reloading the page.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import type { SerializableRecord } from '@kbn/utility-types';
|
||||||
|
import { LocatorDefinition, LocatorPublic } from 'src/plugins/share/public';
|
||||||
|
|
||||||
|
export interface HelloLocatorParams extends SerializableRecord {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type HelloLocator = LocatorPublic<HelloLocatorParams>;
|
||||||
|
|
||||||
|
export class HelloLocatorDefinition implements LocatorDefinition<HelloLocatorParams> {
|
||||||
|
public readonly id = 'HELLO_LOCATOR';
|
||||||
|
|
||||||
|
public readonly getLocation = async ({ name }: HelloLocatorParams) => {
|
||||||
|
return {
|
||||||
|
app: 'sampleAppId',
|
||||||
|
path: `/hello?name=${encodeURIComponent(name)}`,
|
||||||
|
state: {},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Once your locator has been defined, you need to register it in the central locator
|
||||||
|
registry with the `share` plugin:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const locator = plugins.share.url.locators.create(new HelloLocatorDefinition());
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then return the `locator` reference from your plugin contract fro consumption
|
||||||
|
by other plugins:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
class MyPlugin {
|
||||||
|
setup(core, plugins) {
|
||||||
|
const locator = plugins.share.url.locators.create(new HelloLocatorDefinition());
|
||||||
|
|
||||||
|
return {
|
||||||
|
locator,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using locator of another app
|
||||||
|
|
||||||
|
First you need to get access of the locator you want to use. Best way to do it is
|
||||||
|
by acquiring it from the plugin contract of the app you are interested to navigate
|
||||||
|
to. For example, you can get hold of the Dashboard app locator from the `dashboard`
|
||||||
|
plugin contract:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
class MyPlugin {
|
||||||
|
setup(core, plugins) {
|
||||||
|
const dashboardLocator = plugins.dashboard.locator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can also acquire any locator from the central registry in
|
||||||
|
the `share` plugin using the ID of the locator. This is useful, if you run into
|
||||||
|
circular dependency issues, however, it is better to acquire the locator directly
|
||||||
|
from the plugin contract as above, which makes dependencies explicit.
|
||||||
|
|
||||||
|
You can use the `.get()` method on the locators service to acquire the locator
|
||||||
|
from the central registry:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
class MyPlugin {
|
||||||
|
setup(core, plugins) {
|
||||||
|
const dashboardLocator = plugins.share.url.locators.get('DASHBOARD_APP_LOCATOR');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Once have have a reference to the desired locator object, you can use that locator
|
||||||
|
to navigate to various pages in Kibana or use it to build a URL string.
|
||||||
|
|
||||||
|
The best way to use the locator is to use its `.navigateSync()` method to navigate
|
||||||
|
in SPA way (without page reload):
|
||||||
|
|
||||||
|
```ts
|
||||||
|
dashboardLocator.navigateSync({ dashboardId: '123' });
|
||||||
|
```
|
||||||
|
|
||||||
|
The above will immediately navigate to the Dashboard app, to the dashboard with
|
||||||
|
ID `123`.
|
||||||
|
|
||||||
|
Another useful feature of locators is their ability to format a URL string of the
|
||||||
|
destination. The best way to do it is using the `.getRedirectUrl()` method
|
||||||
|
of locators.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const url = dashboardLocator.getRedirectUrl({ dashboardId: '123' });
|
||||||
|
```
|
||||||
|
|
||||||
|
The above will generate a *redirect* URL, which also preserves the serializable
|
||||||
|
*location state* object, which will be passed to the destination app.
|
||||||
|
|
||||||
|
Alternatively, for compatibility with old URL generators, you can also use the
|
||||||
|
`.getUrl()` method of locators to generate just the final app destination URL
|
||||||
|
string without the location state object.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const url = await dashboardLocator.getUrl({ dashboardId: '123' });
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, in this process you lose the location state object, which effectively
|
||||||
|
makes the final destination incorrect, if the app makes use of the location
|
||||||
|
state object.
|
||||||
|
|
||||||
|
For more ways working with locators see the `LocatorPublic` interface.
|
||||||
|
|
||||||
|
|
||||||
|
## Short URLs
|
||||||
|
|
||||||
|
The `share` plugin has Short URL service, which allows to create Kibana short
|
||||||
|
URLs. The service with the same interface is available, both, on the server
|
||||||
|
and browser.
|
||||||
|
|
||||||
|
When creating a short URL it is possible to use a custom short *slug*, used
|
||||||
|
to dereference the short URL. Also, a human-readable short slug can be
|
||||||
|
automatically generated.
|
||||||
|
|
||||||
|
First, to be able to create a short URL, one needs to get hold of a locator
|
||||||
|
reference, for which the short URL will be created. (See above section on
|
||||||
|
*Locators* for more info.) Lets say we want to create a short URL for the
|
||||||
|
Dashboard application, for that, we first acquire reference to the dashboard
|
||||||
|
locator:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
class MyPlugin {
|
||||||
|
setup(core, plugins) {
|
||||||
|
const dashboardLocator = plugins.dashboard.locator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can create a short URL using your locator and the short URL service:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const shortUrls = plugins.share.url.shortUrls.get(null);
|
||||||
|
const url = await shortUrls.create({
|
||||||
|
locator,
|
||||||
|
params: {
|
||||||
|
dashboardId: '123',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can make the short URL slug human-readable by specifying the
|
||||||
|
`humanReadableSlug` flag:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const url = await shortUrls.create({
|
||||||
|
locator,
|
||||||
|
params: {
|
||||||
|
dashboardId: '123',
|
||||||
|
},
|
||||||
|
humanReadableSlug: true,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Or you can manually specify the slug for the short URL using the `slug` option:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const url = await shortUrls.create({
|
||||||
|
locator,
|
||||||
|
params: {
|
||||||
|
dashboardId: '123',
|
||||||
|
},
|
||||||
|
slug: 'my-slug',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
To resolve the short URL, navigate to `/r/s/<slug>` in the browser.
|
Loading…
Add table
Add a link
Reference in a new issue