Navigation: Change dashboard settings to use tabs when dockedMegaMenu is enabled (#75463)

* kinda working

* return to selected parents

* feature toggle everything

* fix toggling of annotations

* use Trans instead of Text

* kick drone
This commit is contained in:
Ashley Harrison 2023-09-28 16:15:00 +01:00 committed by GitHub
parent 0577c5c8e5
commit a2964731eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 64 additions and 20 deletions

View File

@ -1,5 +1,6 @@
import React from 'react';
import { config } from '@grafana/runtime';
import { Permissions } from 'app/core/components/AccessControl';
import { Page } from 'app/core/components/Page/Page';
import { contextSrv } from 'app/core/core';
@ -9,9 +10,10 @@ import { SettingsPageProps } from '../DashboardSettings/types';
export const AccessControlDashboardPermissions = ({ dashboard, sectionNav }: SettingsPageProps) => {
const canSetPermissions = contextSrv.hasPermission(AccessControlAction.DashboardsPermissionsWrite);
const pageNav = config.featureToggles.dockedMegaMenu ? sectionNav.node.parentItem : undefined;
return (
<Page navModel={sectionNav}>
<Page navModel={sectionNav} pageNav={pageNav}>
<Permissions resource={'dashboards'} resourceId={dashboard.uid} canSetPermissions={canSetPermissions} />
</Page>
);

View File

@ -1,6 +1,7 @@
import React, { PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { config } from '@grafana/runtime';
import { Tooltip, Icon, Button } from '@grafana/ui';
import { SlideDown } from 'app/core/components/Animations/SlideDown';
import { Page } from 'app/core/components/Page/Page';
@ -90,17 +91,18 @@ export class DashboardPermissionsUnconnected extends PureComponent<Props, State>
render() {
const { permissions, dashboard, sectionNav } = this.props;
const { isAdding } = this.state;
const pageNav = config.featureToggles.dockedMegaMenu ? sectionNav.node.parentItem : undefined;
if (dashboard.meta.hasUnsavedFolderChange) {
return (
<Page navModel={sectionNav}>
<Page navModel={sectionNav} pageNav={pageNav}>
<h5>You have changed a folder, please save to view permissions.</h5>
</Page>
);
}
return (
<Page navModel={sectionNav}>
<Page navModel={sectionNav} pageNav={pageNav}>
<div className="page-action-bar">
<Tooltip placement="auto" content={<PermissionsInfo />}>
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />

View File

@ -1,7 +1,7 @@
import React from 'react';
import { AnnotationQuery, getDataSourceRef, NavModelItem } from '@grafana/data';
import { getDataSourceSrv, locationService } from '@grafana/runtime';
import { config, getDataSourceSrv, locationService } from '@grafana/runtime';
import { Page } from 'app/core/components/Page/Page';
import { DashboardModel } from '../../state';
@ -29,22 +29,31 @@ export function AnnotationsSettings({ dashboard, editIndex, sectionNav }: Settin
const isEditing = editIndex != null && editIndex < dashboard.annotations.list.length;
return (
<Page navModel={sectionNav} pageNav={getSubPageNav(dashboard, editIndex)}>
<Page navModel={sectionNav} pageNav={getSubPageNav(dashboard, editIndex, sectionNav.node)}>
{!isEditing && <AnnotationSettingsList dashboard={dashboard} onNew={onNew} onEdit={onEdit} />}
{isEditing && <AnnotationSettingsEdit dashboard={dashboard} editIdx={editIndex!} />}
</Page>
);
}
function getSubPageNav(dashboard: DashboardModel, editIndex: number | undefined): NavModelItem | undefined {
function getSubPageNav(
dashboard: DashboardModel,
editIndex: number | undefined,
node: NavModelItem
): NavModelItem | undefined {
const parentItem = config.featureToggles.dockedMegaMenu ? node.parentItem : undefined;
if (editIndex == null) {
return undefined;
return parentItem;
}
const editItem = dashboard.annotations.list[editIndex];
if (editItem) {
return {
text: editItem.name,
parentItem: parentItem && {
...parentItem,
url: node.url,
},
};
}

View File

@ -191,6 +191,11 @@ function getSectionNav(
hideFromBreadcrumbs: true,
};
if (config.featureToggles.dockedMegaMenu) {
main.hideFromBreadcrumbs = false;
main.url = locationUtil.getUrlForPartial(location, { editview: 'settings', editIndex: null });
}
main.children = pages.map((page) => ({
text: page.title,
icon: page.icon,

View File

@ -41,6 +41,7 @@ export function GeneralSettingsUnconnected({
const [renderCounter, setRenderCounter] = useState(0);
const [dashboardTitle, setDashboardTitle] = useState(dashboard.title);
const [dashboardDescription, setDashboardDescription] = useState(dashboard.description);
const pageNav = config.featureToggles.dockedMegaMenu ? sectionNav.node.parentItem : undefined;
const onFolderChange = (newUID: string, newTitle: string) => {
dashboard.meta.folderUid = newUID;
@ -116,7 +117,7 @@ export function GeneralSettingsUnconnected({
];
return (
<Page navModel={sectionNav}>
<Page navModel={sectionNav} pageNav={pageNav}>
<div style={{ maxWidth: '600px' }}>
<div className="gf-form-group">
<Field

View File

@ -2,9 +2,10 @@ import { css } from '@emotion/css';
import React, { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime';
import { Button, CodeEditor, useStyles2 } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import { t, Trans } from 'app/core/internationalization';
import { Trans } from 'app/core/internationalization';
import { dashboardWatcher } from 'app/features/live/dashboard/dashboardWatcher';
import { getDashboardSrv } from '../../services/DashboardSrv';
@ -13,6 +14,7 @@ import { SettingsPageProps } from './types';
export function JsonEditorSettings({ dashboard, sectionNav }: SettingsPageProps) {
const [dashboardJson, setDashboardJson] = useState<string>(JSON.stringify(dashboard.getSaveModelClone(), null, 2));
const pageNav = config.featureToggles.dockedMegaMenu ? sectionNav.node.parentItem : undefined;
const onClick = async () => {
await getDashboardSrv().saveJSONDashboard(dashboardJson);
@ -20,14 +22,14 @@ export function JsonEditorSettings({ dashboard, sectionNav }: SettingsPageProps)
};
const styles = useStyles2(getStyles);
const subTitle = t(
'dashboard-settings.json-editor.subtitle',
'The JSON model below is the data structure that defines the dashboard. This includes dashboard settings, panel settings, layout, queries, and so on.'
);
return (
<Page navModel={sectionNav} subTitle={subTitle}>
<Page navModel={sectionNav} pageNav={pageNav}>
<div className={styles.wrapper}>
<Trans i18nKey="dashboard-settings.json-editor.subtitle">
The JSON model below is the data structure that defines the dashboard. This includes dashboard settings, panel
settings, layout, queries, and so on.
</Trans>
<CodeEditor
value={dashboardJson}
language="json"

View File

@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { NavModelItem } from '@grafana/data';
import { locationService } from '@grafana/runtime';
import { config, locationService } from '@grafana/runtime';
import { Page } from 'app/core/components/Page/Page';
import { LinkSettingsEdit, LinkSettingsList } from '../LinksSettings';
@ -33,6 +33,11 @@ export function LinksSettings({ dashboard, sectionNav, editIndex }: SettingsPage
const isEditing = editIndex !== undefined;
let pageNav: NavModelItem | undefined;
if (config.featureToggles.dockedMegaMenu) {
pageNav = sectionNav.node.parentItem;
}
if (isEditing) {
const title = isNew ? 'New link' : 'Edit link';
const description = isNew ? 'Create a new link on your dashboard' : 'Edit a specific link of your dashboard';
@ -40,6 +45,14 @@ export function LinksSettings({ dashboard, sectionNav, editIndex }: SettingsPage
text: title,
subTitle: description,
};
if (config.featureToggles.dockedMegaMenu) {
const parentUrl = sectionNav.node.url;
pageNav.parentItem = sectionNav.node.parentItem && {
...sectionNav.node.parentItem,
url: parentUrl,
};
}
}
return (

View File

@ -1,5 +1,6 @@
import React, { PureComponent } from 'react';
import { config } from '@grafana/runtime';
import { Spinner, HorizontalGroup } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
@ -138,10 +139,11 @@ export class VersionsSettings extends PureComponent<Props, State> {
const canCompare = versions.filter((version) => version.checked).length === 2;
const showButtons = versions.length > 1;
const hasMore = versions.length >= this.limit;
const pageNav = config.featureToggles.dockedMegaMenu ? this.props.sectionNav.node.parentItem : undefined;
if (viewMode === 'compare') {
return (
<Page navModel={this.props.sectionNav}>
<Page navModel={this.props.sectionNav} pageNav={pageNav}>
<VersionHistoryHeader
onClick={this.reset}
baseVersion={baseInfo?.version}
@ -163,7 +165,7 @@ export class VersionsSettings extends PureComponent<Props, State> {
}
return (
<Page navModel={this.props.sectionNav}>
<Page navModel={this.props.sectionNav} pageNav={pageNav}>
{isLoading ? (
<VersionsHistorySpinner msg="Fetching history list&hellip;" />
) : (

View File

@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { bindActionCreators } from 'redux';
import { locationService } from '@grafana/runtime';
import { config, locationService } from '@grafana/runtime';
import { Page } from 'app/core/components/Page/Page';
import { SettingsPageProps } from 'app/features/dashboard/components/DashboardSettings/types';
@ -105,9 +105,17 @@ class VariableEditorContainerUnconnected extends PureComponent<Props, State> {
};
render() {
const { editIndex, variables } = this.props;
const { editIndex, variables, sectionNav } = this.props;
const variableToEdit = editIndex != null ? variables[editIndex] : undefined;
const subPageNav = variableToEdit ? { text: variableToEdit.name } : undefined;
const node = sectionNav.node;
const parentItem =
config.featureToggles.dockedMegaMenu && node.parentItem
? {
...node.parentItem,
url: node.url,
}
: undefined;
const subPageNav = variableToEdit ? { text: variableToEdit.name, parentItem } : parentItem;
return (
<Page navModel={this.props.sectionNav} pageNav={subPageNav}>