diff --git a/generators/app/templates/index.ts b/generators/app/templates/index.ts index 3c3908cb..845927a0 100644 --- a/generators/app/templates/index.ts +++ b/generators/app/templates/index.ts @@ -1,7 +1,7 @@ <% if (reduxConfig) { -%> import * as namespace from './namespace'; import { actions, selectors, reducer<%= (reduxConfig.withSaga) ? ', getSaga' : '' %> } from './redux'; -import { IReduxEntry } from 'shared/types/app'; +import { IReduxEntry } from 'core/types'; export { namespace, selectors, actions }; <% } -%> diff --git a/generators/app/templates/redux/sagas/index.ts b/generators/app/templates/redux/sagas/index.ts index 5c92cff9..fe1bba39 100644 --- a/generators/app/templates/redux/sagas/index.ts +++ b/generators/app/templates/redux/sagas/index.ts @@ -1,7 +1,7 @@ import { put, call } from 'redux-saga/effects'; import { SagaIterator } from 'redux-saga'; -import { IDependencies } from 'shared/types/app'; +import { IDependencies } from 'core/types'; import * as actions from '../actions'; diff --git a/generators/app/templates/redux/selectors.ts b/generators/app/templates/redux/selectors.ts index 18af37f6..8f92022d 100644 --- a/generators/app/templates/redux/selectors.ts +++ b/generators/app/templates/redux/selectors.ts @@ -1,4 +1,4 @@ -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import * as NS from '../namespace'; export function getFeatureState(state: IAppReduxState): NS.IReduxState { diff --git a/generators/app/templates/view/containers/SomeContainer/SomeContainer.tsx b/generators/app/templates/view/containers/SomeContainer/SomeContainer.tsx index 3090ac67..fe238dc9 100644 --- a/generators/app/templates/view/containers/SomeContainer/SomeContainer.tsx +++ b/generators/app/templates/view/containers/SomeContainer/SomeContainer.tsx @@ -4,7 +4,7 @@ import { bind } from 'decko'; import { connect } from 'react-redux'; import { bindActionCreators, Dispatch } from 'redux'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IReduxState } from '../../../namespace'; import { actions, selectors } from './../../../redux'; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 202cac1e..495b0973 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -19804,9 +19804,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz", - "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==" + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.2.tgz", + "integrity": "sha512-Og2Vn6Mk7JAuWA1hQdDQN/Ekm/SchX80VzLhjKN9ETYrIepBFAd8PkOdOTK2nKt0FCkmMZKBJvQ1dV1gIxPu/A==" }, "ua-parser-js": { "version": "0.7.19", diff --git a/package.json b/package.json index b72b3104..279400fe 100644 --- a/package.json +++ b/package.json @@ -280,7 +280,7 @@ "thread-loader": "^2.1.1", "ts-loader": "^5.3.3", "ts-node": "^7.0.1", - "typescript": "^3.2.2", + "typescript": "^3.4.2", "url-loader": "^1.1.2", "uuid": "^3.3.2" } diff --git a/server/starters.ts b/server/starters.ts index 97c7fa66..b4e36afb 100644 --- a/server/starters.ts +++ b/server/starters.ts @@ -4,7 +4,7 @@ import hotMiddleware from 'webpack-hot-middleware'; import SSRMiddleware from 'webpack-isomorphic-dev-middleware'; import $ from 'cheerio'; -import { IAssets } from '../src/shared/types/app'; +import { IAssets } from '../src/core/types'; function startDevelopmentMode( server: Express, clientConfig: webpack.Configuration, serverConfig: webpack.Configuration, diff --git a/src/assets/Html.tsx b/src/assets/Html.tsx index ca576986..fc028aaf 100644 --- a/src/assets/Html.tsx +++ b/src/assets/Html.tsx @@ -4,8 +4,8 @@ import Helmet from 'react-helmet'; import redux from 'redux'; import { renderToString } from 'react-dom/server'; -import { IAssets } from 'shared/types/app'; import { SheetsRegistry } from 'shared/styles'; +import { IAssets } from 'core/types'; interface IHtmlProps { assets: IAssets; diff --git a/src/client.tsx b/src/client.tsx index e986e8dd..f7486dc8 100644 --- a/src/client.tsx +++ b/src/client.tsx @@ -1,12 +1,12 @@ import 'reflect-metadata'; import 'babel-polyfill'; -import { App } from 'core/App'; import React from 'react'; import ReactDOM from 'react-dom'; import bootstrapper from 'react-async-bootstrapper'; -import configureApp from 'core/configureApp'; -import getEnvParams from './core/getEnvParams'; +import { App } from 'core/render'; +import configureApp from 'core/configure'; +import getEnvParams from 'core/getEnvParams'; const { appVersion } = getEnvParams(); @@ -25,11 +25,11 @@ main(); /* Hot Module Replacement API */ if ((module as any).hot && process.env.NODE_ENV !== 'production') { - (module as any).hot.accept(['./core/App', './core/configureApp'], () => { - const nextConfigureApp: typeof configureApp = require('./core/configureApp').default; - const NextApp: typeof App = require('./core/App').App; + (module as any).hot.accept(['./core/render', './core/configure'], () => { + const nextConfigureApp: typeof configureApp = require('./core/configure').default; + const NextApp: typeof App = require('./core/render').App; const nextAppData = nextConfigureApp(appData); - render(); + render(); }); } diff --git a/src/config/index.ts b/src/config/index.ts new file mode 100644 index 00000000..f43f5bf8 --- /dev/null +++ b/src/config/index.ts @@ -0,0 +1,45 @@ +import Api from 'services/api/Api'; +import * as themeService from 'services/theme'; +import { I18nProvider } from 'services/i18n'; +import * as notsService from 'services/notification'; + +import * as features from 'features'; + +import * as allModules from 'modules'; +import { App } from 'modules/App'; +import { default as routes } from 'modules/routes'; + +import { IBaseDeps, IModule, IReduxEntry } from 'core/types'; + +export const default404RedirectPath: string | null = routes.search.users.getRedirectPath(); + +export function makeDeps(_baseDeps: IBaseDeps) { + return { + api: new Api(), + }; +} + +export const modules: IModule[] = Object.values(allModules); + +export const reduxEntries: IReduxEntry[] = [ + themeService.reduxEntry, + notsService.reduxEntry, +]; + +export const RootComponent: React.ComponentType = App; + +export const reactAppWrappers: React.ComponentType[] = [ + I18nProvider, +]; + +export type ExtraDeps = ReturnType; + +export interface IAppReduxState { + // services + theme: themeService.namespace.IReduxState; + notification: notsService.namespace.IReduxState; + // features + usersSearch: features.usersSearch.namespace.IReduxState; + repositoriesSearch: features.repositoriesSearch.namespace.IReduxState; + profile: features.profile.namespace.IReduxState; +} diff --git a/src/core/ContainersProvider.tsx b/src/core/ContainersProvider.tsx index 86308f1b..93650622 100644 --- a/src/core/ContainersProvider.tsx +++ b/src/core/ContainersProvider.tsx @@ -1,12 +1,11 @@ import React from 'react'; import { bind } from 'decko'; +import { injectable } from 'inversify'; import { Omit, SubSet } from '_helpers'; import * as usersSearchFeature from 'features/usersSearch'; -import { injectable } from 'inversify'; -import { inject, TYPES } from './configureIoc'; - -import { IFeatureEntry, IReduxEntry } from 'shared/types/app'; +import { inject, TYPES, IocTypes } from './configure/ioc'; +import { IFeatureEntry, IReduxEntry } from './types'; interface IContainerTypes { UserDetails: usersSearchFeature.Entry['containers']['UserDetails']; @@ -45,14 +44,14 @@ function containersProvider(containers: L[], preloader?: Re return ( WrappedComponent: React.ComponentType, - ): React.ComponentClass => { + ): React.ComponentClass> => { @injectable() class ContainersProvider extends React.PureComponent { public state: IState = { containers: {} }; @inject(TYPES.connectEntryToStore) - private connectFeatureToStore!: (entry: IReduxEntry) => void; + private connectFeatureToStore!: IocTypes[typeof TYPES.connectEntryToStore]; public componentDidMount() { this.load(); diff --git a/src/core/FeatureConnector.tsx b/src/core/FeatureConnector.tsx index 522dc115..9e2a3b6b 100644 --- a/src/core/FeatureConnector.tsx +++ b/src/core/FeatureConnector.tsx @@ -4,9 +4,8 @@ import * as R from 'ramda'; import { injectable } from 'inversify'; import { Omit, GetProps, SubSet } from '_helpers'; -import { inject, TYPES } from './configureIoc'; - -import { IFeatureEntry, IReduxEntry } from 'shared/types/app'; +import { inject, TYPES, IocTypes } from './configure/ioc'; +import { IFeatureEntry } from './types'; type FeatureLoader = () => Promise; @@ -29,7 +28,7 @@ function featureConnect>(loaders: L, pre public state: IState = { mounted: false }; @inject(TYPES.connectEntryToStore) - private connectFeatureToStore!: (entry: IReduxEntry) => void; + private connectFeatureToStore!: IocTypes[typeof TYPES.connectEntryToStore]; public async bootstrap() { await this.load(); @@ -91,9 +90,8 @@ function featureConnect>(loaders: L, pre }; } -type IFeatureEntryWithContainers< - C extends Record> - > = SubSet; +type IFeatureEntryWithContainers>> = + SubSet; export function getAsyncContainer>, K extends keyof C>( loader: () => Promise>, componentName: K, diff --git a/src/core/configureApp.ts b/src/core/configure/index.ts similarity index 58% rename from src/core/configureApp.ts rename to src/core/configure/index.ts index d4611b48..5f851b74 100644 --- a/src/core/configureApp.ts +++ b/src/core/configure/index.ts @@ -1,44 +1,40 @@ -import configureDeps from './configureDeps'; -import { TYPES, container } from './configureIoc'; -import configureStore, { createReducer } from './configureStore'; - -import * as allModules from 'modules'; -import { configureJss } from 'core/configureJss'; +import { makeDeps, modules, reduxEntries } from 'config'; import { ReducersMap } from 'shared/types/redux'; -import { reduxEntry as themeProviderRE } from 'services/theme'; -import { reduxEntry as notificationReduxEntry } from 'services/notification'; -import { IAppData, IModule, RootSaga, IAppReduxState, IReduxEntry } from 'shared/types/app'; -function configureApp(data?: IAppData): IAppData { - /* Prepare main app elements */ - const modules: IModule[] = Object.values(allModules); +import { IAppData, IModule, RootSaga, IAppReduxState, IReduxEntry, IDependencies } from '../types'; +import { TYPES, container, IocTypes } from './ioc'; +import configureStore, { createReducer } from './store'; +import { configureJss } from './jss'; +function configureApp(data?: IAppData): IAppData { if (data) { - return { ...data, modules }; + return data; } - const sharedReduxEntries: IReduxEntry[] = [ - themeProviderRE, - notificationReduxEntry, - ]; - const connectedSagas: RootSaga[] = []; const connectedReducers: ReducersMap> = {}; const { runSaga, store } = configureStore(); + + const baseDeps = { runSaga, store }; + const dependencies: IDependencies = { + ...baseDeps, + ...makeDeps(baseDeps), + }; + const jssDeps = configureJss(); + try { - container.getAll(TYPES.Store); - container.rebind(TYPES.connectEntryToStore).toConstantValue(connectEntryToStore); - container.rebind(TYPES.Store).toConstantValue(store); + container.getAll(TYPES.Deps); + container.rebind(TYPES.connectEntryToStore) + .toConstantValue(connectEntryToStore); + container.rebind(TYPES.Deps).toConstantValue(dependencies); } catch { - container.bind(TYPES.connectEntryToStore).toConstantValue(connectEntryToStore); - container.bind(TYPES.Store).toConstantValue(store); + container.bind(TYPES.connectEntryToStore) + .toConstantValue(connectEntryToStore); + container.bind(TYPES.Deps).toConstantValue(dependencies); } - const dependencies = configureDeps(store); - const jssDeps = configureJss(); - - sharedReduxEntries.forEach(connectEntryToStore); + reduxEntries.forEach(connectEntryToStore); modules.forEach((module: IModule) => { if (module.getReduxEntry) { connectEntryToStore(module.getReduxEntry()); @@ -76,7 +72,7 @@ function configureApp(data?: IAppData): IAppData { } } - return { modules, store, jssDeps }; + return { deps: dependencies, jssDeps }; } export default configureApp; diff --git a/src/core/configure/ioc.ts b/src/core/configure/ioc.ts new file mode 100644 index 00000000..c4db4e00 --- /dev/null +++ b/src/core/configure/ioc.ts @@ -0,0 +1,21 @@ +import { Container } from 'inversify'; +import getDecorators from 'inversify-inject-decorators'; +import { IDependencies, IReduxEntry } from '../types'; + +const depsSymbol = Symbol('Deps'); +const connectEntryToStoreSymbol = Symbol('connectFeatureToStore'); + +interface IocTypes { + [depsSymbol]: IDependencies; + [connectEntryToStoreSymbol]: (entry: IReduxEntry) => void; +} + +const TYPES = { + Deps: depsSymbol, + connectEntryToStore: connectEntryToStoreSymbol, +} as const; + +const container = new Container(); +const { lazyInject } = getDecorators(container); + +export { TYPES, container, IocTypes, lazyInject as inject }; diff --git a/src/core/configureJss.ts b/src/core/configure/jss.ts similarity index 91% rename from src/core/configureJss.ts rename to src/core/configure/jss.ts index 6d1a6e8a..c27621c0 100644 --- a/src/core/configureJss.ts +++ b/src/core/configure/jss.ts @@ -1,7 +1,7 @@ import { create } from 'jss'; import jssCompose from 'jss-compose'; import { createGenerateClassName, jssPreset } from '@material-ui/core/styles'; -import { IJssDependencies } from 'shared/types/app'; +import { IJssDependencies } from '../types'; export function configureJss(virtual?: boolean): IJssDependencies { // Place to add jss-plugins [https://material-ui.com/customization/css-in-js/#plugins] diff --git a/src/core/configureStore.ts b/src/core/configure/store.ts similarity index 96% rename from src/core/configureStore.ts rename to src/core/configure/store.ts index 16821343..e5423202 100644 --- a/src/core/configureStore.ts +++ b/src/core/configure/store.ts @@ -2,9 +2,9 @@ import { composeWithDevTools } from 'redux-devtools-extension'; import createSagaMiddleware, { SagaMiddleware } from 'redux-saga'; import { compose, applyMiddleware, combineReducers, createStore, Reducer, Middleware, Store } from 'redux'; -import { composeReducers } from 'shared/helpers/redux'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { ReducersMap } from 'shared/types/redux'; +import { composeReducers } from 'shared/helpers/redux'; interface IStoreData { store: Store; diff --git a/src/core/configureDeps.ts b/src/core/configureDeps.ts deleted file mode 100644 index 4af75524..00000000 --- a/src/core/configureDeps.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Store } from 'redux'; - -import { IDependencies, IAppReduxState } from 'shared/types/app'; - -import Api from 'services/api/Api'; - -export default function configureDeps(_store: Store): IDependencies { - const api = new Api(); - - return { api }; -} diff --git a/src/core/configureIoc.ts b/src/core/configureIoc.ts deleted file mode 100644 index 76b27321..00000000 --- a/src/core/configureIoc.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Container } from 'inversify'; -import getDecorators from 'inversify-inject-decorators'; -import TYPES from './iocTypes'; - -const container = new Container(); -const { lazyInject } = getDecorators(container); - -export { TYPES, container, lazyInject as inject }; diff --git a/src/core/index.ts b/src/core/index.ts index f2371ceb..80691437 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,3 +1,3 @@ export { default as containersProvider, IContainerTypes } from './ContainersProvider'; export { default as featureConnect } from './FeatureConnector'; -export { inject, TYPES } from './configureIoc'; +export { inject, TYPES } from './configure/ioc'; diff --git a/src/core/iocTypes.ts b/src/core/iocTypes.ts deleted file mode 100644 index 16932dac..00000000 --- a/src/core/iocTypes.ts +++ /dev/null @@ -1,6 +0,0 @@ -const TYPES = { - Store: Symbol('Store'), - connectEntryToStore: Symbol('connectFeatureToStore'), -}; - -export default TYPES; diff --git a/src/core/App.tsx b/src/core/render/index.tsx similarity index 56% rename from src/core/App.tsx rename to src/core/render/index.tsx index ad46c8cd..39a00ceb 100644 --- a/src/core/App.tsx +++ b/src/core/render/index.tsx @@ -1,27 +1,26 @@ import React from 'react'; import { Provider } from 'react-redux'; import { BrowserRouter, StaticRouter } from 'react-router-dom'; +import { hot } from 'react-hot-loader/root'; import 'normalize.css'; -import { hot } from 'react-hot-loader/root'; import { ThemeProvider } from 'services/theme'; -import { containers as NotificationContainers } from 'services/notification'; -import { I18nProvider } from 'services/i18n'; -import { IAppData, IModule, IJssDependencies } from 'shared/types/app'; -import { BaseStyles, JssProvider, SheetsRegistry } from 'shared/styles'; +import { JssProvider, SheetsRegistry } from 'shared/styles'; -import createRoutes from './routes'; +import { reactAppWrappers } from 'config'; +import { IJssDependencies, IAppData } from '../types'; +import Routes from './Routes'; interface IAppProps { jssDeps: IJssDependencies; disableStylesGeneration?: boolean; } -function ClientApp({ modules, store, jssDeps, disableStylesGeneration }: IAppData & IAppProps) { +function ClientApp({ deps, jssDeps, disableStylesGeneration }: IAppData & IAppProps) { return ( - + - {renderSharedPart(modules, jssDeps, disableStylesGeneration)} + {renderSharedPart(jssDeps, disableStylesGeneration)} ); @@ -36,18 +35,18 @@ interface IServerAppProps { } export function ServerApp(props: IAppData & IServerAppProps & StaticRouter['props']) { - const { modules, store, registry, jssDeps, disableStylesGeneration, ...routerProps } = props; + const { deps, registry, jssDeps, disableStylesGeneration, ...routerProps } = props; return ( - + - {renderSharedPart(modules, jssDeps, disableStylesGeneration, registry)} + {renderSharedPart(jssDeps, disableStylesGeneration, registry)} ); } function renderSharedPart( - modules: IModule[], jssDeps: IJssDependencies, + jssDeps: IJssDependencies, disableStylesGeneration?: boolean, registry?: SheetsRegistry, ) { @@ -61,13 +60,16 @@ function renderSharedPart( disableStylesGeneration={disableStylesGeneration} > - - - {createRoutes(modules)} - - - + {renderWrappers(reactAppWrappers, )} ); } + +function renderWrappers(wraps: typeof reactAppWrappers, child: React.ReactElement) { + if (wraps.length === 0) { + return child; + } + const Cur = wraps[0]; + return {renderWrappers(wraps.slice(1), child)}; +} diff --git a/src/core/render/routes.tsx b/src/core/render/routes.tsx new file mode 100644 index 00000000..2ddf98b3 --- /dev/null +++ b/src/core/render/routes.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { Route, RouteComponentProps, Redirect, Switch } from 'react-router-dom'; +import { default404RedirectPath, modules, RootComponent } from 'config'; + +function Routes(): React.ReactElement> { + return ( + + + + {modules.map(module => module.getRoutes ? module.getRoutes() : null)} + {default404RedirectPath && } + + + + ); +} + +export default Routes; diff --git a/src/core/routes.tsx b/src/core/routes.tsx deleted file mode 100644 index 87d87766..00000000 --- a/src/core/routes.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { Route, RouteComponentProps, Redirect, Switch } from 'react-router-dom'; - -import { App } from 'modules/App'; -import routes from 'modules/routes'; - -import { IModule } from 'shared/types/app'; - -function getRoutes(modules: IModule[]): React.ReactElement> { - return ( - - - - {modules.map(module => module.getRoutes ? module.getRoutes() : null)} - - - - - ); -} - -export default getRoutes; diff --git a/src/shared/types/app.ts b/src/core/types.ts similarity index 64% rename from src/shared/types/app.ts rename to src/core/types.ts index 21784b5b..13d2c464 100644 --- a/src/shared/types/app.ts +++ b/src/core/types.ts @@ -1,14 +1,20 @@ import { ReactElement } from 'react'; import { RouteProps } from 'react-router'; import { Store, Reducer, ActionCreator, Action } from 'redux'; -import { SagaIterator } from 'redux-saga'; +import { SagaIterator, SagaMiddleware } from 'redux-saga'; import { GenerateClassName } from 'jss'; -import * as features from 'features'; -import Api from 'services/api/Api'; -import * as ThemeProviderNS from 'services/theme/namespace'; // TODO: УДОЛИ -import { namespace as NotificationNamespace } from 'services/notification'; import { JSS } from 'shared/styles'; +import { ExtraDeps, IAppReduxState } from 'config'; + +export { IAppReduxState }; + +export interface IBaseDeps { + store: Store; + runSaga: SagaMiddleware['run']; +} + +export type IDependencies = ExtraDeps & IBaseDeps; export abstract class IModule { public getRoutes?(): ReactElement | Array>; @@ -16,8 +22,7 @@ export abstract class IModule { } export interface IAppData { - modules: IModule[]; - store: Store; + deps: IDependencies; jssDeps: IJssDependencies; } @@ -26,10 +31,6 @@ export interface IJssDependencies { generateClassName: GenerateClassName; } -export interface IDependencies { - api: Api; -} - export interface IReduxEntry { reducers?: { [key in keyof IAppReduxState]?: Reducer }; sagas?: Array<(deps: IDependencies) => () => SagaIterator>; @@ -42,16 +43,6 @@ export interface IFeatureEntry { reduxEntry?: IReduxEntry; } -export interface IAppReduxState { - // services - theme: ThemeProviderNS.IReduxState; - notification: NotificationNamespace.IReduxState; - // features - usersSearch: features.usersSearch.namespace.IReduxState; - repositoriesSearch: features.repositoriesSearch.namespace.IReduxState; - profile: features.profile.namespace.IReduxState; -} - export type RootSaga = (deps: IDependencies) => () => SagaIterator; export type Lang = 'en' | 'he'; diff --git a/src/features/profile/redux/selectors.ts b/src/features/profile/redux/selectors.ts index ec3abf3b..9539c60a 100644 --- a/src/features/profile/redux/selectors.ts +++ b/src/features/profile/redux/selectors.ts @@ -1,4 +1,4 @@ -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IProfile } from 'shared/types/models'; function selectFeatureState(state: IAppReduxState) { diff --git a/src/features/profile/view/containers/ProfileEdit/ProfileEdit.tsx b/src/features/profile/view/containers/ProfileEdit/ProfileEdit.tsx index ff3a0098..ccb8470a 100644 --- a/src/features/profile/view/containers/ProfileEdit/ProfileEdit.tsx +++ b/src/features/profile/view/containers/ProfileEdit/ProfileEdit.tsx @@ -6,7 +6,7 @@ import { bind } from 'decko'; import { TextInputField, NumberInputField } from 'shared/view/form'; import { Button } from 'shared/view/elements'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IProfile } from 'shared/types/models'; import { actions as notificationServiceActions } from 'services/notification'; diff --git a/src/features/profile/view/containers/ProfilePreview/ProfilePreview.tsx b/src/features/profile/view/containers/ProfilePreview/ProfilePreview.tsx index 4918007c..c9ac6333 100644 --- a/src/features/profile/view/containers/ProfilePreview/ProfilePreview.tsx +++ b/src/features/profile/view/containers/ProfilePreview/ProfilePreview.tsx @@ -3,7 +3,7 @@ import block from 'bem-cn'; import { connect } from 'react-redux'; import { bind } from 'decko'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IProfile } from 'shared/types/models'; import { Popover } from 'shared/view/components'; diff --git a/src/features/repositoriesSearch/redux/sagas.ts b/src/features/repositoriesSearch/redux/sagas.ts index 581c4cae..7785d5d6 100644 --- a/src/features/repositoriesSearch/redux/sagas.ts +++ b/src/features/repositoriesSearch/redux/sagas.ts @@ -1,7 +1,7 @@ import { put, call, all, takeLatest } from 'redux-saga/effects'; import { SagaIterator } from 'redux-saga'; -import { IDependencies } from 'shared/types/app'; +import { IDependencies } from 'core/types'; import { getErrorMsg } from 'shared/helpers'; import { IRepositoriesSearchResults } from 'shared/types/githubSearch'; import { actions as notificationServiceActions } from 'services/notification'; diff --git a/src/features/repositoriesSearch/redux/selectors.ts b/src/features/repositoriesSearch/redux/selectors.ts index 281999b9..d0466024 100644 --- a/src/features/repositoriesSearch/redux/selectors.ts +++ b/src/features/repositoriesSearch/redux/selectors.ts @@ -1,4 +1,4 @@ -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IRepository } from 'shared/types/models'; import { IPaginationState } from 'shared/types/common'; import { ICommunication } from 'shared/types/redux'; diff --git a/src/features/repositoriesSearch/view/containers/RepositoriesSearchForm/RepositoriesSearchForm.tsx b/src/features/repositoriesSearch/view/containers/RepositoriesSearchForm/RepositoriesSearchForm.tsx index 0ee51909..54c3f8f7 100644 --- a/src/features/repositoriesSearch/view/containers/RepositoriesSearchForm/RepositoriesSearchForm.tsx +++ b/src/features/repositoriesSearch/view/containers/RepositoriesSearchForm/RepositoriesSearchForm.tsx @@ -3,7 +3,7 @@ import { connect } from 'react-redux'; import { bind } from 'decko'; import * as R from 'ramda'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { SearchForm } from 'shared/view/components'; import { replaceObjectKeys } from 'shared/helpers'; diff --git a/src/features/repositoriesSearch/view/containers/RepositoriesSearchResults/RepositoriesSearchResults.tsx b/src/features/repositoriesSearch/view/containers/RepositoriesSearchResults/RepositoriesSearchResults.tsx index 8399e735..d31fc1ee 100644 --- a/src/features/repositoriesSearch/view/containers/RepositoriesSearchResults/RepositoriesSearchResults.tsx +++ b/src/features/repositoriesSearch/view/containers/RepositoriesSearchResults/RepositoriesSearchResults.tsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import { bind } from 'decko'; import { containersProvider, IContainerTypes } from 'core'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IRepository } from 'shared/types/models'; import { IPaginationState } from 'shared/types/common'; import { PaginationControls } from 'shared/view/components'; diff --git a/src/features/usersSearch/redux/sagas.ts b/src/features/usersSearch/redux/sagas.ts index 1ae03bd3..5d0ba9d8 100644 --- a/src/features/usersSearch/redux/sagas.ts +++ b/src/features/usersSearch/redux/sagas.ts @@ -1,7 +1,7 @@ import { put, call, all, takeLatest } from 'redux-saga/effects'; import { SagaIterator } from 'redux-saga'; -import { IDependencies } from 'shared/types/app'; +import { IDependencies } from 'core/types'; import { IDetailedGithubUser } from 'shared/types/models'; import { IUsersSearchResults } from 'shared/types/githubSearch'; import { getErrorMsg } from 'shared/helpers'; diff --git a/src/features/usersSearch/redux/selectors.ts b/src/features/usersSearch/redux/selectors.ts index a0b3e836..8bfecb8a 100644 --- a/src/features/usersSearch/redux/selectors.ts +++ b/src/features/usersSearch/redux/selectors.ts @@ -1,4 +1,4 @@ -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IGithubUser, IDetailedGithubUser } from 'shared/types/models'; import { IPaginationState } from 'shared/types/common'; import { ICommunication } from 'shared/types/redux'; diff --git a/src/features/usersSearch/view/containers/UserDetails/UserDetails.tsx b/src/features/usersSearch/view/containers/UserDetails/UserDetails.tsx index 7fe76f4d..f9a17534 100644 --- a/src/features/usersSearch/view/containers/UserDetails/UserDetails.tsx +++ b/src/features/usersSearch/view/containers/UserDetails/UserDetails.tsx @@ -3,7 +3,7 @@ import block from 'bem-cn'; import { connect } from 'react-redux'; import { bind } from 'decko'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IDetailedGithubUser } from 'shared/types/models'; import { Dialog } from 'shared/view/components'; import { Typography, Preloader } from 'shared/view/elements'; diff --git a/src/features/usersSearch/view/containers/UsersSearchForm/UsersSearchForm.tsx b/src/features/usersSearch/view/containers/UsersSearchForm/UsersSearchForm.tsx index adf32585..4e1918a9 100644 --- a/src/features/usersSearch/view/containers/UsersSearchForm/UsersSearchForm.tsx +++ b/src/features/usersSearch/view/containers/UsersSearchForm/UsersSearchForm.tsx @@ -6,7 +6,7 @@ import * as R from 'ramda'; import { replaceObjectKeys, replaceObjectValues, getSelectValuesToLabelsMap, KeysToValuesFormattersMap, } from 'shared/helpers'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IUsersSearchFilters } from 'shared/types/githubSearch'; import { SearchForm } from 'shared/view/components'; diff --git a/src/features/usersSearch/view/containers/UsersSearchResults/UsersSearchResults.tsx b/src/features/usersSearch/view/containers/UsersSearchResults/UsersSearchResults.tsx index 2f9a0463..761549e3 100644 --- a/src/features/usersSearch/view/containers/UsersSearchResults/UsersSearchResults.tsx +++ b/src/features/usersSearch/view/containers/UsersSearchResults/UsersSearchResults.tsx @@ -3,7 +3,7 @@ import { connect } from 'react-redux'; import block from 'bem-cn'; import { bind } from 'decko'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { IGithubUser } from 'shared/types/models'; import { IPaginationState } from 'shared/types/common'; import { PaginationControls } from 'shared/view/components'; diff --git a/src/modules/App/view/App.tsx b/src/modules/App/view/App.tsx index 1a448ea9..4af8d48c 100644 --- a/src/modules/App/view/App.tsx +++ b/src/modules/App/view/App.tsx @@ -1,10 +1,18 @@ import React from 'react'; +import { containers as NotificationContainers } from 'services/notification'; +import { BaseStyles } from 'shared/styles'; class App extends React.Component { public render() { const { children } = this.props; - return children; + return ( + <> + + + {children} + + ); } } diff --git a/src/modules/Profile/Profile.tsx b/src/modules/Profile/Profile.tsx index f4ab3fc4..31ff5f11 100644 --- a/src/modules/Profile/Profile.tsx +++ b/src/modules/Profile/Profile.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Route } from 'react-router-dom'; +import { IModule } from 'core/types'; import routes from 'modules/routes'; -import { IModule } from 'shared/types/app'; import { ProfileLayout } from './view/components'; diff --git a/src/modules/Profile/routes.ts b/src/modules/Profile/routes.ts deleted file mode 100644 index 7ef1c3f9..00000000 --- a/src/modules/Profile/routes.ts +++ /dev/null @@ -1,5 +0,0 @@ -import buildRouteTree from 'build-route-tree'; - -export const routes = buildRouteTree({ - profile: null, -}); diff --git a/src/modules/Search/Search.tsx b/src/modules/Search/Search.tsx index 345ee138..30452585 100644 --- a/src/modules/Search/Search.tsx +++ b/src/modules/Search/Search.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; +import { IModule } from 'core/types'; import routes from 'modules/routes'; -import { IModule } from 'shared/types/app'; import { UsersSearchLayout, RepositoriesSearchLayout } from './view/components'; diff --git a/src/modules/Search/routes.ts b/src/modules/Search/routes.ts deleted file mode 100644 index 1960d4ed..00000000 --- a/src/modules/Search/routes.ts +++ /dev/null @@ -1,8 +0,0 @@ -import buildRouteTree from 'build-route-tree'; - -export const routes = buildRouteTree({ - search: { - users: null, - repositories: null, - }, -}); diff --git a/src/modules/routes.ts b/src/modules/routes.ts index 7a0abcdc..f6b786b2 100644 --- a/src/modules/routes.ts +++ b/src/modules/routes.ts @@ -1,7 +1,11 @@ -import { routes as searchRoutes } from './Search/routes'; -import { routes as profileRoutes } from './Profile/routes'; +import buildRouteTree from 'build-route-tree'; -export default { - ...searchRoutes, - ...profileRoutes, -}; +export const routes = buildRouteTree({ + profile: null, + search: { + users: null, + repositories: null, + }, +}); + +export default routes; diff --git a/src/modules/shared/Layout/Layout.tsx b/src/modules/shared/Layout/Layout.tsx index 8af9e76b..b943133f 100644 --- a/src/modules/shared/Layout/Layout.tsx +++ b/src/modules/shared/Layout/Layout.tsx @@ -5,9 +5,9 @@ import { bind } from 'decko'; import { featureConnect } from 'core'; import * as features from 'features'; +import routes from 'modules/routes'; import LayoutHeaderMenu, { IHeaderMenuItem } from './LayoutHeaderMenu/LayoutHeaderMenu'; -import routes from '../../routes'; import './Layout.scss'; interface IOwnProps { diff --git a/src/server.tsx b/src/server.tsx index 104e5104..32e9c29c 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -4,12 +4,12 @@ import React from 'react'; import bootstrapper from 'react-async-bootstrapper'; import { renderToString } from 'react-dom/server'; -import { IAssets, IAppData } from 'shared/types/app'; import { SheetsRegistry } from 'shared/styles'; import Html from 'assets/Html'; -import configureApp from 'core/configureApp'; -import { ServerApp } from 'core/App'; +import configureApp from 'core/configure'; +import { ServerApp } from 'core/render'; +import { IAssets, IAppData } from 'core/types'; async function render({ req, res, assets }: { req: express.Request; res: express.Response; assets: IAssets }) { try { @@ -48,7 +48,7 @@ async function renderOnServer(appData: IAppData, assets: IAssets, location: stri const appForBootstrap = ; await bootstrapper(appForBootstrap); const app = ; - const html = ; + const html = ; const document = ` ${renderToString(html)} @@ -57,7 +57,7 @@ async function renderOnServer(appData: IAppData, assets: IAssets, location: stri } function hydrateOnClient(appData: IAppData, assets: IAssets) { - const html = ; + const html = ; const document = ` ${renderToString(html)} diff --git a/src/services/notification/index.ts b/src/services/notification/index.ts index d0a24b67..a5e4e24a 100644 --- a/src/services/notification/index.ts +++ b/src/services/notification/index.ts @@ -1,4 +1,4 @@ -import { IReduxEntry } from 'shared/types/app'; +import { IReduxEntry } from 'core/types'; import * as namespace from './namespace'; import { actions, selectors, reducer, getSaga } from './redux'; diff --git a/src/services/notification/redux/data/selectors.ts b/src/services/notification/redux/data/selectors.ts index 6c824119..fe5e16c4 100644 --- a/src/services/notification/redux/data/selectors.ts +++ b/src/services/notification/redux/data/selectors.ts @@ -1,4 +1,4 @@ -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import * as NS from '../../namespace'; function selectServiceState(state: IAppReduxState): NS.IReduxState { diff --git a/src/services/notification/redux/sagas.ts b/src/services/notification/redux/sagas.ts index a8beeceb..131a8209 100644 --- a/src/services/notification/redux/sagas.ts +++ b/src/services/notification/redux/sagas.ts @@ -1,7 +1,7 @@ import { takeLatest, put, call, all } from 'redux-saga/effects'; import { delay } from 'redux-saga'; -import { IDependencies } from 'shared/types/app'; +import { IDependencies } from 'core/types'; import * as actions from './actions'; import * as NS from '../namespace'; diff --git a/src/services/notification/view/containers/Notification/Notification.tsx b/src/services/notification/view/containers/Notification/Notification.tsx index a601b7d8..5ac92943 100644 --- a/src/services/notification/view/containers/Notification/Notification.tsx +++ b/src/services/notification/view/containers/Notification/Notification.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { connect } from 'react-redux'; import block from 'bem-cn'; -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { INotification } from 'shared/types/common'; import { selectors } from '../../../redux'; diff --git a/src/services/theme/index.ts b/src/services/theme/index.ts index 95cb8220..2d3ff9a5 100644 --- a/src/services/theme/index.ts +++ b/src/services/theme/index.ts @@ -1,9 +1,10 @@ -import { IReduxEntry } from 'shared/types/app'; +import { IReduxEntry } from 'core/types'; import { reducer, actions, selectors } from './redux'; +import * as namespace from './namespace'; import ThemeProvider from './view/containers/ThemeProvider/ThemeProvider'; import ThemeSelector from './view/containers/ThemeSelector/ThemeSelector'; -export { ThemeProvider, ThemeSelector, actions, selectors }; +export { ThemeProvider, ThemeSelector, actions, selectors, namespace }; export const reduxEntry: IReduxEntry = { reducers: { theme: reducer }, }; diff --git a/src/services/theme/redux/selectors.ts b/src/services/theme/redux/selectors.ts index 2eaeda07..1c82fbd3 100644 --- a/src/services/theme/redux/selectors.ts +++ b/src/services/theme/redux/selectors.ts @@ -1,4 +1,4 @@ -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import * as NS from '../namespace'; function selectFeatureState(state: IAppReduxState): NS.IReduxState { diff --git a/src/services/theme/view/containers/ThemeProvider/ThemeProvider.tsx b/src/services/theme/view/containers/ThemeProvider/ThemeProvider.tsx index 009b2273..cc796c49 100644 --- a/src/services/theme/view/containers/ThemeProvider/ThemeProvider.tsx +++ b/src/services/theme/view/containers/ThemeProvider/ThemeProvider.tsx @@ -3,8 +3,8 @@ import { connect } from 'react-redux'; import { withRouter, RouteComponentProps } from 'react-router'; import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'; +import { IAppReduxState } from 'core/types'; import { Theme } from 'shared/styles'; -import { IAppReduxState } from 'shared/types/app'; import { UITheme } from '../../../namespace'; import { selectors } from '../../../redux'; diff --git a/src/services/theme/view/containers/ThemeSelector/ThemeSelector.tsx b/src/services/theme/view/containers/ThemeSelector/ThemeSelector.tsx index 825e2db1..f479e535 100644 --- a/src/services/theme/view/containers/ThemeSelector/ThemeSelector.tsx +++ b/src/services/theme/view/containers/ThemeSelector/ThemeSelector.tsx @@ -1,8 +1,7 @@ import React from 'react'; import { connect } from 'react-redux'; import { bind } from 'decko'; - -import { IAppReduxState } from 'shared/types/app'; +import { IAppReduxState } from 'core/types'; import { UITheme } from '../../../namespace'; import * as actions from './../../../redux/actions'; diff --git a/src/shared/helpers/makeFeatureEntry.ts b/src/shared/helpers/makeFeatureEntry.ts index 7c5822bc..87ebd71f 100644 --- a/src/shared/helpers/makeFeatureEntry.ts +++ b/src/shared/helpers/makeFeatureEntry.ts @@ -1,4 +1,4 @@ -import { IFeatureEntry } from '../types/app'; +import { IFeatureEntry } from 'core/types'; function makeFeatureEntry(entry: E): E { return entry; diff --git a/src/shared/mocks.ts b/src/shared/mocks.ts index 4e43ddf7..8329a2d9 100644 --- a/src/shared/mocks.ts +++ b/src/shared/mocks.ts @@ -1,7 +1,7 @@ import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { IProfile, IGithubUser, IDetailedGithubUser, IRepository } from 'shared/types/models'; -import { IFeatureEntry } from './types/app'; +import { IFeatureEntry } from 'core/types'; export const makeMockComponent = (componentName: string): any => { const Container = () => React.createElement('div'); diff --git a/src/shared/styles/BaseStyles.tsx b/src/shared/styles/BaseStyles.tsx index 905ab3d5..af3783a0 100644 --- a/src/shared/styles/BaseStyles.tsx +++ b/src/shared/styles/BaseStyles.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { rule } from 'shared/helpers/style'; import { withStyles, WithStyles } from './jss'; @@ -24,10 +23,8 @@ const styles = { type StylesProps = WithStyles; -class BaseStyles extends React.Component<{ children: React.ReactNode } & StylesProps> { - public render() { - return this.props.children; - } +function BaseStyles(_props: StylesProps) { + return null; } export default withStyles(styles)(BaseStyles); diff --git a/src/shared/types/redux.ts b/src/shared/types/redux.ts index bf89ff72..1d72201b 100644 --- a/src/shared/types/redux.ts +++ b/src/shared/types/redux.ts @@ -16,11 +16,6 @@ export interface IFailAction extends IPlainFailAction { payload: P; } -export interface IEditFieldAction { - type: T; - payload: IReduxField; -} - export interface IMultiAction { _instanceKey?: string; type: T; @@ -31,12 +26,6 @@ export interface ICommunication { error: E; } -export interface IReduxField { - value: T; - error: string; - touched?: boolean; -} - // TODO: remove export type ReducersMap = { [key in keyof T]: Reducer;