-
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
Allow to define and update a defaultPath for applications #64498
Changes from all commits
071ee2e
3ae2f6e
a5a3554
52538ae
08d81af
5122bbb
62115a1
484f9f9
8fb0107
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [AppBase](./kibana-plugin-core-public.appbase.md) > [defaultPath](./kibana-plugin-core-public.appbase.defaultpath.md) | ||
|
||
## AppBase.defaultPath property | ||
|
||
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 [navigateToApp](./kibana-plugin-core-public.applicationstart.navigatetoapp.md)<!-- -->\`<!-- -->, and will also be appended to the [application navLink](./kibana-plugin-core-public.chromenavlink.md) in the navigation bar. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
defaultPath?: string; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,13 @@ export interface AppBase { | |
*/ | ||
navLinkStatus?: AppNavLinkStatus; | ||
|
||
/** | ||
* 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; | ||
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. Note: this is on 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. should we mark it as 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. It's not deprecated. It's just that even if on |
||
|
||
/** | ||
* An {@link AppUpdater} observable that can be used to update the application {@link AppUpdatableFields} at runtime. | ||
* | ||
|
@@ -187,7 +194,10 @@ export enum AppNavLinkStatus { | |
* Defines the list of fields that can be updated via an {@link AppUpdater}. | ||
* @public | ||
*/ | ||
export type AppUpdatableFields = Pick<AppBase, 'status' | 'navLinkStatus' | 'tooltip'>; | ||
export type AppUpdatableFields = Pick< | ||
AppBase, | ||
'status' | 'navLinkStatus' | 'tooltip' | 'defaultPath' | ||
>; | ||
|
||
/** | ||
* Updater for applications. | ||
|
@@ -642,7 +652,8 @@ export interface ApplicationStart { | |
* Navigate to a given app | ||
* | ||
* @param appId | ||
* @param options.path - optional path inside application to deep link to | ||
* @param options.path - optional path inside application to deep link to. | ||
* If undefined, will use {@link AppBase.defaultPath | the app's default path}` as default. | ||
* @param options.state - optional state to forward to the application | ||
*/ | ||
navigateToApp(appId: string, options?: { path?: string; state?: any }): Promise<void>; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* 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 { removeSlashes, appendAppPath } from './utils'; | ||
|
||
describe('removeSlashes', () => { | ||
it('only removes duplicates by default', () => { | ||
expect(removeSlashes('/some//url//to//')).toEqual('/some/url/to/'); | ||
expect(removeSlashes('some/////other//url')).toEqual('some/other/url'); | ||
}); | ||
|
||
it('remove trailing slash when `trailing` is true', () => { | ||
expect(removeSlashes('/some//url//to//', { trailing: true })).toEqual('/some/url/to'); | ||
}); | ||
|
||
it('remove leading slash when `leading` is true', () => { | ||
expect(removeSlashes('/some//url//to//', { leading: true })).toEqual('some/url/to/'); | ||
}); | ||
|
||
it('does not removes duplicates when `duplicates` is false', () => { | ||
expect(removeSlashes('/some//url//to/', { leading: true, duplicates: false })).toEqual( | ||
'some//url//to/' | ||
); | ||
expect(removeSlashes('/some//url//to/', { trailing: true, duplicates: false })).toEqual( | ||
'/some//url//to' | ||
); | ||
}); | ||
|
||
it('accept mixed options', () => { | ||
expect( | ||
removeSlashes('/some//url//to/', { leading: true, duplicates: false, trailing: true }) | ||
).toEqual('some//url//to'); | ||
expect( | ||
removeSlashes('/some//url//to/', { leading: true, duplicates: true, trailing: true }) | ||
).toEqual('some/url/to'); | ||
}); | ||
}); | ||
|
||
describe('appendAppPath', () => { | ||
it('appends the appBasePath with given path', () => { | ||
expect(appendAppPath('/app/my-app', '/some-path')).toEqual('/app/my-app/some-path'); | ||
expect(appendAppPath('/app/my-app/', 'some-path')).toEqual('/app/my-app/some-path'); | ||
expect(appendAppPath('/app/my-app', 'some-path')).toEqual('/app/my-app/some-path'); | ||
expect(appendAppPath('/app/my-app', '')).toEqual('/app/my-app'); | ||
}); | ||
|
||
it('preserves the trailing slash only if included in the hash', () => { | ||
expect(appendAppPath('/app/my-app', '/some-path/')).toEqual('/app/my-app/some-path'); | ||
expect(appendAppPath('/app/my-app', '/some-path#/')).toEqual('/app/my-app/some-path#/'); | ||
expect(appendAppPath('/app/my-app', '/some-path#/hash/')).toEqual( | ||
'/app/my-app/some-path#/hash/' | ||
); | ||
expect(appendAppPath('/app/my-app', '/some-path#/hash')).toEqual('/app/my-app/some-path#/hash'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* 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. | ||
*/ | ||
|
||
/** | ||
* Utility to remove trailing, leading or duplicate slashes. | ||
* By default will only remove duplicates. | ||
*/ | ||
export const removeSlashes = ( | ||
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. Should I move this to 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. I'd consider to move it when needed in another place |
||
url: string, | ||
{ | ||
trailing = false, | ||
leading = false, | ||
duplicates = true, | ||
}: { trailing?: boolean; leading?: boolean; duplicates?: boolean } = {} | ||
): string => { | ||
if (duplicates) { | ||
url = url.replace(/\/{2,}/g, '/'); | ||
} | ||
if (trailing) { | ||
url = url.replace(/\/$/, ''); | ||
} | ||
if (leading) { | ||
url = url.replace(/^\//, ''); | ||
} | ||
return url; | ||
}; | ||
|
||
export const appendAppPath = (appBasePath: string, path: string = '') => { | ||
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. are there any tests for 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. My bad, this was introduced in my last commit, and I did not add proper coverage for it. Will add. |
||
// Only prepend slash if not a hash or query path | ||
path = path === '' || path.startsWith('#') || path.startsWith('?') ? path : `/${path}`; | ||
// Do not remove trailing slash when in hashbang | ||
const removeTrailing = path.indexOf('#') === -1; | ||
return removeSlashes(`${appBasePath}${path}`, { | ||
trailing: removeTrailing, | ||
duplicates: true, | ||
leading: false, | ||
}); | ||
}; |
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.
from this example I'd expect it to be called as
defaultSubpath
/internalPath
, etc.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.
I think the
default
part is important as the prop is used as a default innavigateToApp
.However in
navigateToApp
, the app path option is calledpath
, notsubPath
, so I choosedefaultPath
.But I'm fine with
defaultSubPath
if we think this is more explicit.