mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ShareDrawer: Wrap render logic and add shareView query param (#92060)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Unsubscribable } from 'rxjs';
|
||||
|
||||
import { AppEvents } from '@grafana/data';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { config, locationService } from '@grafana/runtime';
|
||||
import {
|
||||
SceneGridLayout,
|
||||
SceneObjectBase,
|
||||
@@ -16,6 +16,7 @@ import { KioskMode } from 'app/types';
|
||||
import { PanelInspectDrawer } from '../inspect/PanelInspectDrawer';
|
||||
import { buildPanelEditScene } from '../panel-edit/PanelEditor';
|
||||
import { createDashboardEditViewFor } from '../settings/utils';
|
||||
import { ShareDrawer } from '../sharing/ShareDrawer/ShareDrawer';
|
||||
import { ShareModal } from '../sharing/ShareModal';
|
||||
import { findVizPanelByKey, getDashboardSceneFor, getLibraryPanel, isPanelClone } from '../utils/utils';
|
||||
|
||||
@@ -157,9 +158,13 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
||||
|
||||
if (typeof values.shareView === 'string') {
|
||||
update.shareView = values.shareView;
|
||||
update.overlay = new ShareModal({
|
||||
activeTab: values.shareView,
|
||||
});
|
||||
update.overlay = config.featureToggles.newDashboardSharingComponent
|
||||
? new ShareDrawer({
|
||||
shareView: values.shareView,
|
||||
})
|
||||
: new ShareModal({
|
||||
activeTab: values.shareView,
|
||||
});
|
||||
} else if (shareView && values.shareView === null) {
|
||||
update.overlay = undefined;
|
||||
update.shareView = undefined;
|
||||
|
||||
@@ -24,6 +24,7 @@ import { Trans, t } from 'app/core/internationalization';
|
||||
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
|
||||
import { playlistSrv } from 'app/features/playlist/PlaylistSrv';
|
||||
|
||||
import { shareDashboardType } from '../../dashboard/components/ShareModal/utils';
|
||||
import { PanelEditor, buildPanelEditScene } from '../panel-edit/PanelEditor';
|
||||
import ExportButton from '../sharing/ExportButton/ExportButton';
|
||||
import ShareButton from '../sharing/ShareButton/ShareButton';
|
||||
@@ -313,7 +314,7 @@ export function ToolbarActions({ dashboard }: Props) {
|
||||
fill="outline"
|
||||
onClick={() => {
|
||||
DashboardInteractions.toolbarShareClick();
|
||||
locationService.partial({ shareView: 'link' });
|
||||
locationService.partial({ shareView: shareDashboardType.link });
|
||||
}}
|
||||
data-testid={selectors.components.NavToolbar.shareDashboard}
|
||||
>
|
||||
|
||||
@@ -22,12 +22,8 @@ import { createExtensionSubMenu } from 'app/features/plugins/extensions/utils';
|
||||
import { addDataTrailPanelAction } from 'app/features/trails/Integrations/dashboardIntegration';
|
||||
import { ShowConfirmModalEvent } from 'app/types/events';
|
||||
|
||||
import { ShareSnapshot } from '../sharing/ShareButton/share-snapshot/ShareSnapshot';
|
||||
import { ShareDrawer } from '../sharing/ShareDrawer/ShareDrawer';
|
||||
import { ShareLibraryPanelTab } from '../sharing/ShareLibraryPanelTab';
|
||||
import { ShareModal } from '../sharing/ShareModal';
|
||||
import { SharePanelEmbedTab } from '../sharing/SharePanelEmbedTab';
|
||||
import { SharePanelInternally } from '../sharing/panel-share/SharePanelInternally';
|
||||
import { DashboardInteractions } from '../utils/interactions';
|
||||
import { getEditPanelUrl, getInspectUrl, getViewPanelUrl, tryGetExploreUrlForPanel } from '../utils/urlBuilders';
|
||||
import { getDashboardSceneFor, getPanelIdForVizPanel, getQueryRunnerFor } from '../utils/utils';
|
||||
@@ -91,8 +87,8 @@ export function panelMenuBehavior(menu: VizPanelMenu, isRepeat = false) {
|
||||
shortcut: 'p u',
|
||||
onClick: () => {
|
||||
const drawer = new ShareDrawer({
|
||||
title: t('share-panel.drawer.share-link-title', 'Link settings'),
|
||||
body: new SharePanelInternally({ panelRef: panel.getRef() }),
|
||||
shareView: shareDashboardType.link,
|
||||
panelRef: panel.getRef(),
|
||||
});
|
||||
|
||||
dashboard.showModal(drawer);
|
||||
@@ -104,8 +100,8 @@ export function panelMenuBehavior(menu: VizPanelMenu, isRepeat = false) {
|
||||
shortcut: 'p e',
|
||||
onClick: () => {
|
||||
const drawer = new ShareDrawer({
|
||||
title: t('share-panel.drawer.share-embed-title', 'Share embed'),
|
||||
body: new SharePanelEmbedTab({ panelRef: panel.getRef() }),
|
||||
shareView: shareDashboardType.embed,
|
||||
panelRef: panel.getRef(),
|
||||
});
|
||||
|
||||
dashboard.showModal(drawer);
|
||||
@@ -119,8 +115,8 @@ export function panelMenuBehavior(menu: VizPanelMenu, isRepeat = false) {
|
||||
shortcut: 'p s',
|
||||
onClick: () => {
|
||||
const drawer = new ShareDrawer({
|
||||
title: t('share-panel.drawer.share-snapshot-title', 'Share snapshot'),
|
||||
body: new ShareSnapshot({ dashboardRef: dashboard.getRef(), panelRef: panel.getRef() }),
|
||||
shareView: shareDashboardType.snapshot,
|
||||
panelRef: panel.getRef(),
|
||||
});
|
||||
|
||||
dashboard.showModal(drawer);
|
||||
@@ -192,8 +188,8 @@ export function panelMenuBehavior(menu: VizPanelMenu, isRepeat = false) {
|
||||
text: t('share-panel.menu.new-library-panel-title', 'New library panel'),
|
||||
onClick: () => {
|
||||
const drawer = new ShareDrawer({
|
||||
title: t('share-panel.drawer.new-library-panel-title', 'New library panel'),
|
||||
body: new ShareLibraryPanelTab({ panelRef: panel.getRef() }),
|
||||
shareView: shareDashboardType.libraryPanel,
|
||||
panelRef: panel.getRef(),
|
||||
});
|
||||
|
||||
dashboard.showModal(drawer);
|
||||
|
||||
@@ -2,15 +2,12 @@ import { SetPanelAttentionEvent } from '@grafana/data';
|
||||
import { config, locationService } from '@grafana/runtime';
|
||||
import { sceneGraph, VizPanel } from '@grafana/scenes';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { KeybindingSet } from 'app/core/services/KeybindingSet';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
|
||||
import { ShareSnapshot } from '../sharing/ShareButton/share-snapshot/ShareSnapshot';
|
||||
import { shareDashboardType } from '../../dashboard/components/ShareModal/utils';
|
||||
import { ShareDrawer } from '../sharing/ShareDrawer/ShareDrawer';
|
||||
import { ShareModal } from '../sharing/ShareModal';
|
||||
import { SharePanelEmbedTab } from '../sharing/SharePanelEmbedTab';
|
||||
import { SharePanelInternally } from '../sharing/panel-share/SharePanelInternally';
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
import { getEditPanelUrl, getInspectUrl, getViewPanelUrl, tryGetExploreUrlForPanel } from '../utils/urlBuilders';
|
||||
import { getPanelIdForVizPanel } from '../utils/utils';
|
||||
@@ -56,8 +53,8 @@ export function setupKeyboardShortcuts(scene: DashboardScene) {
|
||||
key: 'p u',
|
||||
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
|
||||
const drawer = new ShareDrawer({
|
||||
title: t('share-panel.drawer.share-link-title', 'Link settings'),
|
||||
body: new SharePanelInternally({ panelRef: vizPanel.getRef() }),
|
||||
shareView: shareDashboardType.link,
|
||||
panelRef: vizPanel.getRef(),
|
||||
});
|
||||
|
||||
scene.showModal(drawer);
|
||||
@@ -67,8 +64,8 @@ export function setupKeyboardShortcuts(scene: DashboardScene) {
|
||||
key: 'p e',
|
||||
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
|
||||
const drawer = new ShareDrawer({
|
||||
title: t('share-panel.drawer.share-embed-title', 'Share embed'),
|
||||
body: new SharePanelEmbedTab({ panelRef: vizPanel.getRef() }),
|
||||
shareView: shareDashboardType.embed,
|
||||
panelRef: vizPanel.getRef(),
|
||||
});
|
||||
|
||||
scene.showModal(drawer);
|
||||
@@ -80,8 +77,8 @@ export function setupKeyboardShortcuts(scene: DashboardScene) {
|
||||
key: 'p s',
|
||||
onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => {
|
||||
const drawer = new ShareDrawer({
|
||||
title: t('share-panel.drawer.share-snapshot-title', 'Share snapshot'),
|
||||
body: new ShareSnapshot({ dashboardRef: scene.getRef(), panelRef: vizPanel.getRef() }),
|
||||
shareView: shareDashboardType.snapshot,
|
||||
panelRef: vizPanel.getRef(),
|
||||
});
|
||||
|
||||
scene.showModal(drawer);
|
||||
|
||||
@@ -8,20 +8,22 @@ import { SceneComponentProps } from '@grafana/scenes';
|
||||
import { Button, ClipboardButton, CodeEditor, Label, Spinner, Stack, Switch, useStyles2 } from '@grafana/ui';
|
||||
import { notifyApp } from 'app/core/actions';
|
||||
import { createSuccessNotification } from 'app/core/copy/appNotification';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { dispatch } from 'app/store/store';
|
||||
|
||||
import { getDashboardSceneFor } from '../../utils/utils';
|
||||
import { ShareExportTab } from '../ShareExportTab';
|
||||
|
||||
const selector = e2eSelectors.pages.ExportDashboardDrawer.ExportAsJson;
|
||||
|
||||
export class ExportAsJson extends ShareExportTab {
|
||||
static Component = ExportAsJsonRenderer;
|
||||
|
||||
public getTabLabel(): string {
|
||||
return t('export.json.title', 'Save dashboard JSON');
|
||||
}
|
||||
}
|
||||
|
||||
function ExportAsJsonRenderer({ model }: SceneComponentProps<ExportAsJson>) {
|
||||
const dashboard = getDashboardSceneFor(model);
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const { isSharingExternally } = model.useState();
|
||||
@@ -98,7 +100,7 @@ function ExportAsJsonRenderer({ model }: SceneComponentProps<ExportAsJson>) {
|
||||
<Button
|
||||
data-testid={selector.cancelButton}
|
||||
variant="secondary"
|
||||
onClick={() => dashboard.closeModal()}
|
||||
onClick={model.useState().onDismiss}
|
||||
fill="outline"
|
||||
>
|
||||
<Trans i18nKey="export.json.cancel-button">Cancel</Trans>
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
|
||||
import { SceneObject } from '@grafana/scenes';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { IconName, Menu } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { getTrackingSource, shareDashboardType } from 'app/features/dashboard/components/ShareModal/utils';
|
||||
|
||||
import { DashboardScene } from '../../scene/DashboardScene';
|
||||
import { DashboardInteractions } from '../../utils/interactions';
|
||||
import { ShareDrawer } from '../ShareDrawer/ShareDrawer';
|
||||
import { SceneShareDrawerState } from '../types';
|
||||
|
||||
import { ExportAsJson } from './ExportAsJson';
|
||||
|
||||
const newExportButtonSelector = e2eSelectors.pages.Dashboard.DashNav.NewExportButton.Menu;
|
||||
|
||||
type CustomDashboardDrawer = new (...args: SceneShareDrawerState[]) => SceneObject;
|
||||
|
||||
export interface ExportDrawerMenuItem {
|
||||
shareId: string;
|
||||
testId: string;
|
||||
@@ -34,17 +28,9 @@ export function addDashboardExportDrawerItem(item: ExportDrawerMenuItem) {
|
||||
}
|
||||
|
||||
export default function ExportMenu({ dashboard }: { dashboard: DashboardScene }) {
|
||||
const onMenuItemClick = useCallback(
|
||||
(title: string, component: CustomDashboardDrawer) => {
|
||||
const drawer = new ShareDrawer({
|
||||
title,
|
||||
body: new component(),
|
||||
});
|
||||
|
||||
dashboard.showModal(drawer);
|
||||
},
|
||||
[dashboard]
|
||||
);
|
||||
const onMenuItemClick = (shareView: string) => {
|
||||
locationService.partial({ shareView });
|
||||
};
|
||||
|
||||
const buildMenuItems = useCallback(() => {
|
||||
const menuItems: ExportDrawerMenuItem[] = [];
|
||||
@@ -57,11 +43,11 @@ export default function ExportMenu({ dashboard }: { dashboard: DashboardScene })
|
||||
icon: 'arrow',
|
||||
label: t('share-dashboard.menu.export-json-title', 'Export as JSON'),
|
||||
renderCondition: true,
|
||||
onClick: () => onMenuItemClick(t('export.json.title', 'Save dashboard JSON'), ExportAsJson),
|
||||
onClick: () => onMenuItemClick(shareDashboardType.export),
|
||||
});
|
||||
|
||||
return menuItems.filter((item) => item.renderCondition);
|
||||
}, [onMenuItemClick]);
|
||||
}, []);
|
||||
|
||||
const onClick = (item: ExportDrawerMenuItem) => {
|
||||
DashboardInteractions.sharingCategoryClicked({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneObject, VizPanel } from '@grafana/scenes';
|
||||
import { config, locationService } from '@grafana/runtime';
|
||||
import { VizPanel } from '@grafana/scenes';
|
||||
import { IconName, Menu } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t } from 'app/core/internationalization';
|
||||
@@ -11,17 +11,9 @@ import { isPublicDashboardsEnabled } from '../../../dashboard/components/ShareMo
|
||||
import { getTrackingSource, shareDashboardType } from '../../../dashboard/components/ShareModal/utils';
|
||||
import { DashboardScene } from '../../scene/DashboardScene';
|
||||
import { DashboardInteractions } from '../../utils/interactions';
|
||||
import { ShareDrawer } from '../ShareDrawer/ShareDrawer';
|
||||
import { SceneShareDrawerState } from '../types';
|
||||
|
||||
import { ShareExternally } from './share-externally/ShareExternally';
|
||||
import { ShareInternally } from './share-internally/ShareInternally';
|
||||
import { ShareSnapshot } from './share-snapshot/ShareSnapshot';
|
||||
|
||||
const newShareButtonSelector = e2eSelectors.pages.Dashboard.DashNav.newShareButton.menu;
|
||||
|
||||
type CustomDashboardDrawer = new (...args: SceneShareDrawerState[]) => SceneObject;
|
||||
|
||||
export interface ShareDrawerMenuItem {
|
||||
shareId: string;
|
||||
testId: string;
|
||||
@@ -39,17 +31,9 @@ export function addDashboardShareDrawerItem(item: ShareDrawerMenuItem) {
|
||||
}
|
||||
|
||||
export default function ShareMenu({ dashboard, panel }: { dashboard: DashboardScene; panel?: VizPanel }) {
|
||||
const onMenuItemClick = useCallback(
|
||||
(title: string, component: CustomDashboardDrawer) => {
|
||||
const drawer = new ShareDrawer({
|
||||
title,
|
||||
body: new component({ dashboardRef: dashboard.getRef(), panelRef: panel?.getRef() }),
|
||||
});
|
||||
|
||||
dashboard.showModal(drawer);
|
||||
},
|
||||
[dashboard, panel]
|
||||
);
|
||||
const onMenuItemClick = (shareView: string) => {
|
||||
locationService.partial({ shareView });
|
||||
};
|
||||
|
||||
const buildMenuItems = useCallback(() => {
|
||||
const menuItems: ShareDrawerMenuItem[] = [];
|
||||
@@ -61,8 +45,7 @@ export default function ShareMenu({ dashboard, panel }: { dashboard: DashboardSc
|
||||
label: t('share-dashboard.menu.share-internally-title', 'Share internally'),
|
||||
description: t('share-dashboard.menu.share-internally-description', 'Advanced settings'),
|
||||
renderCondition: true,
|
||||
onClick: () =>
|
||||
onMenuItemClick(t('share-dashboard.menu.share-internally-title', 'Share internally'), ShareInternally),
|
||||
onClick: () => onMenuItemClick(shareDashboardType.link),
|
||||
});
|
||||
|
||||
menuItems.push({
|
||||
@@ -72,7 +55,7 @@ export default function ShareMenu({ dashboard, panel }: { dashboard: DashboardSc
|
||||
label: t('share-dashboard.menu.share-externally-title', 'Share externally'),
|
||||
renderCondition: !panel && isPublicDashboardsEnabled(),
|
||||
onClick: () => {
|
||||
onMenuItemClick(t('share-dashboard.menu.share-externally-title', 'Share externally'), ShareExternally);
|
||||
onMenuItemClick(shareDashboardType.publicDashboard);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -85,12 +68,12 @@ export default function ShareMenu({ dashboard, panel }: { dashboard: DashboardSc
|
||||
label: t('share-dashboard.menu.share-snapshot-title', 'Share snapshot'),
|
||||
renderCondition: contextSrv.isSignedIn && config.snapshotEnabled && dashboard.canEditDashboard(),
|
||||
onClick: () => {
|
||||
onMenuItemClick(t('share-dashboard.menu.share-snapshot-title', 'Share snapshot'), ShareSnapshot);
|
||||
onMenuItemClick(shareDashboardType.snapshot);
|
||||
},
|
||||
});
|
||||
|
||||
return menuItems.filter((item) => item.renderCondition);
|
||||
}, [onMenuItemClick, dashboard, panel]);
|
||||
}, [panel, dashboard]);
|
||||
|
||||
const onClick = (item: ShareDrawerMenuItem) => {
|
||||
DashboardInteractions.sharingCategoryClicked({
|
||||
|
||||
@@ -20,11 +20,12 @@ import {
|
||||
PublicDashboardShareType,
|
||||
} from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils';
|
||||
import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions';
|
||||
import { getDashboardSceneFor } from 'app/features/dashboard-scene/utils/utils';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import { getDashboardSceneFor } from '../../../utils/utils';
|
||||
import { ShareDrawerConfirmAction } from '../../ShareDrawer/ShareDrawerConfirmAction';
|
||||
import { useShareDrawerContext } from '../../ShareDrawer/ShareDrawerContext';
|
||||
import { SceneShareTabState, ShareView } from '../../types';
|
||||
|
||||
import { EmailSharing } from './EmailShare/EmailSharing';
|
||||
import { PublicSharing } from './PublicShare/PublicSharing';
|
||||
@@ -61,8 +62,12 @@ const getShareExternallyOptions = () => {
|
||||
: [getAnyOneWithTheLinkShareOption()];
|
||||
};
|
||||
|
||||
export class ShareExternally extends SceneObjectBase {
|
||||
export class ShareExternally extends SceneObjectBase<SceneShareTabState> implements ShareView {
|
||||
static Component = ShareExternallyRenderer;
|
||||
|
||||
public getTabLabel() {
|
||||
return t('share-dashboard.menu.share-externally-title', 'Share externally');
|
||||
}
|
||||
}
|
||||
|
||||
function ShareExternallyRenderer({ model }: SceneComponentProps<ShareExternally>) {
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { SceneComponentProps, SceneObjectRef, VizPanel } from '@grafana/scenes';
|
||||
import { SceneComponentProps } from '@grafana/scenes';
|
||||
import { Alert, ClipboardButton, Divider, Text, useStyles2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import ShareInternallyConfiguration from '../../ShareInternallyConfiguration';
|
||||
import { ShareLinkTab } from '../../ShareLinkTab';
|
||||
import { ShareLinkTab, ShareLinkTabState } from '../../ShareLinkTab';
|
||||
import { getShareLinkConfiguration, updateShareLinkConfiguration } from '../utils';
|
||||
|
||||
export class ShareInternally extends ShareLinkTab {
|
||||
static Component = ShareInternallyRenderer;
|
||||
|
||||
constructor(state: { panelRef?: SceneObjectRef<VizPanel> }) {
|
||||
constructor(state: Partial<ShareLinkTabState>) {
|
||||
const { useAbsoluteTimeRange, useShortUrl, theme } = getShareLinkConfiguration();
|
||||
super({
|
||||
...state,
|
||||
@@ -26,6 +26,10 @@ export class ShareInternally extends ShareLinkTab {
|
||||
this.onThemeChange = this.onThemeChange.bind(this);
|
||||
}
|
||||
|
||||
public getTabLabel() {
|
||||
return t('share-dashboard.menu.share-internally-title', 'Share internally');
|
||||
}
|
||||
|
||||
async onToggleLockedTime() {
|
||||
const useLockedTime = !this.state.useLockedTime;
|
||||
updateShareLinkConfiguration({
|
||||
|
||||
@@ -4,18 +4,23 @@ import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
|
||||
import { SceneComponentProps } from '@grafana/scenes';
|
||||
import { Alert } from '@grafana/ui';
|
||||
import { Trans, t } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ShareDrawerConfirmAction } from '../../ShareDrawer/ShareDrawerConfirmAction';
|
||||
import { ShareSnapshotTab } from '../../ShareSnapshotTab';
|
||||
import { ShareView } from '../../types';
|
||||
|
||||
import { CreateSnapshot } from './CreateSnapshot';
|
||||
import { SnapshotActions } from './SnapshotActions';
|
||||
|
||||
const selectors = e2eSelectors.pages.ShareDashboardDrawer.ShareSnapshot;
|
||||
|
||||
export class ShareSnapshot extends ShareSnapshotTab {
|
||||
export class ShareSnapshot extends ShareSnapshotTab implements ShareView {
|
||||
static Component = ShareSnapshotRenderer;
|
||||
|
||||
public getTabLabel() {
|
||||
return t('share-dashboard.menu.share-snapshot-title', 'Share snapshot');
|
||||
}
|
||||
}
|
||||
|
||||
function ShareSnapshotRenderer({ model }: SceneComponentProps<ShareSnapshot>) {
|
||||
@@ -23,7 +28,7 @@ function ShareSnapshotRenderer({ model }: SceneComponentProps<ShareSnapshot>) {
|
||||
const [showDeletedAlert, setShowDeletedAlert] = useState(false);
|
||||
const [step, setStep] = useState(1);
|
||||
|
||||
const { snapshotName, snapshotSharingOptions, selectedExpireOption, dashboardRef, panelRef } = model.useState();
|
||||
const { snapshotName, snapshotSharingOptions, selectedExpireOption, panelRef, onDismiss } = model.useState();
|
||||
|
||||
const [snapshotResult, createSnapshot] = useAsyncFn(async (external = false) => {
|
||||
const response = await model.onSnapshotCreate(external);
|
||||
@@ -39,7 +44,7 @@ function ShareSnapshotRenderer({ model }: SceneComponentProps<ShareSnapshot>) {
|
||||
});
|
||||
|
||||
const onCancelClick = () => {
|
||||
dashboardRef.resolve().closeModal();
|
||||
onDismiss?.();
|
||||
};
|
||||
|
||||
if (showDeleteConfirmation) {
|
||||
|
||||
@@ -1,40 +1,117 @@
|
||||
import {
|
||||
SceneComponentProps,
|
||||
SceneObject,
|
||||
SceneObjectBase,
|
||||
SceneObjectRef,
|
||||
SceneObjectState,
|
||||
VizPanel,
|
||||
} from '@grafana/scenes';
|
||||
import { locationService } from '@grafana/runtime';
|
||||
import { SceneComponentProps, SceneObjectBase, SceneObjectRef, SceneObjectState, VizPanel } from '@grafana/scenes';
|
||||
import { Drawer } from '@grafana/ui';
|
||||
|
||||
import { shareDashboardType } from '../../../dashboard/components/ShareModal/utils';
|
||||
import { DashboardScene } from '../../scene/DashboardScene';
|
||||
import { getDashboardSceneFor } from '../../utils/utils';
|
||||
import { ModalSceneObjectLike } from '../types';
|
||||
import { ExportAsJson } from '../ExportButton/ExportAsJson';
|
||||
import { ShareExternally } from '../ShareButton/share-externally/ShareExternally';
|
||||
import { ShareInternally } from '../ShareButton/share-internally/ShareInternally';
|
||||
import { ShareSnapshot } from '../ShareButton/share-snapshot/ShareSnapshot';
|
||||
import { ShareLibraryPanelTab } from '../ShareLibraryPanelTab';
|
||||
import { SharePanelEmbedTab } from '../SharePanelEmbedTab';
|
||||
import { SharePanelInternally } from '../panel-share/SharePanelInternally';
|
||||
import { ModalSceneObjectLike, SceneShareTabState, ShareView } from '../types';
|
||||
|
||||
import { ShareDrawerContext } from './ShareDrawerContext';
|
||||
|
||||
export interface ShareDrawerState extends SceneObjectState {
|
||||
title: string;
|
||||
panelRef?: SceneObjectRef<VizPanel>;
|
||||
body: SceneObject;
|
||||
shareView: string;
|
||||
activeShare: ShareView;
|
||||
}
|
||||
|
||||
type CustomShareViewType = { id: string; shareOption: new (...args: SceneShareTabState[]) => ShareView };
|
||||
const customShareViewOptions: CustomShareViewType[] = [];
|
||||
|
||||
export function addDashboardShareView(shareView: CustomShareViewType) {
|
||||
customShareViewOptions.push(shareView);
|
||||
}
|
||||
|
||||
export class ShareDrawer extends SceneObjectBase<ShareDrawerState> implements ModalSceneObjectLike {
|
||||
static Component = ShareDrawerRenderer;
|
||||
|
||||
constructor(state: Omit<ShareDrawerState, 'activeShare'>) {
|
||||
super({ ...state, activeShare: new ShareInternally({}) });
|
||||
this.addActivationHandler(() => this.buildActiveShare(state.shareView!));
|
||||
}
|
||||
|
||||
onDismiss = () => {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
dashboard.closeModal();
|
||||
if (this.state.panelRef) {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
dashboard.closeModal();
|
||||
} else {
|
||||
locationService.partial({ shareView: null });
|
||||
}
|
||||
};
|
||||
|
||||
private buildActiveShare(shareView: string) {
|
||||
const { panelRef } = this.state;
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
|
||||
const activeShare = panelRef
|
||||
? getPanelShareView(shareView, this.onDismiss, dashboard.getRef(), panelRef)
|
||||
: getShareView(shareView, this.onDismiss, dashboard.getRef(), panelRef);
|
||||
|
||||
this.setState({ activeShare });
|
||||
}
|
||||
}
|
||||
|
||||
function ShareDrawerRenderer({ model }: SceneComponentProps<ShareDrawer>) {
|
||||
const { title, body } = model.useState();
|
||||
const { activeShare } = model.useState();
|
||||
const dashboard = getDashboardSceneFor(model);
|
||||
|
||||
return (
|
||||
<Drawer title={title} onClose={model.onDismiss} size="md">
|
||||
<ShareDrawerContext.Provider value={{ dashboard }}>{<body.Component model={body} />}</ShareDrawerContext.Provider>
|
||||
<Drawer title={activeShare.getTabLabel()} onClose={model.onDismiss} size="md">
|
||||
<ShareDrawerContext.Provider value={{ dashboard }}>
|
||||
{<activeShare.Component model={activeShare} />}
|
||||
</ShareDrawerContext.Provider>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
function getShareView(
|
||||
shareView: string,
|
||||
onDismiss: () => void,
|
||||
dashboardRef: SceneObjectRef<DashboardScene>,
|
||||
panelRef?: SceneObjectRef<VizPanel>
|
||||
): ShareView {
|
||||
const currentShareView = customShareViewOptions.find((s) => s.id === shareView);
|
||||
if (currentShareView) {
|
||||
return new currentShareView.shareOption({ onDismiss });
|
||||
}
|
||||
|
||||
switch (shareView) {
|
||||
case shareDashboardType.link:
|
||||
return new ShareInternally({ onDismiss });
|
||||
case shareDashboardType.publicDashboard:
|
||||
return new ShareExternally({ onDismiss });
|
||||
case shareDashboardType.snapshot:
|
||||
return new ShareSnapshot({ dashboardRef, panelRef, onDismiss });
|
||||
case shareDashboardType.export:
|
||||
return new ExportAsJson({ onDismiss });
|
||||
default:
|
||||
return new ShareInternally({ onDismiss });
|
||||
}
|
||||
}
|
||||
|
||||
function getPanelShareView(
|
||||
shareView: string,
|
||||
onDismiss: () => void,
|
||||
dashboardRef: SceneObjectRef<DashboardScene>,
|
||||
panelRef: SceneObjectRef<VizPanel>
|
||||
): ShareView {
|
||||
switch (shareView) {
|
||||
case shareDashboardType.link:
|
||||
return new SharePanelInternally({ panelRef, onDismiss });
|
||||
case shareDashboardType.snapshot:
|
||||
return new ShareSnapshot({ dashboardRef, panelRef, onDismiss });
|
||||
case shareDashboardType.embed:
|
||||
return new SharePanelEmbedTab({ panelRef, onDismiss });
|
||||
case shareDashboardType.libraryPanel:
|
||||
return new ShareLibraryPanelTab({ panelRef, onDismiss });
|
||||
default:
|
||||
return new SharePanelInternally({ panelRef, onDismiss });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ import { getVariablesCompatibility } from '../utils/getVariablesCompatibility';
|
||||
import { DashboardInteractions } from '../utils/interactions';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { SceneShareTabState } from './types';
|
||||
import { SceneShareTabState, ShareView } from './types';
|
||||
|
||||
export interface ShareExportTabState extends SceneShareTabState {
|
||||
isSharingExternally?: boolean;
|
||||
isViewingJSON?: boolean;
|
||||
}
|
||||
|
||||
export class ShareExportTab extends SceneObjectBase<ShareExportTabState> {
|
||||
export class ShareExportTab extends SceneObjectBase<ShareExportTabState> implements ShareView {
|
||||
public tabId = shareDashboardType.export;
|
||||
static Component = ShareExportTabRenderer;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneComponentProps, SceneObjectBase, SceneObjectRef, VizPanel } from '@grafana/scenes';
|
||||
import { LibraryPanel } from '@grafana/schema/dist/esm/index.gen';
|
||||
import { t } from 'app/core/internationalization';
|
||||
@@ -20,7 +21,9 @@ export class ShareLibraryPanelTab extends SceneObjectBase<ShareLibraryPanelTabSt
|
||||
static Component = ShareLibraryPanelTabRenderer;
|
||||
|
||||
public getTabLabel() {
|
||||
return t('share-modal.tab-title.library-panel', 'Library panel');
|
||||
return config.featureToggles.newDashboardSharingComponent
|
||||
? t('share-panel.drawer.new-library-panel-title', 'New library panel')
|
||||
: t('share-modal.tab-title.library-panel', 'Library panel');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { DashboardInteractions } from '../utils/interactions';
|
||||
import { getDashboardUrl } from '../utils/urlBuilders';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { SceneShareTabState } from './types';
|
||||
import { SceneShareTabState, ShareView } from './types';
|
||||
export interface ShareLinkTabState extends SceneShareTabState, ShareOptions {
|
||||
panelRef?: SceneObjectRef<VizPanel>;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ interface ShareOptions extends ShareLinkConfiguration {
|
||||
isBuildUrlLoading: boolean;
|
||||
}
|
||||
|
||||
export class ShareLinkTab extends SceneObjectBase<ShareLinkTabState> {
|
||||
export class ShareLinkTab extends SceneObjectBase<ShareLinkTabState> implements ShareView {
|
||||
public tabId = shareDashboardType.link;
|
||||
|
||||
static Component = ShareLinkTabRenderer;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { TimeRange } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneComponentProps, sceneGraph, SceneObjectBase, SceneObjectRef, VizPanel } from '@grafana/scenes';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { ShareEmbed } from 'app/features/dashboard/components/ShareModal/ShareEmbed';
|
||||
@@ -24,7 +25,9 @@ export class SharePanelEmbedTab extends SceneObjectBase<SharePanelEmbedTabState>
|
||||
}
|
||||
|
||||
public getTabLabel() {
|
||||
return t('share-modal.tab-title.panel-embed', 'Embed');
|
||||
return config.featureToggles.newDashboardSharingComponent
|
||||
? t('share-panel.drawer.share-embed-title', 'Share embed')
|
||||
: t('share-modal.tab-title.panel-embed', 'Embed');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { transformSceneToSaveModel, trimDashboardForSnapshot } from '../serialization/transformSceneToSaveModel';
|
||||
import { DashboardInteractions } from '../utils/interactions';
|
||||
|
||||
import { SceneShareTabState } from './types';
|
||||
import { SceneShareTabState, ShareView } from './types';
|
||||
|
||||
const selectors = e2eSelectors.pages.ShareDashboardModal.SnapshotScene;
|
||||
|
||||
@@ -55,7 +55,7 @@ export interface ShareSnapshotTabState extends SceneShareTabState {
|
||||
snapshotSharingOptions?: SnapshotSharingOptions;
|
||||
}
|
||||
|
||||
export class ShareSnapshotTab extends SceneObjectBase<ShareSnapshotTabState> {
|
||||
export class ShareSnapshotTab extends SceneObjectBase<ShareSnapshotTabState> implements ShareView {
|
||||
public tabId = shareDashboardType.snapshot;
|
||||
static Component = ShareSnapshotTabRenderer;
|
||||
|
||||
|
||||
@@ -2,27 +2,30 @@ import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneComponentProps, SceneObjectRef, VizPanel } from '@grafana/scenes';
|
||||
import { SceneComponentProps } from '@grafana/scenes';
|
||||
import { Alert, ClipboardButton, Divider, LinkButton, Stack, Text, useStyles2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { getDashboardSceneFor } from '../../utils/utils';
|
||||
import ShareInternallyConfiguration from '../ShareInternallyConfiguration';
|
||||
import { ShareLinkTab } from '../ShareLinkTab';
|
||||
import { ShareLinkTab, ShareLinkTabState } from '../ShareLinkTab';
|
||||
|
||||
export class SharePanelInternally extends ShareLinkTab {
|
||||
static Component = SharePanelInternallyRenderer;
|
||||
|
||||
constructor({ panelRef }: { panelRef?: SceneObjectRef<VizPanel> }) {
|
||||
super({
|
||||
panelRef,
|
||||
});
|
||||
constructor(state: Partial<ShareLinkTabState>) {
|
||||
super(state);
|
||||
}
|
||||
|
||||
public getTabLabel() {
|
||||
return t('share-panel.drawer.share-link-title', 'Link settings');
|
||||
}
|
||||
}
|
||||
|
||||
function SharePanelInternallyRenderer({ model }: SceneComponentProps<SharePanelInternally>) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const { useLockedTime, useShortUrl, selectedTheme, isBuildUrlLoading, imageUrl } = model.useState();
|
||||
|
||||
const dashboard = getDashboardSceneFor(model);
|
||||
const isDashboardSaved = Boolean(dashboard.state.uid);
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { SceneObject, SceneObjectRef, SceneObjectState, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { SceneObject, SceneObjectRef, SceneObjectState } from '@grafana/scenes';
|
||||
|
||||
export interface ModalSceneObjectLike {
|
||||
onDismiss: () => void;
|
||||
}
|
||||
|
||||
export interface SceneShareTabState extends SceneObjectState {
|
||||
export interface SceneShareTabState extends SceneObjectState, Partial<ModalSceneObjectLike> {
|
||||
modalRef?: SceneObjectRef<ModalSceneObjectLike>;
|
||||
}
|
||||
|
||||
@@ -15,7 +13,6 @@ export interface SceneShareTab<T extends SceneShareTabState = SceneShareTabState
|
||||
tabId: string;
|
||||
}
|
||||
|
||||
export interface SceneShareDrawerState extends SceneObjectState {
|
||||
dashboardRef: SceneObjectRef<DashboardScene>;
|
||||
panelRef?: SceneObjectRef<VizPanel>;
|
||||
export interface ShareView extends SceneObject {
|
||||
getTabLabel(): string;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import { Trans } from 'app/core/internationalization';
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions';
|
||||
|
||||
import { shareDashboardType } from '../ShareModal/utils';
|
||||
|
||||
export const ShareButton = ({ dashboard }: { dashboard: DashboardModel }) => {
|
||||
return (
|
||||
<Button
|
||||
@@ -13,7 +15,7 @@ export const ShareButton = ({ dashboard }: { dashboard: DashboardModel }) => {
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
DashboardInteractions.toolbarShareClick();
|
||||
locationService.partial({ shareView: 'link' });
|
||||
locationService.partial({ shareView: shareDashboardType.link });
|
||||
}}
|
||||
>
|
||||
<Trans i18nKey="dashboard.toolbar.share-button">Share</Trans>
|
||||
|
||||
@@ -70,7 +70,7 @@ export function ShareEmbed({ panel, dashboard, range, onCancelClick, buildIframe
|
||||
<Field>
|
||||
<Stack gap={1} alignItems="start">
|
||||
<Switch
|
||||
label={t('share-modal.embed.time-range', 'Time range')}
|
||||
label={t('share-modal.embed.time-range', 'Lock time range')}
|
||||
id="share-current-time-range"
|
||||
value={useCurrentTimeRange}
|
||||
onChange={onUseCurrentTimeRangeChange}
|
||||
@@ -81,7 +81,7 @@ export function ShareEmbed({ panel, dashboard, range, onCancelClick, buildIframe
|
||||
'Change the current relative time range to an absolute time range'
|
||||
)}
|
||||
>
|
||||
<Trans i18nKey="embed.share.time-range-label">Time range</Trans>
|
||||
<Trans i18nKey="embed.share.time-range-label">Lock time range</Trans>
|
||||
</Label>
|
||||
</Stack>
|
||||
</Field>
|
||||
|
||||
@@ -704,7 +704,7 @@
|
||||
"embed": {
|
||||
"share": {
|
||||
"time-range-description": "Change the current relative time range to an absolute time range",
|
||||
"time-range-label": "Time range"
|
||||
"time-range-label": "Lock time range"
|
||||
}
|
||||
},
|
||||
"explore": {
|
||||
@@ -2244,7 +2244,7 @@
|
||||
"html": "Embed HTML",
|
||||
"html-description": "The HTML code below can be pasted and included in another web page. Unless anonymous access is enabled, the user viewing that page need to be signed into Grafana for the graph to load.",
|
||||
"info": "Generate HTML for embedding an iframe with this panel.",
|
||||
"time-range": "Time range"
|
||||
"time-range": "Lock time range"
|
||||
},
|
||||
"export": {
|
||||
"back-button": "Back to export config",
|
||||
@@ -2316,8 +2316,7 @@
|
||||
"drawer": {
|
||||
"new-library-panel-title": "New library panel",
|
||||
"share-embed-title": "Share embed",
|
||||
"share-link-title": "Link settings",
|
||||
"share-snapshot-title": "Share snapshot"
|
||||
"share-link-title": "Link settings"
|
||||
},
|
||||
"menu": {
|
||||
"new-library-panel-title": "New library panel",
|
||||
|
||||
@@ -704,7 +704,7 @@
|
||||
"embed": {
|
||||
"share": {
|
||||
"time-range-description": "Cĥäʼnģę ŧĥę čūřřęʼnŧ řęľäŧįvę ŧįmę řäʼnģę ŧő äʼn äþşőľūŧę ŧįmę řäʼnģę",
|
||||
"time-range-label": "Ŧįmę řäʼnģę"
|
||||
"time-range-label": "Ŀőčĸ ŧįmę řäʼnģę"
|
||||
}
|
||||
},
|
||||
"explore": {
|
||||
@@ -2244,7 +2244,7 @@
|
||||
"html": "Ēmþęđ ĦŦMĿ",
|
||||
"html-description": "Ŧĥę ĦŦMĿ čőđę þęľőŵ čäʼn þę päşŧęđ äʼnđ įʼnčľūđęđ įʼn äʼnőŧĥęř ŵęþ päģę. Ůʼnľęşş äʼnőʼnymőūş äččęşş įş ęʼnäþľęđ, ŧĥę ūşęř vįęŵįʼnģ ŧĥäŧ päģę ʼnęęđ ŧő þę şįģʼnęđ įʼnŧő Ğřäƒäʼnä ƒőř ŧĥę ģřäpĥ ŧő ľőäđ.",
|
||||
"info": "Ğęʼnęřäŧę ĦŦMĿ ƒőř ęmþęđđįʼnģ äʼn įƒřämę ŵįŧĥ ŧĥįş päʼnęľ.",
|
||||
"time-range": "Ŧįmę řäʼnģę"
|
||||
"time-range": "Ŀőčĸ ŧįmę řäʼnģę"
|
||||
},
|
||||
"export": {
|
||||
"back-button": "ßäčĸ ŧő ęχpőřŧ čőʼnƒįģ",
|
||||
@@ -2316,8 +2316,7 @@
|
||||
"drawer": {
|
||||
"new-library-panel-title": "Ńęŵ ľįþřäřy päʼnęľ",
|
||||
"share-embed-title": "Ŝĥäřę ęmþęđ",
|
||||
"share-link-title": "Ŀįʼnĸ şęŧŧįʼnģş",
|
||||
"share-snapshot-title": "Ŝĥäřę şʼnäpşĥőŧ"
|
||||
"share-link-title": "Ŀįʼnĸ şęŧŧįʼnģş"
|
||||
},
|
||||
"menu": {
|
||||
"new-library-panel-title": "Ńęŵ ľįþřäřy päʼnęľ",
|
||||
|
||||
Reference in New Issue
Block a user