NavTree: Make it possible to configure where in nav tree plugins live (#55484)

* NewIA: Plugin nav config

* progress

* Progress

* Things are working

* Add monitoring node

* Add alerts and incidents

* added experiment with standalone page

* Refactoring by adding a type for navtree root

* First test working

* More tests

* more tests

* Progress on richer config and sorting

* Sort weight working

* Path config

* Improving logic for not including admin or cfg nodes, making it the last step so that enterprise can add admin nodes without having to worry about the section not existing

* fixed index routes

* removed file

* Fixes

* Fixing tests

* Fixing more tests and adding support for weight config

* Updates

* Remove unused fake

* More fixes

* Minor tweak

* Minor fix

* Can now control position using sortweight even when existing items have no sortweight

* Added tests for frontend standalone page logic

* more tests

* Remove unused fake and fixed lint issue

* Moving reading settings to navtree impl package

* remove nav_id setting prefix

* Remove old test file

* Fix trailing newline

* Fixed bug with adding nil node

* fixing lint issue

* remove some code we have to rethink

* move read settings to PrivideService and switch to util.SplitString
This commit is contained in:
Torkel Ödegaard
2022-09-28 08:29:35 +02:00
committed by GitHub
parent 202dce66ff
commit e31cb93ec0
33 changed files with 1064 additions and 586 deletions

View File

@ -2,7 +2,6 @@ import { Location as HistoryLocation } from 'history';
import { GrafanaPlugin, NavIndex, NavModel, NavModelItem, PanelPluginMeta, PluginType } from '@grafana/data';
import { config } from '@grafana/runtime';
import { getNavModel } from 'app/core/selectors/navModel';
import { importPanelPluginFromMeta } from './importPanelPlugin';
import { getPluginSettings } from './pluginSettings';
@ -33,20 +32,24 @@ export async function loadPlugin(pluginId: string): Promise<GrafanaPlugin> {
return result;
}
export function buildPluginSectionNav(location: HistoryLocation, pluginNav: NavModel | null, navIndex: NavIndex) {
export function buildPluginSectionNav(
location: HistoryLocation,
pluginNav: NavModel | null,
navIndex: NavIndex,
pluginId: string
) {
// When topnav is disabled we only just show pluginNav like before
if (!config.featureToggles.topnav) {
return pluginNav;
}
const originalSection = getNavModel(navIndex, 'apps').main;
const section = { ...originalSection };
const section = { ...getPluginSection(location, navIndex, pluginId) };
// If we have plugin nav don't set active page in section as it will cause double breadcrumbs
const currentUrl = config.appSubUrl + location.pathname + location.search;
let activePage: NavModelItem | undefined;
// Set active page
// Find and set active page
section.children = (section?.children ?? []).map((child) => {
if (child.children) {
return {
@ -62,9 +65,39 @@ export function buildPluginSectionNav(location: HistoryLocation, pluginNav: NavM
return pluginPage;
}),
};
} else {
if (currentUrl.startsWith(child.url ?? '')) {
activePage = {
...child,
active: true,
};
return activePage;
}
}
return child;
});
return { main: section, node: activePage ?? section };
}
// TODO make work for sub pages
export function getPluginSection(location: HistoryLocation, navIndex: NavIndex, pluginId: string): NavModelItem {
// First check if this page exist in navIndex using path, some plugin pages are not under their own section
const byPath = navIndex[`standalone-plugin-page-${location.pathname}`];
if (byPath) {
const parent = byPath.parentItem!;
// in case the standalone page is in nested section
return parent.parentItem ?? parent;
}
const navTreeNodeForPlugin = navIndex[`plugin-page-${pluginId}`];
if (!navTreeNodeForPlugin) {
throw new Error('Plugin not found in navigation tree');
}
if (!navTreeNodeForPlugin.parentItem) {
throw new Error('Could not find plugin section');
}
return navTreeNodeForPlugin.parentItem;
}