Dashboards: Update edit button and share button (#115093)

* Dashboards: Update edit button and share button

* update translations
This commit is contained in:
Torkel Ödegaard
2025-12-11 08:54:50 +01:00
committed by GitHub
parent d686a49cf7
commit 33c5cbf4de
6 changed files with 36 additions and 138 deletions
@@ -191,11 +191,6 @@ function getStyles(theme: GrafanaTheme2, headerHeight: number) {
// Because the edit pane splitter handle area adds padding we can reduce it here
paddingRight: theme.spacing(1),
}),
editPane: css({
flexDirection: 'column',
// borderLeft: `1px solid ${theme.colors.border.weak}`,
// background: theme.colors.background.primary,
}),
controlsWrapperSticky: css({
[theme.breakpoints.up('md')]: {
position: 'sticky',
@@ -1,22 +1,26 @@
import { selectors } from '@grafana/e2e-selectors';
import { t } from '@grafana/i18n';
import { Button } 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';
import { ToolbarActionProps } from '../types';
import { ToolbarSwitch } from './ToolbarSwitch';
export const EditDashboardSwitch = ({ dashboard }: ToolbarActionProps) => {
const tooltip = dashboard.state.isEditing
? t('dashboard.toolbar.edit-button.exit-tooltip', 'Exit edit mode')
: t('dashboard.toolbar.edit-button.enter-tooltip', 'Enter edit mode');
if (playlistSrv.state.isPlaying) {
return null;
}
return (
<ToolbarSwitch
checked={!!dashboard.state.isEditing}
icon="pen"
label={t('dashboard.toolbar.new.edit-toggle.enter.label', 'Enter edit mode')}
checkedLabel={t('dashboard.toolbar.new.edit-toggle.exit.label', 'Exit edit mode')}
disabled={playlistSrv.state.isPlaying}
<Button
tooltip={tooltip}
data-testid={selectors.components.NavToolbar.editDashboard.editButton}
variant="secondary"
onClick={(evt) => {
evt.preventDefault();
evt.stopPropagation();
@@ -29,6 +33,10 @@ export const EditDashboardSwitch = ({ dashboard }: ToolbarActionProps) => {
dashboard.exitEditMode({ skipConfirm: false });
}
}}
/>
>
{dashboard.state.isEditing
? t('dashboard.toolbar.edit-button.exit', 'Exit edit')
: t('dashboard.toolbar.edit-button.enter', 'Edit')}
</Button>
);
};
@@ -34,7 +34,7 @@ export const ShareDashboardButton = ({ dashboard }: ToolbarActionProps) => {
arrowLabel={t('dashboard.toolbar.new.share.arrow', 'Share')}
arrowTestId={newShareButtonSelector.arrowMenu}
dashboard={dashboard}
variant={!dashboard.state.isEditing ? 'primary' : 'secondary'}
variant={!dashboard.state.isEditing ? 'primary' : 'canvas'}
/>
);
};
@@ -1,7 +1,7 @@
import { ReactElement, useState } from 'react';
import { t } from '@grafana/i18n';
import { Button, ButtonGroup, Dropdown } from '@grafana/ui';
import { ButtonGroup, Dropdown, ToolbarButton } from '@grafana/ui';
import { appEvents } from 'app/core/app_events';
import { ShowConfirmModalEvent } from 'app/types/events';
@@ -17,7 +17,7 @@ interface Props extends ToolbarActionProps {
onButtonClick?: () => void;
arrowLabel: string;
arrowTestId: string;
variant?: 'primary' | 'secondary';
variant?: 'primary' | 'canvas';
}
export const ShareExportDashboardButton = ({
@@ -31,7 +31,7 @@ export const ShareExportDashboardButton = ({
onButtonClick,
arrowLabel,
arrowTestId,
variant = 'secondary',
variant = 'canvas',
}: Props) => {
const [isOpen, setIsOpen] = useState(false);
@@ -60,9 +60,15 @@ export const ShareExportDashboardButton = ({
}
}}
>
<Button data-testid={buttonTestId} size="md" tooltip={buttonTooltip} variant={variant} onClick={onButtonClick}>
<ToolbarButton
data-testid={buttonTestId}
tooltip={buttonTooltip}
variant={variant}
onClick={onButtonClick}
icon="share-alt"
>
{buttonLabel}
</Button>
</ToolbarButton>
<Dropdown
overlay={menu}
placement="bottom-end"
@@ -76,10 +82,9 @@ export const ShareExportDashboardButton = ({
setIsOpen(isOpen);
}}
>
<Button
<ToolbarButton
aria-label={arrowLabel}
data-testid={arrowTestId}
size="md"
icon={isOpen ? 'angle-up' : 'angle-down'}
variant={variant}
/>
@@ -1,108 +0,0 @@
import { css, cx } from '@emotion/css';
import { MouseEvent } from 'react';
import { GrafanaTheme2, IconName } from '@grafana/data';
import { Icon, styleMixins, Tooltip, useStyles2 } from '@grafana/ui';
interface Props {
icon: IconName;
label: string;
checked: boolean;
checkedIcon?: IconName;
checkedLabel?: string;
disabled?: boolean;
'data-testid'?: string;
onClick: (evt: MouseEvent<HTMLButtonElement>) => void;
}
export const ToolbarSwitch = ({
icon,
label,
checked,
checkedIcon,
checkedLabel,
disabled,
onClick,
'data-testid': dataTestId,
}: Props) => {
const styles = useStyles2(getStyles);
const labelText = checked && checkedLabel ? checkedLabel : label;
const iconName = checked && checkedIcon ? checkedIcon : icon;
return (
<Tooltip content={labelText}>
<button
aria-label={labelText}
className={cx({
[styles.container]: true,
[styles.containerChecked]: checked,
[styles.containerDisabled]: disabled,
})}
data-testid={dataTestId}
onClick={disabled ? undefined : onClick}
>
<div className={cx(styles.box, checked && styles.boxChecked)}>
<Icon name={iconName} size="md" />
</div>
</button>
</Tooltip>
);
};
const getStyles = (theme: GrafanaTheme2) => ({
container: css({
border: `1px solid ${theme.components.input.borderColor}`,
padding: theme.spacing(0.5),
backgroundColor: theme.components.input.background,
borderRadius: theme.shape.radius.default,
width: theme.spacing(6.5),
height: theme.spacing(theme.components.height.md),
cursor: 'pointer',
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
[theme.transitions.handleMotion('no-preference', 'reduce')]: {
transition: 'all 0.2s ease-in-out',
},
'&:hover': {
borderColor: theme.components.input.borderHover,
},
}),
containerChecked: css({
backgroundColor: theme.colors.primary.main,
borderColor: 'transparent',
'&:hover': {
backgroundColor: theme.colors.primary.shade,
borderColor: 'transparent',
},
}),
containerDisabled: css({
cursor: 'initial',
background: theme.colors.action.disabledBackground,
borderColor: theme.colors.border.weak,
}),
box: css({
background: theme.colors.background.primary,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: theme.spacing(3.5),
height: '100%',
transform: 'translateX(0)',
position: 'relative',
borderRadius: styleMixins.getInternalRadius(theme, 2),
border: `1px solid ${theme.colors.border.weak}`,
[theme.transitions.handleMotion('no-preference', 'reduce')]: {
transition: 'all 0.2s ease-in-out',
},
}),
boxChecked: css({
transform: `translateX(calc(100% - 14px))`,
borderColor: 'transparent',
}),
});
+6 -8
View File
@@ -5463,6 +5463,12 @@
"label": "Edit",
"tooltip": "Enter edit mode"
},
"edit-button": {
"enter": "Edit",
"enter-tooltip": "Enter edit mode",
"exit": "Exit edit",
"exit-tooltip": "Exit edit mode"
},
"enter-edit-mode": {
"label": "Make editable",
"tooltip": "This dashboard was marked as read only"
@@ -5484,14 +5490,6 @@
"edit-dashboard-v2-schema": {
"tooltip": "Edit dashboard v2 schema"
},
"edit-toggle": {
"enter": {
"label": "Enter edit mode"
},
"exit": {
"label": "Exit edit mode"
}
},
"enter-edit-mode": {
"label": "Make editable",
"tooltip": "This dashboard was marked as read only"