diff --git a/eslint-suppressions.json b/eslint-suppressions.json index a34461f87d6..e98c47ddfac 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -1817,7 +1817,7 @@ }, "public/app/features/dashboard-scene/edit-pane/DashboardEditPaneSplitter.tsx": { "react-hooks/rules-of-hooks": { - "count": 4 + "count": 5 } }, "public/app/features/dashboard-scene/inspect/HelpWizard/HelpWizard.tsx": { diff --git a/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx b/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx index 7251d2ed85c..6332b5ceefa 100644 --- a/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx +++ b/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx @@ -97,7 +97,13 @@ export const Dropdown = React.memo(({ children, overlay, placement, offset, root see https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/docs/rules/no-static-element-interactions.md#case-the-event-handler-is-only-being-used-to-capture-bubbled-events */} {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */} -
+
{ - if (ref) { - dashboard.onSetScrollRef(new DivScrollElement(ref)); - } - }; - const sidebarContext = useSidebar({ hasOpenPane: Boolean(openPane), contentMargin: 1, @@ -88,39 +87,77 @@ export function DashboardEditPaneSplitter({ dashboard, isEditing, body, controls editPane.clearSelection(); }; + const onBodyRef = (ref: HTMLDivElement | null) => { + if (ref) { + dashboard.onSetScrollRef(new DivScrollElement(ref)); + } + }; + + function renderBody() { + // In kiosk mode the full document body scrolls so we don't need to wrap in our own scrollbar + if (isInKioskMode) { + return ( +
+ {body} +
+ ); + } + + return ( +
+
+ {body} +
+ + + + +
+ ); + } + return (
- - {hasUid && canStar && } - {hasUid && canStar && } - {renderDynamicNavActions()} - - } - /> -
+
{controls}
-
-
- {body} -
- - - -
+ {renderBody()}
); } +function useUpdateAppChromeActions(dashboard: DashboardScene) { + const { chrome } = useGrafana(); + + useLayoutEffect(() => { + const hasUid = Boolean(dashboard.state.uid); + const canStar = Boolean(dashboard.state.meta.canStar); + + const breadcrumbActions = ( + <> + {hasUid && canStar && } + {hasUid && canStar && } + {renderDynamicNavActions()} + + ); + + chrome.update({ breadcrumbActions }); + + return () => { + chrome.update({ breadcrumbActions: undefined }); + }; + }, [chrome, dashboard]); +} + function renderDynamicNavActions() { const dashboard = getDashboardSrv().getCurrent()!; const showProps = { dashboard }; @@ -152,13 +189,17 @@ function getStyles(theme: GrafanaTheme2, headerHeight: number) { bodyWrapper: css({ label: 'body-wrapper', display: 'flex', - flexDirection: 'row', + flexDirection: 'column', flexGrow: 1, position: 'relative', flex: '1 1 0', overflow: 'hidden', }), - bodyWithToolbar: css({ + bodyWrapperKiosk: css({ + padding: theme.spacing(0, 2, 2, 2), + overflow: 'unset', + }), + scrollContainer: css({ display: 'flex', flexDirection: 'column', flexGrow: 1, diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.tsx index 4e3fa954a51..00655036d04 100644 --- a/public/app/features/dashboard-scene/scene/DashboardScene.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardScene.tsx @@ -32,7 +32,7 @@ import { PanelModel } from 'app/features/dashboard/state/PanelModel'; import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher'; import { DashboardJson } from 'app/features/manage-dashboards/types'; import { VariablesChanged } from 'app/features/variables/types'; -import { DashboardDTO, DashboardMeta, KioskMode, SaveDashboardResponseDTO } from 'app/types/dashboard'; +import { DashboardDTO, DashboardMeta, SaveDashboardResponseDTO } from 'app/types/dashboard'; import { ShowConfirmModalEvent } from 'app/types/events'; import { @@ -140,8 +140,6 @@ export interface DashboardSceneState extends SceneObjectState { editPanel?: PanelEditor; /** Scene object that handles the current drawer or modal */ overlay?: SceneObject; - /** Kiosk mode */ - kioskMode?: KioskMode; /** Share view */ shareView?: string; /** Renders panels in grid and filtered */ diff --git a/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.test.ts b/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.test.ts index c065b45d98f..52deaf2523a 100644 --- a/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.test.ts +++ b/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.test.ts @@ -1,5 +1,4 @@ import { SceneQueryRunner, VizPanel } from '@grafana/scenes'; -import { KioskMode } from 'app/types/dashboard'; import { DashboardScene } from './DashboardScene'; import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutManager'; @@ -22,25 +21,6 @@ describe('DashboardSceneUrlSync', () => { layout.state.grid.setState({ UNSAFE_fitPanels: true }); expect(scene.urlSync?.getUrlState().autofitpanels).toBe('true'); }); - - it('Should set kiosk mode when url has kiosk', () => { - const scene = buildTestScene(); - - scene.urlSync?.updateFromUrl({ kiosk: 'invalid' }); - expect(scene.state.kioskMode).toBe(undefined); - scene.urlSync?.updateFromUrl({ kiosk: '' }); - expect(scene.state.kioskMode).toBe(KioskMode.Full); - scene.urlSync?.updateFromUrl({ kiosk: 'true' }); - expect(scene.state.kioskMode).toBe(KioskMode.Full); - }); - - it('Should get the kiosk mode from the scene state', () => { - const scene = buildTestScene(); - - expect(scene.urlSync?.getUrlState().kiosk).toBe(undefined); - scene.setState({ kioskMode: KioskMode.Full }); - expect(scene.urlSync?.getUrlState().kiosk).toBe('true'); - }); }); describe('entering edit mode', () => { diff --git a/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.ts b/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.ts index 44c51dd4de7..45b35c3d57f 100644 --- a/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.ts +++ b/public/app/features/dashboard-scene/scene/DashboardSceneUrlSync.ts @@ -1,6 +1,5 @@ import { SceneObjectUrlSyncHandler, SceneObjectUrlValues, VizPanel } from '@grafana/scenes'; import { contextSrv } from 'app/core/services/context_srv'; -import { KioskMode } from 'app/types/dashboard'; import { buildPanelEditScene } from '../panel-edit/PanelEditor'; import { createDashboardEditViewFor } from '../settings/utils'; @@ -15,7 +14,7 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler { constructor(private _scene: DashboardScene) {} getKeys(): string[] { - return ['inspect', 'viewPanel', 'editPanel', 'editview', 'autofitpanels', 'kiosk', 'shareView']; + return ['inspect', 'viewPanel', 'editPanel', 'editview', 'autofitpanels', 'shareView']; } getUrlState(): SceneObjectUrlValues { @@ -26,7 +25,6 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler { viewPanel: state.viewPanel, editview: state.editview?.getUrlKey(), editPanel: state.editPanel?.getUrlKey() || undefined, - kiosk: state.kioskMode === KioskMode.Full ? 'true' : undefined, shareView: state.shareView, orgId: contextSrv.user.orgId.toString(), }; @@ -117,12 +115,6 @@ export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler { } } - if (typeof values.kiosk === 'string') { - if (values.kiosk === 'true' || values.kiosk === '') { - update.kioskMode = KioskMode.Full; - } - } - if (Object.keys(update).length > 0) { this._scene.setState(update); } diff --git a/public/app/features/dashboard-scene/scene/new-toolbar/actions/EditDashboardSwitch.tsx b/public/app/features/dashboard-scene/scene/new-toolbar/actions/EditDashboardSwitch.tsx index 777c3892860..8c43b455a8d 100644 --- a/public/app/features/dashboard-scene/scene/new-toolbar/actions/EditDashboardSwitch.tsx +++ b/public/app/features/dashboard-scene/scene/new-toolbar/actions/EditDashboardSwitch.tsx @@ -1,6 +1,6 @@ import { selectors } from '@grafana/e2e-selectors'; import { t } from '@grafana/i18n'; -import { Button } from '@grafana/ui'; +import { ToolbarButton } from '@grafana/ui'; import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions'; import { trackDashboardSceneEditButtonClicked } from 'app/features/dashboard-scene/utils/tracking'; import { playlistSrv } from 'app/features/playlist/PlaylistSrv'; @@ -17,10 +17,11 @@ export const EditDashboardSwitch = ({ dashboard }: ToolbarActionProps) => { } return ( - + ); };