Skip to content

Commit c051d65

Browse files
committed
Merge branch 'master' into alerts/alerting-exempt-rbac-remnant
* master: (55 commits) [Grok] Fix missing error message in error toasts (#77499) [Alerting] Exempt Alerts pre 7.10 from RBAC on their Action execution until updated (#75563) [ML] fix type in apply_influencer_filters_action (#77495) [Lens] create reusable component for filters and range aggregation (#77453) fix eslint violations Collapse alert chart previews by default (#77479) [ML] Fixing field caps wrapper endpoint (#77546) showing service maps when filte by environment not defined (#77483) [Lens] Settings panel redesign and separate settings per y axis (#76373) log request body in new ES client (#77150) use `navigateToUrl` to navigate to recent nav links (#77446) Move core config service to `kbn/config` package (#76874) [UBI] Copy license to /licenses folder (#77563) Skip flaky Events Viewer Cypress test [Lens] Remove dynamic names in telemetry fields (#76988) [Maps] Add DynamicStyleProperty#getMbPropertyName and DynamicStyleProperty#getMbPropertyValue (#77366) [Enterprise Search] Add flag to restrict width of layout (#77539) [Security Solutions][Cases - Timeline] Fix bug when adding a timeline to a case (#76967) [Security Solution][Detections] Integration test for Editing a Rule (#77090) [Ingest pipelines] Polish pipeline debugging workflow (#76058) ...
2 parents e891d14 + f70aace commit c051d65

File tree

993 files changed

+20334
-15763
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

993 files changed

+20334
-15763
lines changed

.github/CODEOWNERS

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,12 @@
6464
/src/apm.js @watson @vigneshshanmugam
6565

6666
# Client Side Monitoring (lives in APM directories but owned by Uptime)
67-
/x-pack/plugins/apm/e2e/cypress/support/step_definitions/rum @elastic/uptime
67+
/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm @elastic/uptime
6868
/x-pack/plugins/apm/public/application/csmApp.tsx @elastic/uptime
6969
/x-pack/plugins/apm/public/components/app/RumDashboard @elastic/uptime
7070
/x-pack/plugins/apm/server/lib/rum_client @elastic/uptime
7171
/x-pack/plugins/apm/server/routes/rum_client.ts @elastic/uptime
72+
/x-pack/plugins/apm/server/projections/rum_overview.ts @elastic/uptime
7273

7374
# Beats
7475
/x-pack/legacy/plugins/beats_management/ @elastic/beats
@@ -129,6 +130,7 @@
129130
/packages/kbn-test/ @elastic/kibana-operations
130131
/packages/kbn-ui-shared-deps/ @elastic/kibana-operations
131132
/packages/kbn-es-archiver/ @elastic/kibana-operations
133+
/packages/kbn-utils/ @elastic/kibana-operations
132134
/src/legacy/server/keystore/ @elastic/kibana-operations
133135
/src/legacy/server/pid/ @elastic/kibana-operations
134136
/src/legacy/server/sass/ @elastic/kibana-operations
@@ -153,6 +155,7 @@
153155
/x-pack/plugins/cloud/ @elastic/kibana-platform
154156
/x-pack/test/saved_objects_field_count/ @elastic/kibana-platform
155157
/packages/kbn-config-schema/ @elastic/kibana-platform
158+
/packages/kbn-std/ @elastic/kibana-platform
156159
/src/legacy/server/config/ @elastic/kibana-platform
157160
/src/legacy/server/http/ @elastic/kibana-platform
158161
/src/legacy/server/logging/ @elastic/kibana-platform
@@ -294,6 +297,7 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib
294297
/x-pack/plugins/infra/**/*.scss @elastic/observability-design
295298
/x-pack/plugins/ingest_manager/**/*.scss @elastic/observability-design
296299
/x-pack/plugins/observability/**/*.scss @elastic/observability-design
300+
/x-pack/plugins/monitoring/**/*.scss @elastic/observability-design
297301

298302
# Ent. Search design
299303
/x-pack/plugins/enterprise_search/**/*.scss @elastic/ent-search-design
161 KB
Loading

docs/developer/best-practices/index.asciidoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,14 @@ In addition, if users are relying on state stored in your app’s URL as
122122
part of your public contract, keep in mind that you may also need to
123123
provide backwards compatibility for bookmarked URLs.
124124

125+
[discrete]
126+
=== Routing, Navigation and URL
127+
128+
The {kib} platform provides a set of tools to help developers build consistent experience around routing and browser navigation.
129+
Some of that tooling is inside `core`, some is available as part of various plugins.
130+
131+
<<kibana-navigation, Follow this guide>> to get an idea of available tools and common approaches for handling routing and browser navigation.
132+
125133
[discrete]
126134
=== Testing & stability
127135

@@ -131,6 +139,8 @@ Review:
131139
* <<stability>>
132140
* <<security-best-practices>>
133141

142+
include::navigation.asciidoc[leveloffset=+1]
143+
134144
include::stability.asciidoc[leveloffset=+1]
135145

136146
include::security.asciidoc[leveloffset=+1]
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
[[kibana-navigation]]
2+
== Routing, Navigation and URL
3+
4+
The {kib} platform provides a set of tools to help developers build consistent experience around routing and browser navigation.
5+
Some of that tooling is inside `core`, some is available as part of various plugins.
6+
7+
The purpose of this guide is to give a high-level overview of available tools and to explain common approaches for handling routing and browser navigation.
8+
9+
This guide covers following topics:
10+
11+
* <<deep-linking>>
12+
* <<navigating-between-kibana-apps>>
13+
* <<routing>>
14+
* <<history-and-location>>
15+
* <<state-sync>>
16+
* <<preserve-state>>
17+
18+
[[deep-linking]]
19+
=== Deep-linking into {kib} apps
20+
21+
Assuming you want to link from your app to *Discover*. When building such URL there are two things to consider:
22+
23+
1. Prepending a proper `basePath`.
24+
2. Specifying *Discover* state.
25+
26+
==== Prepending a proper `basePath`
27+
28+
To prepend {kib}'s `basePath` use {kib-repo}tree/{branch}/docs/development/core/public/kibana-plugin-core-public.ibasepath.prepend.md[core.http.basePath.prepend] helper:
29+
30+
[source,typescript jsx]
31+
----
32+
const discoverUrl = core.http.basePath.prepend(`/discover`);
33+
34+
console.log(discoverUrl); // http://localhost:5601/bpr/s/space/app/discover
35+
----
36+
37+
==== Specifying state
38+
39+
**Consider a {kib} app URL a part of app's plugin contract:**
40+
41+
. Avoid hardcoding other app's URL in your app's code.
42+
. Avoid generating other app's state and serializing it into URL query params.
43+
44+
[source,typescript jsx]
45+
----
46+
// Avoid relying on other app's state structure in your app's code:
47+
const discoverUrlWithSomeState = core.http.basePath.prepend(`/discover#/?_g=(filters:!(),refreshInterval:(pause:!t,value:0),time:(from:'2020-09-10T11:39:50.203Z',to:'2020-09-10T11:40:20.249Z'))&_a=(columns:!(_source),filters:!(),index:'90943e30-9a47-11e8-b64d-95841ca0b247',interval:auto,query:(language:kuery,query:''),sort:!())`);
48+
----
49+
50+
Instead, each app should expose {kib-repo}tree/{branch}/src/plugins/share/public/url_generators/README.md[a URL generator].
51+
Other apps should use those URL generators for creating URLs.
52+
53+
[source,typescript jsx]
54+
----
55+
// Properly generated URL to *Discover* app. Generator code is owned by *Discover* app and available on *Discover*'s plugin contract.
56+
const discoverUrl = discoverUrlGenerator.createUrl({filters, timeRange});
57+
----
58+
59+
To get a better idea, take a look at *Discover* URL generator {kib-repo}tree/{branch}/src/plugins/discover/public/url_generator.ts[implementation].
60+
It allows specifying various **Discover** app state pieces like: index pattern, filters, query, time range and more.
61+
62+
There are two ways to access other's app URL generator in your code:
63+
64+
1. From a plugin contract of a destination app *(preferred)*.
65+
2. Using URL generator service instance on `share` plugin contract (in case an explicit plugin dependency is not possible).
66+
67+
In case you want other apps to link to your app, then you should create a URL generator and expose it on your plugin's contract.
68+
69+
70+
[[navigating-between-kibana-apps]]
71+
=== Navigating between {kib} apps
72+
73+
{kib} is a single page application and there is a set of simple rules developers should follow
74+
to make sure there is no page reload when navigating from one place in {kib} to another.
75+
76+
For example, navigation using native browser APIs would cause a full page reload.
77+
78+
[source,js]
79+
----
80+
const urlToADashboard = core.http.basePath.prepend(`/dashboard/my-dashboard`);
81+
82+
// this would cause a full page reload:
83+
window.location.href = urlToADashboard;
84+
----
85+
86+
To navigate between different {kib} apps without a page reload there are APIs in `core`:
87+
88+
* {kib-repo}tree/{branch}/docs/development/core/public/kibana-plugin-core-public.applicationstart.navigatetoapp.md[core.application.navigateToApp]
89+
* {kib-repo}tree/{branch}/docs/development/core/public/kibana-plugin-core-public.applicationstart.navigatetourl.md[core.application.navigateToUrl]
90+
91+
*Rendering a link to a different {kib} app on its own would also cause a full page reload:*
92+
93+
[source,typescript jsx]
94+
----
95+
const myLink = () =>
96+
<a href={urlToADashboard}>Go to Dashboard</a>;
97+
----
98+
99+
A workaround could be to handle a click, prevent browser navigation and use `core.application.navigateToApp` API:
100+
101+
[source,typescript jsx]
102+
----
103+
const MySPALink = () =>
104+
<a
105+
href={urlToADashboard}
106+
onClick={(e) => {
107+
e.preventDefault();
108+
core.application.navigateToApp('dashboard', { path: '/my-dashboard' });
109+
}}
110+
>
111+
Go to Dashboard
112+
</a>;
113+
----
114+
115+
As it would be too much boilerplate to do this for each {kib} link in your app, there is a handy wrapper that helps with it:
116+
{kib-repo}tree/{branch}/src/plugins/kibana_react/public/app_links/redirect_app_link.tsx#L49[RedirectAppLinks].
117+
118+
[source,typescript jsx]
119+
----
120+
const MyApp = () =>
121+
<RedirectAppLinks application={core.application}>
122+
{/*...*/}
123+
{/* navigations using this link will happen in SPA friendly way */}
124+
<a href={urlToADashboard}>Go to Dashboard</a>
125+
{/*...*/}
126+
</RedirectAppLinks>
127+
----
128+
129+
[[routing]]
130+
=== Setting up internal app routing
131+
132+
It is very common for {kib} apps to use React and React Router.
133+
Common rules to follow in this scenario:
134+
135+
* Set up `BrowserRouter` and not `HashRouter`.
136+
* *Initialize your router with `history` instance provided by the `core`.*
137+
138+
This is required to make sure `core` is aware of navigations triggered inside your app, so it could act accordingly when needed.
139+
140+
* `Core`'s {kib-repo}tree/{branch}/docs/development/core/public/kibana-plugin-core-public.scopedhistory.md[ScopedHistory] instance.
141+
* {kib-repo}tree/{branch}/docs/development/core/public/kibana-plugin-core-public.appmountparameters.history.md[Example usage]
142+
* {kib-repo}tree/{branch}/test/plugin_functional/plugins/core_plugin_a/public/application.tsx#L120[Example plugin]
143+
144+
Relative links will be resolved relative to your app's route (e.g.: `http://localhost5601/app/{your-app-id}`)
145+
and setting up internal links in your app in SPA friendly way would look something like:
146+
147+
[source,typescript jsx]
148+
----
149+
import {Link} from 'react-router-dom';
150+
151+
const MyInternalLink = () => <Link to="/my-other-page"></Link>
152+
----
153+
154+
[[history-and-location]]
155+
=== Using history and browser location
156+
157+
Try to avoid using `window.location` and `window.history` directly. +
158+
Instead, consider using {kib-repo}tree/{branch}/docs/development/core/public/kibana-plugin-core-public.scopedhistory.md[ScopedHistory]
159+
instance provided by `core`.
160+
161+
* This way `core` will know about location changes triggered within your app, and it would act accordingly.
162+
* Some plugins are listening to location changes. Triggering location change manually could lead to unpredictable and hard-to-catch bugs.
163+
164+
Common use-case for using
165+
`core`'s {kib-repo}tree/{branch}/docs/development/core/public/kibana-plugin-core-public.scopedhistory.md[ScopedHistory] directly:
166+
167+
* Reading/writing query params or hash.
168+
* Imperatively triggering internal navigations within your app.
169+
* Listening to browser location changes.
170+
171+
172+
[[state-sync]]
173+
=== Syncing state with URL
174+
175+
Historically {kib} apps store _a lot_ of application state in the URL.
176+
The most common pattern that {kib} apps follow today is storing state in `_a` and `_g` query params in https://github.com/w33ble/rison-node#readme[rison] format.
177+
[[query-params]]
178+
Those query params follow the convention:
179+
180+
* `_g` (*global*) - global UI state that should be shared and synced across multiple apps. common example from Analyze group apps: time range, refresh interval, *pinned* filters.
181+
* `_a` (*application*) - UI state scoped to current app.
182+
183+
NOTE: After migrating to KP platform we got navigations without page reloads. Since then there is no real need to follow `_g` and `_a` separation anymore. It's up you to decide if you want to follow this pattern or if you prefer a single query param or something else. The need for this separation earlier is explained in <<preserve-state>>.
184+
185+
There are utils to help you to implement such kind of state syncing.
186+
187+
**When you should consider using state syncing utils:**
188+
189+
* You want to sync your application state with URL in similar manner Analyze group applications do.
190+
* You want to follow platform's <<history-and-location, working with browser history and location best practices>> out of the box.
191+
* You want to support `state:storeInSessionStore` escape hatch for URL overflowing out of the box.
192+
* You should also consider using them if you'd like to serialize state to different (not `rison`) format. Utils are composable, and you can implement your own `storage`.
193+
* In case you want to sync part of your state with URL, but other part of it with browser storage.
194+
195+
**When you shouldn't use state syncing utils:**
196+
197+
* Adding a query param flag or simple key/value to the URL.
198+
199+
Follow {kib-repo}tree/{branch}/src/plugins/kibana_utils/docs/state_sync#state-syncing-utilities[these] docs to learn more.
200+
201+
202+
[[preserve-state]]
203+
=== Preserving state between navigations
204+
205+
Consider the scenario:
206+
207+
1. You are in *Dashboard* app looking at a dashboard with some filters applied;
208+
2. Navigate to *Discover* using in-app navigation;
209+
3. Change the time filter'
210+
4. Navigate to *Dashboard* using in-app navigation.
211+
212+
You'd notice that you were navigated to *Dashboard* app with the *same state* that you left it with,
213+
except that the time filter has changed to the one you applied on *Discover* app.
214+
215+
Historically {kib} Analyze groups apps achieve that behavior relying on state in the URL.
216+
If you'd have a closer look on a link in the navigation,
217+
you'd notice that state is stored inside that link, and it also gets updated whenever relevant state changes happen:
218+
219+
[role="screenshot"]
220+
image:images/state_inside_the_link.png[State is stored inside the navigation link]
221+
222+
This is where <<query-params, separation>> into `_a` and `_g` query params comes into play. What is considered a *global* state gets constantly updated in those navigation links. In the example above it was a time filter.
223+
This is backed by {kib-repo}tree/{branch}/src/plugins/kibana_utils/public/state_management/url/kbn_url_tracker.ts#L57[KbnUrlTracker] util. You can use it to achieve similar behavior.
224+
225+
NOTE: After migrating to KP navigation works without page reloads and all plugins are loaded simultaneously.
226+
Hence, likely there are simpler ways to preserve state of your application, unless you want to do it through URL.

docs/developer/plugin/external-plugin-functional-tests.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ To get started copy and paste this example to `test/functional/config.js`:
1313
["source","js"]
1414
-----------
1515
import { resolve } from 'path';
16-
import { REPO_ROOT } from '@kbn/dev-utils';
16+
import { REPO_ROOT } from '@kbn/utils';
1717
1818
import { MyServiceProvider } from './services/my_service';
1919
import { MyAppPageProvider } from './services/my_app_page';

docs/development/core/public/kibana-plugin-core-public.assertnever.md

Lines changed: 0 additions & 24 deletions
This file was deleted.

docs/development/core/public/kibana-plugin-core-public.deepfreeze.md

Lines changed: 0 additions & 24 deletions
This file was deleted.

docs/development/core/public/kibana-plugin-core-public.environmentmode.dev.md

Lines changed: 0 additions & 11 deletions
This file was deleted.

docs/development/core/public/kibana-plugin-core-public.environmentmode.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

docs/development/core/public/kibana-plugin-core-public.environmentmode.name.md

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)