mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Show chrome in redirect apps to improve navigation between apps (#210586)
## Summary possibly fixes https://github.com/elastic/kibana/issues/210058 - make it `chromless:false, visibleIn: []` so that in-app redirects via /r/ route feel smoother as chrome will stay visible - `<EuiPageTemplate minHeight={0} offset={0}>` places loading/error in the middle of the screen, remove scroll - `abortController.signal` to cancel redirect in-case user has already navigated away while waiting for shortUrl resolve (edge case) - EuiDelayRender around "Redirecting..." spinner - Also do it for `forwardApp` ### Demo (download and slowdown to see the difference): **before in between apps navigation** (chrome remounts for a moment, adds junk) https://github.com/user-attachments/assets/36d98ce9-8051-4f91-8dd9-7b406d613a73 **after in between apps navigation** (chome stays, feels smoother) https://github.com/user-attachments/assets/4ad46954-aefe-4bde-ac4c-d598aac8b8fe **before initial load** (chrome mounts only with discover) https://github.com/user-attachments/assets/2618f25d-85fe-4474-8800-cbcb06db4b8e **after initial load** (chrome mounts earlier, feels like apps loads faster) https://github.com/user-attachments/assets/1adc0af3-6c3c-4334-9157-fba2f008d8d5 - As a bonus, because chrome is rendered now, the error state is friendlier, as it allows to navigate away:   --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
ed30926f0f
commit
63394e6bfd
3 changed files with 21 additions and 12 deletions
|
@ -16,7 +16,6 @@ export const createLegacyUrlForwardApp = (
|
|||
forwards: ForwardDefinition[]
|
||||
): App => ({
|
||||
id: 'kibana',
|
||||
chromeless: true,
|
||||
title: 'Legacy URL migration',
|
||||
appRoute: '/app/kibana#/',
|
||||
visibleIn: [],
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
import * as React from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
|
||||
import { EuiPageTemplate } from '@elastic/eui';
|
||||
import { EuiPageTemplate, EuiDelayRender } from '@elastic/eui';
|
||||
import type { CustomBrandingSetup } from '@kbn/core-custom-branding-browser';
|
||||
import type { ChromeDocTitle, ThemeServiceSetup } from '@kbn/core/public';
|
||||
import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme';
|
||||
|
@ -42,7 +42,7 @@ export const Page: React.FC<PageProps> = ({
|
|||
if (error) {
|
||||
return (
|
||||
<KibanaThemeProvider {...startServices}>
|
||||
<EuiPageTemplate>
|
||||
<EuiPageTemplate minHeight={0} offset={0}>
|
||||
<RedirectEmptyPrompt docTitle={docTitle} error={error} homeHref={homeHref} />
|
||||
</EuiPageTemplate>
|
||||
</KibanaThemeProvider>
|
||||
|
@ -51,9 +51,11 @@ export const Page: React.FC<PageProps> = ({
|
|||
|
||||
return (
|
||||
<KibanaThemeProvider {...startServices}>
|
||||
<EuiPageTemplate>
|
||||
<Spinner showPlainSpinner={Boolean(hasCustomBranding)} />
|
||||
</EuiPageTemplate>
|
||||
<EuiDelayRender>
|
||||
<EuiPageTemplate minHeight={0} offset={0}>
|
||||
<Spinner showPlainSpinner={Boolean(hasCustomBranding)} />
|
||||
</EuiPageTemplate>
|
||||
</EuiDelayRender>
|
||||
</KibanaThemeProvider>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -35,8 +35,11 @@ export class RedirectManager {
|
|||
application.register({
|
||||
id: 'r',
|
||||
title: 'Redirect endpoint',
|
||||
chromeless: true,
|
||||
visibleIn: [],
|
||||
mount: async (params) => {
|
||||
const abortController = new AbortController();
|
||||
this.onMount(params.history.location, abortController.signal);
|
||||
|
||||
const { render } = await import('./render');
|
||||
const [start] = await core.getStartServices();
|
||||
const { chrome, uiSettings, userProfile } = start;
|
||||
|
@ -50,9 +53,8 @@ export class RedirectManager {
|
|||
homeHref: getHomeHref(http, uiSettings),
|
||||
});
|
||||
|
||||
this.onMount(params.history.location);
|
||||
|
||||
return () => {
|
||||
abortController.abort();
|
||||
unmount();
|
||||
};
|
||||
},
|
||||
|
@ -92,11 +94,11 @@ export class RedirectManager {
|
|||
});
|
||||
}
|
||||
|
||||
public onMount(location: Location) {
|
||||
public onMount(location: Location, abortSignal?: AbortSignal) {
|
||||
const pathname = location.pathname;
|
||||
const isShortUrlRedirectBySlug = pathname.startsWith('/s/');
|
||||
if (isShortUrlRedirectBySlug) {
|
||||
this.navigateToShortUrlBySlug(pathname.substring('/s/'.length));
|
||||
this.navigateToShortUrlBySlug(pathname.substring('/s/'.length), abortSignal);
|
||||
return;
|
||||
}
|
||||
const urlLocationSearch = location.search;
|
||||
|
@ -104,17 +106,23 @@ export class RedirectManager {
|
|||
this.navigate(options);
|
||||
}
|
||||
|
||||
private navigateToShortUrlBySlug(slug: string) {
|
||||
private navigateToShortUrlBySlug(slug: string, abortSignal?: AbortSignal) {
|
||||
(async () => {
|
||||
const urlService = this.deps.url;
|
||||
const shortUrls = urlService.shortUrls.get(null);
|
||||
const shortUrl = await shortUrls.resolve(slug);
|
||||
|
||||
if (abortSignal?.aborted)
|
||||
return; /* it means that the user navigated away before the short url resolved */
|
||||
|
||||
const locatorId = shortUrl.data.locator.id;
|
||||
const locator = urlService.locators.get(locatorId);
|
||||
if (!locator) throw new Error(`Locator "${locatorId}" not found.`);
|
||||
const locatorState = shortUrl.data.locator.state;
|
||||
await locator.navigate(locatorState, { replace: true });
|
||||
})().catch((error) => {
|
||||
if (abortSignal?.aborted) return;
|
||||
|
||||
this.error$.next(error);
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue