@ -1,6 +1,5 @@
import { css } from '@emotion/css' ;
import { useEffect , useId , useState } from 'react' ;
import * as React from 'react' ;
import { memo , ReactNode , useEffect , useId , useState } from 'react' ;
import { GrafanaTheme2 , store } from '@grafana/data' ;
import { selectors } from '@grafana/e2e-selectors' ;
@ -43,7 +42,7 @@ interface Props {
dashboard : DashboardScene ;
}
export const NavToolbarActions = React . memo < Props > ( ( { dashboard } ) = > {
export const NavToolbarActions = memo < Props > ( ( { dashboard } ) = > {
const id = useId ( ) ;
const actions = < ToolbarActions dashboard = { dashboard } key = { id } / > ;
@ -80,7 +79,7 @@ export function ToolbarActions({ dashboard }: Props) {
const dashboardNewLayouts = config . featureToggles . dashboardNewLayouts ;
if ( ! isEditingPanel ) {
// This adds the prec ence indicators in enterprise
// This adds the pres ence indicators in enterprise
addDynamicActions ( toolbarActions , dynamicDashNavActions . left , 'left-actions' ) ;
}
@ -116,7 +115,7 @@ export function ToolbarActions({ dashboard }: Props) {
return (
< Badge
color = "blue"
text = "Public"
text = { t ( 'dashboard.toolbar.public-dashboard' , 'Public' ) }
key = "public-dashboard-button-badge"
className = { styles . publicBadge }
data - testid = { selectors . pages . Dashboard . DashNav . publicDashboardTag }
@ -134,7 +133,7 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > (
< ToolbarButton
key = "view-in-old-dashboard-button"
tooltip = { 'Switch to old dashboard page'}
tooltip = { t ( 'dashboard.toolbar.switch-old-dashboard' , 'Switch to old dashboard page') }
icon = "apps"
onClick = { ( ) = > {
locationService . partial ( { scenes : false } ) ;
@ -172,7 +171,7 @@ export function ToolbarActions({ dashboard }: Props) {
} }
data - testid = { selectors . components . PageToolbar . itemButton ( 'add_visualization' ) }
>
Panel
< Trans i18nKey = "dashboard.toolbar.add-panel" > Panel < / Trans >
< / Button >
) ,
} ) ;
@ -191,7 +190,7 @@ export function ToolbarActions({ dashboard }: Props) {
} }
data - testid = { selectors . components . PageToolbar . itemButton ( 'add_row' ) }
>
Row
< Trans i18nKey = "dashboard.toolbar.add-row" > Row < / Trans >
< / Button >
) ,
} ) ;
@ -211,7 +210,7 @@ export function ToolbarActions({ dashboard }: Props) {
DashboardInteractions . toolbarAddButtonClicked ( { item : 'add_library_panel' } ) ;
} }
>
Import
< Trans i18nKey = "dashboard.toolbar.add-panel-lib" > Import < / Trans >
< / Button >
) ,
} ) ;
@ -363,7 +362,7 @@ export function ToolbarActions({ dashboard }: Props) {
icon = "arrow-left"
data - testid = { selectors . components . NavToolbar . editDashboard . backToDashboardButton }
>
Back to dashboard
< Trans i18nKey = "dashboard.toolbar.back-to-dashboard" > Back to dashboard < / Trans >
< / Button >
) ,
} ) ;
@ -384,7 +383,7 @@ export function ToolbarActions({ dashboard }: Props) {
icon = "arrow-left"
data - testid = { selectors . components . NavToolbar . editDashboard . backToDashboardButton }
>
Back to dashboard
< Trans i18nKey = "dashboard.toolbar.back-to-dashboard" > Back to dashboard < / Trans >
< / Button >
) ,
} ) ;
@ -396,7 +395,7 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > (
< Button
key = "share-dashboard-button"
tooltip = { t ( 'dashboard.toolbar.share' , 'Share dashboard' ) }
tooltip = { t ( 'dashboard.toolbar.share.tooltip ' , 'Share dashboard' ) }
size = "sm"
className = { styles . buttonWithExtraMargin }
fill = "outline"
@ -406,7 +405,7 @@ export function ToolbarActions({ dashboard }: Props) {
} }
data - testid = { selectors . components . NavToolbar . shareDashboard }
>
Share
< Trans i18nKey = "dashboard.toolbar.share.label" > Share < / Trans >
< / Button >
) ,
} ) ;
@ -419,14 +418,14 @@ export function ToolbarActions({ dashboard }: Props) {
onClick = { ( ) = > {
dashboard . onEnterEditMode ( ) ;
} }
tooltip = "Enter edit mode"
tooltip = { t ( 'dashboard.toolbar.edit.tooltip' , 'Enter edit mode' ) }
key = "edit"
className = { styles . buttonWithExtraMargin }
variant = { config . featureToggles . newDashboardSharingComponent ? 'secondary' : 'primary' }
size = "sm"
data - testid = { selectors . components . NavToolbar . editDashboard . editButton }
>
Edit
< Trans i18nKey = "dashboard.toolbar.edit.label" > Edit < / Trans >
< / Button >
) ,
} ) ;
@ -440,14 +439,14 @@ export function ToolbarActions({ dashboard }: Props) {
dashboard . onEnterEditMode ( ) ;
dashboard . setState ( { editable : true , meta : { . . . meta , canEdit : true } } ) ;
} }
tooltip = "This dashboard was marked as read only"
tooltip = { t ( 'dashboard.toolbar.enter-edit-mode.tooltip' , 'This dashboard was marked as read only' ) }
key = "edit"
className = { styles . buttonWithExtraMargin }
variant = "secondary"
size = "sm"
data - testid = { selectors . components . NavToolbar . editDashboard . editButton }
>
Make editable
< Trans i18nKey = "dashboard.toolbar.enter-edit-mode.label" > Make editable < / Trans >
< / Button >
) ,
} ) ;
@ -472,14 +471,14 @@ export function ToolbarActions({ dashboard }: Props) {
onClick = { ( ) = > {
dashboard . onOpenSettings ( ) ;
} }
tooltip = "Dashboard settings"
tooltip = { t ( 'dashboard.toolbar.dashboard-settings.tooltip' , 'Dashboard settings' ) }
fill = "text"
size = "sm"
key = "settings"
variant = "secondary"
data - testid = { selectors . components . NavToolbar . editDashboard . settingsButton }
>
Settings
< Trans i18nKey = "dashboard.toolbar.dashboard-settings.label" > Settings < / Trans >
< / Button >
) ,
} ) ;
@ -490,14 +489,14 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > (
< Button
onClick = { ( ) = > dashboard . exitEditMode ( { skipConfirm : false } ) }
tooltip = "Exits edit mode and discards unsaved changes"
tooltip = { t ( 'dashboard.toolbar.exit-edit-mode.tooltip' , 'Exits edit mode and discards unsaved changes' ) }
size = "sm"
key = "discard"
fill = "text"
variant = "primary"
data - testid = { selectors . components . NavToolbar . editDashboard . exitButton }
>
Exit edit
< Trans i18nKey = "dashboard.toolbar.exit-edit-mode.label" > Exit edit < / Trans >
< / Button >
) ,
} ) ;
@ -508,7 +507,11 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > (
< Button
onClick = { editPanel ? . onDiscard }
tooltip = { editPanel ? . state . isNewPanel ? 'Discard panel' : 'Discard panel changes' }
tooltip = {
editPanel ? . state . isNewPanel
? t ( 'dashboard.toolbar.discard-panel-new' , 'Discard panel' )
: t ( 'dashboard.toolbar.discard-panel' , 'Discard panel changes' )
}
size = "sm"
disabled = { ! isEditedPanelDirty }
key = "discard"
@ -516,7 +519,11 @@ export function ToolbarActions({ dashboard }: Props) {
variant = "destructive"
data - testid = { selectors . components . NavToolbar . editDashboard . discardChangesButton }
>
{ editPanel ? . state . isNewPanel ? 'Discard panel' : 'Discard panel changes' }
{ editPanel ? . state . isNewPanel ? (
< Trans i18nKey = "dashboard.toolbar.discard-panel-new" > Discard panel < / Trans >
) : (
< Trans i18nKey = "dashboard.toolbar.discard-panel" > Discard panel changes < / Trans >
) }
< / Button >
) ,
} ) ;
@ -527,14 +534,14 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > (
< Button
onClick = { editPanel ? . onDiscard }
tooltip = "Discard library panel changes"
tooltip = { t ( 'dashboard.toolbar.discard-library-panel-changes' , 'Discard library panel changes' ) }
size = "sm"
key = "discardLibraryPanel"
fill = "outline"
variant = "destructive"
data - testid = { selectors . components . NavToolbar . editDashboard . discardChangesButton }
>
Discard library panel changes
< Trans i18nKey = "dashboard.toolbar.discard-library-panel-changes" > Discard library panel changes < / Trans >
< / Button >
) ,
} ) ;
@ -545,14 +552,14 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > (
< Button
onClick = { editPanel ? . onUnlinkLibraryPanel }
tooltip = "Unlink library panel"
tooltip = { t ( 'dashboard.toolbar.unlink-library-panel' , 'Unlink library panel' ) }
size = "sm"
key = "unlinkLibraryPanel"
fill = "outline"
variant = "secondary"
data - testid = { selectors . components . NavToolbar . editDashboard . unlinkLibraryPanelButton }
>
Unlink library panel
< Trans i18nKey = "dashboard.toolbar.unlink-library-panel" > Unlink library panel < / Trans >
< / Button >
) ,
} ) ;
@ -563,14 +570,14 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > (
< Button
onClick = { editPanel ? . onSaveLibraryPanel }
tooltip = "Save library panel"
tooltip = { t ( 'dashboard.toolbar.save-library-panel' , 'Save library panel' ) }
size = "sm"
key = "saveLibraryPanel"
fill = "outline"
variant = "primary"
data - testid = { selectors . components . NavToolbar . editDashboard . saveLibraryPanelButton }
>
Save library panel
< Trans i18nKey = "dashboard.toolbar.save-library-panel" > Save library panel < / Trans >
< / Button >
) ,
} ) ;
@ -587,13 +594,13 @@ export function ToolbarActions({ dashboard }: Props) {
dashboard . openSaveDrawer ( { } ) ;
} }
className = { styles . buttonWithExtraMargin }
tooltip = "Save changes"
tooltip = { t ( 'dashboard.toolbar.save-dashboard.tooltip' , 'Save changes' ) }
key = "save"
size = "sm"
variant = { 'primary' }
variant = "primary"
data - testid = { selectors . components . NavToolbar . editDashboard . saveButton }
>
Save dashboard
< Trans i18nKey = "dashboard.toolbar.save-dashboard.label" > Save dashboard < / Trans >
< / Button >
) ;
}
@ -606,12 +613,12 @@ export function ToolbarActions({ dashboard }: Props) {
dashboard . openSaveDrawer ( { saveAsCopy : true } ) ;
} }
className = { styles . buttonWithExtraMargin }
tooltip = "Save as copy"
tooltip = { t ( 'dashboard.toolbar.save-dashboard-copy.tooltip' , 'Save as copy' ) }
key = "save"
size = "sm"
variant = { isDirty ? 'primary' : 'secondary' }
>
Save as copy
< Trans i18nKey = "dashboard.toolbar.save-dashboard-copy.label" > Save as copy < / Trans >
< / Button >
) ;
}
@ -620,14 +627,14 @@ export function ToolbarActions({ dashboard }: Props) {
const menu = (
< Menu >
< Menu.Item
label = "Save"
label = { t ( 'dashboard.toolbar.save-dashboard-short' , 'Save' ) }
icon = "save"
onClick = { ( ) = > {
dashboard . openSaveDrawer ( { } ) ;
} }
/ >
< Menu.Item
label = "Save as copy"
label = { t ( 'dashboard.toolbar.save-dashboard-copy.label' , 'Save as copy' ) }
icon = "copy"
onClick = { ( ) = > {
dashboard . openSaveDrawer ( { saveAsCopy : true } ) ;
@ -642,16 +649,16 @@ export function ToolbarActions({ dashboard }: Props) {
onClick = { ( ) = > {
dashboard . openSaveDrawer ( { } ) ;
} }
tooltip = "Save changes"
tooltip = { t ( 'dashboard.toolbar.save-dashboard.tooltip' , 'Save changes' ) }
size = "sm"
data - testid = { selectors . components . NavToolbar . editDashboard . saveButton }
variant = { isDirty ? 'primary' : 'secondary' }
>
Save dashboard
< Trans i18nKey = "dashboard.toolbar.save-dashboard.label" > Save dashboard < / Trans >
< / Button >
< Dropdown overlay = { menu } >
< Button
aria - label = "More save options"
aria - label = { t ( 'dashboard.toolbar.more-save-options' , 'More save options' ) }
icon = "angle-down"
variant = { isDirty ? 'primary' : 'secondary' }
size = "sm"
@ -669,7 +676,7 @@ export function ToolbarActions({ dashboard }: Props) {
render : ( ) = > {
return (
< ToolbarButton
tooltip = { 'Edit dashboard v2 schema'}
tooltip = { t ( 'dashboard.toolbar.edit-dashboard-v2-schema' , 'Edit dashboard v2 schema') }
icon = { < Icon name = "brackets-curly" size = "lg" type = "default" / > }
key = "schema-v2-button"
onClick = { ( ) = > {
@ -680,21 +687,21 @@ export function ToolbarActions({ dashboard }: Props) {
} ,
} ) ;
const rigt hActionsElements : React. ReactNode[ ] = renderActionElements ( toolbarActions ) ;
const leftActionsElements : React.React Node [ ] = renderActionElements ( leftActions ) ;
const right ActionsElements : ReactNode [ ] = renderActionElements ( toolbarActions ) ;
const leftActionsElements : ReactNode [ ] = renderActionElements ( leftActions ) ;
const hasActionsToLeftAndRight = showScopesSelector || leftActionsElements . length > 0 ;
return (
< Stack flex = { 1 } minWidth = { 0 } justifyContent = { hasActionsToLeftAndRight ? 'space-between' : 'flex-end' } >
{ showScopesSelector && < ScopesSelector / > }
{ leftActionsElements . length > 0 && < ToolbarButtonRow alignment = "left" > { leftActionsElements } < / ToolbarButtonRow > }
< ToolbarButtonRow alignment = "right" > { rigt hActionsElements } < / ToolbarButtonRow >
< ToolbarButtonRow alignment = "right" > { right ActionsElements } < / ToolbarButtonRow >
< / Stack >
) ;
}
function renderActionElements ( toolbarActions : ToolbarAction [ ] ) {
const actionElements : React.React Node [ ] = [ ] ;
const actionElements : ReactNode [ ] = [ ] ;
let lastGroup = '' ;
for ( const action of toolbarActions ) {
@ -709,6 +716,7 @@ function renderActionElements(toolbarActions: ToolbarAction[]) {
actionElements . push ( action . render ( ) ) ;
lastGroup = action . group ;
}
return actionElements ;
}
@ -755,7 +763,7 @@ function usePanelEditDirty(panelEditor?: PanelEditor) {
interface ToolbarAction {
group : string ;
condition? : boolean | string ;
render : ( ) = > React . React Node;
render : ( ) = > ReactNode ;
}
function getStyles ( theme : GrafanaTheme2 ) {