From 1e7cd9e9eca5ccebb2d11820008cf82a8e2ed103 Mon Sep 17 00:00:00 2001 From: Juan Cabanas Date: Thu, 27 Jun 2024 14:30:33 -0300 Subject: [PATCH] ShareDrawer: Schedule Report (#89802) --- .../sharing/ShareButton/ShareMenu.tsx | 114 +++++++++++------- .../sharing/ShareSnapshotTab.tsx | 4 +- .../features/dashboard-scene/sharing/types.ts | 9 +- 3 files changed, 83 insertions(+), 44 deletions(-) diff --git a/public/app/features/dashboard-scene/sharing/ShareButton/ShareMenu.tsx b/public/app/features/dashboard-scene/sharing/ShareButton/ShareMenu.tsx index 6177ca3e94b..250f723d41f 100644 --- a/public/app/features/dashboard-scene/sharing/ShareButton/ShareMenu.tsx +++ b/public/app/features/dashboard-scene/sharing/ShareButton/ShareMenu.tsx @@ -1,13 +1,16 @@ +import { useCallback } from 'react'; + import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; import { config } from '@grafana/runtime'; -import { VizPanel } from '@grafana/scenes'; -import { Menu } from '@grafana/ui'; +import { SceneObject, VizPanel } from '@grafana/scenes'; +import { IconName, Menu } from '@grafana/ui'; import { contextSrv } from 'app/core/core'; import { t } from 'app/core/internationalization'; import { isPublicDashboardsEnabled } from '../../../dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils'; import { DashboardScene } from '../../scene/DashboardScene'; import { ShareDrawer } from '../ShareDrawer/ShareDrawer'; +import { SceneShareDrawerState } from '../types'; import { ShareExternally } from './share-externally/ShareExternally'; import { ShareInternally } from './share-internally/ShareInternally'; @@ -15,59 +18,86 @@ import { ShareSnapshot } from './share-snapshot/ShareSnapshot'; const newShareButtonSelector = e2eSelectors.pages.Dashboard.DashNav.newShareButton.menu; +type CustomDashboardDrawer = new (...args: SceneShareDrawerState[]) => SceneObject; + +export interface ShareDrawerMenuItem { + testId: string; + label: string; + description?: string; + icon: IconName; + renderCondition: boolean; + onClick: (d: DashboardScene) => void; +} + +const customShareDrawerItem: ShareDrawerMenuItem[] = []; + +export function addDashboardShareDrawerItem(item: ShareDrawerMenuItem) { + customShareDrawerItem.push(item); +} + export default function ShareMenu({ dashboard, panel }: { dashboard: DashboardScene; panel?: VizPanel }) { - const onShareInternallyClick = () => { - const drawer = new ShareDrawer({ - title: t('share-dashboard.menu.share-internally-title', 'Share internally'), - body: new ShareInternally({ panelRef: panel?.getRef() }), + 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 buildMenuItems = useCallback(() => { + const menuItems: ShareDrawerMenuItem[] = []; + + menuItems.push({ + testId: newShareButtonSelector.shareInternally, + icon: 'building', + 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), }); - dashboard.showModal(drawer); - }; - - const onShareExternallyClick = () => { - const drawer = new ShareDrawer({ - title: t('share-dashboard.menu.share-externally-title', 'Share externally'), - body: new ShareExternally({}), + menuItems.push({ + testId: newShareButtonSelector.shareExternally, + icon: 'share-alt', + 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); + }, }); - dashboard.showModal(drawer); - }; + customShareDrawerItem.forEach((d) => menuItems.push(d)); - const onShareSnapshotClick = () => { - const drawer = new ShareDrawer({ - title: t('share-dashboard.menu.share-snapshot-title', 'Share snapshot'), - body: new ShareSnapshot({ dashboardRef: dashboard.getRef() }), + menuItems.push({ + testId: newShareButtonSelector.shareSnapshot, + icon: 'camera', + 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); + }, }); - dashboard.showModal(drawer); - }; + return menuItems.filter((item) => item.renderCondition); + }, [onMenuItemClick, dashboard, panel]); return ( - - {isPublicDashboardsEnabled() && ( + {buildMenuItems().map((item) => ( item.onClick(dashboard)} /> - )} - {contextSrv.isSignedIn && config.snapshotEnabled && dashboard.canEditDashboard() && ( - - )} + ))} ); } diff --git a/public/app/features/dashboard-scene/sharing/ShareSnapshotTab.tsx b/public/app/features/dashboard-scene/sharing/ShareSnapshotTab.tsx index 6ac56345c50..f584a8cfe6a 100644 --- a/public/app/features/dashboard-scene/sharing/ShareSnapshotTab.tsx +++ b/public/app/features/dashboard-scene/sharing/ShareSnapshotTab.tsx @@ -59,7 +59,9 @@ export class ShareSnapshotTab extends SceneObjectBase { public tabId = shareDashboardType.snapshot; static Component = ShareSnapshotTabRenderer; - public constructor(state: Omit) { + public constructor( + state: Omit + ) { super({ ...state, snapshotName: state.dashboardRef.resolve().state.title, diff --git a/public/app/features/dashboard-scene/sharing/types.ts b/public/app/features/dashboard-scene/sharing/types.ts index dc4ddb676e6..6531995ac2f 100644 --- a/public/app/features/dashboard-scene/sharing/types.ts +++ b/public/app/features/dashboard-scene/sharing/types.ts @@ -1,4 +1,6 @@ -import { SceneObject, SceneObjectRef, SceneObjectState } from '@grafana/scenes'; +import { SceneObject, SceneObjectRef, SceneObjectState, VizPanel } from '@grafana/scenes'; + +import { DashboardScene } from '../scene/DashboardScene'; export interface ModalSceneObjectLike { onDismiss: () => void; @@ -12,3 +14,8 @@ export interface SceneShareTab; + panelRef?: SceneObjectRef; +}