From 9964d1aa28629080f9244d055c081020476e3c65 Mon Sep 17 00:00:00 2001 From: Nikolay Mendyaev Date: Fri, 17 Apr 2020 14:46:37 +0300 Subject: [PATCH] file bug --- package-lock.json | 39 ++++----- package.json | 6 +- src/App.js | 15 ++-- src/components/Routes.js | 37 ++++---- src/components/Routes.test.js | 151 +++++++++++++++++++++++++++++++++ src/core.js | 4 +- src/index.js | 112 ++++++++++++------------ src/module.js | 3 +- src/store/history.js | 3 + src/store/index.js | 6 +- src/test-utils/coreInstance.js | 3 +- 11 files changed, 269 insertions(+), 110 deletions(-) create mode 100644 src/components/Routes.test.js diff --git a/package-lock.json b/package-lock.json index 905cc4b..7b7b5d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@tarantool.io/frontend-core", - "version": "6.3.0", + "version": "6.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10377,9 +10377,9 @@ } }, "react": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", - "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -10459,14 +10459,14 @@ } }, "react-dom": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.9.0.tgz", - "integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", + "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.15.0" + "scheduler": "^0.19.1" } }, "react-draggable": { @@ -10598,21 +10598,14 @@ } }, "react-test-renderer": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.9.0.tgz", - "integrity": "sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.13.1.tgz", + "integrity": "sha512-Sn2VRyOK2YJJldOqoh8Tn/lWQ+ZiKhyZTPtaO0Q6yNj+QDbmRkVFap6pZPy3YQk8DScRDfyqm/KxKYP9gCMRiQ==", "requires": { "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "react-is": "^16.9.0", - "scheduler": "^0.15.0" - }, - "dependencies": { - "react-is": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", - "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==" - } + "react-is": "^16.8.6", + "scheduler": "^0.19.1" } }, "read-pkg": { @@ -11106,9 +11099,9 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "scheduler": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", - "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" diff --git a/package.json b/package.json index 62595e0..0fa4793 100644 --- a/package.json +++ b/package.json @@ -61,16 +61,16 @@ "promise": "8.0.1", "raf": "3.4.0", "ramda": "^0.25.0", - "react": "^16.9.0", + "react": "16.13.1", "react-dev-utils": "9.0.1", - "react-dom": "^16.9.0", + "react-dom": "16.13.1", "react-emotion": "^9.2.6", "react-redux": "^5.0.7", "react-router": "^4.3.1", "react-router-dom": "^4.3.1", "react-scrollbars-custom": "^4.0.18", "react-side-effect": "1.1.5", - "react-test-renderer": "^16.9.0", + "react-test-renderer": "16.13.1", "redux": "^4.0.0", "redux-thunk": "^2.3.0", "reselect": "^4.0.0", diff --git a/src/App.js b/src/App.js index 1b3cbe8..b3fa72f 100644 --- a/src/App.js +++ b/src/App.js @@ -5,14 +5,18 @@ import { ConnectedRouter } from 'connected-react-router' import Routes from './components/Routes' // $FlowFixMe import 'antd/dist/antd.less' -import history from './store/history' -import store from './store' import './styles/reset' import { css } from 'react-emotion' import Menu from './components/Menu' import Header from './components/Header' import NotificationList from './components/NotificationList' import FavIcon from './components/FavIcon' +import Core from './core' + +type AppProps = { + store: Object, + core: Core +} const sideColor = '#000000;' const styles = { @@ -52,8 +56,9 @@ const styles = { ` } -export default class App extends Component { +export default class App extends Component { render() { + const { store, core } = this.props return (
@@ -62,9 +67,7 @@ export default class App extends Component {
- - - +
diff --git a/src/components/Routes.js b/src/components/Routes.js index df94d42..67cabda 100644 --- a/src/components/Routes.js +++ b/src/components/Routes.js @@ -4,41 +4,46 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom' import { connect } from 'react-redux' import NoComponent from './NoComponent' -import coreInstance from '../coreInstance' import type { State } from '../store' import { selectRouteIsAllowed } from '../store/selectors' +import { ConnectedRouter } from "connected-react-router" +import Core from '../core' type RoutesProps = { routeIsAllowed: boolean, -} - -const mapRoutesModule = () => { - const modules = coreInstance.getModules() - return modules.map(module => ( - - )) + core: Core } class Routes extends React.Component { + mapRoutesModule() { + const modules = this.props.core.getModules() + return modules.map(module => ( + + )) + } + componentDidMount() { - coreInstance.subscribe('registerModule', () => { + this.props.core.subscribe('registerModule', () => { this.forceUpdate() }) } render() { - const { routeIsAllowed } = this.props; + const { routeIsAllowed, core } = this.props; return ( - - {routeIsAllowed && mapRoutesModule()} - - + + + {routeIsAllowed && this.mapRoutesModule()} + + + ) } } -export default connect((state: State) => { +export default connect((state: State, { core }) => { return { - routeIsAllowed: selectRouteIsAllowed(state) + routeIsAllowed: selectRouteIsAllowed(state), + core } })(Routes) diff --git a/src/components/Routes.test.js b/src/components/Routes.test.js new file mode 100644 index 0000000..2cd464e --- /dev/null +++ b/src/components/Routes.test.js @@ -0,0 +1,151 @@ +import Routes from './Routes' +import { generateCoreWithStore } from '../test-utils/coreInstance' +import renderer from 'react-test-renderer' +import React from 'react' +import { Route, Router, Switch } from 'react-router-dom' +import testSvg from './Notification/success-circle.svg' +import { push } from "connected-react-router" +import { Provider } from 'react-redux' +import NoComponent from './NoComponent' + +test('not found', () => { + const { coreInstance, store } = generateCoreWithStore() + + class NotFound extends React.Component{ + render() { + return
Not found
+ } + } + + class LocalTest extends React.Component { + render() { + return ( +
+ + + ( +
+ 1 +
+ )} + /> + ( +
+ +
+ )} + /> +
+
+
+ ) + } + } + + class LocalTestTwo extends React.Component { + render() { + return ( +
+ + + ( +
+ 2 +
+ )} + /> + ( +
+ + +
+ )} + /> +
+
+
+ ) + } + } + + class RouteProvider extends React.Component{ + render(): React.ReactNode { + const { store, core } = this.props + return
+ +
+ +
+
+
+ } + } + + coreInstance.register( + 'mytest', + [ + { + label: 'My Test', + path: '/mytest/test', + icon: 'hdd' + } + ], + LocalTest, + 'react' + ) + + coreInstance.register( + 'other', + [ + { + label: 'Other', + path: '/other/test', + icon: testSvg + } + ], + LocalTestTwo, + 'react' + ) + + store.dispatch(push('/other/test')) + console.log('first render') + const unregisterFilter = coreInstance.pageFilter.registerFilter(() => false) + const component = renderer.create( + + ) + console.log('after render', JSON.stringify(component.toJSON())) + + expect(component.root.findAllByType('div')).toEqual([]) + + component.update( + + ) + + unregisterFilter() + + component.update( + + ) + + + + expect(component.root.findAllByType(NotFound)).toEqual([]) + + store.dispatch(push('/mytest/test')) + component.update( + + ) + + + + expect(component.root.findAllByType(NotFound)).toEqual([]) + +}) diff --git a/src/core.js b/src/core.js index 7f35d7f..9330e74 100644 --- a/src/core.js +++ b/src/core.js @@ -2,7 +2,7 @@ import React, { type ComponentType } from 'react' import ReactDom from 'react-dom' import * as R from 'ramda' -import history from './store/history' +import { createHistory } from './store/history' import { sendNotification } from './store/actions/notifications' import pageFilter from './pageFilter' import { ReactComponentLike } from 'prop-types' @@ -83,7 +83,7 @@ export default class Core { this.modules = [] this.activeEngines = { react: 'loaded' } this.notifiers = {} - this.history = history + this.history = createHistory() this.header = null this.pageFilter = pageFilter(this) } diff --git a/src/index.js b/src/index.js index 7948d17..a851798 100644 --- a/src/index.js +++ b/src/index.js @@ -27,33 +27,54 @@ class Test extends React.Component { render() { return (
- - Tarantool - Frontend Core + (
- - - - -

Test title page

+ 1
)} /> (
- - {textElements} + Not found +
+ )} + /> +
+
+
+ ) + } +} + +class TestTwo extends React.Component { + render() { + return ( +
+ + + ( +
+ 2 +
+ )} + /> + ( +
+ Not found
)} /> -
Just content
} /> -
Some root
} />
@@ -62,54 +83,29 @@ class Test extends React.Component { } core.register( - 'test', + 'mytest', [ { - label: 'Simple Title Example', - path: '/test/test', + label: 'My Test', + path: '/mytest/test', icon: 'hdd' - }, - { - label: 'SubItems Example', - path: '/test/sub', - items: textElements.map((r, i) => ({ label: `Subitem ${i}`, path: `/test/sub/${i}` })) - }, - { - label: 'Test custom icon', - path: '/test/icon/1' - }, - { - label: 'Съешь же', - path: '/test/icon/2', - icon: - }, - { - label: ещё этих, - path: '/test/icon/3', - icon: 'hdd' - }, - { - label: мягких французских, - path: '/test/icon/4', - icon: 'hdd' - }, - { - label: ( - - булок, да выпей чаю - - ), - path: '/test/icon/5' - }, - { - label: 'Меня не видно', - path: '/test/icon/6' } ], Test, - 'react', - null, - ({ path }) => !path.includes('/test/icon/6') + 'react' +) + +core.register( + 'other', + [ + { + label: 'Other', + path: '/other/test', + icon: testSvg + } + ], + TestTwo, + 'react' ) core.notify({ @@ -144,3 +140,9 @@ core.dispatch('setAppName', 'Frontend Core') setTimeout(() => { core.setHeaderComponent(null) }, 3000) + +const unregisterFilter = core.pageFilter.registerFilter(() => false) + +setTimeout(() => { + unregisterFilter() +}, 1000) diff --git a/src/module.js b/src/module.js index 7ed66b8..4129b3d 100644 --- a/src/module.js +++ b/src/module.js @@ -7,6 +7,7 @@ import core from './coreInstance' import AppTitle from './components/AppTitle' import apiMethods from './api' import analyticModule from './analytics' +import store from './store' core.components = { AppTitle @@ -17,7 +18,7 @@ core.logo = require('./components/tarantool-logo.svg') core.apiMethods = apiMethods core.analyticModule = analyticModule -ReactDOM.render(, document.getElementById('root')) +ReactDOM.render(, document.getElementById('root')) export default core window.tarantool_enterprise_core = core diff --git a/src/store/history.js b/src/store/history.js index 89cb60a..6f6edcb 100644 --- a/src/store/history.js +++ b/src/store/history.js @@ -5,4 +5,7 @@ if (!window.__tarantool_admin_prefix) { } export const APP_PATH_PREFIX = window.__tarantool_admin_prefix + '/admin' + +export const createHistory = () => createBrowserHistory({ basename: `${APP_PATH_PREFIX}/` }) + export default createBrowserHistory({ basename: `${APP_PATH_PREFIX}/` }) diff --git a/src/store/index.js b/src/store/index.js index 916e85c..bf48b05 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -9,7 +9,7 @@ import { setAppName } from './actions/title' import appTitleReducer, { type AppTitleState } from './reducers/title' import thunk from 'redux-thunk' import { connectRouter, routerMiddleware, RouterState } from 'connected-react-router' -import history, { APP_PATH_PREFIX } from './history' +import { APP_PATH_PREFIX } from './history' import coreInstance from '../coreInstance' import * as constants from './constants' import Core, { type FSA } from '../core' @@ -36,7 +36,7 @@ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose export const createCoreStore = (core: Core) => { const store = createStore( - connectRouter(history)( + connectRouter(core.history)( combineReducers({ menu: menuReducer.reduce, appTitle: appTitleReducer, @@ -51,7 +51,7 @@ export const createCoreStore = (core: Core) => { composeEnhancers( applyMiddleware( thunk, - routerMiddleware(history), + routerMiddleware(core.history), menuReducer.middleware, saveNotificationsMiddleware, changeTitleMiddleware, diff --git a/src/test-utils/coreInstance.js b/src/test-utils/coreInstance.js index 1f4a500..ca6a4cd 100644 --- a/src/test-utils/coreInstance.js +++ b/src/test-utils/coreInstance.js @@ -1,11 +1,12 @@ import Core from '../core' import { createCoreStore } from '../store' +import { createHistory } from '../store/history' export const generateCoreWithStore = () => { const coreInstance = new Core() const store = createCoreStore(coreInstance) return { coreInstance, - store + store, } }