Dashboard: Edit pane tabs (#101145)
* Dashboard: Edit pane tabs * update design * Added translation elements * Update * Update * Update * Fix css issue * Update
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Box, Card, Icon } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { DashboardInteractions } from '../utils/interactions';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { DashboardEditPane } from './DashboardEditPane';
|
||||
|
||||
export interface Props {
|
||||
editPane: DashboardEditPane;
|
||||
}
|
||||
|
||||
export function DashboardAddPane({ editPane }: Props) {
|
||||
const dashboard = getDashboardSceneFor(editPane);
|
||||
|
||||
return (
|
||||
<Box display={'flex'} direction={'column'} gap={1} padding={2}>
|
||||
<Card
|
||||
onClick={() => dashboard.onCreateNewPanel()}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('add_visualization')}
|
||||
title={t('dashboard.toolbar.add-panel-description', 'A container for visualizations and other content')}
|
||||
>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="dashboard.toolbar.add-panel">Panel</Trans>
|
||||
</Card.Heading>
|
||||
<Card.Figure>
|
||||
<Icon name="graph-bar" size="xl" />
|
||||
</Card.Figure>
|
||||
</Card>
|
||||
<Card
|
||||
onClick={() => {
|
||||
dashboard.onShowAddLibraryPanelDrawer();
|
||||
DashboardInteractions.toolbarAddButtonClicked({ item: 'add_library_panel' });
|
||||
}}
|
||||
data-testid={selectors.pages.AddDashboard.itemButton('Add new panel from panel library menu item')}
|
||||
title={t(
|
||||
'dashboard.toolbar.libray-panel-description',
|
||||
'Libray panels allow you share and reuse panels between dashboards'
|
||||
)}
|
||||
>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="dashboard.toolbar.add-panel-lib">Import library panel</Trans>
|
||||
</Card.Heading>
|
||||
<Card.Figure>
|
||||
<Icon name="import" size="xl" />
|
||||
</Card.Figure>
|
||||
</Card>
|
||||
<Card
|
||||
onClick={() => dashboard.onCreateNewRow()}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('add_row')}
|
||||
title={t('dashboard.toolbar.row-description', 'A group of panels with an optional header')}
|
||||
>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="dashboard.toolbar.add-row">Row</Trans>
|
||||
</Card.Heading>
|
||||
<Card.Figure>
|
||||
<Icon name="list-ul" size="xl" />
|
||||
</Card.Figure>
|
||||
</Card>
|
||||
<Card
|
||||
onClick={() => dashboard.onCreateNewTab()}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('add_tab')}
|
||||
title={t('dashboard.toolbar.tabs-description', 'Break up your dashboard into different horizontal tabs')}
|
||||
>
|
||||
<Card.Heading>
|
||||
<Trans i18nKey="dashboard.toolbar.add-tab">Tab</Trans>
|
||||
</Card.Heading>
|
||||
<Card.Figure>
|
||||
<Icon name="layer-group" size="xl" />
|
||||
</Card.Figure>
|
||||
</Card>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -4,12 +4,20 @@ import { useEffect, useRef } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { SceneObjectState, SceneObjectBase, SceneObject, sceneGraph, useSceneObjectState } from '@grafana/scenes';
|
||||
import { ElementSelectionContextItem, ElementSelectionContextState, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import {
|
||||
ElementSelectionContextItem,
|
||||
ElementSelectionContextState,
|
||||
Tab,
|
||||
TabsBar,
|
||||
ToolbarButton,
|
||||
useStyles2,
|
||||
} from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { isInCloneChain } from '../utils/clone';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { DashboardAddPane } from './DashboardAddPane';
|
||||
import { ElementEditPane } from './ElementEditPane';
|
||||
import { ElementSelection } from './ElementSelection';
|
||||
import { useEditableElement } from './useEditableElement';
|
||||
@@ -17,8 +25,11 @@ import { useEditableElement } from './useEditableElement';
|
||||
export interface DashboardEditPaneState extends SceneObjectState {
|
||||
selection?: ElementSelection;
|
||||
selectionContext: ElementSelectionContextState;
|
||||
tab?: EditPaneTab;
|
||||
}
|
||||
|
||||
export type EditPaneTab = 'add' | 'configure' | 'outline';
|
||||
|
||||
export class DashboardEditPane extends SceneObjectBase<DashboardEditPaneState> {
|
||||
public constructor() {
|
||||
super({
|
||||
@@ -122,6 +133,10 @@ export class DashboardEditPane extends SceneObjectBase<DashboardEditPaneState> {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public onChangeTab = (tab: EditPaneTab) => {
|
||||
this.setState({ tab });
|
||||
};
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
@@ -157,7 +172,7 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
}
|
||||
}, [editPane, isCollapsed]);
|
||||
|
||||
const { selection } = useSceneObjectState(editPane, { shouldActivateOrKeepAlive: true });
|
||||
const { selection, tab = 'configure' } = useSceneObjectState(editPane, { shouldActivateOrKeepAlive: true });
|
||||
const styles = useStyles2(getStyles);
|
||||
const paneRef = useRef<HTMLDivElement>(null);
|
||||
const editableElement = useEditableElement(selection);
|
||||
@@ -191,7 +206,28 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper} ref={paneRef}>
|
||||
<ElementEditPane element={editableElement} key={editableElement.typeName} />
|
||||
<TabsBar className={styles.tabsbar}>
|
||||
<Tab
|
||||
active={tab === 'add'}
|
||||
label={t('dashboard.editpane.add', 'Add')}
|
||||
onChangeTab={() => editPane.onChangeTab('add')}
|
||||
/>
|
||||
<Tab
|
||||
active={tab === 'configure'}
|
||||
label={t('dashboard.editpane.configure', 'Configure')}
|
||||
onChangeTab={() => editPane.onChangeTab('configure')}
|
||||
/>
|
||||
<Tab
|
||||
active={tab === 'outline'}
|
||||
label={t('dashboard.editpane.outline', 'Outline')}
|
||||
onChangeTab={() => editPane.onChangeTab('outline')}
|
||||
/>
|
||||
</TabsBar>
|
||||
<div className={styles.tabContent}>
|
||||
{tab === 'add' && <DashboardAddPane editPane={editPane} />}
|
||||
{tab === 'configure' && <ElementEditPane element={editableElement} key={editableElement.typeName} />}
|
||||
{tab === 'outline' && <div />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -202,11 +238,21 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: '1 1 0',
|
||||
}),
|
||||
tabContent: css({
|
||||
display: 'flex',
|
||||
flex: '1 1 0',
|
||||
flexDirection: 'column',
|
||||
minHeight: 0,
|
||||
overflow: 'auto',
|
||||
}),
|
||||
rotate180: css({
|
||||
rotate: '180deg',
|
||||
}),
|
||||
tabsbar: css({
|
||||
padding: theme.spacing(0, 1),
|
||||
margin: theme.spacing(0.5, 1),
|
||||
}),
|
||||
expandOptionsWrapper: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
@@ -156,83 +156,6 @@ export function ToolbarActions({ dashboard }: Props) {
|
||||
}
|
||||
|
||||
if (dashboardNewLayouts) {
|
||||
leftActions.push({
|
||||
group: 'add-panel',
|
||||
condition: isEditingAndShowingDashboard,
|
||||
render: () => (
|
||||
<Button
|
||||
key="add-panel-button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
icon="plus"
|
||||
fill="text"
|
||||
onClick={() => {
|
||||
dashboard.onCreateNewPanel();
|
||||
}}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('add_visualization')}
|
||||
>
|
||||
<Trans i18nKey="dashboard.toolbar.add-panel">Panel</Trans>
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
leftActions.push({
|
||||
group: 'add-panel',
|
||||
condition: isEditingAndShowingDashboard,
|
||||
render: () => (
|
||||
<Button
|
||||
key="add-panel-button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
icon="plus"
|
||||
fill="text"
|
||||
onClick={() => {
|
||||
dashboard.onCreateNewRow();
|
||||
}}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('add_row')}
|
||||
>
|
||||
<Trans i18nKey="dashboard.toolbar.add-row">Row</Trans>
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
leftActions.push({
|
||||
group: 'add-panel',
|
||||
condition: isEditingAndShowingDashboard,
|
||||
render: () => (
|
||||
<Button
|
||||
key="add-tab-button"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
icon="plus"
|
||||
fill="text"
|
||||
onClick={() => {
|
||||
dashboard.onCreateNewTab();
|
||||
}}
|
||||
data-testid={selectors.components.PageToolbar.itemButton('add_tab')}
|
||||
>
|
||||
<Trans i18nKey="dashboard.toolbar.add-tab">Tab</Trans>
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
leftActions.push({
|
||||
group: 'add-panel',
|
||||
condition: isEditingAndShowingDashboard,
|
||||
render: () => (
|
||||
<Button
|
||||
key="add-panel-lib"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
icon="plus"
|
||||
fill="text"
|
||||
data-testid={selectors.pages.AddDashboard.itemButton('Add new panel from panel library menu item')}
|
||||
onClick={() => {
|
||||
dashboard.onShowAddLibraryPanelDrawer();
|
||||
DashboardInteractions.toolbarAddButtonClicked({ item: 'add_library_panel' });
|
||||
}}
|
||||
>
|
||||
<Trans i18nKey="dashboard.toolbar.add-panel-lib">Import</Trans>
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
leftActions.push({
|
||||
group: 'hidden-elements',
|
||||
condition: isEditingAndShowingDashboard,
|
||||
|
||||
@@ -1057,6 +1057,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"editpane": {
|
||||
"add": "Add",
|
||||
"configure": "Configure",
|
||||
"outline": "Outline"
|
||||
},
|
||||
"empty": {
|
||||
"add-library-panel-body": "Add visualizations that are shared with other dashboards.",
|
||||
"add-library-panel-button": "Add library panel",
|
||||
@@ -1194,7 +1199,8 @@
|
||||
"toolbar": {
|
||||
"add": "Add",
|
||||
"add-panel": "Panel",
|
||||
"add-panel-lib": "Import",
|
||||
"add-panel-description": "A container for visualizations and other content",
|
||||
"add-panel-lib": "Import library panel",
|
||||
"add-row": "Row",
|
||||
"add-tab": "Tab",
|
||||
"alert-rules": "Alert rules",
|
||||
@@ -1219,6 +1225,7 @@
|
||||
"label": "Exit edit",
|
||||
"tooltip": "Exits edit mode and discards unsaved changes"
|
||||
},
|
||||
"libray-panel-description": "Libray panels allow you share and reuse panels between dashboards",
|
||||
"mark-favorite": "Mark as favorite",
|
||||
"more-save-options": "More save options",
|
||||
"open-original": "Open original dashboard",
|
||||
@@ -1227,6 +1234,7 @@
|
||||
"playlist-stop": "Stop playlist",
|
||||
"public-dashboard": "Public",
|
||||
"refresh": "Refresh dashboard",
|
||||
"row-description": "A group of panels with an optional header",
|
||||
"save": "Save dashboard",
|
||||
"save-dashboard": {
|
||||
"label": "Save dashboard",
|
||||
@@ -1246,6 +1254,7 @@
|
||||
"share-button": "Share",
|
||||
"show-hidden-elements": "Show hidden",
|
||||
"switch-old-dashboard": "Switch to old dashboard page",
|
||||
"tabs-description": "Break up your dashboard into different horizontal tabs",
|
||||
"unlink-library-panel": "Unlink library panel",
|
||||
"unmark-favorite": "Unmark as favorite"
|
||||
},
|
||||
|
||||
@@ -1057,6 +1057,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"editpane": {
|
||||
"add": "Åđđ",
|
||||
"configure": "Cőʼnƒįģūřę",
|
||||
"outline": "Øūŧľįʼnę"
|
||||
},
|
||||
"empty": {
|
||||
"add-library-panel-body": "Åđđ vįşūäľįžäŧįőʼnş ŧĥäŧ äřę şĥäřęđ ŵįŧĥ őŧĥęř đäşĥþőäřđş.",
|
||||
"add-library-panel-button": "Åđđ ľįþřäřy päʼnęľ",
|
||||
@@ -1194,7 +1199,8 @@
|
||||
"toolbar": {
|
||||
"add": "Åđđ",
|
||||
"add-panel": "Päʼnęľ",
|
||||
"add-panel-lib": "Ĩmpőřŧ",
|
||||
"add-panel-description": "Å čőʼnŧäįʼnęř ƒőř vįşūäľįžäŧįőʼnş äʼnđ őŧĥęř čőʼnŧęʼnŧ",
|
||||
"add-panel-lib": "Ĩmpőřŧ ľįþřäřy päʼnęľ",
|
||||
"add-row": "Ŗőŵ",
|
||||
"add-tab": "Ŧäþ",
|
||||
"alert-rules": "Åľęřŧ řūľęş",
|
||||
@@ -1219,6 +1225,7 @@
|
||||
"label": "Ēχįŧ ęđįŧ",
|
||||
"tooltip": "Ēχįŧş ęđįŧ mőđę äʼnđ đįşčäřđş ūʼnşävęđ čĥäʼnģęş"
|
||||
},
|
||||
"libray-panel-description": "Ŀįþřäy päʼnęľş äľľőŵ yőū şĥäřę äʼnđ řęūşę päʼnęľş þęŧŵęęʼn đäşĥþőäřđş",
|
||||
"mark-favorite": "Mäřĸ äş ƒävőřįŧę",
|
||||
"more-save-options": "Mőřę şävę őpŧįőʼnş",
|
||||
"open-original": "Øpęʼn őřįģįʼnäľ đäşĥþőäřđ",
|
||||
@@ -1227,6 +1234,7 @@
|
||||
"playlist-stop": "Ŝŧőp pľäyľįşŧ",
|
||||
"public-dashboard": "Pūþľįč",
|
||||
"refresh": "Ŗęƒřęşĥ đäşĥþőäřđ",
|
||||
"row-description": "Å ģřőūp őƒ päʼnęľş ŵįŧĥ äʼn őpŧįőʼnäľ ĥęäđęř",
|
||||
"save": "Ŝävę đäşĥþőäřđ",
|
||||
"save-dashboard": {
|
||||
"label": "Ŝävę đäşĥþőäřđ",
|
||||
@@ -1246,6 +1254,7 @@
|
||||
"share-button": "Ŝĥäřę",
|
||||
"show-hidden-elements": "Ŝĥőŵ ĥįđđęʼn",
|
||||
"switch-old-dashboard": "Ŝŵįŧčĥ ŧő őľđ đäşĥþőäřđ päģę",
|
||||
"tabs-description": "ßřęäĸ ūp yőūř đäşĥþőäřđ įʼnŧő đįƒƒęřęʼnŧ ĥőřįžőʼnŧäľ ŧäþş",
|
||||
"unlink-library-panel": "Ůʼnľįʼnĸ ľįþřäřy päʼnęľ",
|
||||
"unmark-favorite": "Ůʼnmäřĸ äş ƒävőřįŧę"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user