Dashboard: Fixes url links to embedded panels in scene based dashboards (#109837)
* Dashboard: Fixes url links to embedded panels in scene based dashboards * fix
This commit is contained in:
@@ -71,6 +71,8 @@ export const AnnoKeyDashboardGnetId = 'grafana.app/dashboard-gnet-id';
|
||||
export const AnnoKeyFolderTitle = 'grafana.app/folderTitle';
|
||||
/** @deprecated NOT A REAL annotation -- this is just a shim */
|
||||
export const AnnoKeyFolderUrl = 'grafana.app/folderUrl';
|
||||
/** @deprecated NOT A REAL annotation -- this is just a shim */
|
||||
export const AnnoKeyEmbedded = 'grafana.app/embedded';
|
||||
|
||||
/** @experimental only provided by proxies for setup with reloadDashboardsOnParamsChange toggle on */
|
||||
/** Not intended to be used in production, we will be removing this in short-term future */
|
||||
@@ -108,6 +110,8 @@ type GrafanaClientAnnotations = {
|
||||
[AnnoKeySavedFromUI]?: string;
|
||||
[AnnoKeyDashboardIsSnapshot]?: string;
|
||||
[AnnoKeyDashboardSnapshotOriginalUrl]?: string;
|
||||
[AnnoKeyEmbedded]?: string;
|
||||
|
||||
[AnnoKeyGrantPermissions]?: string;
|
||||
// TODO: This should be provided by the API
|
||||
// This is the dashboard ID for the Gcom API. This set when a dashboard is created through importing a dashboard from Grafana.com.
|
||||
|
||||
@@ -8,6 +8,7 @@ import { StateManagerBase } from 'app/core/services/StateManagerBase';
|
||||
import { getMessageFromError, getMessageIdFromError, getStatusFromError } from 'app/core/utils/errors';
|
||||
import { startMeasure, stopMeasure } from 'app/core/utils/metrics';
|
||||
import {
|
||||
AnnoKeyEmbedded,
|
||||
AnnoKeyFolder,
|
||||
AnnoKeyManagerIdentity,
|
||||
AnnoKeyManagerKind,
|
||||
@@ -639,8 +640,8 @@ export class DashboardScenePageStateManagerV2 extends DashboardScenePageStateMan
|
||||
rsp = await this.dashboardLoader.loadDashboard(type || 'db', slug || '', uid);
|
||||
|
||||
if (route === DashboardRoutes.Embedded) {
|
||||
throw new Error('Method not implemented.');
|
||||
// rsp.meta.isEmbedded = true;
|
||||
rsp.metadata.annotations = rsp.metadata.annotations || {};
|
||||
rsp.metadata.annotations[AnnoKeyEmbedded] = 'embedded';
|
||||
}
|
||||
}
|
||||
if (rsp.access.url && route === DashboardRoutes.Normal) {
|
||||
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
AnnoKeyUpdatedTimestamp,
|
||||
AnnoKeyDashboardIsSnapshot,
|
||||
DeprecatedInternalId,
|
||||
AnnoKeyEmbedded,
|
||||
} from 'app/features/apiserver/types';
|
||||
import { DashboardWithAccessInfo } from 'app/features/dashboard/api/types';
|
||||
import {
|
||||
@@ -139,6 +140,7 @@ export function transformSaveModelSchemaV2ToScene(dto: DashboardWithAccessInfo<D
|
||||
updatedBy: metadata.annotations?.[AnnoKeyUpdatedBy],
|
||||
folderUid: metadata.annotations?.[AnnoKeyFolder],
|
||||
isSnapshot: Boolean(metadata.annotations?.[AnnoKeyDashboardIsSnapshot]),
|
||||
isEmbedded: Boolean(metadata.annotations?.[AnnoKeyEmbedded]),
|
||||
|
||||
// UI-only metadata, ref: DashboardModel.initMeta
|
||||
showSettings: Boolean(dto.access.canEdit),
|
||||
|
||||
@@ -8,7 +8,7 @@ import { buildParams, shareDashboardType } from 'app/features/dashboard/componen
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { PanelTimeRange } from '../scene/PanelTimeRange';
|
||||
import { getDashboardUrl } from '../utils/getDashboardUrl';
|
||||
import { getDashboardSceneFor, getPanelIdForVizPanel } from '../utils/utils';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { SceneShareTabState } from './types';
|
||||
|
||||
@@ -37,17 +37,14 @@ function SharePanelEmbedTabRenderer({ model }: SceneComponentProps<SharePanelEmb
|
||||
|
||||
const dash = getDashboardSceneFor(model);
|
||||
const { uid: dashUid } = dash.useState();
|
||||
const id = getPanelIdForVizPanel(p);
|
||||
const timeRangeState = sceneGraph.getTimeRange(p);
|
||||
|
||||
const timeFrom = timeRangeState instanceof PanelTimeRange ? timeRangeState.state.timeFrom : undefined;
|
||||
|
||||
return (
|
||||
<ShareEmbed
|
||||
panel={{
|
||||
id,
|
||||
timeFrom,
|
||||
}}
|
||||
panelId={p.state.key!}
|
||||
timeFrom={timeFrom}
|
||||
range={timeRangeState.state.value}
|
||||
dashboard={{ uid: dashUid ?? '', time: timeRangeState.state.value }}
|
||||
buildIframe={getIframeBuilder(dash)}
|
||||
@@ -62,12 +59,13 @@ const getIframeBuilder =
|
||||
useCurrentTimeRange: boolean,
|
||||
_dashboardUid: string,
|
||||
selectedTheme?: string,
|
||||
panel?: { timeFrom?: string; id: number },
|
||||
panelId?: string,
|
||||
timeFrom?: string,
|
||||
range?: TimeRange
|
||||
) => {
|
||||
const params = buildParams({ useCurrentTimeRange, selectedTheme, panel, range });
|
||||
const panelId = params.get('editPanel') ?? params.get('viewPanel') ?? '';
|
||||
params.set('panelId', panelId);
|
||||
const params = buildParams({ useCurrentTimeRange, selectedTheme, panelId, timeFrom, range });
|
||||
const editOrViewPanel = params.get('editPanel') ?? params.get('viewPanel') ?? '';
|
||||
params.set('panelId', editOrViewPanel);
|
||||
params.delete('editPanel');
|
||||
params.delete('viewPanel');
|
||||
params.set('__feature.dashboardSceneSolo', 'true');
|
||||
|
||||
@@ -5,7 +5,6 @@ import { setEchoSrv } from '@grafana/runtime';
|
||||
import config from 'app/core/config';
|
||||
|
||||
import { Echo } from '../../../../core/services/echo/Echo';
|
||||
import { PanelModel } from '../../state/PanelModel';
|
||||
import { createDashboardModelFixture } from '../../state/__fixtures__/dashboardFixtures';
|
||||
|
||||
import { ShareEmbed } from './ShareEmbed';
|
||||
@@ -72,16 +71,13 @@ describe('ShareEmbed', () => {
|
||||
const mockDashboard = createDashboardModelFixture({
|
||||
uid: 'mockDashboardUid',
|
||||
});
|
||||
const mockPanel = new PanelModel({
|
||||
id: 'mockPanelId',
|
||||
});
|
||||
mockLocationHref(`http://dashboards.grafana.com/d/${mockDashboard.uid}?orgId=1`);
|
||||
render(<ShareEmbed dashboard={mockDashboard} panel={mockPanel} />);
|
||||
render(<ShareEmbed dashboard={mockDashboard} panelId={'mockPanelId'} />);
|
||||
|
||||
const embedUrl = screen.getByTestId('share-embed-html');
|
||||
expect(embedUrl).toBeInTheDocument();
|
||||
expect(embedUrl).toHaveTextContent(
|
||||
`http://dashboards.grafana.com/d-solo/${mockDashboard.uid}?orgId=1&from=1000&to=2000&panelId=${mockPanel.id}`
|
||||
`http://dashboards.grafana.com/d-solo/${mockDashboard.uid}?orgId=1&from=1000&to=2000&panelId=mockPanelId`
|
||||
);
|
||||
});
|
||||
|
||||
@@ -90,15 +86,13 @@ describe('ShareEmbed', () => {
|
||||
const mockDashboard = createDashboardModelFixture({
|
||||
uid: 'mockDashboardUid',
|
||||
});
|
||||
const mockPanel = new PanelModel({
|
||||
id: 'mockPanelId',
|
||||
});
|
||||
render(<ShareEmbed dashboard={mockDashboard} panel={mockPanel} />);
|
||||
|
||||
render(<ShareEmbed dashboard={mockDashboard} panelId={'mockPanelId'} />);
|
||||
|
||||
const embedUrl = screen.getByTestId('share-embed-html');
|
||||
expect(embedUrl).toBeInTheDocument();
|
||||
expect(embedUrl).toHaveTextContent(
|
||||
`http://dashboards.grafana.com/d-solo/${mockDashboard.uid}?orgId=1&from=1000&to=2000&panelId=${mockPanel.id}`
|
||||
`http://dashboards.grafana.com/d-solo/${mockDashboard.uid}?orgId=1&from=1000&to=2000&panelId=mockPanelId`
|
||||
);
|
||||
});
|
||||
|
||||
@@ -108,15 +102,13 @@ describe('ShareEmbed', () => {
|
||||
const mockDashboard = createDashboardModelFixture({
|
||||
uid: 'mockDashboardUid',
|
||||
});
|
||||
const mockPanel = new PanelModel({
|
||||
id: 'mockPanelId',
|
||||
});
|
||||
render(<ShareEmbed dashboard={mockDashboard} panel={mockPanel} />);
|
||||
|
||||
render(<ShareEmbed dashboard={mockDashboard} panelId={'mockPanelId'} />);
|
||||
|
||||
const embedUrl = screen.getByTestId('share-embed-html');
|
||||
expect(embedUrl).toBeInTheDocument();
|
||||
expect(embedUrl).toHaveTextContent(
|
||||
`http://dashboards.grafana.com/dashboard-solo/snapshot/${mockSlug}?orgId=1&from=1000&to=2000&panelId=${mockPanel.id}`
|
||||
`http://dashboards.grafana.com/dashboard-solo/snapshot/${mockSlug}?orgId=1&from=1000&to=2000&panelId=mockPanelId`
|
||||
);
|
||||
});
|
||||
|
||||
@@ -126,15 +118,13 @@ describe('ShareEmbed', () => {
|
||||
const mockDashboard = createDashboardModelFixture({
|
||||
uid: 'mockDashboardUid',
|
||||
});
|
||||
const mockPanel = new PanelModel({
|
||||
id: 'mockPanelId',
|
||||
});
|
||||
render(<ShareEmbed dashboard={mockDashboard} panel={mockPanel} />);
|
||||
|
||||
render(<ShareEmbed dashboard={mockDashboard} panelId={'mockPanelId'} />);
|
||||
|
||||
const embedUrl = screen.getByTestId('share-embed-html');
|
||||
expect(embedUrl).toBeInTheDocument();
|
||||
expect(embedUrl).toHaveTextContent(
|
||||
`http://dashboards.grafana.com/dashboard-solo/script/${mockSlug}?orgId=1&from=1000&to=2000&panelId=${mockPanel.id}`
|
||||
`http://dashboards.grafana.com/dashboard-solo/script/${mockSlug}?orgId=1&from=1000&to=2000&panelId=mockPanelId`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,22 +11,30 @@ import { ShareModalTabProps } from './types';
|
||||
import { buildIframeHtml, getTrackingSource } from './utils';
|
||||
|
||||
interface Props extends Omit<ShareModalTabProps, 'panel' | 'dashboard'> {
|
||||
panel?: { timeFrom?: string; id: number };
|
||||
panelId: string;
|
||||
timeFrom?: string;
|
||||
dashboard: { uid: string; time: RawTimeRange };
|
||||
range?: TimeRange;
|
||||
buildIframe?: typeof buildIframeHtml;
|
||||
onCancelClick?: () => void;
|
||||
}
|
||||
|
||||
export function ShareEmbed({ panel, dashboard, range, onCancelClick, buildIframe = buildIframeHtml }: Props) {
|
||||
export function ShareEmbed({
|
||||
panelId,
|
||||
timeFrom,
|
||||
dashboard,
|
||||
range,
|
||||
onCancelClick,
|
||||
buildIframe = buildIframeHtml,
|
||||
}: Props) {
|
||||
const [useCurrentTimeRange, setUseCurrentTimeRange] = useState(true);
|
||||
const [selectedTheme, setSelectedTheme] = useState('current');
|
||||
const [iframeHtml, setIframeHtml] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const newIframeHtml = buildIframe(useCurrentTimeRange, dashboard.uid, selectedTheme, panel, range);
|
||||
const newIframeHtml = buildIframe(useCurrentTimeRange, dashboard.uid, selectedTheme, panelId, timeFrom, range);
|
||||
setIframeHtml(newIframeHtml);
|
||||
}, [selectedTheme, useCurrentTimeRange, dashboard, panel, range, buildIframe]);
|
||||
}, [selectedTheme, useCurrentTimeRange, dashboard, panelId, timeFrom, range, buildIframe]);
|
||||
|
||||
const onIframeHtmlChange = (event: FormEvent<HTMLTextAreaElement>) => {
|
||||
setIframeHtml(event.currentTarget.value);
|
||||
@@ -49,7 +57,7 @@ export function ShareEmbed({ panel, dashboard, range, onCancelClick, buildIframe
|
||||
DashboardInteractions.embedSnippetCopy({
|
||||
currentTimeRange: useCurrentTimeRange,
|
||||
theme: selectedTheme,
|
||||
shareResource: getTrackingSource(panel),
|
||||
shareResource: getTrackingSource(panelId),
|
||||
});
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -17,7 +17,7 @@ import { ShareExport } from './ShareExport';
|
||||
import { ShareLibraryPanel } from './ShareLibraryPanel';
|
||||
import { ShareLink } from './ShareLink';
|
||||
import { ShareSnapshot } from './ShareSnapshot';
|
||||
import { ShareModalTabModel } from './types';
|
||||
import { ShareModalTabModel, ShareModalTabProps } from './types';
|
||||
import { getTrackingSource, shareDashboardType } from './utils';
|
||||
|
||||
const customDashboardTabs: ShareModalTabModel[] = [];
|
||||
@@ -46,7 +46,7 @@ function getTabs(canEditDashboard: boolean, panel?: PanelModel, activeTab?: stri
|
||||
|
||||
if (panel) {
|
||||
const embedLabel = t('share-modal.tab-title.embed', 'Embed');
|
||||
tabs.push({ label: embedLabel, value: shareDashboardType.embed, component: ShareEmbed });
|
||||
tabs.push({ label: embedLabel, value: shareDashboardType.embed, component: ShareEmbedTab });
|
||||
|
||||
if (!isPanelModelLibraryPanel(panel)) {
|
||||
const libraryPanelLabel = t('share-modal.tab-title.library-panel', 'Library panel');
|
||||
@@ -79,6 +79,17 @@ function getTabs(canEditDashboard: boolean, panel?: PanelModel, activeTab?: stri
|
||||
};
|
||||
}
|
||||
|
||||
function ShareEmbedTab(props: ShareModalTabProps) {
|
||||
return (
|
||||
<ShareEmbed
|
||||
dashboard={props.dashboard}
|
||||
panelId={String(props.panel?.id)}
|
||||
timeFrom={props.panel?.timeFrom}
|
||||
onDismiss={props.onDismiss}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
interface Props extends Themeable2 {
|
||||
dashboard: DashboardModel;
|
||||
panel?: PanelModel;
|
||||
|
||||
@@ -4,42 +4,42 @@ import { buildParams } from './utils';
|
||||
|
||||
describe('buildParams', () => {
|
||||
it.each`
|
||||
search | useCurrentTimeRange | selectedTheme | panel | expected
|
||||
search | useCurrentTimeRange | selectedTheme | panelId | expected
|
||||
${''} | ${true} | ${'current'} | ${undefined} | ${'from=1000&to=2000&orgId=2'}
|
||||
${''} | ${true} | ${'current'} | ${{ id: 3 }} | ${'from=1000&to=2000&orgId=2&viewPanel=3'}
|
||||
${''} | ${true} | ${'current'} | ${'3'} | ${'from=1000&to=2000&orgId=2&viewPanel=3'}
|
||||
${''} | ${true} | ${'light'} | ${undefined} | ${'from=1000&to=2000&orgId=2&theme=light'}
|
||||
${''} | ${true} | ${'light'} | ${{ id: 3 }} | ${'from=1000&to=2000&orgId=2&theme=light&viewPanel=3'}
|
||||
${''} | ${true} | ${'light'} | ${'3'} | ${'from=1000&to=2000&orgId=2&theme=light&viewPanel=3'}
|
||||
${''} | ${false} | ${'current'} | ${undefined} | ${'orgId=2'}
|
||||
${''} | ${false} | ${'current'} | ${{ id: 3 }} | ${'orgId=2&viewPanel=3'}
|
||||
${''} | ${false} | ${'current'} | ${'3'} | ${'orgId=2&viewPanel=3'}
|
||||
${''} | ${false} | ${'light'} | ${undefined} | ${'orgId=2&theme=light'}
|
||||
${''} | ${false} | ${'light'} | ${{ id: 3 }} | ${'orgId=2&theme=light&viewPanel=3'}
|
||||
${''} | ${false} | ${'light'} | ${'3'} | ${'orgId=2&theme=light&viewPanel=3'}
|
||||
${'editPanel=4'} | ${true} | ${'current'} | ${undefined} | ${'editPanel=4&from=1000&to=2000&orgId=2'}
|
||||
${'editPanel=4'} | ${true} | ${'current'} | ${{ id: 3 }} | ${'editPanel=4&from=1000&to=2000&orgId=2'}
|
||||
${'editPanel=4'} | ${true} | ${'current'} | ${'3'} | ${'editPanel=4&from=1000&to=2000&orgId=2'}
|
||||
${'editPanel=4'} | ${true} | ${'light'} | ${undefined} | ${'editPanel=4&from=1000&to=2000&orgId=2&theme=light'}
|
||||
${'editPanel=4'} | ${true} | ${'light'} | ${{ id: 3 }} | ${'editPanel=4&from=1000&to=2000&orgId=2&theme=light'}
|
||||
${'editPanel=4'} | ${true} | ${'light'} | ${'3'} | ${'editPanel=4&from=1000&to=2000&orgId=2&theme=light'}
|
||||
${'editPanel=4'} | ${false} | ${'current'} | ${undefined} | ${'editPanel=4&orgId=2'}
|
||||
${'editPanel=4'} | ${false} | ${'current'} | ${{ id: 3 }} | ${'editPanel=4&orgId=2'}
|
||||
${'editPanel=4'} | ${false} | ${'current'} | ${'3'} | ${'editPanel=4&orgId=2'}
|
||||
${'editPanel=4'} | ${false} | ${'light'} | ${undefined} | ${'editPanel=4&orgId=2&theme=light'}
|
||||
${'editPanel=4'} | ${false} | ${'light'} | ${{ id: 3 }} | ${'editPanel=4&orgId=2&theme=light'}
|
||||
${'editPanel=4'} | ${false} | ${'light'} | ${'3'} | ${'editPanel=4&orgId=2&theme=light'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${true} | ${'current'} | ${undefined} | ${'var=%2B1&var=a+value+with+spaces&var=true&from=1000&to=2000&orgId=2'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${true} | ${'current'} | ${{ id: 3 }} | ${'var=%2B1&var=a+value+with+spaces&var=true&from=1000&to=2000&orgId=2&viewPanel=3'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${true} | ${'current'} | ${'3'} | ${'var=%2B1&var=a+value+with+spaces&var=true&from=1000&to=2000&orgId=2&viewPanel=3'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${true} | ${'light'} | ${undefined} | ${'var=%2B1&var=a+value+with+spaces&var=true&from=1000&to=2000&orgId=2&theme=light'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${true} | ${'light'} | ${{ id: 3 }} | ${'var=%2B1&var=a+value+with+spaces&var=true&from=1000&to=2000&orgId=2&theme=light&viewPanel=3'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${true} | ${'light'} | ${'3'} | ${'var=%2B1&var=a+value+with+spaces&var=true&from=1000&to=2000&orgId=2&theme=light&viewPanel=3'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${false} | ${'current'} | ${undefined} | ${'var=%2B1&var=a+value+with+spaces&var=true&orgId=2'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${false} | ${'current'} | ${{ id: 3 }} | ${'var=%2B1&var=a+value+with+spaces&var=true&orgId=2&viewPanel=3'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${false} | ${'current'} | ${'3'} | ${'var=%2B1&var=a+value+with+spaces&var=true&orgId=2&viewPanel=3'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${false} | ${'light'} | ${undefined} | ${'var=%2B1&var=a+value+with+spaces&var=true&orgId=2&theme=light'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${false} | ${'light'} | ${{ id: 3 }} | ${'var=%2B1&var=a+value+with+spaces&var=true&orgId=2&theme=light&viewPanel=3'}
|
||||
${'var=%2B1&var=a+value+with+spaces&var=true'} | ${false} | ${'light'} | ${'3'} | ${'var=%2B1&var=a+value+with+spaces&var=true&orgId=2&theme=light&viewPanel=3'}
|
||||
${'auth_token=1234'} | ${true} | ${'current'} | ${undefined} | ${'from=1000&to=2000&orgId=2'}
|
||||
`(
|
||||
"when called with search: '$search' and useCurrentTimeRange: '$useCurrentTimeRange' and selectedTheme: '$selectedTheme' and panel: '$panel'then result should be '$expected'",
|
||||
({ search, useCurrentTimeRange, selectedTheme, panel, expected }) => {
|
||||
({ search, useCurrentTimeRange, selectedTheme, panelId, expected }) => {
|
||||
const range: TimeRange = {
|
||||
from: 1000,
|
||||
to: 2000,
|
||||
raw: { from: 'now-6h', to: 'now' },
|
||||
} as unknown as TimeRange;
|
||||
const orgId = 2;
|
||||
const result = buildParams({ useCurrentTimeRange, selectedTheme, panel, search, range, orgId });
|
||||
const result = buildParams({ useCurrentTimeRange, selectedTheme, panelId, search, range, orgId });
|
||||
|
||||
expect(result.toString()).toEqual(expected);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { dateTime, locationUtil, TimeRange, urlUtil, rangeUtil } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneObjectRef, VizPanel } from '@grafana/scenes';
|
||||
import { createShortLink } from 'app/core/utils/shortLinks';
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
|
||||
@@ -9,7 +8,8 @@ import { PanelModel } from '../../state/PanelModel';
|
||||
export interface BuildParamsArgs {
|
||||
useCurrentTimeRange: boolean;
|
||||
selectedTheme?: string;
|
||||
panel?: { timeFrom?: string; id: number };
|
||||
panelId?: string;
|
||||
timeFrom?: string;
|
||||
search?: string;
|
||||
range?: TimeRange;
|
||||
orgId?: number;
|
||||
@@ -18,17 +18,17 @@ export interface BuildParamsArgs {
|
||||
export function buildParams({
|
||||
useCurrentTimeRange,
|
||||
selectedTheme,
|
||||
panel,
|
||||
panelId,
|
||||
timeFrom,
|
||||
search = window.location.search,
|
||||
range = getTimeSrv().timeRange(),
|
||||
orgId = config.bootData.user.orgId,
|
||||
}: BuildParamsArgs): URLSearchParams {
|
||||
const searchParams = new URLSearchParams(search);
|
||||
const relative = panel?.timeFrom;
|
||||
|
||||
// Use panel's relative time if it's set
|
||||
if (relative) {
|
||||
const { from, to } = rangeUtil.describeTextRange(relative);
|
||||
if (timeFrom) {
|
||||
const { from, to } = rangeUtil.describeTextRange(timeFrom);
|
||||
searchParams.set('from', from);
|
||||
searchParams.set('to', to);
|
||||
} else {
|
||||
@@ -46,8 +46,8 @@ export function buildParams({
|
||||
searchParams.set('theme', selectedTheme!);
|
||||
}
|
||||
|
||||
if (panel && !searchParams.has('editPanel')) {
|
||||
searchParams.set('viewPanel', String(panel.id));
|
||||
if (panelId && !searchParams.has('editPanel')) {
|
||||
searchParams.set('viewPanel', panelId);
|
||||
}
|
||||
|
||||
// Token is unique to the authenticated identity and should not be shared with the URL,
|
||||
@@ -78,7 +78,12 @@ export async function buildShareUrl(
|
||||
shortenUrl?: boolean
|
||||
) {
|
||||
const baseUrl = buildBaseUrl();
|
||||
const params = buildParams({ useCurrentTimeRange, selectedTheme, panel });
|
||||
const params = buildParams({
|
||||
useCurrentTimeRange,
|
||||
selectedTheme,
|
||||
panelId: panel?.id ? String(panel.id) : undefined,
|
||||
timeFrom: panel?.timeFrom,
|
||||
});
|
||||
const shareUrl = urlUtil.appendQueryToUrl(baseUrl, params.toString());
|
||||
if (shortenUrl) {
|
||||
return await createShortLink(shareUrl);
|
||||
@@ -90,11 +95,18 @@ export function buildSoloUrl(
|
||||
useCurrentTimeRange: boolean,
|
||||
dashboardUid: string,
|
||||
selectedTheme?: string,
|
||||
panel?: { timeFrom?: string; id: number },
|
||||
panelId?: string,
|
||||
timeFrom?: string,
|
||||
range?: TimeRange
|
||||
) {
|
||||
const baseUrl = buildBaseUrl();
|
||||
const params = buildParams({ useCurrentTimeRange, selectedTheme, panel, range });
|
||||
const params = buildParams({
|
||||
useCurrentTimeRange,
|
||||
selectedTheme,
|
||||
panelId: panelId,
|
||||
timeFrom,
|
||||
range,
|
||||
});
|
||||
|
||||
let soloUrl = baseUrl.replace(config.appSubUrl + '/dashboard/', config.appSubUrl + '/dashboard-solo/');
|
||||
soloUrl = soloUrl.replace(config.appSubUrl + '/d/', config.appSubUrl + '/d-solo/');
|
||||
@@ -105,8 +117,8 @@ export function buildSoloUrl(
|
||||
soloUrl = `${config.appUrl}d-solo/${dashboardUid}`;
|
||||
}
|
||||
|
||||
const panelId = params.get('editPanel') ?? params.get('viewPanel') ?? '';
|
||||
params.set('panelId', panelId);
|
||||
const editOrViewPanel = params.get('editPanel') ?? params.get('viewPanel') ?? '';
|
||||
params.set('panelId', editOrViewPanel);
|
||||
params.delete('editPanel');
|
||||
params.delete('viewPanel');
|
||||
|
||||
@@ -119,7 +131,13 @@ export function buildImageUrl(
|
||||
selectedTheme?: string,
|
||||
panel?: PanelModel
|
||||
) {
|
||||
let soloUrl = buildSoloUrl(useCurrentTimeRange, dashboardUid, selectedTheme, panel);
|
||||
let soloUrl = buildSoloUrl(
|
||||
useCurrentTimeRange,
|
||||
dashboardUid,
|
||||
selectedTheme,
|
||||
panel?.id ? String(panel.id) : undefined,
|
||||
panel?.timeFrom
|
||||
);
|
||||
let imageUrl = soloUrl.replace(config.appSubUrl + '/dashboard-solo/', config.appSubUrl + '/render/dashboard-solo/');
|
||||
imageUrl = imageUrl.replace(config.appSubUrl + '/d-solo/', config.appSubUrl + '/render/d-solo/');
|
||||
imageUrl +=
|
||||
@@ -135,10 +153,11 @@ export function buildIframeHtml(
|
||||
useCurrentTimeRange: boolean,
|
||||
dashboardUid: string,
|
||||
selectedTheme?: string,
|
||||
panel?: { timeFrom?: string; id: number },
|
||||
panelId?: string,
|
||||
timeFrom?: string,
|
||||
range?: TimeRange
|
||||
) {
|
||||
let soloUrl = buildSoloUrl(useCurrentTimeRange, dashboardUid, selectedTheme, panel, range);
|
||||
let soloUrl = buildSoloUrl(useCurrentTimeRange, dashboardUid, selectedTheme, panelId, timeFrom, range);
|
||||
return `<iframe src="${soloUrl}" width="450" height="200" frameborder="0"></iframe>`;
|
||||
}
|
||||
|
||||
@@ -163,9 +182,7 @@ export function getLocalTimeZone() {
|
||||
return '&tz=' + encodeURIComponent(options.timeZone);
|
||||
}
|
||||
|
||||
export const getTrackingSource = (
|
||||
panel?: PanelModel | SceneObjectRef<VizPanel> | { timeFrom?: string; id: number }
|
||||
) => {
|
||||
export const getTrackingSource = (panel?: Object | undefined) => {
|
||||
return panel ? 'panel' : 'dashboard';
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user