mirror of
https://github.com/grafana/grafana.git
synced 2026-02-03 20:49:50 -05:00
Some checks are pending
Actionlint / Lint GitHub Actions files (push) Waiting to run
Backend Code Checks / Detect whether code changed (push) Waiting to run
Backend Code Checks / Validate Backend Configs (push) Blocked by required conditions
Backend Unit Tests / Detect whether code changed (push) Waiting to run
Backend Unit Tests / Grafana (1/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (2/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (3/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (4/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (5/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (6/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (7/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana (8/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (1/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (2/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (3/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (4/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (5/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (6/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (7/8) (push) Blocked by required conditions
Backend Unit Tests / Grafana Enterprise (8/8) (push) Blocked by required conditions
Backend Unit Tests / All backend unit tests complete (push) Blocked by required conditions
CodeQL checks / Detect whether code changed (push) Waiting to run
CodeQL checks / Analyze (push) Blocked by required conditions
Deploy Storybook / Detect whether code changed (push) Waiting to run
Deploy Storybook / Deploy Storybook (push) Blocked by required conditions
Lint Frontend / Detect whether code changed (push) Waiting to run
Lint Frontend / Lint (push) Blocked by required conditions
Lint Frontend / Typecheck (push) Blocked by required conditions
Lint Frontend / Verify API clients (push) Waiting to run
Lint Frontend / Verify API clients (enterprise) (push) Waiting to run
Lint Frontend / Verify packed frontend packages (push) Blocked by required conditions
golangci-lint / Detect whether code changed (push) Waiting to run
golangci-lint / go-fmt (push) Blocked by required conditions
golangci-lint / lint-go (push) Blocked by required conditions
Crowdin Upload Action / upload-sources-to-crowdin (push) Waiting to run
Verify i18n / verify-i18n (push) Waiting to run
Documentation / Build & Verify Docs (push) Waiting to run
End-to-end tests / Detect whether code changed (push) Waiting to run
End-to-end tests / Build & Package Grafana (push) Blocked by required conditions
End-to-end tests / Build E2E test runner (push) Blocked by required conditions
End-to-end tests / push-docker-image (push) Blocked by required conditions
End-to-end tests / dashboards-suite (old arch) (push) Blocked by required conditions
End-to-end tests / panels-suite (old arch) (push) Blocked by required conditions
End-to-end tests / smoke-tests-suite (old arch) (push) Blocked by required conditions
End-to-end tests / various-suite (old arch) (push) Blocked by required conditions
End-to-end tests / Verify Storybook (Playwright) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (1/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (2/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (3/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (4/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (5/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (6/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (7/8) (push) Blocked by required conditions
End-to-end tests / Playwright E2E tests (8/8) (push) Blocked by required conditions
End-to-end tests / run-azure-monitor-e2e (push) Blocked by required conditions
End-to-end tests / All Playwright tests complete (push) Blocked by required conditions
End-to-end tests / A11y test (push) Blocked by required conditions
End-to-end tests / Publish metrics (push) Blocked by required conditions
End-to-end tests / All E2E tests complete (push) Blocked by required conditions
Frontend tests / Detect whether code changed (push) Waiting to run
Frontend tests / Unit tests (1 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (10 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (11 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (12 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (13 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (14 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (15 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (16 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (2 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (3 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (4 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (5 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (6 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (7 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (8 / 16) (push) Blocked by required conditions
Frontend tests / Unit tests (9 / 16) (push) Blocked by required conditions
Frontend tests / Decoupled plugin tests (push) Blocked by required conditions
Frontend tests / Packages unit tests (push) Blocked by required conditions
Frontend tests / All frontend unit tests complete (push) Blocked by required conditions
Frontend tests / Devenv frontend-service build (push) Blocked by required conditions
Integration Tests / Detect whether code changed (push) Waiting to run
Integration Tests / Sqlite (1/4) (push) Blocked by required conditions
Integration Tests / Sqlite (2/4) (push) Blocked by required conditions
Integration Tests / Sqlite (3/4) (push) Blocked by required conditions
Integration Tests / Sqlite (4/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (1/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (2/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (3/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (4/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo (profiled) (push) Blocked by required conditions
Integration Tests / MySQL (1/16) (push) Blocked by required conditions
Integration Tests / MySQL (10/16) (push) Blocked by required conditions
Integration Tests / MySQL (11/16) (push) Blocked by required conditions
Integration Tests / MySQL (12/16) (push) Blocked by required conditions
Integration Tests / MySQL (13/16) (push) Blocked by required conditions
Integration Tests / MySQL (14/16) (push) Blocked by required conditions
Integration Tests / MySQL (15/16) (push) Blocked by required conditions
Integration Tests / MySQL (16/16) (push) Blocked by required conditions
Integration Tests / MySQL (2/16) (push) Blocked by required conditions
Integration Tests / MySQL (3/16) (push) Blocked by required conditions
Integration Tests / MySQL (4/16) (push) Blocked by required conditions
Integration Tests / MySQL (5/16) (push) Blocked by required conditions
Integration Tests / MySQL (6/16) (push) Blocked by required conditions
Integration Tests / MySQL (7/16) (push) Blocked by required conditions
Integration Tests / MySQL (8/16) (push) Blocked by required conditions
Integration Tests / MySQL (9/16) (push) Blocked by required conditions
Integration Tests / Postgres (1/16) (push) Blocked by required conditions
Integration Tests / Postgres (10/16) (push) Blocked by required conditions
Integration Tests / Postgres (11/16) (push) Blocked by required conditions
Integration Tests / Postgres (12/16) (push) Blocked by required conditions
Integration Tests / Postgres (13/16) (push) Blocked by required conditions
Integration Tests / Postgres (14/16) (push) Blocked by required conditions
Integration Tests / Postgres (15/16) (push) Blocked by required conditions
Integration Tests / Postgres (16/16) (push) Blocked by required conditions
Integration Tests / Postgres (2/16) (push) Blocked by required conditions
Integration Tests / Postgres (3/16) (push) Blocked by required conditions
Integration Tests / Postgres (4/16) (push) Blocked by required conditions
Integration Tests / Postgres (5/16) (push) Blocked by required conditions
Integration Tests / Postgres (6/16) (push) Blocked by required conditions
Integration Tests / Postgres (7/16) (push) Blocked by required conditions
Integration Tests / Postgres (8/16) (push) Blocked by required conditions
Integration Tests / Postgres (9/16) (push) Blocked by required conditions
Integration Tests / Sqlite Enterprise (1/4) (push) Blocked by required conditions
Integration Tests / Sqlite Enterprise (2/4) (push) Blocked by required conditions
Integration Tests / Sqlite Enterprise (3/4) (push) Blocked by required conditions
Integration Tests / Sqlite Enterprise (4/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo Enterprise (1/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo Enterprise (2/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo Enterprise (3/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo Enterprise (4/4) (push) Blocked by required conditions
Integration Tests / Sqlite Without CGo Enterprise (profiled) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (1/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (10/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (11/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (12/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (13/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (14/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (15/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (16/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (2/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (3/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (4/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (5/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (6/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (7/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (8/16) (push) Blocked by required conditions
Integration Tests / MySQL Enterprise (9/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (1/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (10/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (11/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (12/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (13/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (14/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (15/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (16/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (2/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (3/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (4/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (5/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (6/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (7/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (8/16) (push) Blocked by required conditions
Integration Tests / Postgres Enterprise (9/16) (push) Blocked by required conditions
Integration Tests / All backend integration tests complete (push) Blocked by required conditions
publish-kinds-next / main (push) Waiting to run
publish-technical-documentation-next / sync (push) Waiting to run
Reject GitHub secrets / reject-gh-secrets (push) Waiting to run
Build Release Packages / setup (push) Waiting to run
Build Release Packages / Dispatch grafana-enterprise build (push) Blocked by required conditions
Build Release Packages / / darwin-amd64 (push) Blocked by required conditions
Build Release Packages / / darwin-arm64 (push) Blocked by required conditions
Build Release Packages / / linux-amd64 (push) Blocked by required conditions
Build Release Packages / / linux-armv6 (push) Blocked by required conditions
Build Release Packages / / linux-armv7 (push) Blocked by required conditions
Build Release Packages / / linux-arm64 (push) Blocked by required conditions
Build Release Packages / / linux-s390x (push) Blocked by required conditions
Build Release Packages / / windows-amd64 (push) Blocked by required conditions
Build Release Packages / / windows-arm64 (push) Blocked by required conditions
Build Release Packages / Upload artifacts (push) Blocked by required conditions
Build Release Packages / publish-dockerhub (push) Blocked by required conditions
Build Release Packages / Dispatch publish NPM canaries (push) Blocked by required conditions
Build Release Packages / notify-pr (push) Blocked by required conditions
Run dashboard schema v2 e2e / dashboard-schema-v2-e2e (push) Waiting to run
Shellcheck / Shellcheck scripts (push) Waiting to run
Run Storybook a11y tests / Detect whether code changed (push) Waiting to run
Run Storybook a11y tests / Run Storybook a11y tests (light theme) (push) Blocked by required conditions
Run Storybook a11y tests / Run Storybook a11y tests (dark theme) (push) Blocked by required conditions
Swagger generated code / Detect whether code changed (push) Waiting to run
Swagger generated code / Verify committed API specs match (push) Blocked by required conditions
Dispatch sync to mirror / dispatch-job (push) Waiting to run
* remove ldap sso ft * add test cases for lbac disabled * remove legacy ldap pages * fix tests * fix: add ldap provider to TestService_List expected results
617 lines
22 KiB
TypeScript
617 lines
22 KiB
TypeScript
import { useEffect } from 'react';
|
|
import { Navigate, useLocation, useParams } from 'react-router-dom-v5-compat';
|
|
|
|
import { isTruthy } from '@grafana/data';
|
|
import { NavLandingPage } from 'app/core/components/NavLandingPage/NavLandingPage';
|
|
import { PageNotFound } from 'app/core/components/PageNotFound/PageNotFound';
|
|
import config from 'app/core/config';
|
|
import { contextSrv } from 'app/core/services/context_srv';
|
|
import { getAlertingRoutes } from 'app/features/alerting/routes';
|
|
import { isAdmin, isLocalDevEnv, isOpenSourceEdition } from 'app/features/alerting/unified/utils/misc';
|
|
import { ConnectionsRedirectNotice } from 'app/features/connections/components/ConnectionsRedirectNotice/ConnectionsRedirectNotice';
|
|
import { ROUTES as CONNECTIONS_ROUTES } from 'app/features/connections/constants';
|
|
import { getRoutes as getDataConnectionsRoutes } from 'app/features/connections/routes';
|
|
import { DASHBOARD_LIBRARY_ROUTES } from 'app/features/dashboard/dashgrid/types';
|
|
import { DATASOURCES_ROUTES } from 'app/features/datasources/constants';
|
|
import { ConfigureIRM } from 'app/features/gops/configuration-tracker/components/ConfigureIRM';
|
|
import { getRoutes as getPluginCatalogRoutes } from 'app/features/plugins/admin/routes';
|
|
import { getAppPluginRoutes } from 'app/features/plugins/routes';
|
|
import { getProfileRoutes } from 'app/features/profile/routes';
|
|
import { AccessControlAction } from 'app/types/accessControl';
|
|
import { DashboardRoutes } from 'app/types/dashboard';
|
|
|
|
import { SafeDynamicImport } from '../core/components/DynamicImports/SafeDynamicImport';
|
|
import { RouteDescriptor } from '../core/navigation/types';
|
|
import { getPublicDashboardRoutes } from '../features/dashboard/routes';
|
|
import { isDashboardSceneSoloEnabled } from '../features/dashboard-scene/utils/utils';
|
|
import { getProvisioningRoutes } from '../features/provisioning/utils/routes';
|
|
|
|
const isDevEnv = config.buildInfo.env === 'development';
|
|
export const extraRoutes: RouteDescriptor[] = [];
|
|
|
|
export function getAppRoutes(): RouteDescriptor[] {
|
|
const routes: Array<RouteDescriptor | undefined | false> = [
|
|
// Based on the Grafana configuration standalone plugin pages can even override and extend existing core pages, or they can register new routes under existing ones.
|
|
// In order to make it possible we need to register them first due to how `<Switch>` is evaluating routes. (This will be unnecessary once/when we upgrade to React Router v6 and start using `<Routes>` instead.)
|
|
...getAppPluginRoutes(),
|
|
{
|
|
path: '/',
|
|
pageClass: 'page-dashboard',
|
|
routeName: DashboardRoutes.Home,
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardPageProxy" */ '../features/dashboard/containers/DashboardPageProxy')
|
|
),
|
|
},
|
|
{
|
|
path: '/d/:uid/:slug?',
|
|
pageClass: 'page-dashboard',
|
|
routeName: DashboardRoutes.Normal,
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardPageProxy" */ '../features/dashboard/containers/DashboardPageProxy')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboard/new',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.DashboardsCreate]),
|
|
pageClass: 'page-dashboard',
|
|
routeName: DashboardRoutes.New,
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPageProxy')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboard/assistant-preview/*',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.DashboardsCreate]),
|
|
pageClass: 'page-dashboard',
|
|
routeName: DashboardRoutes.AssistantPreview,
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(/* webpackChunkName: "DashboardScenePage" */ '../features/dashboard-scene/pages/DashboardScenePage')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboard/new-with-ds/:datasourceUid',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.DashboardsCreate]),
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/NewDashboardWithDS')
|
|
),
|
|
},
|
|
(config.featureToggles.suggestedDashboards || config.featureToggles.dashboardLibrary) && {
|
|
path: DASHBOARD_LIBRARY_ROUTES.Template,
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.DashboardsCreate]),
|
|
pageClass: 'page-dashboard',
|
|
routeName: DashboardRoutes.Template,
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPageProxy')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboard/:type/:slug',
|
|
allowAnonymous: (params) => params.type === 'snapshot',
|
|
pageClass: 'page-dashboard',
|
|
routeName: DashboardRoutes.Normal,
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardPage" */ '../features/dashboard/containers/DashboardPageProxy')
|
|
),
|
|
},
|
|
{
|
|
// We currently have no core usage of the embedded dashboard so is to have a page for e2e to test
|
|
path: '/dashboards/embedding-test',
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(
|
|
/* webpackChunkName: "DashboardPage"*/ 'app/features/dashboard-scene/embedding/EmbeddedDashboardTestPage'
|
|
)
|
|
),
|
|
},
|
|
{
|
|
path: '/d-solo/:uid/:slug?',
|
|
routeName: DashboardRoutes.Normal,
|
|
chromeless: true,
|
|
component: SafeDynamicImport(() =>
|
|
isDashboardSceneSoloEnabled()
|
|
? import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard-scene/solo/SoloPanelPage')
|
|
: import(/* webpackChunkName: "SoloPanelPageOld" */ '../features/dashboard/containers/SoloPanelPage')
|
|
),
|
|
},
|
|
// This route handles embedding of snapshot/scripted dashboard panels
|
|
{
|
|
path: '/dashboard-solo/:type/:slug',
|
|
routeName: DashboardRoutes.Normal,
|
|
chromeless: true,
|
|
component: SafeDynamicImport(() =>
|
|
isDashboardSceneSoloEnabled()
|
|
? import(/* webpackChunkName: "SoloPanelPage" */ '../features/dashboard-scene/solo/SoloPanelPage')
|
|
: import(/* webpackChunkName: "SoloPanelPageOld" */ '../features/dashboard/containers/SoloPanelPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboard/import',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardImport"*/ 'app/features/manage-dashboards/DashboardImportPage')
|
|
),
|
|
},
|
|
{
|
|
path: DATASOURCES_ROUTES.List,
|
|
component: () => <Navigate replace to={CONNECTIONS_ROUTES.DataSources} />,
|
|
},
|
|
{
|
|
path: DATASOURCES_ROUTES.Edit,
|
|
component: DataSourceEditRoute,
|
|
},
|
|
{
|
|
path: DATASOURCES_ROUTES.Dashboards,
|
|
component: DataSourceDashboardRoute,
|
|
},
|
|
{
|
|
path: DATASOURCES_ROUTES.New,
|
|
component: () => <Navigate replace to={CONNECTIONS_ROUTES.DataSourcesNew} />,
|
|
},
|
|
{
|
|
path: '/datasources/correlations',
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(/* webpackChunkName: "CorrelationsPageWrapper" */ 'app/features/correlations/CorrelationsPageWrapper')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboards',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardListPage"*/ 'app/features/browse-dashboards/BrowseDashboardsPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboards/f/:uid/:slug',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardListPage"*/ 'app/features/browse-dashboards/BrowseDashboardsPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboards/f/:uid',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "DashboardListPage"*/ 'app/features/browse-dashboards/BrowseDashboardsPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/explore',
|
|
pageClass: 'page-explore',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.DataSourcesExplore]),
|
|
component: SafeDynamicImport(() =>
|
|
config.exploreEnabled
|
|
? import(/* webpackChunkName: "explore" */ 'app/features/explore/ExplorePage')
|
|
: import(/* webpackChunkName: "explore-feature-toggle-page" */ 'app/features/explore/FeatureTogglePage')
|
|
),
|
|
},
|
|
{
|
|
path: '/drilldown',
|
|
component: () => <NavLandingPage navId="drilldown" />,
|
|
},
|
|
{
|
|
path: '/apps',
|
|
component: () => <NavLandingPage navId="apps" />,
|
|
},
|
|
{
|
|
path: '/alerts-and-incidents',
|
|
component: () => {
|
|
return (
|
|
<NavLandingPage
|
|
navId="alerts-and-incidents"
|
|
header={(!isOpenSourceEdition() && isAdmin()) || isLocalDevEnv() ? <ConfigureIRM /> : undefined}
|
|
/>
|
|
);
|
|
},
|
|
},
|
|
{
|
|
path: '/testing-and-synthetics',
|
|
component: () => <NavLandingPage navId="testing-and-synthetics" />,
|
|
},
|
|
{
|
|
path: '/adaptive-telemetry',
|
|
component: () => <NavLandingPage navId="adaptive-telemetry" />,
|
|
},
|
|
{
|
|
path: '/monitoring',
|
|
component: () => <Navigate replace to="/observability" />,
|
|
},
|
|
{
|
|
path: '/observability',
|
|
component: () => <NavLandingPage navId="observability" />,
|
|
},
|
|
{
|
|
path: '/infrastructure',
|
|
component: () => <NavLandingPage navId="infrastructure" />,
|
|
},
|
|
{
|
|
path: '/frontend',
|
|
component: () => <NavLandingPage navId="frontend" />,
|
|
},
|
|
{
|
|
path: '/admin/general',
|
|
component: () => <NavLandingPage navId="cfg/general" />,
|
|
},
|
|
{
|
|
path: '/admin/plugins',
|
|
component: () => <NavLandingPage navId="cfg/plugins" />,
|
|
},
|
|
{
|
|
path: '/admin/extensions',
|
|
roles: () =>
|
|
contextSrv.evaluatePermission([AccessControlAction.PluginsInstall, AccessControlAction.PluginsWrite]),
|
|
component:
|
|
isDevEnv || config.featureToggles.enableExtensionsAdminPage
|
|
? SafeDynamicImport(
|
|
() =>
|
|
import(/* webpackChunkName: "PluginExtensionsLog" */ 'app/features/plugins/extensions/logs/LogViewer')
|
|
)
|
|
: () => <Navigate replace to="/admin" />,
|
|
},
|
|
{
|
|
path: '/admin/access',
|
|
component: () => <NavLandingPage navId="cfg/access" />,
|
|
},
|
|
{
|
|
path: '/org',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "OrgDetailsPage" */ '../features/org/OrgDetailsPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/org/new',
|
|
component: SafeDynamicImport(() => import(/* webpackChunkName: "NewOrgPage" */ 'app/features/org/NewOrgPage')),
|
|
},
|
|
{
|
|
path: '/org/users',
|
|
// Org users page has been combined with admin users
|
|
component: () => <Navigate replace to={'/admin/users'} />,
|
|
},
|
|
{
|
|
path: '/org/users/invite',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "UserInvitePage" */ 'app/features/org/UserInvitePage')
|
|
),
|
|
},
|
|
{
|
|
path: '/org/serviceaccounts',
|
|
roles: () =>
|
|
contextSrv.evaluatePermission([
|
|
AccessControlAction.ServiceAccountsRead,
|
|
AccessControlAction.ServiceAccountsCreate,
|
|
]),
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(/* webpackChunkName: "ServiceAccountsPage" */ 'app/features/serviceaccounts/ServiceAccountsListPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/org/serviceaccounts/create',
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(
|
|
/* webpackChunkName: "ServiceAccountCreatePage" */ 'app/features/serviceaccounts/ServiceAccountCreatePage'
|
|
)
|
|
),
|
|
},
|
|
{
|
|
path: '/org/serviceaccounts/:id',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "ServiceAccountPage" */ 'app/features/serviceaccounts/ServiceAccountPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/org/teams',
|
|
roles: () =>
|
|
contextSrv.evaluatePermission([AccessControlAction.ActionTeamsRead, AccessControlAction.ActionTeamsCreate]),
|
|
component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamList" */ 'app/features/teams/TeamList')),
|
|
},
|
|
{
|
|
path: '/org/teams/new',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.ActionTeamsCreate]),
|
|
component: SafeDynamicImport(() => import(/* webpackChunkName: "CreateTeam" */ 'app/features/teams/CreateTeam')),
|
|
},
|
|
{
|
|
path: '/org/teams/edit/:uid/:page?',
|
|
roles: () =>
|
|
contextSrv.evaluatePermission([AccessControlAction.ActionTeamsRead, AccessControlAction.ActionTeamsCreate]),
|
|
component: SafeDynamicImport(() => import(/* webpackChunkName: "TeamPages" */ 'app/features/teams/TeamPages')),
|
|
},
|
|
// ADMIN
|
|
{
|
|
path: '/admin',
|
|
component: () => <NavLandingPage navId="cfg" header={<ConnectionsRedirectNotice />} />,
|
|
},
|
|
{
|
|
path: '/admin/authentication',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.SettingsWrite]),
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/AuthProvidersListPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/authentication/ldap',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "LdapSettingsPage" */ 'app/features/admin/ldap/LdapSettingsPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/authentication/:provider',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.SettingsWrite]),
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/ProviderConfigPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/settings',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "AdminSettings" */ 'app/features/admin/AdminSettings')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/upgrading',
|
|
component: SafeDynamicImport(() => import('app/features/admin/UpgradePage')),
|
|
},
|
|
{
|
|
path: '/admin/users',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "UserListPage" */ 'app/features/admin/UserListPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/users/create',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "UserCreatePage" */ 'app/features/admin/UserCreatePage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/users/edit/:id',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "UserAdminPage" */ 'app/features/admin/UserAdminPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/orgs',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "AdminListOrgsPage" */ 'app/features/admin/AdminListOrgsPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/orgs/edit/:id',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "AdminEditOrgPage" */ 'app/features/admin/AdminEditOrgPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/admin/stats',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "ServerStats" */ 'app/features/admin/ServerStats')
|
|
),
|
|
},
|
|
config.cloudMigrationEnabled && {
|
|
path: '/admin/migrate-to-cloud',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.MigrationAssistantMigrate]),
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "MigrateToCloud" */ 'app/features/migrate-to-cloud/MigrateToCloud')
|
|
),
|
|
},
|
|
// LOGIN / SIGNUP
|
|
{
|
|
path: '/login',
|
|
allowAnonymous: true,
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "LoginPage" */ 'app/core/components/Login/LoginPage')
|
|
),
|
|
pageClass: 'login-page',
|
|
chromeless: true,
|
|
},
|
|
{
|
|
path: '/invite/:code',
|
|
allowAnonymous: true,
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "SignupInvited" */ 'app/features/invites/SignupInvited')
|
|
),
|
|
chromeless: true,
|
|
},
|
|
{
|
|
path: '/verify',
|
|
component: !config.verifyEmailEnabled
|
|
? () => <Navigate replace to="/signup" />
|
|
: SafeDynamicImport(
|
|
() => import(/* webpackChunkName "VerifyEmailPage"*/ 'app/core/components/Signup/VerifyEmailPage')
|
|
),
|
|
pageClass: 'login-page',
|
|
chromeless: true,
|
|
},
|
|
{
|
|
path: '/signup',
|
|
allowAnonymous: true,
|
|
component: config.disableUserSignUp
|
|
? () => <Navigate replace to="/login" />
|
|
: SafeDynamicImport(() => import(/* webpackChunkName "SignupPage"*/ 'app/core/components/Signup/SignupPage')),
|
|
pageClass: 'login-page',
|
|
chromeless: true,
|
|
},
|
|
{
|
|
path: '/user/password/send-reset-email',
|
|
allowAnonymous: true,
|
|
chromeless: true,
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(/* webpackChunkName: "SendResetMailPage" */ 'app/core/components/ForgottenPassword/SendResetMailPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/user/password/reset',
|
|
allowAnonymous: true,
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(
|
|
/* webpackChunkName: "ChangePasswordPage" */ 'app/core/components/ForgottenPassword/ChangePasswordPage'
|
|
)
|
|
),
|
|
pageClass: 'login-page',
|
|
chromeless: true,
|
|
},
|
|
{
|
|
path: '/dashboard/snapshots',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.SnapshotsRead]),
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "SnapshotListPage" */ 'app/features/manage-dashboards/SnapshotListPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/playlists',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "PlaylistPage"*/ 'app/features/playlist/PlaylistPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/playlists/play/:uid',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "PlaylistStartPage"*/ 'app/features/playlist/PlaylistStartPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/playlists/new',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "PlaylistNewPage"*/ 'app/features/playlist/PlaylistNewPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/playlists/edit/:uid',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "PlaylistEditPage"*/ 'app/features/playlist/PlaylistEditPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/sandbox/benchmarks',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "BenchmarksPage"*/ 'app/features/sandbox/BenchmarksPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/sandbox/test',
|
|
allowAnonymous: true, // purposefully to allow testing
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "TestStuffPage"*/ 'app/features/sandbox/TestStuffPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboards/f/:uid/:slug/library-panels',
|
|
component: SafeDynamicImport(
|
|
() =>
|
|
import(
|
|
/* webpackChunkName: "FolderLibraryPanelsPage"*/ 'app/features/browse-dashboards/BrowseFolderLibraryPanelsPage'
|
|
)
|
|
),
|
|
},
|
|
{
|
|
path: '/dashboards/f/:uid/:slug/alerting',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.AlertingRuleRead]),
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "FolderAlerting"*/ 'app/features/browse-dashboards/BrowseFolderAlertingPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/library-panels',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "LibraryPanelsPage"*/ 'app/features/library-panels/LibraryPanelsPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/notifications',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "NotificationsPage"*/ 'app/features/notifications/NotificationsPage')
|
|
),
|
|
},
|
|
{
|
|
// A redirect to the Grafana Metrics Drilldown app from legacy Explore Metrics routes
|
|
path: '/explore/metrics/*',
|
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.DataSourcesExplore]),
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "MetricsDrilldownRedirect"*/ 'app/features/trails/RedirectToDrilldownApp')
|
|
),
|
|
},
|
|
{
|
|
path: '/bookmarks',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "BookmarksPage"*/ 'app/features/bookmarks/BookmarksPage')
|
|
),
|
|
},
|
|
{
|
|
path: '/theme-playground',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "ThemePlayground"*/ 'app/features/theme-playground/ThemePlayground')
|
|
),
|
|
},
|
|
config.featureToggles.restoreDashboards && {
|
|
path: '/dashboard/recently-deleted',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "RecentlyDeletedPage" */ 'app/features/browse-dashboards/RecentlyDeletedPage')
|
|
),
|
|
},
|
|
{
|
|
// Redirect the /femt dev page to the root
|
|
path: '/femt',
|
|
component: () => <Navigate replace to="/" />,
|
|
},
|
|
...getPluginCatalogRoutes(),
|
|
...getSupportBundleRoutes(),
|
|
...getAlertingRoutes(),
|
|
...getProfileRoutes(),
|
|
...extraRoutes,
|
|
...getPublicDashboardRoutes(),
|
|
...getDataConnectionsRoutes(),
|
|
...getProvisioningRoutes(),
|
|
{
|
|
path: '/goto/*',
|
|
component: HandleGoToRedirect,
|
|
},
|
|
{
|
|
path: '/*',
|
|
component: PageNotFound,
|
|
},
|
|
];
|
|
|
|
return routes.filter(isTruthy);
|
|
}
|
|
|
|
export function getSupportBundleRoutes(cfg = config): RouteDescriptor[] {
|
|
if (!cfg.supportBundlesEnabled) {
|
|
return [];
|
|
}
|
|
|
|
return [
|
|
{
|
|
path: '/support-bundles',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "SupportBundles" */ 'app/features/support-bundles/SupportBundles')
|
|
),
|
|
},
|
|
{
|
|
path: '/support-bundles/create',
|
|
component: SafeDynamicImport(
|
|
() => import(/* webpackChunkName: "SupportBundlesCreate" */ 'app/features/support-bundles/SupportBundlesCreate')
|
|
),
|
|
},
|
|
];
|
|
}
|
|
|
|
function DataSourceDashboardRoute() {
|
|
const { uid = '' } = useParams();
|
|
return <Navigate replace to={CONNECTIONS_ROUTES.DataSourcesDashboards.replace(':uid', uid)} />;
|
|
}
|
|
|
|
function DataSourceEditRoute() {
|
|
const { uid = '' } = useParams();
|
|
return <Navigate replace to={CONNECTIONS_ROUTES.DataSourcesEdit.replace(':uid', uid)} />;
|
|
}
|
|
|
|
// Explicitly send "goto" URLs to server, bypassing client-side routing
|
|
function HandleGoToRedirect() {
|
|
const { pathname } = useLocation();
|
|
|
|
useEffect(() => {
|
|
window.location.href = pathname;
|
|
}, [pathname]);
|
|
|
|
return null;
|
|
}
|