mirror of
https://github.com/grafana/grafana.git
synced 2024-12-29 10:21:41 -06:00
AppPlugins: Expose react-router to apps (#33775)
* Allow Route component usage in app plugins * i tried * fix catalog app * fix catalog app * remove catalog changes from this PR * remove extra files * feat(plugins): expose react-router to plugins rather than export via grafana-ui * Bring back query and pathname to AppRootPage and add deprecation notice Co-authored-by: Ryan McKinley <ryantxu@gmail.com> Co-authored-by: Jack Westbrook <jack.westbrook@gmail.com>
This commit is contained in:
parent
fb9223ab42
commit
4cbffae1b4
@ -12,14 +12,27 @@ export enum CoreApp {
|
||||
|
||||
export interface AppRootProps<T = KeyValue> {
|
||||
meta: AppPluginMeta<T>;
|
||||
|
||||
path: string; // The URL path to this page
|
||||
query: KeyValue; // The URL query parameters
|
||||
/**
|
||||
* base URL segment for an app, /app/pluginId
|
||||
*/
|
||||
basename: string; // The URL path to this page
|
||||
|
||||
/**
|
||||
* Pass the nav model to the container... is there a better way?
|
||||
*/
|
||||
onNavChanged: (nav: NavModel) => void;
|
||||
|
||||
/**
|
||||
* The URL query parameters
|
||||
* @deprecated Use react-router instead
|
||||
*/
|
||||
query: KeyValue;
|
||||
|
||||
/**
|
||||
* The URL path to this page
|
||||
* @deprecated Use react-router instead
|
||||
*/
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface AppPluginMeta<T = KeyValue> extends PluginMeta<T> {
|
||||
|
@ -185,6 +185,7 @@ const getBaseWebpackConfig: WebpackConfigurationGetter = async (options) => {
|
||||
'react-redux',
|
||||
'redux',
|
||||
'rxjs',
|
||||
'react-router-dom',
|
||||
'd3',
|
||||
'angular',
|
||||
'@grafana/ui',
|
||||
|
@ -59,7 +59,7 @@ export class AppWrapper extends React.Component<AppWrapperProps, AppWrapperState
|
||||
|
||||
return (
|
||||
<Route
|
||||
exact
|
||||
exact={route.exact === undefined ? true : route.exact}
|
||||
path={route.path}
|
||||
key={route.path}
|
||||
render={(props) => {
|
||||
|
@ -16,4 +16,5 @@ export interface RouteDescriptor {
|
||||
pageClass?: string;
|
||||
/** Can be used like an id for the route if the same component is used by many routes */
|
||||
routeName?: string;
|
||||
exact?: boolean;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Libraries
|
||||
import React, { Component } from 'react';
|
||||
import { AppEvents, AppPlugin, AppPluginMeta, NavModel, PluginType } from '@grafana/data';
|
||||
import { AppEvents, AppPlugin, AppPluginMeta, KeyValue, NavModel, PluginType } from '@grafana/data';
|
||||
import { createHtmlPortalNode, InPortal, OutPortal, HtmlPortalNode } from 'react-reverse-portal';
|
||||
|
||||
import Page from 'app/core/components/Page/Page';
|
||||
@ -10,6 +10,7 @@ import { getNotFoundNav, getWarningNav, getExceptionNav } from 'app/core/nav_mod
|
||||
import { appEvents } from 'app/core/core';
|
||||
import PageLoader from 'app/core/components/PageLoader/PageLoader';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { locationSearchToObject } from '@grafana/runtime';
|
||||
|
||||
interface RouteParams {
|
||||
pluginId: string;
|
||||
@ -91,7 +92,6 @@ class AppRootPage extends Component<Props, State> {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { location, queryParams } = this.props;
|
||||
const { loading, plugin, nav, portalNode } = this.state;
|
||||
|
||||
if (plugin && !plugin.root) {
|
||||
@ -105,9 +105,10 @@ class AppRootPage extends Component<Props, State> {
|
||||
{plugin && plugin.root && (
|
||||
<plugin.root
|
||||
meta={plugin.meta}
|
||||
query={queryParams}
|
||||
path={location.pathname}
|
||||
basename={this.props.match.url}
|
||||
onNavChanged={this.onNavChanged}
|
||||
query={locationSearchToObject(this.props.location.search) as KeyValue}
|
||||
path={this.props.location.pathname}
|
||||
/>
|
||||
)}
|
||||
</InPortal>
|
||||
|
@ -46,6 +46,8 @@ grafanaUI.DataSourceApi = grafanaData.DataSourceApi;
|
||||
// rxjs
|
||||
import * as rxjs from 'rxjs';
|
||||
import * as rxjsOperators from 'rxjs/operators';
|
||||
// routing
|
||||
import * as reactRouter from 'react-router-dom';
|
||||
|
||||
// add cache busting
|
||||
const bust = `?_cache=${Date.now()}`;
|
||||
@ -92,6 +94,7 @@ exposeToPlugin('angular', angular);
|
||||
exposeToPlugin('d3', d3);
|
||||
exposeToPlugin('rxjs', rxjs);
|
||||
exposeToPlugin('rxjs/operators', rxjsOperators);
|
||||
exposeToPlugin('react-router-dom', reactRouter);
|
||||
|
||||
// Experimental modules
|
||||
exposeToPlugin('prismjs', prismjs);
|
||||
|
@ -149,6 +149,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
||||
},
|
||||
{
|
||||
path: '/a/:pluginId/',
|
||||
exact: false,
|
||||
// Someday * and will get a ReactRouter under that path!
|
||||
component: SafeDynamicImport(
|
||||
() => import(/* webpackChunkName: "AppRootPage" */ 'app/features/plugins/AppRootPage')
|
||||
|
Loading…
Reference in New Issue
Block a user