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

[Dashboard Navigation] Make locator generic #166890

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/plugins/dashboard/public/dashboard_app/dashboard_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
} from './url/search_sessions_integration';
import { DashboardAPI, DashboardRenderer } from '..';
import { type DashboardEmbedSettings } from './types';
import { DASHBOARD_APP_LOCATOR } from './locator/locator';
import { DASHBOARD_APP_ID } from '../dashboard_constants';
import { pluginServices } from '../services/plugin_services';
import { DashboardTopNav } from './top_nav/dashboard_top_nav';
Expand Down Expand Up @@ -64,6 +65,12 @@ export function DashboardApp({
redirectTo,
history,
}: DashboardAppProps) {
const {
share: {
url: { locators },
},
} = pluginServices.getServices();

const [showNoDataPage, setShowNoDataPage] = useState<boolean>(false);

useMount(() => {
Expand Down Expand Up @@ -139,6 +146,7 @@ export function DashboardApp({
};

return Promise.resolve<DashboardCreationOptions>({
locator: locators.get(DASHBOARD_APP_LOCATOR),
getIncomingEmbeddable: () =>
getStateTransfer().getIncomingEmbeddablePackage(DASHBOARD_APP_ID, true),

Expand All @@ -163,6 +171,7 @@ export function DashboardApp({
});
}, [
history,
locators,
embedSettings,
validateOutcome,
getScopedHistory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export const panelPlacementStrategies = {
const otherPanels = { ...currentPanels };
for (const [id, panel] of Object.entries(currentPanels)) {
const currentPanel = cloneDeep(panel);
console.log('MOVING PANEL', currentPanel.explicitInput.title);
currentPanel.gridData.y = currentPanel.gridData.y + height;
otherPanels[id] = currentPanel;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
getDefaultControlGroupInput,
persistableControlGroupInputIsEqual,
} from '@kbn/controls-plugin/common';
import { LocatorPublic } from '@kbn/share-plugin/common';
import { ExitFullScreenButtonKibanaProvider } from '@kbn/shared-ux-button-exit-full-screen';

import {
Expand All @@ -44,12 +45,12 @@ import {
addOrUpdateEmbeddable,
} from './api';

import { DASHBOARD_CONTAINER_TYPE } from '../..';
import { placePanel } from '../component/panel_placement';
import { pluginServices } from '../../services/plugin_services';
import { initializeDashboard } from './create/create_dashboard';
import { DashboardCreationOptions } from './dashboard_container_factory';
import { DashboardAnalyticsService } from '../../services/analytics/types';
import { DashboardAppLocatorParams, DASHBOARD_CONTAINER_TYPE } from '../..';
import { DashboardViewport } from '../component/viewport/dashboard_viewport';
import { DashboardPanelState, DashboardContainerInput } from '../../../common';
import { DashboardReduxState, DashboardRenderPerformanceStats } from '../types';
Expand Down Expand Up @@ -102,6 +103,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
public controlGroup?: ControlGroupContainer;

public searchSessionId?: string;
public locator?: LocatorPublic<DashboardAppLocatorParams>;

// cleanup
public stopSyncingWithUnifiedSearch?: () => void;
Expand Down Expand Up @@ -155,6 +157,7 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
customBranding: this.customBranding,
} = pluginServices.getServices());

this.locator = creationOptions?.locator;
this.creationOptions = creationOptions;
this.searchSessionId = initialSessionId;
this.dashboardCreationStartTime = dashboardCreationStartTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
EmbeddableFactoryDefinition,
EmbeddablePackageState,
} from '@kbn/embeddable-plugin/public';
import { SerializableRecord } from '@kbn/utility-types';
import { LocatorPublic } from '@kbn/share-plugin/common';
import { SearchSessionInfoProvider } from '@kbn/data-plugin/public';
import { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public';
import { EmbeddablePersistableStateService } from '@kbn/embeddable-plugin/common';
Expand Down Expand Up @@ -58,6 +60,8 @@ export interface DashboardCreationOptions {
validateLoadedSavedObject?: (result: LoadDashboardReturn) => 'valid' | 'invalid' | 'redirected';

isEmbeddedExternally?: boolean;

locator?: LocatorPublic<SerializableRecord>; // TODO: Should this be a string and the `get` happens in the link embeddable?
}

export class DashboardContainerFactoryDefinition
Expand Down
1 change: 1 addition & 0 deletions src/plugins/dashboard/public/services/share/share.stub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const shareServiceFactory: ShareServiceFactory = () => {
const pluginMock = sharePluginMock.createStartContract();

return {
url: pluginMock.url,
toggleShareContextMenu: pluginMock.toggleShareContextMenu,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ export const shareServiceFactory: ShareServiceFactory = ({ startPlugins }) => {
const { share } = startPlugins;
if (!share) return {};

const { toggleShareContextMenu } = share;
const { toggleShareContextMenu, url } = share;

return {
url,
toggleShareContextMenu,
};
};
1 change: 1 addition & 0 deletions src/plugins/dashboard/public/services/share/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
import { SharePluginStart } from '@kbn/share-plugin/public';

export interface DashboardShareService {
url: SharePluginStart['url'];
toggleShareContextMenu?: SharePluginStart['toggleShareContextMenu'];
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ import {
} from '@kbn/presentation-util-plugin/public';
import { EuiButtonEmpty, EuiListGroupItem } from '@elastic/eui';
import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container';
import { DashboardAppLocatorParams, getEmbeddableParams } from '@kbn/dashboard-plugin/public';

import {
NAV_VERTICAL_LAYOUT,
NavigationLayoutType,
NavigationEmbeddableLink,
} from '../../../common/content_management';
import { coreServices } from '../../services/kibana_services';
import { fetchDashboard } from './dashboard_link_tools';
import { dashboardServices } from '../../services/kibana_services';
import { DashboardLinkStrings } from './dashboard_link_strings';
import { useNavigationEmbeddable } from '../../embeddable/navigation_embeddable';
import { fetchDashboard, getDashboardHref, getDashboardLocator } from './dashboard_link_tools';

export const DashboardLinkComponent = ({
link,
Expand Down Expand Up @@ -103,13 +104,15 @@ export const DashboardLinkComponent = ({
...link.options,
} as DashboardDrilldownOptions;

const locator = await getDashboardLocator({
link: { ...link, options: linkOptions },
navEmbeddable,
});
const params: DashboardAppLocatorParams = {
dashboardId: link.destination,
...getEmbeddableParams(navEmbeddable, linkOptions),
};

const locator = dashboardServices.locator;
if (!locator) return;

const href = getDashboardHref(locator);
const href = locator.getRedirectUrl(params);
return {
href,
onClick: async (event: React.MouseEvent) => {
Expand All @@ -127,11 +130,7 @@ export const DashboardLinkComponent = ({
if (linkOptions.openInNewTab) {
window.open(href, '_blank');
} else {
const { app, path, state } = locator;
await coreServices.application.navigateToApp(app, {
path,
state,
});
locator.navigate(params);
}
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,8 @@

import { isEmpty, filter } from 'lodash';

import {
cleanEmptyKeys,
getEmbeddableParams,
DashboardAppLocatorParams,
} from '@kbn/dashboard-plugin/public';
import { isFilterPinned } from '@kbn/es-query';
import { KibanaLocation } from '@kbn/share-plugin/public';
import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public';
import { DashboardDrilldownOptions } from '@kbn/presentation-util-plugin/public';

import { DashboardItem } from '../../embeddable/types';
import { NavigationEmbeddable } from '../../embeddable';
import { NavigationEmbeddableLink } from '../../../common/content_management';
import { coreServices, dashboardServices } from '../../services/kibana_services';
import { dashboardServices } from '../../services/kibana_services';

/**
* ----------------------------------
Expand Down Expand Up @@ -96,56 +84,3 @@ export const fetchDashboards = async ({

return simplifiedDashboardList;
};

/**
* ----------------------------------
* Navigate from one dashboard to another
* ----------------------------------
*/

interface GetDashboardLocatorProps {
link: NavigationEmbeddableLink & { options: DashboardDrilldownOptions };
navEmbeddable: NavigationEmbeddable;
}

/**
* Fetch the locator to use for dashboard navigation
* @param props `GetDashboardLocatorProps`
* @returns The locator to use for dashboard navigation
*/
export const getDashboardLocator = async ({ link, navEmbeddable }: GetDashboardLocatorProps) => {
const params: DashboardAppLocatorParams = {
dashboardId: link.destination,
...getEmbeddableParams(navEmbeddable, link.options),
};

const locator = dashboardServices.locator; // TODO: Make this generic as part of https://github.com/elastic/kibana/issues/164748
if (locator) {
const location: KibanaLocation<DashboardAppLocatorParams> = await locator.getLocation(params);
return location;
}
};

/**
* Get URL for dashboard app - should only be used when relying on native `href` functionality
* @param locator Locator that should be used to get the URL
* @returns A full URL to the dashboard, with all state included
*/
export const getDashboardHref = ({
app,
path,
state,
}: KibanaLocation<DashboardAppLocatorParams>): string => {
return coreServices.application.getUrlForApp(app, {
path: setStateToKbnUrl(
'_a',
cleanEmptyKeys({
query: state.query,
filters: state.filters?.filter((f) => !isFilterPinned(f)),
}),
{ useHash: false, storeInHashQuery: true },
path
),
absolute: true,
});
};
2 changes: 0 additions & 2 deletions src/plugins/navigation_embeddable/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
"@kbn/core-saved-objects-server",
"@kbn/saved-objects-plugin",
"@kbn/ui-actions-enhanced-plugin",
"@kbn/es-query",
"@kbn/share-plugin",
"@kbn/kibana-utils-plugin",
"@kbn/utility-types",
"@kbn/ui-actions-plugin"
Expand Down