diff --git a/packages/grafana-data/src/types/icon.ts b/packages/grafana-data/src/types/icon.ts index b1092680181..36bdbb34a7b 100644 --- a/packages/grafana-data/src/types/icon.ts +++ b/packages/grafana-data/src/types/icon.ts @@ -170,6 +170,7 @@ export const availableIconsIndex = { kubernetes: true, 'layer-group': true, 'layers-alt': true, + layers: true, 'legend-hide': true, 'legend-show': true, 'library-panel': true, diff --git a/public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingData.tsx b/public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingData.tsx index 47e60687dc6..e5604082adf 100644 --- a/public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingData.tsx +++ b/public/app/features/dashboard-scene/conditional-rendering/ConditionalRenderingData.tsx @@ -47,6 +47,7 @@ export class ConditionalRenderingData extends ConditionalRenderingBase { this._subs.add( d.subscribeToState(() => { diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardAddPane.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardAddPane.tsx index f7c6143037f..267af6b800e 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardAddPane.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardAddPane.tsx @@ -1,8 +1,9 @@ import { css } from '@emotion/css'; import { useEffect, useState } from 'react'; +import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { Box, Card, Icon, IconName, useStyles2 } from '@grafana/ui'; +import { Box, Card, Icon, IconButton, IconName, useStyles2 } from '@grafana/ui'; import { LS_PANEL_COPY_KEY } from 'app/core/constants'; import { t } from 'app/core/internationalization'; import store from 'app/core/store'; @@ -84,22 +85,35 @@ export function DashboardAddPane({ editPane }: Props) { ]; return ( - - {cards.map(({ icon, heading, title, testId, onClick, hide }) => - hide ? null : ( - - {heading} - - - - - ) - )} - + <> +
+ editPane.toggleAddPane()} aria-label="Close add pane" /> + {t('dashboard.edit-pane.add.title', 'Add element')} +
+ + {cards.map(({ icon, heading, title, testId, onClick, hide }) => + hide ? null : ( + + {heading} + + + + + ) + )} + + ); } -const getStyles = () => ({ +const getStyles = (theme: GrafanaTheme2) => ({ + header: css({ + display: 'flex', + alignItems: 'center', + padding: theme.spacing(1, 2), + gap: theme.spacing(1), + borderBottom: `1px solid ${theme.colors.border.weak}`, + }), figure: css({ pointerEvents: 'none', }), diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx index fbb8f414e4d..b6fc29882fd 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx @@ -1,16 +1,19 @@ import { css, cx } from '@emotion/css'; import { Resizable } from 're-resizable'; -import { useEffect, useRef } from 'react'; +import { useEffect } from 'react'; +import { useLocalStorage } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; import { SceneObjectState, SceneObjectBase, SceneObject, sceneGraph, useSceneObjectState } from '@grafana/scenes'; import { ElementSelectionContextItem, ElementSelectionContextState, - Tab, - TabsBar, + ScrollContainer, ToolbarButton, + useSplitter, useStyles2, + Text, + Icon, } from '@grafana/ui'; import { t } from 'app/core/internationalization'; @@ -27,7 +30,7 @@ import { useEditableElement } from './useEditableElement'; export interface DashboardEditPaneState extends SceneObjectState { selection?: ElementSelection; selectionContext: ElementSelectionContextState; - tab?: EditPaneTab; + showAddPane?: boolean; } export type EditPaneTab = 'add' | 'configure' | 'outline'; @@ -63,9 +66,7 @@ export class DashboardEditPane extends SceneObjectBase { this._subs.add( dashboard.subscribeToEvent(ObjectsReorderedOnCanvasEvent, ({ payload }) => { - if (this.state.tab === 'outline') { - this.forceRender(); - } + this.forceRender(); }) ); } @@ -103,6 +104,10 @@ export class DashboardEditPane extends SceneObjectBase { return this.state.selection?.getSelection(); } + public toggleAddPane() { + this.setState({ showAddPane: !this.state.showAddPane }); + } + public selectObject(obj: SceneObject, id: string, multi?: boolean) { const prevItem = this.state.selection?.getFirstObject(); if (prevItem === obj && !multi) { @@ -125,6 +130,7 @@ export class DashboardEditPane extends SceneObjectBase { ...this.state.selectionContext, selected, }, + showAddPane: false, }); } @@ -163,15 +169,11 @@ export class DashboardEditPane extends SceneObjectBase { }); } - public onChangeTab = (tab: EditPaneTab) => { - this.setState({ tab }); - }; - private newObjectAddedToCanvas(obj: SceneObject) { this.selectObject(obj, obj.state.key!, false); - if (this.state.tab !== 'configure') { - this.onChangeTab('configure'); + if (this.state.showAddPane) { + this.setState({ showAddPane: false }); } } } @@ -202,11 +204,27 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla } }, [editPane, isCollapsed]); - const { selection, tab = 'configure' } = useSceneObjectState(editPane, { shouldActivateOrKeepAlive: true }); + const { selection, showAddPane } = useSceneObjectState(editPane, { shouldActivateOrKeepAlive: true }); const styles = useStyles2(getStyles); - const paneRef = useRef(null); const editableElement = useEditableElement(selection, editPane); const selectedObject = selection?.getFirstObject(); + const [outlineCollapsed, setOutlineCollapsed] = useLocalStorage( + 'grafana.dashboard.edit-pane.outline.collapsed', + false + ); + const [outlinePaneSize = 0.4, setOutlinePaneSize] = useLocalStorage('grafana.dashboard.edit-pane.outline.size', 0.4); + + // splitter for template and payload editor + const splitter = useSplitter({ + direction: 'column', + handleSize: 'sm', + // if Grafana Alertmanager, split 50/50, otherwise 100/0 because there is no payload editor + initialSize: 1 - outlinePaneSize, + dragPosition: 'middle', + onSizeChanged: (size) => { + setOutlinePaneSize(1 - size); + }, + }); if (!editableElement) { return null; @@ -221,43 +239,67 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla icon="arrow-to-right" onClick={onToggleCollapse} variant="canvas" + narrow={true} className={styles.rotate180} aria-label={t('dashboard.edit-pane.open', 'Open options pane')} /> {openOverlay && ( - - + + )} ); } + if (outlineCollapsed) { + splitter.primaryProps.style.flexGrow = 1; + splitter.primaryProps.style.minHeight = 'unset'; + splitter.secondaryProps.style.flexGrow = 0; + splitter.secondaryProps.style.minHeight = 'min-content'; + } else { + splitter.primaryProps.style.minHeight = 'unset'; + splitter.secondaryProps.style.minHeight = 'unset'; + } + + if (showAddPane) { + return ( +
+ +
+ ); + } + return ( -
- - editPane.onChangeTab('add')} +
+
+
+ +
+
- editPane.onChangeTab('configure')} - /> - editPane.onChangeTab('outline')} - /> - -
- {tab === 'add' && } - {tab === 'configure' && } - {tab === 'outline' && } +
+
setOutlineCollapsed(!outlineCollapsed)} + className={styles.outlineCollapseButton} + > + Outline + +
+ {!outlineCollapsed && ( +
+ + + +
+ )} +
); @@ -269,13 +311,27 @@ function getStyles(theme: GrafanaTheme2) { display: 'flex', flexDirection: 'column', flex: '1 1 0', + marginTop: theme.spacing(2), + borderLeft: `1px solid ${theme.colors.border.weak}`, + borderTop: `1px solid ${theme.colors.border.weak}`, + background: theme.colors.background.primary, }), - tabContent: css({ + overlayWrapper: css({ + right: 0, + bottom: 0, + top: theme.spacing(2), + position: 'absolute !important' as 'absolute', + background: theme.colors.background.primary, + borderLeft: `1px solid ${theme.colors.border.weak}`, + borderTop: `1px solid ${theme.colors.border.weak}`, + boxShadow: theme.shadows.z3, + zIndex: theme.zIndex.navbarFixed, + flexGrow: 1, + }), + paneContent: css({ + overflow: 'hidden', display: 'flex', - flex: '1 1 0', flexDirection: 'column', - minHeight: 0, - overflow: 'auto', }), rotate180: css({ rotate: '180deg', @@ -287,20 +343,30 @@ function getStyles(theme: GrafanaTheme2) { expandOptionsWrapper: css({ display: 'flex', flexDirection: 'column', - padding: theme.spacing(2, 1), + padding: theme.spacing(2, 1, 2, 0), }), - // @ts-expect-error csstype doesn't allow !important. see https://github.com/frenic/csstype/issues/114 - fixed: css({ - position: 'absolute !important', + splitter: css({ + '&:after': { + display: 'none', + }, }), - container: css({ - right: 0, - background: theme.colors.background.primary, - borderLeft: `1px solid ${theme.colors.border.weak}`, - boxShadow: theme.shadows.z3, - zIndex: theme.zIndex.navbarFixed, - overflowX: 'hidden', - overflowY: 'scroll', + outlineCollapseButton: css({ + display: 'flex', + padding: theme.spacing(0.5, 2), + gap: theme.spacing(1), + justifyContent: 'space-between', + alignItems: 'center', + background: theme.colors.background.secondary, + + '&:hover': { + background: theme.colors.action.hover, + }, + }), + outlineContainer: css({ + display: 'flex', + flexDirection: 'column', + flexGrow: 1, + overflow: 'hidden', }), }; } diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardEditPaneSplitter.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardEditPaneSplitter.tsx index 48d3ab22af2..0b6bf54ecd2 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardEditPaneSplitter.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardEditPaneSplitter.tsx @@ -48,7 +48,7 @@ export function DashboardEditPaneSplitter({ dashboard, isEditing, body, controls collapsed: isCollapsed, paneOptions: { - collapseBelowPixels: 250, + collapseBelowPixels: 150, snapOpenToPixels: 400, }, }); @@ -97,7 +97,11 @@ export function DashboardEditPaneSplitter({ dashboard, isEditing, body, controls
{isEditing && ( <> -
+
this.dashboard.onOpenSettings()} tooltip={t('dashboard.toolbar.dashboard-settings.tooltip', 'Dashboard settings')} > diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx index be3066396f4..67a7ba72c14 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx @@ -3,8 +3,8 @@ import { useMemo, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { SceneObject, VizPanel } from '@grafana/scenes'; -import { Box, Icon, IconButton, Stack, Text, useElementSelection, useStyles2 } from '@grafana/ui'; -import { t, Trans } from 'app/core/internationalization'; +import { Box, Icon, Text, useElementSelection, useStyles2 } from '@grafana/ui'; +import { Trans } from 'app/core/internationalization'; import { DashboardGridItem } from '../scene/layout-default/DashboardGridItem'; import { isInCloneChain } from '../utils/clone'; @@ -21,7 +21,7 @@ export function DashboardOutline({ editPane }: Props) { const dashboard = getDashboardSceneFor(editPane); return ( - + ); @@ -40,34 +40,19 @@ function DashboardOutlineNode({ sceneObject, expandable }: { sceneObject: SceneO return ( <> - { + onSelect?.(evt); + setIsExpanded(!isExpanded); + }} > - {expandable && ( - setIsExpanded(!isExpanded)} - aria-label={ - isExpanded - ? t('dashboard.outline.tree.item.collapse', 'Collapse item') - : t('dashboard.outline.tree.item.expand', 'Expand item') - } - /> - )} - - + {expandable && } + + {elementInfo.instanceName} + + {expandable && isExpanded && (
{children.length > 0 ? ( @@ -94,7 +79,7 @@ function getStyles(theme: GrafanaTheme2) { container: css({ display: 'flex', flexDirection: 'column', - gap: theme.spacing(1), + gap: theme.spacing(0.5), marginLeft: theme.spacing(1), paddingLeft: theme.spacing(1.5), borderLeft: `1px solid ${theme.colors.border.medium}`, @@ -105,12 +90,16 @@ function getStyles(theme: GrafanaTheme2) { background: 'transparent', padding: theme.spacing(0.25, 1), borderRadius: theme.shape.radius.default, + color: theme.colors.text.secondary, display: 'flex', alignItems: 'center', - gap: theme.spacing(1), + gap: theme.spacing(0.5), overflow: 'hidden', '&:hover': { - backgroundColor: theme.colors.action.hover, + color: theme.colors.text.primary, + outline: `1px dashed ${theme.colors.border.strong}`, + outlineOffset: '0px', + backgroundColor: theme.colors.emphasize(theme.colors.background.canvas, 0.08), }, '> span': { whiteSpace: 'nowrap', @@ -119,7 +108,12 @@ function getStyles(theme: GrafanaTheme2) { }, }), nodeButtonSelected: css({ - color: theme.colors.primary.text, + color: theme.colors.text.primary, + outline: `1px dashed ${theme.colors.primary.border}`, + outlineOffset: '0px', + '&:hover': { + outline: `1px dashed ${theme.colors.primary.border}`, + }, }), nodeButtonClone: css({ color: theme.colors.text.secondary, diff --git a/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx index d4a3071c2a5..01a5263d833 100644 --- a/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx +++ b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx @@ -1,26 +1,43 @@ import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; -import { Button, Menu, Stack, Text, useStyles2, ConfirmButton, Dropdown, Icon } from '@grafana/ui'; +import { Button, Menu, Stack, Text, useStyles2, ConfirmButton, Dropdown, Icon, IconButton } from '@grafana/ui'; import { t } from 'app/core/internationalization'; import { EditableDashboardElement } from '../scene/types/EditableDashboardElement'; +import { DashboardEditPane } from './DashboardEditPane'; + interface EditPaneHeaderProps { element: EditableDashboardElement; + editPane: DashboardEditPane; } -export function EditPaneHeader({ element }: EditPaneHeaderProps) { +export function EditPaneHeader({ element, editPane }: EditPaneHeaderProps) { const elementInfo = element.getEditableElementInfo(); const styles = useStyles2(getStyles); const onCopy = element.onCopy?.bind(element); const onDuplicate = element.onDuplicate?.bind(element); const onDelete = element.onDelete?.bind(element); + // temporary simple solution, should select parent element + const onGoBack = () => editPane.clearSelection(); + const canGoBack = editPane.state.selection; return (
- {elementInfo.typeName} + + {canGoBack && ( + + )} + {elementInfo.typeName} + {element.renderActions && element.renderActions()} {(onCopy || onDelete) && ( @@ -80,7 +97,7 @@ function getStyles(theme: GrafanaTheme2) { display: 'flex', alignItems: 'center', justifyContent: 'space-between', - padding: theme.spacing(2), + padding: theme.spacing(1, 2), borderBottom: `1px solid ${theme.colors.border.weak}`, }), }; diff --git a/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx b/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx index f60b4bd7e26..7806715e3b9 100644 --- a/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx +++ b/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx @@ -1,20 +1,37 @@ -import { Stack } from '@grafana/ui'; +import { css } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { ScrollContainer, useStyles2 } from '@grafana/ui'; import { EditableDashboardElement } from '../scene/types/EditableDashboardElement'; +import { DashboardEditPane } from './DashboardEditPane'; import { EditPaneHeader } from './EditPaneHeader'; export interface Props { element: EditableDashboardElement; + editPane: DashboardEditPane; } -export function ElementEditPane({ element }: Props) { +export function ElementEditPane({ element, editPane }: Props) { const categories = element.useEditPaneOptions ? element.useEditPaneOptions() : []; + const styles = useStyles2(getStyles); return ( - - - {categories.map((cat) => cat.render())} - +
+ + {categories.map((cat) => cat.render())} +
); } + +function getStyles(theme: GrafanaTheme2) { + return { + wrapper: css({ + display: 'flex', + flexDirection: 'column', + flex: '1 1 0', + height: '100%', + }), + }; +} diff --git a/public/app/features/dashboard-scene/scene/layout-rows/RowItem.tsx b/public/app/features/dashboard-scene/scene/layout-rows/RowItem.tsx index 8bdc2ad2163..12b916670c8 100644 --- a/public/app/features/dashboard-scene/scene/layout-rows/RowItem.tsx +++ b/public/app/features/dashboard-scene/scene/layout-rows/RowItem.tsx @@ -65,7 +65,7 @@ export class RowItem return { typeName: t('dashboard.edit-pane.elements.row', 'Row'), instanceName: sceneGraph.interpolate(this, this.state.title, undefined, 'text'), - icon: 'line-alt', + icon: 'list-ul', }; } diff --git a/public/app/features/dashboard-scene/scene/layout-tabs/TabItem.tsx b/public/app/features/dashboard-scene/scene/layout-tabs/TabItem.tsx index 6bef7c0bf8d..62db0d875ca 100644 --- a/public/app/features/dashboard-scene/scene/layout-tabs/TabItem.tsx +++ b/public/app/features/dashboard-scene/scene/layout-tabs/TabItem.tsx @@ -46,7 +46,7 @@ export class TabItem return { typeName: t('dashboard.edit-pane.elements.tab', 'Tab'), instanceName: sceneGraph.interpolate(this, this.state.title, undefined, 'text'), - icon: 'tag-alt', + icon: 'layers', }; } diff --git a/public/app/features/dashboard-scene/scene/new-toolbar/RightActions.tsx b/public/app/features/dashboard-scene/scene/new-toolbar/RightActions.tsx index b809a9fb90a..b7362e5d1d1 100644 --- a/public/app/features/dashboard-scene/scene/new-toolbar/RightActions.tsx +++ b/public/app/features/dashboard-scene/scene/new-toolbar/RightActions.tsx @@ -8,6 +8,7 @@ import { isLibraryPanel } from '../../utils/utils'; import { DashboardScene } from '../DashboardScene'; import { BackToDashboardButton } from './actions/BackToDashboardButton'; +import { DashboardAddButton } from './actions/DashboardAddButton'; import { DashboardSettingsButton } from './actions/DashboardSettingsButton'; import { DiscardLibraryPanelButton } from './actions/DiscardLibraryPanelButton'; import { DiscardPanelButton } from './actions/DiscardPanelButton'; @@ -98,6 +99,12 @@ export const RightActions = ({ dashboard }: { dashboard: DashboardScene }) => { group: 'panel', condition: showPanelButtons && isEditingLibraryPanel, }, + { + key: 'dashboard-add-button', + component: DashboardAddButton, + group: 'dashboard', + condition: isEditingAndShowingDashboard && dashboard.canEditDashboard(), + }, { key: 'edit-schema-v2-button', component: EditSchemaV2Button, diff --git a/public/app/features/dashboard-scene/scene/new-toolbar/actions/DashboardAddButton.tsx b/public/app/features/dashboard-scene/scene/new-toolbar/actions/DashboardAddButton.tsx new file mode 100644 index 00000000000..41104d28c31 --- /dev/null +++ b/public/app/features/dashboard-scene/scene/new-toolbar/actions/DashboardAddButton.tsx @@ -0,0 +1,21 @@ +import { selectors } from '@grafana/e2e-selectors'; +import { Button } from '@grafana/ui'; +import { t, Trans } from 'app/core/internationalization'; + +import { ToolbarActionProps } from '../types'; + +export function DashboardAddButton({ dashboard }: ToolbarActionProps) { + return ( + + ); +} diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx index a9e43013151..44c39ddd8e1 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategory.tsx @@ -16,7 +16,7 @@ export interface OptionsPaneCategoryProps { renderTitle?: (isExpanded: boolean) => React.ReactNode; isOpenDefault?: boolean; itemsCount?: number; - forceOpen?: number; + forceOpen?: boolean; className?: string; isNested?: boolean; children: ReactNode; @@ -42,37 +42,24 @@ export const OptionsPaneCategory = React.memo( isExpanded: isOpenDefault, }); - const [isExpanded, setIsExpanded] = useState(savedState?.isExpanded ?? isOpenDefault); - const manualClickTime = useRef(0); + const isExpandedInitialValue = forceOpen || (savedState?.isExpanded ?? isOpenDefault); + const [isExpanded, setIsExpanded] = useState(isExpandedInitialValue); const ref = useRef(null); const [queryParams, updateQueryParams] = useQueryParams(); const isOpenFromUrl = queryParams[CATEGORY_PARAM_NAME] === id; + // Handle opening by forceOpen param or from URL useEffect(() => { - if (manualClickTime.current) { - // ignore changes since the click handled the expected behavior - if (Date.now() - manualClickTime.current < 200) { - return; - } - } - if (isOpenFromUrl || forceOpen) { - if (!isExpanded) { - setIsExpanded(true); - } - if (isOpenFromUrl) { + if ((forceOpen || isOpenFromUrl) && !isExpanded) { + setIsExpanded(true); + setTimeout(() => { ref.current?.scrollIntoView(); - } + }, 200); } - }, [forceOpen, isExpanded, isOpenFromUrl]); + }, [isExpanded, isOpenFromUrl, forceOpen]); const onToggle = useCallback(() => { - manualClickTime.current = Date.now(); - updateQueryParams( - { - [CATEGORY_PARAM_NAME]: isExpanded ? undefined : id, - }, - true - ); + updateQueryParams({ [CATEGORY_PARAM_NAME]: isExpanded ? undefined : id }, true); setSavedState({ isExpanded: !isExpanded }); setIsExpanded(!isExpanded); }, [updateQueryParams, isExpanded, id, setSavedState]); diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx index 854b5be01e7..210610f3e6a 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx @@ -10,7 +10,7 @@ export interface OptionsPaneCategoryDescriptorProps { title: string; renderTitle?: (isExpanded: boolean) => React.ReactNode; isOpenDefault?: boolean; - forceOpen?: number; + forceOpen?: boolean; className?: string; isNested?: boolean; itemsCount?: number; diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx index 20ef00f4069..6464794b9de 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx @@ -96,7 +96,7 @@ export const OptionsPaneOptions = (props: OptionPaneRenderProps) => { break; case OptionFilter.Recent: mainBoxElements.push( - + {getRecentOptions(allOptions).map((item) => item.render())} ); @@ -163,7 +163,7 @@ export function renderSearchHits( id="Found options" title={`Matched ${optionHits.length}/${totalCount} options`} key="Normal options" - forceOpen={1} + forceOpen={true} > {optionHits.map((hit) => hit.render(searchQuery))} diff --git a/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx b/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx index a4b0eda3423..0e4cbec3364 100644 --- a/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx +++ b/public/app/features/dashboard/components/PanelEditor/getFieldOverrideElements.tsx @@ -85,7 +85,7 @@ export function getFieldOverrideCategories( const configPropertiesOptions = getOverrideProperties(registry); const isSystemOverride = isSystemOverrideGuard(override); // A way to force open new override categories - const forceOpen = override.properties.length === 0 ? 1 : 0; + const forceOpen = override.properties.length === 0; const category = new OptionsPaneCategoryDescriptor({ title: overrideName, diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 5e041f22713..f8bcfe145d2 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -1395,7 +1395,8 @@ "tab": { "heading": "Tab", "title": "Break up your dashboard into different horizontal tabs" - } + }, + "title": "Add element" }, "elements": { "dashboard": "Dashboard", @@ -1415,11 +1416,6 @@ } } }, - "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", @@ -1503,9 +1499,7 @@ "outline": { "tree": { "item": { - "collapse": "Collapse item", - "empty": "(empty)", - "expand": "Expand item" + "empty": "(empty)" } } }, @@ -1607,6 +1601,9 @@ }, "toolbar": { "add": "Add", + "add-new": { + "tooltip": "Add panels and other elements" + }, "alert-rules": "Alert rules", "back-to-dashboard": "Back to dashboard", "dashboard-settings": { @@ -2409,6 +2406,13 @@ "requires-license": "Requires a Grafana Enterprise license", "title": "Enterprise" }, + "grafana": { + "dashboard": { + "edit-pane": { + "go-back": "Go back" + } + } + }, "grafana-ui": { "action-editor": { "button": {