Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Search][Dashboard] Restore searchSessionId from URL #81489

Merged
merged 2 commits into from
Nov 4, 2020

Conversation

Dosant
Copy link
Contributor

@Dosant Dosant commented Oct 22, 2020

Build on top of #81297
Part of #61738

Summary

  • Restore searchSessionId from URL
  • Add searchSessionId support to dashboard's URL generator

Additional info

  • Didn't do any additional handling to return to background search using back button. I spent some time trying to make it reliable, but I think to make it work in 100% of case it will require additional work and refactoring around dashboard state management. (Unless I missed something obvious) Created a ticket, please see explanation of the problem: [Search][State Management] Restoring background session and back button #82419

How to test

You can build a dashboard URL with fake session id:

${dashboardURL}&searchSessionId=__fake__

Open it.
And you should see __fake__ as session id in inspector.

^^ this is what a functional test does

Checklist

Delete any items that are not applicable to this PR.

@Dosant Dosant added Feature:Search Querying infrastructure in Kibana Feature:Dashboard Dashboard related features v8.0.0 Team:AppArch release_note:skip Skip the PR/issue when compiling release notes v7.11.0 labels Oct 22, 2020
Copy link
Member

@lukasolson lukasolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we merge with master to avoid the noise of the previous PR? Thanks!

import { parse, ParsedQuery } from 'query-string';
import { Location } from 'history';

export function getQueryParams(location: Location): ParsedQuery {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very similar to the utility in src/plugins/es_ui_shared/public/url/extract_query_params.ts. Not sure the best approach here but it would be nice if we could combine these.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for point me to it!
I extracted my function from existing history helper (in kibana_utils) so technically I didn't introduce new code.
I decided to leave as is keeping dashboard -> kibana_utils dep and not introducing dashboard -> es_ui dep.

Probably ideally es_ui_shared/public/url/extract_query_params.ts should be removed and utility from kibana_utils should be used instead, but es_ui_shared is not dependent on kibana_utils today, so doesn't worth introducing dependency to maintain for these couple lines.

import { parse, ParsedQuery } from 'query-string';
import { Location } from 'history';

export function getQueryParams(location: Location): ParsedQuery {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we make this generic, can we avoid the cast as string above?

Suggested change
export function getQueryParams(location: Location): ParsedQuery {
export function getQueryParams<T>(location: Location): ParsedQuery<T> {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked into it,
ParsedQuery<T> is a weird loose type:

export interface ParsedQuery<T = string> {
	[key: string]: T | T[] | null;
}

that attempt to cover all the query cases and doesn't cover undefined.
T in that case is just type of value in query object.

So I guess possible way to improve with typecasting for us is something like:

export function getQueryParams<T>(location: Location): T {
 return query as unknown as T
}

But I think this is worth then current downcasting on consumer level, because this involves unknown

@Dosant Dosant marked this pull request as ready for review November 2, 2020 13:21
@Dosant Dosant requested a review from a team as a code owner November 2, 2020 13:21
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-arch (Team:AppArch)

Copy link
Member

@lukasolson lukasolson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Added a nit below and just wanted to confirm: Is this the first place we're using actual query parameters instead of stuffing things in the _a or _g (app/global state)? Are there any ramifications of this we need to be aware of?

Also wanted to note that I tested this and things seemed to function as expected (sessionId was properly set and displayed in the inspector and properly cleared when making a change that resulted in a re-fetch, which generated a new sessionId).

@@ -120,6 +126,9 @@ interface UrlParamValues extends Omit<UrlParamsSelectedMap, UrlParams.SHOW_FILTE
[UrlParams.HIDE_FILTER_BAR]: boolean;
}

const getSearchSessionIdFromURL = (history: History): string | undefined =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This would probably make more sense inside src/plugins/dashboard/public/url_generator.ts. We could add a test for it there too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am keeping it separate because it depends on client side history and url_generator stuff shouldn't depend on it and should be moved to common eventually.

@Dosant
Copy link
Contributor Author

Dosant commented Nov 3, 2020

@lukasolson,

Is this the first place we're using actual query parameters instead of stuffing things in the _a or _g (app/global state)? Are there any ramifications of this we need to be aware of?

No, this is not the first place. Dashboard has bunch of other query params options.

Reasons I thought we are better of with separate query param:

  1. From dashboard perspective _a state is stored is stored in the saved object. We don't need to store sessionId in saved object.
  2. Each change of state which is synced with _a is normally synced back to the URL. But we don't want newly created search ids synced back
  3. It seemed that If we try to put sessionId into state management part of dashboard then becomes more complicated in the following way that a single change causes two separate state changes: Change filter -> trigger state change -> trigger new search -> again trigger state change to persist new sessionId

Copy link
Contributor

@ThomThomson ThomThomson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally in chrome. Restoring a search session works well, and everything else still works as expected. Tests and code LGTM!

);

if (state.searchSessionId) {
url = `${url}&${DashboardConstants.SEARCH_SESSION_ID}=${state.searchSessionId}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

//nit
We don't have any function in our code base to serialize url params?

Copy link
Contributor Author

@Dosant Dosant Nov 3, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would be
import { stringify } from 'query-string'; but I guess in this particular case using it would add more code then not using it

(can't benefit from it for _a & _g params here because their helpers already handling everything)

Copy link
Contributor

@lizozom lizozom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Added one nit

@Dosant
Copy link
Contributor Author

Dosant commented Nov 3, 2020

@elasticmachine merge upstream

@kibanamachine kibanamachine requested a review from a team as a code owner November 3, 2020 17:43
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

@kbn/optimizer bundle module count

id before after diff
kibanaUtils 189 190 +1

async chunks size

id before after diff
dashboard 197.6KB 198.0KB +486.0B

page load bundle size

id before after diff
dashboard 311.4KB 311.5KB +154.0B
kibanaUtils 147.8KB 148.0KB +180.0B
total +334.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Dashboard Dashboard related features Feature:Search Querying infrastructure in Kibana release_note:skip Skip the PR/issue when compiling release notes v7.11.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants