Skip to content

Commit

Permalink
sharing via link to expanded panel
Browse files Browse the repository at this point in the history
  • Loading branch information
rshen91 committed Aug 12, 2024
1 parent f7a2af2 commit 6d28f6e
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/plugins/dashboard/common/dashboard_container/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export interface DashboardContainerInput extends EmbeddableInput {
description?: string;
isEmbeddedExternally?: boolean;
executionContext: KibanaExecutionContext;
expandedPanelId?: string;

// dashboard options: TODO, build a new system to avoid all shared state appearing here. See https://github.com/elastic/kibana/issues/144532 for more information.
hidePanelTitles: DashboardOptions['hidePanelTitles'];
Expand Down
21 changes: 18 additions & 3 deletions src/plugins/dashboard/public/dashboard_app/dashboard_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useExecutionContext } from '@kbn/kibana-react-plugin/public';
import { createKbnUrlStateStorage, withNotifyOnErrors } from '@kbn/kibana-utils-plugin/public';

import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import { DashboardContainerInput } from '../../common';
import {
DashboardAppNoDataPage,
isDashboardAppInNoDataState,
Expand All @@ -36,7 +37,11 @@ import { pluginServices } from '../services/plugin_services';
import { AwaitingDashboardAPI } from '../dashboard_container';
import { DashboardRedirect } from '../dashboard_container/types';
import { useDashboardMountContext } from './hooks/dashboard_mount_context';
import { createDashboardEditUrl, DASHBOARD_APP_ID } from '../dashboard_constants';
import {
createDashboardEditUrl,
DASHBOARD_APP_ID,
DASHBOARD_STATE_STORAGE_KEY,
} from '../dashboard_constants';
import { useDashboardOutcomeValidation } from './hooks/use_dashboard_outcome_validation';
import { loadDashboardHistoryLocationState } from './locator/load_dashboard_history_location_state';
import type { DashboardCreationOptions } from '../dashboard_container/embeddable/dashboard_container_factory';
Expand Down Expand Up @@ -68,9 +73,16 @@ export function DashboardApp({
history,
}: DashboardAppProps) {
const [showNoDataPage, setShowNoDataPage] = useState<boolean>(false);
const [redirectToExpandedPanel, setRedirectToExpandedPanel] = useState<string | undefined>();

useMount(() => {
(async () => setShowNoDataPage(await isDashboardAppInNoDataState()))();
(async () => {
setShowNoDataPage(await isDashboardAppInNoDataState());
const state: DashboardContainerInput | null = kbnUrlStateStorage.get(
DASHBOARD_STATE_STORAGE_KEY
);
if (state) setRedirectToExpandedPanel(state?.expandedPanelId);
})();
});
const [dashboardAPI, setDashboardAPI] = useState<AwaitingDashboardAPI>(null);

Expand Down Expand Up @@ -197,8 +209,11 @@ export function DashboardApp({
kbnUrlStateStorage,
dashboardAPI,
});
if (redirectToExpandedPanel) {
return dashboardAPI?.setExpandedPanelId(redirectToExpandedPanel);
}
return () => stopWatchingAppStateInUrl();
}, [dashboardAPI, kbnUrlStateStorage, savedDashboardId]);
}, [dashboardAPI, kbnUrlStateStorage, redirectToExpandedPanel, savedDashboardId]);

const locator = useMemo(() => url?.locators.get(DASHBOARD_APP_LOCATOR), [url]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ describe('ShowShareModal', () => {
isDirty: true,
anchorElement: document.createElement('div'),
getDashboardState: () => ({} as DashboardContainerInput),
hasExpandedPanel: unsavedState?.expandedPanelId ?? undefined,
};
};

Expand Down Expand Up @@ -221,4 +222,10 @@ describe('ShowShareModal', () => {
expect(shareLocatorParams.panels![1].embeddableConfig.changedKey2).toBe('definitely changed');
expect(shareLocatorParams.panels![2].embeddableConfig.changedKey3).toBe('should still exist');
});
it('generates a shareable URL to the application state with an expanded panel', () => {
const showModalProps = getPropsAndShare({ expandedPanelId: 'panel_1' });
ShowShareModal(showModalProps);
const mockShareableUrl = toggleShareMenuSpy.mock.calls[0][0].shareableUrl;
expect(mockShareableUrl).toBe('http://localhost/#?_g=!n&_a=(expandedPanelId:panel_1)');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface ShowShareModalProps {
dashboardTitle?: string;
anchorElement: HTMLElement;
getDashboardState: () => DashboardContainerInput;
hasExpandedPanel?: string;
}

export const showPublicUrlSwitch = (anonymousUserCapabilities: Capabilities) => {
Expand All @@ -51,6 +52,7 @@ export function ShowShareModal({
savedObjectId,
dashboardTitle,
getDashboardState,
hasExpandedPanel,
}: ShowShareModalProps) {
const {
dashboardCapabilities: { createShortUrl: allowShortUrl },
Expand Down Expand Up @@ -199,7 +201,7 @@ export function ShowShareModal({

const shareableUrl = setStateToKbnUrl(
'_a',
unsavedStateForLocator,
{ ...unsavedStateForLocator, expandedPanelId: hasExpandedPanel },
{ useHash: false, storeInHashQuery: true },
unhashUrl(baseUrl)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const useDashboardMenuItems = ({
savedObjectId: lastSavedId,
isDirty: Boolean(hasUnsavedChanges),
getDashboardState: () => dashboard.getState().explicitInput,
hasExpandedPanel: dashboard.getExpandedPanelId(),
});
},
[dashboardTitle, hasUnsavedChanges, lastSavedId, dashboard]
Expand Down

0 comments on commit 6d28f6e

Please sign in to comment.