diff --git a/packages/grafana-data/src/types/navModel.ts b/packages/grafana-data/src/types/navModel.ts index 10c1eb5a23e..567cd3e9410 100644 --- a/packages/grafana-data/src/types/navModel.ts +++ b/packages/grafana-data/src/types/navModel.ts @@ -70,4 +70,5 @@ export type NavIndex = { [s: string]: NavModelItem }; export enum PageLayoutType { Standard, Canvas, + Custom, } diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index 24a1586b919..74bb6b5b155 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -123,7 +123,7 @@ export const Components = { DataPane: { content: 'Panel editor data pane content', }, - applyButton: 'Apply changes and go back to dashboard', + applyButton: 'data-testid Apply changes and go back to dashboard', toggleVizPicker: 'toggle-viz-picker', toggleVizOptions: 'toggle-viz-options', toggleTableView: 'toggle-table-view', diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx index 77d1fe00d70..ac9c8a4c332 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx @@ -41,6 +41,7 @@ export interface TimeRangePickerProps { history?: TimeRange[]; hideQuickRanges?: boolean; widthOverride?: number; + isOnCanvas?: boolean; } export interface State { @@ -64,6 +65,7 @@ export function TimeRangePicker(props: TimeRangePickerProps) { onChangeFiscalYearStartMonth, hideQuickRanges, widthOverride, + isOnCanvas, } = props; const onChange = (timeRange: TimeRange) => { @@ -87,7 +89,7 @@ export function TimeRangePicker(props: TimeRangePickerProps) { const styles = useStyles2(getStyles); const hasAbsolute = isDateTime(value.raw.from) || isDateTime(value.raw.to); - const variant = isSynced ? 'active' : 'default'; + const variant = isSynced ? 'active' : isOnCanvas ? 'canvas' : 'default'; return ( diff --git a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx index ed23a182234..c2704534503 100644 --- a/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx +++ b/packages/grafana-ui/src/components/RefreshPicker/RefreshPicker.tsx @@ -23,6 +23,7 @@ export interface Props { noIntervalPicker?: boolean; width?: string; primary?: boolean; + isOnCanvas?: boolean; // These props are used to translate the component offOptionLabelMsg?: string; offOptionAriaLabelMsg?: string; @@ -59,13 +60,16 @@ export class RefreshPicker extends PureComponent { if (this.props.isLive) { return 'primary'; } + if (this.props.isLoading) { return 'destructive'; } + if (this.props.primary) { return 'primary'; } - return 'default'; + + return this.props.isOnCanvas ? 'canvas' : 'default'; } render() { @@ -125,6 +129,7 @@ export class RefreshPicker extends PureComponent { options={options} onChange={this.onChangeSelect as any} variant={variant} + title="Set auto refresh interval" data-testid={selectors.components.RefreshPicker.intervalButtonV2} aria-label={ariaLabel} /> diff --git a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx index ed5e1ae9a87..e79bd97af2f 100644 --- a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx +++ b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx @@ -37,7 +37,7 @@ type CommonProps = { export type ToolbarButtonProps = CommonProps & ButtonHTMLAttributes; -export type ToolbarButtonVariant = 'default' | 'primary' | 'destructive' | 'active'; +export type ToolbarButtonVariant = 'default' | 'primary' | 'destructive' | 'active' | 'canvas'; export const ToolbarButton = forwardRef( ( @@ -195,6 +195,7 @@ const getStyles = (theme: GrafanaTheme2) => { } `, default: theme.flags.topnav ? defaultTopNav : defaultOld, + canvas: defaultOld, active: css` color: ${theme.v1.palette.orangeDark}; border-color: ${theme.v1.palette.orangeDark}; diff --git a/packages/grafana-ui/src/themes/GlobalStyles/page.ts b/packages/grafana-ui/src/themes/GlobalStyles/page.ts index 8e39b1b907c..033d0beac4a 100644 --- a/packages/grafana-ui/src/themes/GlobalStyles/page.ts +++ b/packages/grafana-ui/src/themes/GlobalStyles/page.ts @@ -113,14 +113,7 @@ export function getPageStyles(theme: GrafanaTheme2) { margin-top: ${theme.spacing(0.5)}; } - .dashboard-content { - display: 'flex'; - flex-grow: 1; - min-height: 0; - flex-direction: 'column'; - } - - .dashboard-content--hidden { + .page-hidden { display: none; } `; diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts index fc81391c049..79e87f3c5b6 100644 --- a/packages/grafana-ui/src/types/index.ts +++ b/packages/grafana-ui/src/types/index.ts @@ -5,3 +5,4 @@ export * from './storybook'; export * from './forms'; export * from './icon'; export * from './select'; +export * from './size'; diff --git a/public/app/core/components/AppChrome/AppChromeUpdate.tsx b/public/app/core/components/AppChrome/AppChromeUpdate.tsx index fa3364b3f50..00644c83b67 100644 --- a/public/app/core/components/AppChrome/AppChromeUpdate.tsx +++ b/public/app/core/components/AppChrome/AppChromeUpdate.tsx @@ -1,21 +1,19 @@ import React, { useEffect } from 'react'; -import { NavModelItem } from '@grafana/data'; import { useGrafana } from 'app/core/context/GrafanaContext'; export interface AppChromeUpdateProps { - pageNav?: NavModelItem; actions?: React.ReactNode; } /** * This needs to be moved to @grafana/ui or runtime. * This is the way core pages and plugins update the breadcrumbs and page toolbar actions */ -export const AppChromeUpdate = React.memo(({ pageNav, actions }: AppChromeUpdateProps) => { +export const AppChromeUpdate = React.memo(({ actions }: AppChromeUpdateProps) => { const { chrome } = useGrafana(); useEffect(() => { - chrome.update({ pageNav, actions }); + chrome.update({ actions }); }); return null; }); diff --git a/public/app/core/components/AppChrome/NavToolbar.tsx b/public/app/core/components/AppChrome/NavToolbar.tsx index af5c2367553..78b54fbea46 100644 --- a/public/app/core/components/AppChrome/NavToolbar.tsx +++ b/public/app/core/components/AppChrome/NavToolbar.tsx @@ -52,7 +52,7 @@ const getStyles = (theme: GrafanaTheme2) => { pageToolbar: css({ height: TOP_BAR_LEVEL_HEIGHT, display: 'flex', - padding: theme.spacing(0, 2), + padding: theme.spacing(0, 1, 0, 2), alignItems: 'center', justifyContent: 'space-between', }), diff --git a/public/app/core/components/NavBar/NavBar.tsx b/public/app/core/components/NavBar/NavBar.tsx index 47a5fef4cdc..0c3be17b2bc 100644 --- a/public/app/core/components/NavBar/NavBar.tsx +++ b/public/app/core/components/NavBar/NavBar.tsx @@ -1,13 +1,14 @@ import { css, cx } from '@emotion/css'; import { FocusScope } from '@react-aria/focus'; +import { Location as HistoryLocation } from 'history'; import { cloneDeep } from 'lodash'; import React, { useState } from 'react'; import { useSelector } from 'react-redux'; import { useLocation } from 'react-router-dom'; import { GrafanaTheme2, NavModelItem, NavSection } from '@grafana/data'; -import { config, locationService, reportInteraction } from '@grafana/runtime'; -import { CustomScrollbar, Icon, useTheme2 } from '@grafana/ui'; +import { config, locationSearchToObject, locationService, reportInteraction } from '@grafana/runtime'; +import { Icon, useTheme2, CustomScrollbar } from '@grafana/ui'; import { getKioskMode } from 'app/core/navigation/kiosk'; import { KioskMode, StoreState } from 'app/types'; @@ -38,7 +39,6 @@ export const NavBar = React.memo(() => { const theme = useTheme2(); const styles = getStyles(theme); const location = useLocation(); - const kiosk = getKioskMode(); const [showSwitcherModal, setShowSwitcherModal] = useState(false); const [menuOpen, setMenuOpen] = useState(false); const [menuAnimationInProgress, setMenuAnimationInProgress] = useState(false); @@ -85,9 +85,10 @@ export const NavBar = React.memo(() => { const activeItem = isSearchActive(location) ? searchItem : getActiveItem(navTree, location.pathname); - if (kiosk !== KioskMode.Off) { + if (shouldHideNavBar(location)) { return null; } + return (