-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Lens][Dashboard] Adding Lens to Dashboard #53110
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
283ca5b
First version of adding Lens to dashboard
1842088
Fix failing unit test
57bef33
Replacing explicit Lens query param with a more generic one
75a3d26
Fixing failing unit test
449d5f4
Adding a unit test for redirect
e50a051
Do not show Save New if adding from Dashboard
3411d59
Adding functional test
a316315
Adding functional test
452b4dc
Fixing type issues
494b855
Renaming query params
12c3142
Fixing failing unit test
3a39424
Removing unused constants
d28733e
Fixing erroneous imports
e44ce7a
Fixing erroneous import
e335b91
Fixing import
1bfec16
Fix failing typecheck
bbfcc34
Removing timefilter from Dashboard URL
8022cea
Fixing type error
64e6ceb
Replacing time parsing with rison
fe9ab85
Merge branch 'master' into add-lens-to-dash
elasticmachine 25010ff
Replacing URL regex parsing with legacy URLs
f78bdc7
Fixing failing test
9e15430
Merge branch 'master' into add-lens-to-dash
elasticmachine File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
117 changes: 117 additions & 0 deletions
117
src/legacy/core_plugins/kibana/public/dashboard/__tests__/url_helper.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
jest.mock('../', () => ({ | ||
DashboardConstants: { | ||
ADD_EMBEDDABLE_ID: 'addEmbeddableId', | ||
ADD_EMBEDDABLE_TYPE: 'addEmbeddableType', | ||
}, | ||
})); | ||
|
||
jest.mock('../legacy_imports', () => { | ||
return { | ||
absoluteToParsedUrl: jest.fn(() => { | ||
return { | ||
basePath: '/pep', | ||
appId: 'kibana', | ||
appPath: '/dashboard?addEmbeddableType=lens&addEmbeddableId=123eb456cd&x=1&y=2&z=3', | ||
hostname: 'localhost', | ||
port: 5601, | ||
protocol: 'http:', | ||
addQueryParameter: () => {}, | ||
getAbsoluteUrl: () => { | ||
return 'http://localhost:5601/pep/app/kibana#/dashboard?addEmbeddableType=lens&addEmbeddableId=123eb456cd&x=1&y=2&z=3'; | ||
}, | ||
}; | ||
}), | ||
}; | ||
}); | ||
|
||
import { | ||
addEmbeddableToDashboardUrl, | ||
getLensUrlFromDashboardAbsoluteUrl, | ||
getUrlVars, | ||
} from '../np_ready/url_helper'; | ||
|
||
describe('Dashboard URL Helper', () => { | ||
beforeEach(() => { | ||
jest.resetModules(); | ||
}); | ||
|
||
it('addEmbeddableToDashboardUrl', () => { | ||
const id = '123eb456cd'; | ||
const type = 'lens'; | ||
const urlVars = { | ||
x: '1', | ||
y: '2', | ||
z: '3', | ||
}; | ||
const basePath = '/pep'; | ||
const url = | ||
"http://localhost:5601/pep/app/kibana#/dashboard?_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_a=(description:'',filters:!()"; | ||
expect(addEmbeddableToDashboardUrl(url, basePath, id, urlVars, type)).toEqual( | ||
`http://localhost:5601/pep/app/kibana#/dashboard?addEmbeddableType=${type}&addEmbeddableId=${id}&x=1&y=2&z=3` | ||
); | ||
}); | ||
|
||
it('getUrlVars', () => { | ||
let url = | ||
"http://localhost:5601/app/kibana#/dashboard?_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_a=(description:'',filters:!()"; | ||
expect(getUrlVars(url)).toEqual({ | ||
_g: '(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))', | ||
_a: "(description:'',filters:!()", | ||
}); | ||
url = 'http://mybusiness.mydomain.com/app/kibana#/dashboard?x=y&y=z'; | ||
expect(getUrlVars(url)).toEqual({ | ||
x: 'y', | ||
y: 'z', | ||
}); | ||
url = 'http://notDashboardUrl'; | ||
expect(getUrlVars(url)).toEqual({}); | ||
url = 'http://localhost:5601/app/kibana#/dashboard/777182'; | ||
expect(getUrlVars(url)).toEqual({}); | ||
}); | ||
|
||
it('getLensUrlFromDashboardAbsoluteUrl', () => { | ||
const id = '1244'; | ||
const basePath = '/wev'; | ||
let url = | ||
"http://localhost:5601/wev/app/kibana#/dashboard?_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_a=(description:'',filters:!()"; | ||
expect(getLensUrlFromDashboardAbsoluteUrl(url, basePath, id)).toEqual( | ||
'http://localhost:5601/wev/app/kibana#/lens/edit/1244' | ||
); | ||
|
||
url = | ||
"http://localhost:5601/wev/app/kibana#/dashboard/625357282?_a=(description:'',filters:!()&_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))"; | ||
expect(getLensUrlFromDashboardAbsoluteUrl(url, basePath, id)).toEqual( | ||
'http://localhost:5601/wev/app/kibana#/lens/edit/1244' | ||
); | ||
|
||
url = 'http://myserver.mydomain.com:5601/wev/app/kibana#/dashboard/777182'; | ||
expect(getLensUrlFromDashboardAbsoluteUrl(url, basePath, id)).toEqual( | ||
'http://myserver.mydomain.com:5601/wev/app/kibana#/lens/edit/1244' | ||
); | ||
|
||
url = | ||
"http://localhost:5601/app/kibana#/dashboard?_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now))&_a=(description:'',filters:!()"; | ||
expect(getLensUrlFromDashboardAbsoluteUrl(url, '', id)).toEqual( | ||
'http://localhost:5601/app/kibana#/lens/edit/1244' | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
src/legacy/core_plugins/kibana/public/dashboard/np_ready/url_helper.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
import { parse } from 'url'; | ||
import { absoluteToParsedUrl } from '../legacy_imports'; | ||
import { DashboardConstants } from './dashboard_constants'; | ||
/** | ||
* Return query params from URL | ||
* @param url given url | ||
*/ | ||
export function getUrlVars(url: string): Record<string, string> { | ||
const vars: Record<string, string> = {}; | ||
// @ts-ignore | ||
url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(_, key, value) { | ||
// @ts-ignore | ||
vars[key] = value; | ||
}); | ||
return vars; | ||
} | ||
|
||
/** * | ||
* Returns dashboard URL with added embeddableType and embeddableId query params | ||
* eg. | ||
* input: url: http://localhost:5601/lib/app/kibana#/dashboard?_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now)), embeddableId: 12345, embeddableType: 'lens' | ||
* output: http://localhost:5601/lib/app/kibana#dashboard?addEmbeddableType=lens&addEmbeddableId=12345&_g=(refreshInterval:(pause:!t,value:0),time:(from:now-15m,to:now)) | ||
* @param url dasbhoard absolute url | ||
* @param embeddableId id of the saved visualization | ||
* @param basePath current base path | ||
* @param urlVars url query params (optional) | ||
* @param embeddableType 'lens' or 'visualization' (optional, default is 'lens') | ||
*/ | ||
export function addEmbeddableToDashboardUrl( | ||
url: string | undefined, | ||
basePath: string, | ||
embeddableId: string, | ||
urlVars?: Record<string, string>, | ||
embeddableType?: string | ||
): string | null { | ||
if (!url) { | ||
return null; | ||
} | ||
const dashboardUrl = getUrlWithoutQueryParams(url); | ||
const dashboardParsedUrl = absoluteToParsedUrl(dashboardUrl, basePath); | ||
if (urlVars) { | ||
const keys = Object.keys(urlVars).sort(); | ||
keys.forEach(key => { | ||
dashboardParsedUrl.addQueryParameter(key, urlVars[key]); | ||
}); | ||
} | ||
dashboardParsedUrl.addQueryParameter( | ||
DashboardConstants.ADD_EMBEDDABLE_TYPE, | ||
embeddableType || 'lens' | ||
); | ||
dashboardParsedUrl.addQueryParameter(DashboardConstants.ADD_EMBEDDABLE_ID, embeddableId); | ||
return dashboardParsedUrl.getAbsoluteUrl(); | ||
} | ||
|
||
/** | ||
* Return Lens URL from dashboard absolute URL | ||
* @param dashboardAbsoluteUrl | ||
* @param basePath current base path | ||
* @param id Lens id | ||
*/ | ||
export function getLensUrlFromDashboardAbsoluteUrl( | ||
dashboardAbsoluteUrl: string | undefined | null, | ||
basePath: string | null | undefined, | ||
id: string | ||
): string | null { | ||
if (!dashboardAbsoluteUrl || basePath === null || basePath === undefined) { | ||
return null; | ||
} | ||
const { host, protocol } = parse(dashboardAbsoluteUrl); | ||
return `${protocol}//${host}${basePath}/app/kibana#/lens/edit/${id}`; | ||
} | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the documentation, that's very helpful! |
||
* Returns the portion of the URL without query params | ||
* eg. | ||
* input: http://localhost:5601/lib/app/kibana#/dashboard?param1=x¶m2=y¶m3=z | ||
* output:http://localhost:5601/lib/app/kibana#/dashboard | ||
* input: http://localhost:5601/lib/app/kibana#/dashboard/39292992?param1=x¶m2=y¶m3=z | ||
* output: http://localhost:5601/lib/app/kibana#/dashboard/39292992 | ||
* @param url url to parse | ||
*/ | ||
function getUrlWithoutQueryParams(url: string): string { | ||
return url.split('?')[0]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's an interesting usage of
replace
. However I think we can usematchAll
in this scenario:Then you don;t need any
ts-ignore
s.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was taken from here:
kibana/x-pack/legacy/plugins/ml/public/application/jobs/jobs_list/components/utils.js
Line 374 in 8e9a8a8
So I assumed it was well-tested. But I like any suggestion that gets rid of ts-ignore directives 👍