Skip to content

Commit

Permalink
Connections: Simplify connections nav (#66813)
Browse files Browse the repository at this point in the history
* Connections: Simplify connections nav

* rename Connections pages everywhere

---------

Co-authored-by: Miklós Tolnai <miklos.tolnai@grafana.com>
  • Loading branch information
torkelo and mikkancso committed May 2, 2023
1 parent 2316178 commit 9614dc2
Show file tree
Hide file tree
Showing 19 changed files with 112 additions and 192 deletions.
8 changes: 4 additions & 4 deletions pkg/api/api.go
Expand Up @@ -126,11 +126,11 @@ func (hs *HTTPServer) registerRoutes() {
r.Get("/plugins/:id/edit", middleware.CanAdminPlugins(hs.Cfg), hs.Index) // deprecated
r.Get("/plugins/:id/page/:page", middleware.CanAdminPlugins(hs.Cfg), hs.Index)

r.Get("/connections/your-connections/datasources", authorize(reqOrgAdmin, datasources.ConfigurationPageAccess), hs.Index)
r.Get("/connections/your-connections/datasources/new", authorize(reqOrgAdmin, datasources.NewPageAccess), hs.Index)
r.Get("/connections/your-connections/datasources/edit/*", authorize(reqOrgAdmin, datasources.EditPageAccess), hs.Index)
r.Get("/connections/your-datasources", authorize(reqOrgAdmin, datasources.ConfigurationPageAccess), hs.Index)
r.Get("/connections/your-datasources/new", authorize(reqOrgAdmin, datasources.NewPageAccess), hs.Index)
r.Get("/connections/your-datasources/edit/*", authorize(reqOrgAdmin, datasources.EditPageAccess), hs.Index)
r.Get("/connections", authorize(reqOrgAdmin, datasources.ConfigurationPageAccess), hs.Index)
r.Get("/connections/connect-data", authorize(reqOrgAdmin, datasources.ConfigurationPageAccess), hs.Index)
r.Get("/connections/add-new-connection", authorize(reqOrgAdmin, datasources.ConfigurationPageAccess), hs.Index)
r.Get("/connections/datasources/:id", middleware.CanAdminPlugins(hs.Cfg), hs.Index)
r.Get("/connections/datasources/:id/page/:page", middleware.CanAdminPlugins(hs.Cfg), hs.Index)

Expand Down
22 changes: 11 additions & 11 deletions pkg/services/navtree/navtreeimpl/applinks_test.go
Expand Up @@ -93,8 +93,8 @@ func TestAddAppLinks(t *testing.T) {
AddToNav: true,
},
{
Name: "Connect data",
Path: "/connections/connect-data",
Name: "Add new connection",
Path: "/connections/add-new-connection",
Type: "page",
AddToNav: false,
},
Expand Down Expand Up @@ -296,7 +296,7 @@ func TestAddAppLinks(t *testing.T) {
service.features = featuremgmt.WithFeatures(featuremgmt.FlagDataConnectionsConsole)
service.navigationAppConfig = map[string]NavigationAppConfig{}
service.navigationAppPathConfig = map[string]NavigationAppConfig{
"/connections/connect-data": {SectionID: "connections"},
"/connections/add-new-connection": {SectionID: "connections"},
}

// Build nav-tree and check if the "Connections" page is there
Expand All @@ -306,19 +306,19 @@ func TestAddAppLinks(t *testing.T) {
require.NotNil(t, connectionsNode)
require.Equal(t, "Connections", connectionsNode.Text)

// Check if the original "Connect data" page (served by core) is there until we add the standalone plugin page
// Check if the original "Add new connection" page (served by core) is there until we add the standalone plugin page
connectDataNode := connectionsNode.Children[0]
require.Equal(t, "Connect data", connectDataNode.Text)
require.Equal(t, "connections-connect-data", connectDataNode.Id)
require.Equal(t, "Add new connection", connectDataNode.Text)
require.Equal(t, "connections-add-new-connection", connectDataNode.Id)
require.Equal(t, "", connectDataNode.PluginID)

// Check if the standalone plugin page appears under the section where we registered it and if it overrides the original page
err := service.addAppLinks(&treeRoot, reqCtx)

require.NoError(t, err)
require.Equal(t, "Connections", connectionsNode.Text)
require.Equal(t, "Connect data", connectDataNode.Text)
require.Equal(t, "standalone-plugin-page-/connections/connect-data", connectDataNode.Id) // Overridden "Connect data" page
require.Equal(t, "Add new connection", connectDataNode.Text)
require.Equal(t, "standalone-plugin-page-/connections/add-new-connection", connectDataNode.Id) // Overridden "Add new connection" page
require.Equal(t, "test-app3", connectDataNode.PluginID)

// Check if the standalone plugin page does not appear under the app section anymore
Expand All @@ -342,12 +342,12 @@ func TestAddAppLinks(t *testing.T) {
require.NoError(t, err)

// The original core page should exist under the section
connectDataNode := treeRoot.FindById("connections-connect-data")
require.Equal(t, "connections-connect-data", connectDataNode.Id)
connectDataNode := treeRoot.FindById("connections-add-new-connection")
require.Equal(t, "connections-add-new-connection", connectDataNode.Id)
require.Equal(t, "", connectDataNode.PluginID)

// The standalone plugin page should not be found in the navtree at all (as we didn't configure it)
standaloneConnectDataNode := treeRoot.FindById("standalone-plugin-page-/connections/connect-data")
standaloneConnectDataNode := treeRoot.FindById("standalone-plugin-page-/connections/add-new-connection")
require.Nil(t, standaloneConnectDataNode)

// Only the pages that have `AddToNav=true` appear under the plugin navigation
Expand Down
31 changes: 12 additions & 19 deletions pkg/services/navtree/navtreeimpl/navtree.go
Expand Up @@ -481,29 +481,22 @@ func (s *ServiceImpl) buildDataConnectionsNavLink(c *contextmodel.ReqContext) *n
baseUrl := s.cfg.AppSubURL + "/connections"

if hasAccess(ac.ReqOrgAdmin, datasources.ConfigurationPageAccess) {
// Connect data
// Add new connection
children = append(children, &navtree.NavLink{
Id: "connections-connect-data",
Text: "Connect data",
SubTitle: "Browse and create new connections",
IsSection: true,
Url: s.cfg.AppSubURL + "/connections/connect-data",
Children: []*navtree.NavLink{},
Id: "connections-add-new-connection",
Text: "Add new connection",
SubTitle: "Browse and create new connections",
Url: baseUrl + "/add-new-connection",
Children: []*navtree.NavLink{},
})

// Your connections
// Your data sources
children = append(children, &navtree.NavLink{
Id: "connections-your-connections",
Text: "Your connections",
SubTitle: "Manage your existing connections",
Url: baseUrl + "/your-connections",
// Datasources
Children: []*navtree.NavLink{{
Id: "connections-your-connections-datasources",
Text: "Data sources",
SubTitle: "View and manage your connected data source connections",
Url: baseUrl + "/your-connections/datasources",
}},
Id: "connections-your-datasources",
Text: "Your data sources",
SubTitle: "View and manage your connected data source connections",
Url: baseUrl + "/your-datasources",
Children: []*navtree.NavLink{},
})
}

Expand Down
65 changes: 14 additions & 51 deletions public/app/features/connections/Connections.test.tsx
Expand Up @@ -38,56 +38,49 @@ describe('Connections', () => {
(contextSrv.hasPermission as jest.Mock) = jest.fn().mockReturnValue(true);
});

test('shows the "Connect data" page by default', async () => {
test('shows the "Add new connection" page by default', async () => {
renderPage();

// Data sources group
expect(await screen.findByText('Data sources')).toBeVisible();

// Heading
expect(await screen.findByText('Connect data')).toBeVisible();
expect(await screen.findByText('Add new connection')).toBeVisible();
expect(await screen.findByText('Browse and create new connections')).toBeVisible();
});

test('shows a landing page for Your connections', async () => {
renderPage(ROUTES.YourConnections);

expect(await screen.findByRole('link', { name: 'Datasources' })).toBeVisible();
expect(await screen.findByText('Manage your existing datasource connections')).toBeVisible();
});

test('renders the correct tab even if accessing it with a "sub-url"', async () => {
renderPage(ROUTES.ConnectData);
renderPage(ROUTES.AddNewConnection);

expect(await screen.findByText('Connect data')).toBeVisible();
expect(await screen.findByText('Add new connection')).toBeVisible();
expect(await screen.findByText('Browse and create new connections')).toBeVisible();

// Should not render the "Your datasources" page
expect(screen.queryByText('Manage your existing datasource connections')).not.toBeInTheDocument();
});

test('renders the core "Connect data" page in case there is no standalone plugin page override for it', async () => {
renderPage(ROUTES.ConnectData);
test('renders the core "Add new connection" page in case there is no standalone plugin page override for it', async () => {
renderPage(ROUTES.AddNewConnection);

// We expect to see no results and "Data sources" as a header (we only have data sources in OSS Grafana at this point)
expect(await screen.findByText('Data sources')).toBeVisible();
expect(await screen.findByText('No results matching your query were found.')).toBeVisible();
});

test('does not render anything for the "Connect data" page in case it is displayed by a standalone plugin page', async () => {
// We are overriding the navIndex to have the "Connect data" page registered by a plugin
test('does not render anything for the "Add new connection" page in case it is displayed by a standalone plugin page', async () => {
// We are overriding the navIndex to have the "Add new connection" page registered by a plugin
const standalonePluginPage = {
id: 'standalone-plugin-page-/connections/connect-data',
text: 'Connect data',
id: 'standalone-plugin-page-/connections/add-new-connection',
text: 'Add new connection',
subTitle: 'Browse and create new connections',
url: '/connections/connect-data',
url: '/connections/add-new-connection',
pluginId: 'grafana-easystart-app',
};

const connections = {
...navIndex.connections,
children: navIndex.connections.children?.map((child) => {
if (child.id === 'connections-connect-data') {
if (child.id === 'connections-add-new-connection') {
return standalonePluginPage;
}

Expand All @@ -100,40 +93,10 @@ describe('Connections', () => {
plugins: getPluginsStateMock([]),
});

renderPage(ROUTES.ConnectData, store);
renderPage(ROUTES.AddNewConnection, store);

// We expect not to see the text that would be rendered by the core "Connect data" page
// We expect not to see the text that would be rendered by the core "Add new connection" page
expect(screen.queryByText('Data sources')).not.toBeInTheDocument();
expect(screen.queryByText('No results matching your query were found.')).not.toBeInTheDocument();
});

test('Your connections redirects to Data sources if it has one child', async () => {
const navIndexCopy = {
...navIndex,
'connections-your-connections': {
id: 'connections-your-connections',
text: 'Your connections',
subTitle: 'Manage your existing connections',
url: '/connections/your-connections',
children: [
{
id: 'connections-your-connections-datasources',
text: 'Datasources',
subTitle: 'Manage your existing datasource connections',
url: '/connections/your-connections/datasources',
},
],
},
};

const store = configureStore({
navIndex: navIndexCopy,
plugins: getPluginsStateMock([]),
});

renderPage(ROUTES.YourConnections, store);

expect(await screen.findByPlaceholderText('Search by name or type')).toBeInTheDocument();
expect(await screen.queryByRole('link', { name: 'Datasources' })).toBeNull();
});
});
21 changes: 8 additions & 13 deletions public/app/features/connections/Connections.tsx
@@ -1,13 +1,12 @@
import * as React from 'react';
import { Redirect, Route, Switch } from 'react-router-dom';

import { NavLandingPage } from 'app/core/components/NavLandingPage/NavLandingPage';
import { DataSourcesRoutesContext } from 'app/features/datasources/state';
import { StoreState, useSelector } from 'app/types';

import { ROUTES } from './constants';
import {
ConnectDataPage,
AddNewConnectionPage,
DataSourceDashboardsPage,
DataSourceDetailsPage,
DataSourcesListPage,
Expand All @@ -17,12 +16,7 @@ import {

export default function Connections() {
const navIndex = useSelector((state: StoreState) => state.navIndex);
const isConnectDataPageOverriden = Boolean(navIndex['standalone-plugin-page-/connections/connect-data']);

const YourConnectionsPage =
navIndex['connections-your-connections'].children && navIndex['connections-your-connections'].children?.length > 1
? () => <NavLandingPage navId="connections-your-connections" />
: () => <Redirect to={ROUTES.DataSources} />;
const isAddNewConnectionPageOverridden = Boolean(navIndex['standalone-plugin-page-/connections/add-new-connection']);

return (
<DataSourcesRoutesContext.Provider
Expand All @@ -34,17 +28,18 @@ export default function Connections() {
}}
>
<Switch>
{/* Redirect to "Connect data" by default */}
<Route exact sensitive path={ROUTES.Base} component={() => <Redirect to={ROUTES.ConnectData} />} />
<Route exact sensitive path={ROUTES.YourConnections} component={YourConnectionsPage} />
{/* Redirect to "Add new connection" by default */}
<Route exact sensitive path={ROUTES.Base} component={() => <Redirect to={ROUTES.AddNewConnection} />} />
<Route exact sensitive path={ROUTES.DataSources} component={DataSourcesListPage} />
<Route exact sensitive path={ROUTES.DataSourcesDetails} component={DataSourceDetailsPage} />
<Route exact sensitive path={ROUTES.DataSourcesNew} component={NewDataSourcePage} />
<Route exact sensitive path={ROUTES.DataSourcesEdit} component={EditDataSourcePage} />
<Route exact sensitive path={ROUTES.DataSourcesDashboards} component={DataSourceDashboardsPage} />

{/* "Connect data" page - we don't register a route in case a plugin already registers a standalone page for it */}
{!isConnectDataPageOverriden && <Route exact sensitive path={ROUTES.ConnectData} component={ConnectDataPage} />}
{/* "Add new connection" page - we don't register a route in case a plugin already registers a standalone page for it */}
{!isAddNewConnectionPageOverridden && (
<Route exact sensitive path={ROUTES.AddNewConnection} component={AddNewConnectionPage} />
)}

{/* Not found */}
<Route component={() => <Redirect to="/notfound" />} />
Expand Down
80 changes: 26 additions & 54 deletions public/app/features/connections/__mocks__/store.navIndex.mock.ts
Expand Up @@ -229,30 +229,22 @@ export const navIndex: NavIndex = {
sortWeight: -1300,
children: [
{
id: 'connections-your-connections',
text: 'Your connections',
subTitle: 'Manage your existing connections',
url: '/connections/your-connections',
children: [
{
id: 'connections-your-connections-datasources',
text: 'Datasources',
subTitle: 'Manage your existing datasource connections',
url: '/connections/your-connections/datasources',
},
{
id: 'standalone-plugin-page-/connections/your-connections/infrastructure',
text: 'Infrastructure',
url: '/connections/your-connections/infrastructure',
pluginId: 'grafana-easystart-app',
},
],
id: 'connections-add-new-connection',
text: 'Add new connection',
subTitle: 'Browse and create new connections',
url: '/connections/add-new-connection',
},
{
id: 'connections-connect-data',
text: 'Connect data',
subTitle: 'Browse and create new connections',
url: '/connections/connect-data',
id: 'connections-your-datasources',
text: 'Your data sources',
subTitle: 'Manage your existing datasource connections',
url: '/connections/your-datasources',
},
{
id: 'standalone-plugin-page-/connections/your-infrastructure',
text: 'Your infrastructure',
url: '/connections/your-infrastructure',
pluginId: 'grafana-easystart-app',
},
],
parentItem: {
Expand All @@ -263,43 +255,23 @@ export const navIndex: NavIndex = {
sortWeight: -2000,
},
},
'connections-your-connections': {
id: 'connections-your-connections',
text: 'Your connections',
subTitle: 'Manage your existing connections',
url: '/connections/your-connections',
children: [
{
id: 'connections-your-connections-datasources',
text: 'Datasources',
subTitle: 'Manage your existing datasource connections',
url: '/connections/your-connections/datasources',
},
{
id: 'standalone-plugin-page-/connections/your-connections/infrastructure',
text: 'Infrastructure',
url: '/connections/your-connections/infrastructure',
pluginId: 'grafana-easystart-app',
},
],
},
'connections-your-connections-datasources': {
id: 'connections-your-connections-datasources',
text: 'Datasources',
'connections-your-datasources': {
id: 'connections-your-datasources',
text: 'Your data sources',
subTitle: 'Manage your existing datasource connections',
url: '/connections/your-connections/datasources',
url: '/connections/your-datasources',
},
'standalone-plugin-page-/connections/your-connections/infrastructure': {
id: 'standalone-plugin-page-/connections/your-connections/infrastructure',
text: 'Infrastructure',
url: '/connections/your-connections/infrastructure',
'standalone-plugin-page-/connections/your-infrastructure': {
id: 'standalone-plugin-page-/connections/your-infrastructure',
text: 'Your infrastructure',
url: '/connections/your-infrastructure',
pluginId: 'grafana-easystart-app',
},
'connections-connect-data': {
id: 'connections-connect-data',
text: 'Connect data',
'connections-add-new-connection': {
id: 'connections-add-new-connection',
text: 'Add new connection',
subTitle: 'Browse and create new connections',
url: '/connections/connect-data',
url: '/connections/add-new-connection',
},
cfg: {
id: 'cfg',
Expand Down

0 comments on commit 9614dc2

Please sign in to comment.