Dashboards: Use new sidebar in dynamic dashboards (#114245)
* Dynamic dashboards sidebar wip * Progress * Outline in view mode cannot change name * Only one pane at a time * Adding starbutton and custom precence * undo / redo working * Progress * Update * Progress * Update * Public badge, provisining badge * playlist stop * Update * some initial unit tests * Fix export tooltip * Close pane when leaving edit mode if pane is an element * Update * e2e fixes * fixing e2e * Fix lint suppressions * e2e fixes * fixing more e2e * fixing e2e * fix e2e * e2e fixes * Fixinfg e2e * fixing e2e
This commit is contained in:
@@ -57,6 +57,11 @@ export const versionedComponents = {
|
||||
'12.1.0': 'data-testid DashboardEditPaneSplitter primary body',
|
||||
},
|
||||
},
|
||||
Sidebar: {
|
||||
closePane: {
|
||||
'12.4.0': 'data-testid Sidebar close pane',
|
||||
},
|
||||
},
|
||||
EditPaneHeader: {
|
||||
deleteButton: {
|
||||
'12.1.0': 'data-testid EditPaneHeader delete panel',
|
||||
@@ -70,9 +75,6 @@ export const versionedComponents = {
|
||||
duplicate: {
|
||||
'12.1.0': 'data-testid EditPaneHeader duplicate',
|
||||
},
|
||||
backButton: {
|
||||
'12.1.0': 'data-testid EditPaneHeader back',
|
||||
},
|
||||
},
|
||||
TimePicker: {
|
||||
openButton: {
|
||||
|
||||
@@ -183,6 +183,14 @@ export const versionedPages = {
|
||||
url: {
|
||||
[MIN_GRAFANA_VERSION]: (uid: string) => `/d/${uid}`,
|
||||
},
|
||||
Sidebar: {
|
||||
optionsButton: {
|
||||
'12.4.0': 'data-testid Dashboard Sidebar options button',
|
||||
},
|
||||
outlineButton: {
|
||||
'12.4.0': 'data-testid Dashboard Sidebar outline button',
|
||||
},
|
||||
},
|
||||
DashNav: {
|
||||
nav: {
|
||||
[MIN_GRAFANA_VERSION]: 'Dashboard navigation',
|
||||
|
||||
@@ -59,8 +59,9 @@ export function SiderbarToolbar({ children }: SiderbarToolbarProps) {
|
||||
{context.hasOpenPane && (
|
||||
<SidebarButton
|
||||
icon={'web-section-alt'}
|
||||
onClick={context.onDockChange}
|
||||
onClick={context.onToggleDock}
|
||||
title={context.isDocked ? t('grafana-ui.sidebar.undock', 'Undock') : t('grafana-ui.sidebar.dock', 'Dock')}
|
||||
data-testid="sidebar-dock-toggle"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import { useContext } from 'react';
|
||||
import React, { ButtonHTMLAttributes, useContext } from 'react';
|
||||
|
||||
import { GrafanaTheme2, IconName, isIconName } from '@grafana/data';
|
||||
|
||||
@@ -11,38 +11,48 @@ import { Tooltip } from '../Tooltip/Tooltip';
|
||||
|
||||
import { SidebarContext } from './useSidebar';
|
||||
|
||||
export interface Props {
|
||||
export interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
icon: IconName;
|
||||
active?: boolean;
|
||||
onClick?: () => void;
|
||||
title: string;
|
||||
tooltip?: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export function SidebarButton({ icon, active, onClick, title, tooltip }: Props) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const context = useContext(SidebarContext);
|
||||
export const SidebarButton = React.forwardRef<HTMLButtonElement, Props>(
|
||||
({ icon, active, onClick, title, tooltip, ...restProps }, ref) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const context = useContext(SidebarContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error('Sidebar.Button must be used within a Sidebar component');
|
||||
if (!context) {
|
||||
throw new Error('Sidebar.Button must be used within a Sidebar component');
|
||||
}
|
||||
|
||||
const buttonClass = cx(
|
||||
styles.button,
|
||||
context.compact && styles.compact,
|
||||
active && styles.active,
|
||||
context.position === 'left' && styles.leftButton
|
||||
);
|
||||
|
||||
return (
|
||||
<Tooltip ref={ref} content={tooltip ?? title} placement={context.position === 'left' ? 'right' : 'left'}>
|
||||
<button
|
||||
className={buttonClass}
|
||||
aria-label={title}
|
||||
aria-expanded={active}
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
{...restProps}
|
||||
>
|
||||
<div className={styles.iconWrapper}>{renderIcon(icon, context.compact)}</div>
|
||||
{!context.compact && <div className={cx(styles.title, active && styles.titleActive)}>{title}</div>}
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const buttonClass = cx(
|
||||
styles.button,
|
||||
context.compact && styles.compact,
|
||||
active && styles.active,
|
||||
context.position === 'left' && styles.leftButton
|
||||
);
|
||||
|
||||
return (
|
||||
<Tooltip content={tooltip ?? title} placement={context.position === 'left' ? 'right' : 'left'}>
|
||||
<button className={buttonClass} aria-label={title} aria-expanded={active} type="button" onClick={onClick}>
|
||||
<div className={styles.iconWrapper}>{renderIcon(icon, context.compact)}</div>
|
||||
{!context.compact && <div className={cx(styles.title, active && styles.titleActive)}>{title}</div>}
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
SidebarButton.displayName = 'SidebarButton';
|
||||
|
||||
function renderIcon(icon: IconName | React.ReactNode, compact?: boolean) {
|
||||
if (!icon) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { css } from '@emotion/css';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { useStyles2 } from '../../themes/ThemeContext';
|
||||
@@ -27,6 +28,7 @@ export function SidebarPaneHeader({ children, onClose, title }: Props) {
|
||||
onClick={onClose}
|
||||
aria-label={t('grafana-ui.sidebar.close', 'Close')}
|
||||
tooltip={t('grafana-ui.sidebar.close', 'Close')}
|
||||
data-testid={selectors.components.Sidebar.closePane}
|
||||
/>
|
||||
)}
|
||||
<Text weight="medium" variant="h6" truncate data-testid="sidebar-pane-header-title">
|
||||
|
||||
@@ -16,7 +16,7 @@ export interface SidebarContextValue {
|
||||
bottomMargin: number;
|
||||
edgeMargin: number;
|
||||
contentMargin: number;
|
||||
onDockChange: () => void;
|
||||
onToggleDock: () => void;
|
||||
onResize: (diff: number) => void;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export function useSidebar({
|
||||
// Used to accumulate drag distance to know when to change compact mode
|
||||
const [_, setCompactDrag] = React.useState(0);
|
||||
|
||||
const onDockChange = useCallback(() => setIsDocked((prev) => !prev), []);
|
||||
const onToggleDock = useCallback(() => setIsDocked((prev) => !prev), []);
|
||||
|
||||
const prop = position === 'right' ? 'paddingRight' : 'paddingLeft';
|
||||
const toolbarWidth =
|
||||
@@ -98,7 +98,7 @@ export function useSidebar({
|
||||
|
||||
return {
|
||||
isDocked,
|
||||
onDockChange,
|
||||
onToggleDock,
|
||||
onResize,
|
||||
outerWrapperProps,
|
||||
position,
|
||||
|
||||
Reference in New Issue
Block a user