grafana/public/app/routes/ReactContainer.tsx
Chi-Hsuan Huang 546f569e0c
Chore: Enable eslint-plugin-react partial rules (#29428)
* Chore: Enable eslint react/display-name

Enable react/display-name and fixed the corresponding linting issue

part of: #29201

* Chore: Enable eslint react/no-deprecated

Enable react/no-deprecated and add the UNSAFE_ prefix for deprected methods

part of: #29201

* Chore: Enable eslint react/no-find-dom-node

Enable react/no-find-dom-node rule and use ref instead

part of: #29201

* Test: Update TeamGroupSync test snapshot

Since we added the displayName for ToolTip compontent and tag name is changed.

* Fix: Fixed ClickOutsideWrapper render

The props.children might contains numbers of nodes which make cloneElement failed. Change to simply use a div to wrapper
the children and assign the ref to div for this feature

* Style: Use shorthand method definition style for inline component

* Fix: Rebase master and fix linting

Rebase from master branch and fix new displayName linting warning
2020-12-01 16:19:52 +01:00

83 lines
2.2 KiB
TypeScript

// Libraries
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
// Utils and services
import coreModule from 'app/core/core_module';
import { store } from 'app/store/store';
import { ContextSrv } from 'app/core/services/context_srv';
import { provideTheme } from 'app/core/utils/ConfigProvider';
import { ErrorBoundaryAlert, ModalRoot, ModalsProvider } from '@grafana/ui';
import { GrafanaRootScope } from './GrafanaCtrl';
export function WrapInProvider(store: any, Component: any, props: any) {
return (
<Provider store={store}>
<ErrorBoundaryAlert style="page">
<Component {...props} />
</ErrorBoundaryAlert>
</Provider>
);
}
export const provideModalsContext = (component: any) => {
// eslint-disable-next-line react/display-name
return (props: any) => (
<ModalsProvider>
<>
{React.createElement(component, { ...props })}
<ModalRoot />
</>
</ModalsProvider>
);
};
/** @ngInject */
export function reactContainer(
$route: any,
$location: any,
$injector: any,
$rootScope: GrafanaRootScope,
contextSrv: ContextSrv
) {
return {
restrict: 'E',
template: '',
link(scope: any, elem: JQuery) {
// Check permissions for this component
const roles: string[] = $route.current.locals.roles;
if (roles && roles.length) {
if (!roles.some(r => contextSrv.hasRole(r))) {
$location.url('/');
}
}
let { component } = $route.current.locals;
// Dynamic imports return whole module, need to extract default export
if (component.default) {
component = component.default;
}
const props = {
$injector: $injector,
$rootScope: $rootScope,
$scope: scope,
$contextSrv: contextSrv,
routeInfo: $route.current.$$route?.routeInfo,
};
document.body.classList.add('is-react');
ReactDOM.render(WrapInProvider(store, provideTheme(provideModalsContext(component)), props), elem[0]);
scope.$on('$destroy', () => {
document.body.classList.remove('is-react');
ReactDOM.unmountComponentAtNode(elem[0]);
});
},
};
}
coreModule.directive('reactContainer', reactContainer);