Explore: move items out of topnav & use canvas variant for toolbar buttons (#60630)

* Explore: remove topnav

* PageToolbar: fix left items margin when no title or page icon is set

* add missing key prop & fix tests

* use canvas variant in live logs

* avoid rendering empty space

* fix test

* avoid disabling split resize button when live tailing

* minor touchups

* Update packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
Giordano Ricci
2023-01-05 22:26:58 +00:00
committed by GitHub
co-authored by Torkel Ödegaard
parent 97e25d70e7
commit dfed7e59a5
7 changed files with 27 additions and 58 deletions
@@ -190,7 +190,7 @@ const getStyles = (theme: GrafanaTheme2) => {
min-width: 0; min-width: 0;
`, `,
h1Styles: css` h1Styles: css`
margin: 0; margin: ${spacing(0, 1, 0, 0)};
line-height: inherit; line-height: inherit;
flex-grow: 1; flex-grow: 1;
min-width: 0; min-width: 0;
@@ -229,7 +229,7 @@ const getStyles = (theme: GrafanaTheme2) => {
${theme.breakpoints.up('md')} { ${theme.breakpoints.up('md')} {
align-items: center; align-items: center;
display: flex; display: flex;
padding-left: ${spacing(0.5)}; padding-right: ${spacing(0.5)};
} }
`, `,
}; };
@@ -20,6 +20,7 @@ export const AddToDashboard = ({ exploreId }: Props) => {
<> <>
<ToolbarButton <ToolbarButton
icon="apps" icon="apps"
variant="canvas"
onClick={() => setIsOpen(true)} onClick={() => setIsOpen(true)}
aria-label="Add to dashboard" aria-label="Add to dashboard"
disabled={!explorePaneHasQueries} disabled={!explorePaneHasQueries}
+1 -9
View File
@@ -79,9 +79,6 @@ const getStyles = (theme: GrafanaTheme2) => {
padding: ${theme.spacing(2)}; padding: ${theme.spacing(2)};
padding-top: 0; padding-top: 0;
`, `,
exploreContainerTopnav: css`
padding-top: ${theme.spacing(2)};
`,
}; };
}; };
@@ -409,7 +406,6 @@ export class Explore extends React.PureComponent<Props, ExploreState> {
showTrace, showTrace,
showNodeGraph, showNodeGraph,
showFlameGraph, showFlameGraph,
splitted,
timeZone, timeZone,
isFromCompactUrl, isFromCompactUrl,
} = this.props; } = this.props;
@@ -441,11 +437,7 @@ export class Explore extends React.PureComponent<Props, ExploreState> {
{isFromCompactUrl ? this.renderCompactUrlWarning() : null} {isFromCompactUrl ? this.renderCompactUrlWarning() : null}
{datasourceMissing ? this.renderEmptyState(styles.exploreContainer) : null} {datasourceMissing ? this.renderEmptyState(styles.exploreContainer) : null}
{datasourceInstance && ( {datasourceInstance && (
<div <div className={styles.exploreContainer}>
className={cx(styles.exploreContainer, {
[styles.exploreContainerTopnav]: Boolean(config.featureToggles.topnav && !splitted),
})}
>
<PanelContainer className={styles.queryContainer}> <PanelContainer className={styles.queryContainer}>
<QueryRows exploreId={exploreId} /> <QueryRows exploreId={exploreId} />
<SecondaryActions <SecondaryActions
@@ -88,6 +88,7 @@ export class ExploreTimeControls extends Component<Props> {
return ( return (
<TimePickerWithHistory <TimePickerWithHistory
isOnCanvas
{...timePickerCommonProps} {...timePickerCommonProps}
timeSyncButton={timeSyncButton} timeSyncButton={timeSyncButton}
isSynced={syncedTimes} isSynced={syncedTimes}
+20 -45
View File
@@ -4,14 +4,7 @@ import { connect, ConnectedProps } from 'react-redux';
import { DataSourceInstanceSettings, RawTimeRange } from '@grafana/data'; import { DataSourceInstanceSettings, RawTimeRange } from '@grafana/data';
import { config, DataSourcePicker, reportInteraction } from '@grafana/runtime'; import { config, DataSourcePicker, reportInteraction } from '@grafana/runtime';
import { import { defaultIntervals, PageToolbar, RefreshPicker, SetInterval, ToolbarButton, ButtonGroup } from '@grafana/ui';
defaultIntervals,
PageToolbar,
RefreshPicker,
SetInterval,
ToolbarButton,
ToolbarButtonRow,
} from '@grafana/ui';
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate'; import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
import { contextSrv } from 'app/core/core'; import { contextSrv } from 'app/core/core';
import { createAndCopyShortLink } from 'app/core/utils/shortLinks'; import { createAndCopyShortLink } from 'app/core/utils/shortLinks';
@@ -142,8 +135,6 @@ class UnConnectedExploreToolbar extends PureComponent<Props> {
syncedTimes, syncedTimes,
onChangeTimeZone, onChangeTimeZone,
onChangeFiscalYearStartMonth, onChangeFiscalYearStartMonth,
refreshInterval,
loading,
isPaused, isPaused,
hasLiveOption, hasLiveOption,
containerWidth, containerWidth,
@@ -168,6 +159,7 @@ class UnConnectedExploreToolbar extends PureComponent<Props> {
return [ return [
!splitted ? ( !splitted ? (
<ToolbarButton <ToolbarButton
variant="canvas"
key="split" key="split"
tooltip="Split the pane" tooltip="Split the pane"
onClick={this.onOpenSplitView} onClick={this.onOpenSplitView}
@@ -177,19 +169,19 @@ class UnConnectedExploreToolbar extends PureComponent<Props> {
Split Split
</ToolbarButton> </ToolbarButton>
) : ( ) : (
<React.Fragment key="splitActions"> <ButtonGroup key="split-controls">
<ToolbarButton <ToolbarButton
variant="canvas"
tooltip={`${isLargerExploreId ? 'Narrow' : 'Widen'} pane`} tooltip={`${isLargerExploreId ? 'Narrow' : 'Widen'} pane`}
disabled={isLive}
onClick={onClickResize} onClick={onClickResize}
icon={isLargerExploreId ? 'gf-movepane-left' : 'gf-movepane-right'} icon={isLargerExploreId ? 'gf-movepane-left' : 'gf-movepane-right'}
iconOnly={true} iconOnly={true}
className={styles.rotateIcon} className={styles.rotateIcon}
/> />
<ToolbarButton tooltip="Close split pane" onClick={this.onCloseSplitView} icon="times"> <ToolbarButton tooltip="Close split pane" onClick={this.onCloseSplitView} icon="times" variant="canvas">
Close Close
</ToolbarButton> </ToolbarButton>
</React.Fragment> </ButtonGroup>
), ),
showExploreToDashboard && ( showExploreToDashboard && (
@@ -217,10 +209,6 @@ class UnConnectedExploreToolbar extends PureComponent<Props> {
this.renderRefreshPicker(showSmallTimePicker), this.renderRefreshPicker(showSmallTimePicker),
refreshInterval && (
<SetInterval key="setInterval" func={this.onRunQuery} interval={refreshInterval} loading={loading} />
),
hasLiveOption && ( hasLiveOption && (
<LiveTailControls key="liveControls" exploreId={exploreId}> <LiveTailControls key="liveControls" exploreId={exploreId}>
{(c) => { {(c) => {
@@ -251,12 +239,13 @@ class UnConnectedExploreToolbar extends PureComponent<Props> {
}; };
render() { render() {
const { datasourceMissing, exploreId, splitted, containerWidth, topOfViewRef } = this.props; const { datasourceMissing, exploreId, splitted, containerWidth, topOfViewRef, refreshInterval, loading } =
this.props;
const showSmallDataSourcePicker = (splitted ? containerWidth < 700 : containerWidth < 800) || false; const showSmallDataSourcePicker = (splitted ? containerWidth < 700 : containerWidth < 800) || false;
const isTopnav = config.featureToggles.topnav; const isTopnav = config.featureToggles.topnav;
const getDashNav = () => ( const shareButton = (
<DashNavButton <DashNavButton
key="share" key="share"
tooltip="Copy shortened link" tooltip="Copy shortened link"
@@ -278,39 +267,25 @@ class UnConnectedExploreToolbar extends PureComponent<Props> {
/> />
); );
const topNavActions = [ const toolbarLeftItems = [
getDashNav(), // We only want to show the shortened link button in the left Toolbar if topnav is not enabled as with topnav enabled it sits next to the brecrumbs
!splitted && getDataSourcePicker(), !isTopnav && exploreId === ExploreId.left && shareButton,
<div style={{ flex: 1 }} key="spacer" />,
<ToolbarButtonRow key="actions" alignment="right">
{this.renderActions()}
</ToolbarButtonRow>,
].filter(Boolean);
const toolbarLeftItems = [exploreId === ExploreId.left && getDashNav(), getDataSourcePicker()].filter(Boolean);
const toolbarLeftItemsTopNav = [
exploreId === ExploreId.left && (
<AppChromeUpdate
actions={[getDashNav(), !splitted && getDataSourcePicker(), <div style={{ flex: 1 }} key="spacer" />].filter(
Boolean
)}
/>
),
getDataSourcePicker(), getDataSourcePicker(),
].filter(Boolean); ].filter(Boolean);
return isTopnav && !splitted ? ( return (
<div ref={topOfViewRef}>
<AppChromeUpdate actions={topNavActions} />
</div>
) : (
<div ref={topOfViewRef}> <div ref={topOfViewRef}>
{refreshInterval && <SetInterval func={this.onRunQuery} interval={refreshInterval} loading={loading} />}
{isTopnav && (
<div ref={topOfViewRef}>
<AppChromeUpdate actions={[shareButton, <div style={{ flex: 1 }} key="spacer" />]} />
</div>
)}
<PageToolbar <PageToolbar
aria-label="Explore toolbar" aria-label="Explore toolbar"
title={exploreId === ExploreId.left && !isTopnav ? 'Explore' : undefined} title={exploreId === ExploreId.left && !isTopnav ? 'Explore' : undefined}
pageIcon={exploreId === ExploreId.left && !isTopnav ? 'compass' : undefined} pageIcon={exploreId === ExploreId.left && !isTopnav ? 'compass' : undefined}
leftItems={isTopnav ? toolbarLeftItemsTopNav : toolbarLeftItems} leftItems={toolbarLeftItems}
> >
{this.renderActions()} {this.renderActions()}
</PageToolbar> </PageToolbar>
@@ -16,7 +16,7 @@ type LiveTailButtonProps = {
export function LiveTailButton(props: LiveTailButtonProps) { export function LiveTailButton(props: LiveTailButtonProps) {
const { start, pause, resume, isLive, isPaused, stop, splitted } = props; const { start, pause, resume, isLive, isPaused, stop, splitted } = props;
const buttonVariant = isLive && !isPaused ? 'active' : 'default'; const buttonVariant = isLive && !isPaused ? 'active' : 'canvas';
const onClickMain = isLive ? (isPaused ? resume : pause) : start; const onClickMain = isLive ? (isPaused ? resume : pause) : start;
return ( return (
@@ -20,7 +20,7 @@ export function TimeSyncButton(props: TimeSyncButtonProps) {
<Tooltip content={syncTimesTooltip} placement="bottom"> <Tooltip content={syncTimesTooltip} placement="bottom">
<ToolbarButton <ToolbarButton
icon="link" icon="link"
variant={isSynced ? 'active' : 'default'} variant={isSynced ? 'active' : 'canvas'}
aria-label={isSynced ? 'Synced times' : 'Unsynced times'} aria-label={isSynced ? 'Synced times' : 'Unsynced times'}
onClick={onClick} onClick={onClick}
/> />