From 0e0daae389292136a4dffa537ed6b00796828c88 Mon Sep 17 00:00:00 2001 From: Nuttapat Kirawittaya Date: Wed, 1 Nov 2017 16:30:29 +0700 Subject: [PATCH 01/34] Remove unused component --- src/components/Avartar/Avartar.css | 13 ----- src/components/Avartar/Avartar.tsx | 41 -------------- src/components/Avartar/index.ts | 3 -- .../BottomFloatingButton.css | 27 ---------- .../BottomFloatingButton.tsx | 32 ----------- src/components/BottomFloatingButton/index.ts | 3 -- src/components/LanguageProvider/index.tsx | 32 ----------- .../LanguageSwitcher/LanguageSwitcher.tsx | 53 ------------------- src/components/LanguageSwitcher/index.ts | 3 -- 9 files changed, 207 deletions(-) delete mode 100644 src/components/Avartar/Avartar.css delete mode 100644 src/components/Avartar/Avartar.tsx delete mode 100644 src/components/Avartar/index.ts delete mode 100644 src/components/BottomFloatingButton/BottomFloatingButton.css delete mode 100644 src/components/BottomFloatingButton/BottomFloatingButton.tsx delete mode 100644 src/components/BottomFloatingButton/index.ts delete mode 100644 src/components/LanguageProvider/index.tsx delete mode 100644 src/components/LanguageSwitcher/LanguageSwitcher.tsx delete mode 100644 src/components/LanguageSwitcher/index.ts diff --git a/src/components/Avartar/Avartar.css b/src/components/Avartar/Avartar.css deleted file mode 100644 index 6b5b2af..0000000 --- a/src/components/Avartar/Avartar.css +++ /dev/null @@ -1,13 +0,0 @@ -.wrapper { - /*display: inline-block;*/ - position: relative; - /*overflow: hidden;*/ -} - -.circle { - border-radius: 50%; -} - -img.reponsive-img { - margin-left: -50px; -} diff --git a/src/components/Avartar/Avartar.tsx b/src/components/Avartar/Avartar.tsx deleted file mode 100644 index 6dfa514..0000000 --- a/src/components/Avartar/Avartar.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import * as cx from 'classnames'; -import withStyles from 'isomorphic-style-loader/lib/withStyles'; -import * as React from 'react'; -import * as s from './Avartar.css'; - -interface IAvatarProps { - alt?: string; - className?: string; - size?: number; - src: string; -} - -interface IDefaultStyle { - height: number; - width: number; -} - -class Avartar extends React.Component { - style: IDefaultStyle; - public constructor(props) { - super(props); - this.style = { - height: this.props.size || 200, - width: this.props.size || 200, - }; - } - public render() { - return ( -
- {this.props.alt} -
- ); - } -} - -export default withStyles(s)(Avartar); diff --git a/src/components/Avartar/index.ts b/src/components/Avartar/index.ts deleted file mode 100644 index e6e2e4a..0000000 --- a/src/components/Avartar/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import Avartar from './Avartar'; - -export default Avartar; diff --git a/src/components/BottomFloatingButton/BottomFloatingButton.css b/src/components/BottomFloatingButton/BottomFloatingButton.css deleted file mode 100644 index 4625b9b..0000000 --- a/src/components/BottomFloatingButton/BottomFloatingButton.css +++ /dev/null @@ -1,27 +0,0 @@ -.float { - & { - position: absolute; - bottom: -2rem; - right: 1.5rem; - z-index: 120; - } - &.show { - bottom: 2rem; - } - > .action-button { - display: flex; - padding: 1rem; - border-radius: 50%; - font-size: 1rem; - background-color: #5a6669; - color: #ffffff; - - cursor: pointer; - height: 56px; - width: 56px; - - user-select: none; - - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2); - } -} \ No newline at end of file diff --git a/src/components/BottomFloatingButton/BottomFloatingButton.tsx b/src/components/BottomFloatingButton/BottomFloatingButton.tsx deleted file mode 100644 index 3b4dd44..0000000 --- a/src/components/BottomFloatingButton/BottomFloatingButton.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as cx from 'classnames'; -import withStyles from 'isomorphic-style-loader/lib/withStyles'; -import * as React from 'react'; -import { Link } from 'react-router-dom'; -import * as s from './BottomFloatingButton.css'; - -interface IBottomFloatingButton extends React.Props { - show: boolean; - onClick?: React.EventHandler>; - to?: string; -} - -class BottomFloatingButton extends React.Component { - public render() { - const { show, onClick, to } = this.props; - return ( -
- { - to ? : - - {this.props.children} - - } -
- ); - } -} - -export default withStyles(s)(BottomFloatingButton); diff --git a/src/components/BottomFloatingButton/index.ts b/src/components/BottomFloatingButton/index.ts deleted file mode 100644 index 2ca8167..0000000 --- a/src/components/BottomFloatingButton/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as t from './BottomFloatingButton'; - -export default t.default; diff --git a/src/components/LanguageProvider/index.tsx b/src/components/LanguageProvider/index.tsx deleted file mode 100644 index 5c158f1..0000000 --- a/src/components/LanguageProvider/index.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import { IntlProvider } from 'react-intl'; -import { connect } from 'react-redux'; - -namespace LanguageProvider { - export interface IProps { - messages: Map; - children: React.ReactNode; - } - - export interface IConnectedState { - locale: string; - } - - export type Props = IProps & IConnectedState; -} - -const mapStateToProps = (state): LanguageProvider.IConnectedState => ({ - locale: state.intl.locale, -}); - -class LanguageProvider extends React.Component { - public render() { - return ( - - {React.Children.only(this.props.children)} - - ); - } -} - -export default connect(mapStateToProps)(LanguageProvider); diff --git a/src/components/LanguageSwitcher/LanguageSwitcher.tsx b/src/components/LanguageSwitcher/LanguageSwitcher.tsx deleted file mode 100644 index 8ace75e..0000000 --- a/src/components/LanguageSwitcher/LanguageSwitcher.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react'; -import { connect } from 'react-redux'; -import { ISetLocale, setLocale } from '../../reduxs/intl/actions'; - -namespace LanguageSwitcher { - export interface IConnectState { - currentLocale: string; - availableLocales: string[]; - } - - export interface IConnectDispatch { - setLocale({ locale: string }): ISetLocale; - } - - export type Props = IConnectState & IConnectDispatch; -} - -const LanguageSwitcher: React.StatelessComponent - = ({ currentLocale, availableLocales, setLocale: setLocale_ }) => { - const isSelected = (locale) => locale === currentLocale; - const localeDict = { - 'en-US': 'English', - 'cs-CZ': 'Česky', - }; - const localeName = (locale) => localeDict[locale] || locale; - return ( -
- {availableLocales.map((locale) => ( - - {isSelected(locale) ? ( - {localeName(locale)} - ) : ( - { - setLocale_({ locale }); - e.preventDefault(); - }} - >{localeName(locale)} - )} - {' '} - - ))} -
- ); -}; - -export default connect((state) => ({ - availableLocales: state.runtime.availableLocales, - currentLocale: state.intl.locale, -}), { - setLocale, -})(LanguageSwitcher); diff --git a/src/components/LanguageSwitcher/index.ts b/src/components/LanguageSwitcher/index.ts deleted file mode 100644 index e8e5b57..0000000 --- a/src/components/LanguageSwitcher/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import LanguageSwitcher from './LanguageSwitcher'; - -export default LanguageSwitcher; From 8b30f6c48e67dab7d9d3b9fa017ca5a27994d82f Mon Sep 17 00:00:00 2001 From: Nuttapat Kirawittaya Date: Wed, 1 Nov 2017 16:31:10 +0700 Subject: [PATCH 02/34] Remove redux --- package.json | 19 ++---- src/reduxs/configureStore.ts | 69 --------------------- src/reduxs/createHelpers.ts | 53 ---------------- src/reduxs/index.ts | 28 --------- src/reduxs/intl/actions.ts | 106 -------------------------------- src/reduxs/intl/constants.ts | 8 --- src/reduxs/intl/intl.gql | 6 -- src/reduxs/intl/reducers.ts | 59 ------------------ src/reduxs/logger.ts | 70 --------------------- src/reduxs/runtime/actions.ts | 21 ------- src/reduxs/runtime/constants.ts | 2 - src/reduxs/runtime/reducers.ts | 18 ------ src/reduxs/ui/actions.ts | 66 -------------------- src/reduxs/ui/constants.ts | 14 ----- src/reduxs/ui/reducers.ts | 101 ------------------------------ src/reduxs/user/actions.ts | 15 ----- src/reduxs/user/constants.ts | 2 - src/reduxs/user/reducers.ts | 16 ----- 18 files changed, 4 insertions(+), 669 deletions(-) delete mode 100644 src/reduxs/configureStore.ts delete mode 100644 src/reduxs/createHelpers.ts delete mode 100644 src/reduxs/index.ts delete mode 100644 src/reduxs/intl/actions.ts delete mode 100644 src/reduxs/intl/constants.ts delete mode 100644 src/reduxs/intl/intl.gql delete mode 100644 src/reduxs/intl/reducers.ts delete mode 100644 src/reduxs/logger.ts delete mode 100644 src/reduxs/runtime/actions.ts delete mode 100644 src/reduxs/runtime/constants.ts delete mode 100644 src/reduxs/runtime/reducers.ts delete mode 100644 src/reduxs/ui/actions.ts delete mode 100644 src/reduxs/ui/constants.ts delete mode 100644 src/reduxs/ui/reducers.ts delete mode 100644 src/reduxs/user/actions.ts delete mode 100644 src/reduxs/user/constants.ts delete mode 100644 src/reduxs/user/reducers.ts diff --git a/package.json b/package.json index bd6547c..b5c68ee 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,9 @@ "accept-language": "^3.0.18", "apollo-cache-inmemory": "^1.0.0", "apollo-client": "^2.0.1", + "apollo-link": "^1.0.0", "apollo-link-http": "^1.0.0", + "apollo-link-state": "^0.0.2", "apollo-server-express": "^1.2.0", "autoprefixer": "^7.1.6", "babel-polyfill": "^6.26.0", @@ -30,23 +32,18 @@ "dotenv": "^4.0.0", "express": "^4.16.2", "express-jwt": "^5.3.0", - "extend": "^3.0.1", "extract-text-webpack-plugin": "^3.0.2", - "fastclick": "^1.0.6", "fontfaceobserver": "^2.0.13", "graphql": "^0.11.7", "graphql-date": "^1.0.3", "graphql-subscriptions": "^0.5.4", "graphql-tag": "^2.5.0", "graphql-tools": "^2.6.1", - "helmet": "^3.9.0", - "immutable": "^3.8.2", "intl": "^1.2.5", "iridium": "^7.2.5", "isomorphic-fetch": "^2.2.1", "lost": "^8.2.0", "normalize.css": "^7.0.0", - "offline-plugin": "^4.8.4", "passport": "^0.4.0", "passport-facebook": "^2.1.1", "path": "^0.12.7", @@ -58,27 +55,18 @@ "react-async-component": "^1.0.2", "react-deep-force-update": "^1.1.1", "react-dom": "^16.0.0", - "react-grounding": "^0.0.3", - "react-headroom": "^2.2.2", - "react-helmet": "^5.2.0", "react-icon-base": "^2.1.1", "react-icons": "^2.2.7", "react-intl": "^2.4.0", - "react-redux": "^5.0.6", "react-router": "^4.2.0", "react-router-dom": "^4.2.2", "react-transition-group": "^2.2.1", - "redux": "^3.7.2", - "redux-logger": "^3.0.6", - "redux-thunk": "^2.1.0", - "reselect": "^3.0.1", "semantic-ui-css": "^2.2.12", "semantic-ui-react": "^0.75.1", "sequelize": "^4.20.1", "sequelize-typescript": "^0.5.0", "serialize-javascript": "^1.4.0", - "serve-favicon": "^2.4.5", - "webpack-node-externals": "^1.6.0" + "serve-favicon": "^2.4.5" }, "devDependencies": { "@types/babel-core": "^6.25.3", @@ -171,6 +159,7 @@ "webpack-dev-middleware": "^1.12.0", "webpack-dev-server": "^2.9.3", "webpack-hot-middleware": "^2.20.0", + "webpack-node-externals": "^1.6.0", "write-file-webpack-plugin": "^4.2.0" }, "scripts": { diff --git a/src/reduxs/configureStore.ts b/src/reduxs/configureStore.ts deleted file mode 100644 index 518ca7b..0000000 --- a/src/reduxs/configureStore.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { NormalizedCache } from 'apollo-cache-inmemory'; -import ApolloClient from 'apollo-client'; -import { routerMiddleware } from 'react-router-redux'; -import * as Redux from 'redux'; -import { applyMiddleware, compose, createStore } from 'redux'; -import thunk from 'redux-thunk'; -import { createReducer, injectAsyncReducer, State } from './'; -import createHelpers from './createHelpers'; -import logger from './logger'; - -interface IStore extends Redux.Store { - asyncReducers?: any; - injectAsyncReducer?: (store, name, asyncReducer) => void; -} - -interface Config { - history: any; - cookie?: any; - apolloClient: ApolloClient; - fetch: any; -} - -export function configureStore(initialState: State, config?: Config): Redux.Store { - const helpers = createHelpers(config); - const { apolloClient } = config; - - let middleware: Redux.Middleware[] = [ - // routerMiddleware(helpersConfig.history), - thunk.withExtraArgument(createHelpers(helpers)), - // apolloClient.middleware(), - ]; - - let enhancer; - - if (__DEV__) { - middleware.push(logger()); - - // https://github.com/zalmoxisus/redux-devtools-extension#redux-devtools-extension - let devToolsExtension = (f) => f; - if (process.env.BROWSER && window.devToolsExtension) { - devToolsExtension = window.devToolsExtension(); - } - - enhancer = compose(applyMiddleware(...middleware), devToolsExtension); - } else { - enhancer = applyMiddleware(...middleware); - } - - const rootReducer = createReducer({ - apolloClient, - }); - if (process.env.NODE_ENV === 'development' && process.env.BROWSER) { - middleware = [...middleware, logger]; - } - - // See https://github.com/rackt/redux/releases/tag/v3.1.0 - const store = createStore(rootReducer, initialState, enhancer); - - // Hot reload reducers (requires Webpack or Browserify HMR to be enabled) - if (__DEV__ && module.hot) { - module.hot.accept('./', () => - // Don't forget to remove `()` if you change reducers back to normal rootReducer. - // eslint-disable-next-line global-require - store.replaceReducer(require('./').createReducer({ apolloClient })), - ); - } - - return store; -} diff --git a/src/reduxs/createHelpers.ts b/src/reduxs/createHelpers.ts deleted file mode 100644 index a8bba93..0000000 --- a/src/reduxs/createHelpers.ts +++ /dev/null @@ -1,53 +0,0 @@ -const graphqlRequestDeprecatedMessage = `\`graphqlRequest\` has been deprecated. -You should use Apollo: \`client.query({ query, variables...})\` or \`client.mutate()\` -Don't forget to enclose your query to gql\`…\` tag or import *.graphql file. -See docs at http://dev.apollodata.com/core/apollo-client-api.html#ApolloClient\\.query`; - -interface IOptions { - skipCache?: boolean; -} - -function createGraphqlRequest(apolloClient) { - return async function graphqlRequest(queryOrString, variables, options: IOptions = {}) { - if (__DEV__) { - console.error(graphqlRequestDeprecatedMessage); - } - - const { skipCache } = options; - let query = queryOrString; - if (typeof queryOrString === 'string') { - const gql = await (require as any).ensure( - ['graphql-tag'], - (require) => require('graphql-tag'), - 'graphql-tag', - ); - query = gql([queryOrString]); - } - - if (skipCache) { - return apolloClient.networkInterface.query({ query, variables }); - } - - let isMutation = false; - if (query.definitions) { - isMutation = query.definitions.some((definition) => - (definition && (definition.operation === 'mutation'))); - } - if (isMutation) { - return apolloClient.mutate({ mutation: query, variables }); - } - return apolloClient.query({ query, variables }); - }; -} - -export default function createHelpers({ apolloClient, fetch, history }) { - return { - client: apolloClient, - history, - fetch, - // @deprecated('Use `client` instead') - apolloClient, - // @deprecated('Use `client.query()` or `client.mutate()` instead') - graphqlRequest: createGraphqlRequest(fetch), - }; -} diff --git a/src/reduxs/index.ts b/src/reduxs/index.ts deleted file mode 100644 index c28f8c2..0000000 --- a/src/reduxs/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { combineReducers, Dispatch } from 'redux'; -import { intlReducers, IntlState } from './intl/reducers'; -import { runtimeReducers, RuntimeState } from './runtime/reducers'; -import { uiReducers, UIState } from './ui/reducers'; -import { userReducers, UserState } from './user/reducers'; - -export interface State { - readonly user?: UserState; - readonly intl?: IntlState; - readonly runtime?: RuntimeState; - readonly ui?: UIState; - readonly apollo?: any; -} - -export function createReducer({ apolloClient }) { - return combineReducers({ - apollo: apolloClient.reducer(), - intl: intlReducers, - runtime: runtimeReducers, - user: userReducers, - ui: uiReducers, - }); -} - -export const injectAsyncReducer = (store, name, asyncReducer) => { - store.asyncReducers[name] = asyncReducer; - store.replaceReducer(createReducer(store.asyncReducers)); -}; diff --git a/src/reduxs/intl/actions.ts b/src/reduxs/intl/actions.ts deleted file mode 100644 index 4786594..0000000 --- a/src/reduxs/intl/actions.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { NormalizedCache } from 'apollo-cache-inmemory'; -import ApolloClient from 'apollo-client'; -import { IntlProvider } from 'react-intl'; -import { Dispatch } from 'react-redux'; -import { State } from '../'; -import * as constants from './constants'; -import * as queryIntl from './intl.gql'; - -interface IQueryIntl { - intl: Array<{ - id: string, - message: string, - }>; -} - -export type ISetLocale = (dispatch: Dispatch, getState: () => void, context: { - client: ApolloClient, -}) => any; - -export interface ISetLocaleStart { - type: constants.SET_LOCALE_START; - payload: { - locale: string, - }; -} - -export interface ISetLocaleSuccess { - type: constants.SET_LOCALE_SUCCESS; - payload: { - locale: string, - messages: { - [key: string]: string; - }, - }; -} - -export interface ISetLocaleError { - type: constants.SET_LOCALE_ERROR; - payload: { - locale: string, - error: Error, - }; -} - -export type IntlAction = ISetLocaleStart | ISetLocaleSuccess | ISetLocaleError; - -function getIntlFromState(state) { - const intl = (state && state.intl) || {}; - const { initialNow, locale, messages } = intl; - const localeMessages = (messages && messages[locale]) || {}; - const provider = new IntlProvider({ - initialNow, - locale, - messages: localeMessages, - defaultLocale: 'en-US', - }); - return provider.getChildContext().intl; -} - -export function getIntl() { - return (dispatch, getState) => getIntlFromState(getState()); -} - -export function setLocale({ locale }): ISetLocale { - return async (dispatch, getState, { client }) => { - dispatch({ - type: constants.SET_LOCALE_START, - payload: { - locale, - }, - }); - - try { - const { data } = await client.query({ query: queryIntl, variables: { locale }}); - const messages = data.intl.reduce((msgs, msg) => { - msgs[msg.id] = msg.message; // eslint-disable-line no-param-reassign - return msgs; - }, {}); - dispatch({ - type: constants.SET_LOCALE_SUCCESS, - payload: { - locale, - messages, - }, - }); - - // remember locale for every new request - if (process.env.BROWSER) { - const maxAge = 3650 * 24 * 3600; // 10 years in seconds - document.cookie = `lang=${locale};path=/;max-age=${maxAge}`; - } - - // return bound intl instance at the end - return getIntlFromState(getState()); - } catch (error) { - dispatch({ - type: constants.SET_LOCALE_ERROR, - payload: { - locale, - error, - }, - }); - return null; - } - }; -} diff --git a/src/reduxs/intl/constants.ts b/src/reduxs/intl/constants.ts deleted file mode 100644 index 94dcaa2..0000000 --- a/src/reduxs/intl/constants.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const SET_LOCALE_START = 'SET_LOCALE_START'; -export type SET_LOCALE_START = typeof SET_LOCALE_START; - -export const SET_LOCALE_SUCCESS = 'SET_LOCALE_SUCCESS'; -export type SET_LOCALE_SUCCESS = typeof SET_LOCALE_SUCCESS; - -export const SET_LOCALE_ERROR = 'SET_LOCALE_ERROR'; -export type SET_LOCALE_ERROR = typeof SET_LOCALE_ERROR; diff --git a/src/reduxs/intl/intl.gql b/src/reduxs/intl/intl.gql deleted file mode 100644 index e3bab4c..0000000 --- a/src/reduxs/intl/intl.gql +++ /dev/null @@ -1,6 +0,0 @@ -query ($locale:String!) { - intl (locale:$locale) { - id - message - } -} \ No newline at end of file diff --git a/src/reduxs/intl/reducers.ts b/src/reduxs/intl/reducers.ts deleted file mode 100644 index 4f8036d..0000000 --- a/src/reduxs/intl/reducers.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { IntlAction } from './actions'; -import { - SET_LOCALE_ERROR, - SET_LOCALE_START, - SET_LOCALE_SUCCESS, -} from './constants'; - -export interface IntlState { - initialNow: Date; - locale: string; - newLocale: string; - messages: { - [key: string]: { - [key: string]: string, - }, - }; -} - -export const intlReducers = function intl(state: IntlState = null, action: IntlAction) { - if (state === null) { - return { - initialNow: Date.now(), - }; - } - - switch (action.type) { - case SET_LOCALE_START: { - const locale = state[action.payload.locale] ? action.payload.locale : state.locale; - return { - ...state, - locale, - newLocale: action.payload.locale, - }; - } - - case SET_LOCALE_SUCCESS: { - return { - ...state, - locale: action.payload.locale, - newLocale: null, - messages: { - ...state.messages, - [action.payload.locale]: action.payload.messages, - }, - }; - } - - case SET_LOCALE_ERROR: { - return { - ...state, - newLocale: null, - }; - } - - default: { - return state; - } - } -}; diff --git a/src/reduxs/logger.ts b/src/reduxs/logger.ts deleted file mode 100644 index d4be088..0000000 --- a/src/reduxs/logger.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { createLogger } from 'redux-logger'; -import { inspect } from 'util'; - -function inspectObject(object) { - return inspect(object, { - colors: true, - }); -} - -function singleLine(str) { - return str.replace(/\s+/g, ' '); -} - -const actionFormatters = { - // This is used at feature/apollo branch, but it can help you when implementing Apollo - APOLLO_QUERY_INIT: (a) => - `queryId:${a.queryId} variables:${inspectObject( - a.variables, - )}\n ${singleLine(a.queryString)}`, - - APOLLO_QUERY_RESULT: (a) => - `queryId:${a.queryId}\n ${singleLine(inspectObject(a.result))}`, - - APOLLO_QUERY_STOP: (a) => `queryId:${a.queryId}`, - - SET_LOCALE_SUCCESS: (a) => - `locale ${a.payload.locale}: ${Object.keys(a.payload.messages) - .length} messages`, -}; - -let logger; -if (process.env.BROWSER) { - logger = () => { - return createLogger({ - collapsed: true, - - stateTransformer: (state) => { - return state.toJS ? state.toJS() : state; - }, - predicate: (getState, { type }) => { - return type !== 'redux-form/BLUR' && - type !== 'redux-form/CHANGE' && - type !== 'redux-form/FOCUS' && - type !== 'redux-form/TOUCH'; - }, - }); - }; -} else { - logger = () => { - return (store) => (next) => (action) => { - let formattedPayload = ''; - const actionFormatter = actionFormatters[action.type]; - if (typeof actionFormatter === 'function') { - formattedPayload = actionFormatter(action); - } else if (action.toString !== Object.prototype.toString) { - formattedPayload = action.toString(); - } else if (typeof action.payload !== 'undefined') { - formattedPayload = inspectObject(action.payload); - } else { - formattedPayload = inspectObject(action); - } - - // tslint:disable-next-line:no-console - console.log(` * ${action.type}: ${formattedPayload}`); - return next(action); - }; - }; -} - -export default logger; diff --git a/src/reduxs/runtime/actions.ts b/src/reduxs/runtime/actions.ts deleted file mode 100644 index 1ccc252..0000000 --- a/src/reduxs/runtime/actions.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { SET_RUNTIME_VARIABLE } from './constants'; - -export interface ISetRuntimeVariable { - type: SET_RUNTIME_VARIABLE; - payload: { - name: string, - value: any, - }; -} - -export type RuntimeAction = ISetRuntimeVariable; - -export function setRuntimeVariable({ name, value }): ISetRuntimeVariable { - return { - type: SET_RUNTIME_VARIABLE, - payload: { - name, - value, - }, - }; -} diff --git a/src/reduxs/runtime/constants.ts b/src/reduxs/runtime/constants.ts deleted file mode 100644 index e71858b..0000000 --- a/src/reduxs/runtime/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const SET_RUNTIME_VARIABLE = 'SET_RUNTIME_VARIABLE'; -export type SET_RUNTIME_VARIABLE = typeof SET_RUNTIME_VARIABLE; diff --git a/src/reduxs/runtime/reducers.ts b/src/reduxs/runtime/reducers.ts deleted file mode 100644 index 6686186..0000000 --- a/src/reduxs/runtime/reducers.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { RuntimeAction } from './actions'; -import { SET_RUNTIME_VARIABLE } from './constants'; - -export interface RuntimeState { - [key: string]: any; -} - -export const runtimeReducers = function runtime(state: RuntimeState = {}, action: RuntimeAction) { - switch (action.type) { - case SET_RUNTIME_VARIABLE: - return { - ...state, - [action.payload.name]: action.payload.value, - }; - default: - return state; - } -}; diff --git a/src/reduxs/ui/actions.ts b/src/reduxs/ui/actions.ts deleted file mode 100644 index 3212379..0000000 --- a/src/reduxs/ui/actions.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - LEFT_SIDEBAR_TOGGLE, - RIGHT_SIDEBAR_TOGGLE, - SET_LEFT_SIDEBAR_EXPAND, - SET_RIGHT_SIDEBAR_EXPAND, - SET_SIDEBAR_EXPAND, -} from './constants'; - -export interface ISetSidebarExpand { - type: SET_SIDEBAR_EXPAND; - payload: string; -} - -export interface IRightSidebarExpand { - type: SET_RIGHT_SIDEBAR_EXPAND; - payload: boolean; -} - -export interface IRightSidebarToggle { - type: RIGHT_SIDEBAR_TOGGLE; -} - -export interface ILeftSidebarExpand { - type: SET_LEFT_SIDEBAR_EXPAND; - payload: boolean; -} - -export interface ILeftSidebarToggle { - type: LEFT_SIDEBAR_TOGGLE; -} - -export type UIAction = ISetSidebarExpand | IRightSidebarExpand | IRightSidebarToggle - | ILeftSidebarExpand | ILeftSidebarToggle; - -export function setSidebarExpand(expand): ISetSidebarExpand { - return { - type: SET_SIDEBAR_EXPAND, - payload: expand, - }; -} - -export function rightSidebarExpand(expanded): IRightSidebarExpand { - return { - type: SET_RIGHT_SIDEBAR_EXPAND, - payload: expanded, - }; -} - -export function rightSidebarToggle(): IRightSidebarToggle { - return { - type: RIGHT_SIDEBAR_TOGGLE, - }; -} - -export function leftSidebarExpand(expanded): ILeftSidebarExpand { - return { - type: SET_LEFT_SIDEBAR_EXPAND, - payload: expanded, - }; -} - -export function leftSidebarToggle(): ILeftSidebarToggle { - return { - type: LEFT_SIDEBAR_TOGGLE, - }; -} diff --git a/src/reduxs/ui/constants.ts b/src/reduxs/ui/constants.ts deleted file mode 100644 index a59bc71..0000000 --- a/src/reduxs/ui/constants.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const SET_SIDEBAR_EXPAND = 'SET_SIDEBAR_EXPAND'; -export type SET_SIDEBAR_EXPAND = typeof SET_SIDEBAR_EXPAND; - -export const SET_RIGHT_SIDEBAR_EXPAND = 'SET_RIGHT_SIDEBAR_EXPAND'; -export type SET_RIGHT_SIDEBAR_EXPAND = typeof SET_RIGHT_SIDEBAR_EXPAND; - -export const RIGHT_SIDEBAR_TOGGLE = 'RIGHT_SIDEBAR_TOGGLE'; -export type RIGHT_SIDEBAR_TOGGLE = typeof RIGHT_SIDEBAR_TOGGLE; - -export const SET_LEFT_SIDEBAR_EXPAND = 'SET_LEFT_SIDEBAR_EXPAND'; -export type SET_LEFT_SIDEBAR_EXPAND = typeof SET_LEFT_SIDEBAR_EXPAND; - -export const LEFT_SIDEBAR_TOGGLE = 'LEFT_SIDEBAR_TOGGLE'; -export type LEFT_SIDEBAR_TOGGLE = typeof LEFT_SIDEBAR_TOGGLE; diff --git a/src/reduxs/ui/reducers.ts b/src/reduxs/ui/reducers.ts deleted file mode 100644 index 299a013..0000000 --- a/src/reduxs/ui/reducers.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { UIAction } from './actions'; -import { - LEFT_SIDEBAR_TOGGLE, - RIGHT_SIDEBAR_TOGGLE, - SET_LEFT_SIDEBAR_EXPAND, - SET_RIGHT_SIDEBAR_EXPAND, - SET_SIDEBAR_EXPAND, -} from './constants'; - -export interface UIState { - sidebar: { - expand: { - left: boolean, - right: boolean, - }; - }; -} - -export const uiReducers = function ui(state: UIState = null, action: UIAction) { - if (state === null) { - return { - floatingButton: { - to: null, - icon: null, - show: false, - }, - sidebar: { - expand: { - left: true, - right: false, - }, - }, - }; - } - - switch (action.type) { - case SET_SIDEBAR_EXPAND: { - return { - ...state, - sidebar: { - expand: { - left: action.payload === 'left', - right: action.payload === 'right', - }, - }, - }; - } - - case SET_LEFT_SIDEBAR_EXPAND: { - return { - ...state, - sidebar: { - expand: { - left: true, - right: state.sidebar.expand.right, - }, - }, - }; - } - - case LEFT_SIDEBAR_TOGGLE: { - return { - ...state, - sidebar: { - expand: { - left: true, - right: state.sidebar.expand.right, - }, - }, - }; - } - - case SET_RIGHT_SIDEBAR_EXPAND: { - return { - ...state, - sidebar: { - expand: { - left: state.sidebar.expand.left, - right: action.payload, - }, - }, - }; - } - - case RIGHT_SIDEBAR_TOGGLE: { - return { - ...state, - sidebar: { - expand: { - left: state.sidebar.expand.left, - right: !state.sidebar.expand.right, - }, - }, - }; - } - - default: { - return state; - } - } -}; diff --git a/src/reduxs/user/actions.ts b/src/reduxs/user/actions.ts deleted file mode 100644 index 49f2e5a..0000000 --- a/src/reduxs/user/actions.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Dispatch } from 'react-redux'; -import { push } from 'react-router-redux'; -import { State } from '../'; -import { SIGN_OUT } from './constants'; - -export type ISignOut = (dispatch: Dispatch) => void; - -export function signOut() { - return (dispatch) => { - dispatch({ - type: SIGN_OUT, - }); - dispatch(push('/logout')); - }; -} diff --git a/src/reduxs/user/constants.ts b/src/reduxs/user/constants.ts deleted file mode 100644 index 94e3503..0000000 --- a/src/reduxs/user/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const SIGN_OUT = 'SIGN_OUT'; -export type SIGN_OUT = typeof SIGN_OUT; diff --git a/src/reduxs/user/reducers.ts b/src/reduxs/user/reducers.ts deleted file mode 100644 index f5980b2..0000000 --- a/src/reduxs/user/reducers.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as Express from 'express'; -import { SIGN_OUT } from './constants'; - -export interface UserState { - username?: string; - email?: string; -} - -export const userReducers = function user(state: UserState = {}, action) { - switch (action.type) { - case SIGN_OUT: - return {}; - default: - return state; - } -}; From 57a3ed6f3899b9c8614763089d1dba1c6008afcc Mon Sep 17 00:00:00 2001 From: Nuttapat Kirawittaya Date: Wed, 1 Nov 2017 16:31:29 +0700 Subject: [PATCH 03/34] Update apollo v2 --- src/core/ServerLink.ts | 60 ++++++++++++++++++++++++++++++++++++++ src/local/index.ts | 24 ++++++++++++++++ src/main.client.tsx | 31 ++++++++++++-------- src/main.server.tsx | 65 ++++++++++++++++++------------------------ 4 files changed, 131 insertions(+), 49 deletions(-) create mode 100644 src/core/ServerLink.ts create mode 100644 src/local/index.ts diff --git a/src/core/ServerLink.ts b/src/core/ServerLink.ts new file mode 100644 index 0000000..9310807 --- /dev/null +++ b/src/core/ServerLink.ts @@ -0,0 +1,60 @@ +import { ApolloLink, Observable, RequestHandler } from 'apollo-link'; +import { + execute, + GraphQLSchema, + specifiedRules, + validate, +} from 'graphql'; + +interface FetchOptions { + schema: GraphQLSchema; + rootValue?: any; + context?: any; + validationRules?: any; +} + +export class ServerLink extends ApolloLink { + public schema: GraphQLSchema; + public optionsData: { + rootValue?: any, + context?: any, + validationRules?: any, + }; + + constructor(opts: FetchOptions) { + super(); + + const { schema, ...options } = opts; + this.schema = schema; + this.optionsData = options; + } + + public request(operation) { + return new Observable((observer) => { + let validationRules = specifiedRules; + const customValidationRules = this.optionsData.validationRules; + if (customValidationRules) { + validationRules = validationRules.concat(customValidationRules); + } + + const validationErrors = validate(this.schema, operation.query, validationRules); + if (validationErrors.length > 0) { + return { errors: validationErrors }; + } + + execute( + this.schema, + operation.query, + this.optionsData.rootValue, + this.optionsData.context, + operation.variables, + operation.operationName, + ) + .then((data) => { + observer.next(data); + observer.complete(); + }) + .catch(observer.error.bind(observer)); + }); + } +} diff --git a/src/local/index.ts b/src/local/index.ts new file mode 100644 index 0000000..737ea3f --- /dev/null +++ b/src/local/index.ts @@ -0,0 +1,24 @@ +import { withClientState } from 'apollo-link-state'; + +export const local = withClientState({ + Query: { + vote: (_, __, { cache }) => { + console.log(cache); + }, + locales: () => ({ + availableLocales: ['en-Us', 'th-TH'], + currentLocale: 'en-US', + }), + }, + Mutation: { + setLocale(locale: string) { + console.log(locale); + }, + upVote: (_, { id }, { cache }) => { + id = `ListItem:${id}`; + }, + downVote: (_, { id }, { cache }) => { + console.log('downVote'); + }, + }, +}); diff --git a/src/main.client.tsx b/src/main.client.tsx index c3f4354..98360ea 100644 --- a/src/main.client.tsx +++ b/src/main.client.tsx @@ -13,7 +13,7 @@ import { createPath } from 'history/PathUtils'; import * as React from 'react'; import { ApolloProvider } from 'react-apollo'; import * as ReactDOM from 'react-dom'; -import { addLocaleData } from 'react-intl'; +import { addLocaleData, IntlProvider } from 'react-intl'; /* @intl-code-template import ${lang} from 'react-intl/locale-data/${lang}'; */ import cs from 'react-intl/locale-data/cs'; import en from 'react-intl/locale-data/en'; @@ -26,14 +26,18 @@ import { ErrorReporter } from './core/devUtils'; import { updateMeta } from './core/DOMUtils'; import history from './core/history'; import createFetch from './createFetch'; -import { configureStore } from './reduxs/configureStore'; -import { getIntl } from './reduxs/intl/actions'; +import { local } from './local'; + +/* + Apollo Client v2 +*/ +const http = new HttpLink({ + uri: '/graphql', + credentials: 'include', +}); const apolloClient = createApolloClient({ - link: new HttpLink({ - uri: '/graphql', - credentials: 'include', - }), + link: local.concat(http), cache: new InMemoryCache(), ssrForceFetchDelay: 100, }); @@ -65,6 +69,13 @@ const fetch = createFetch(self.fetch, { // apolloClient, // }); +const intl = new IntlProvider({ + initialNow: Date.now(), + // locale, + messages: {}, + defaultLocale: 'en-US', +}).getChildContext().intl; + const context = { // Enables critical path CSS rendering // https://github.com/kriasoft/isomorphic-style-loader @@ -76,12 +87,8 @@ const context = { fetch, // For react-apollo client: apolloClient, - // Initialize a new Redux store - // http://redux.js.org/docs/basics/UsageWithReact.html - // store, - storeSubscription: null, // intl instance as it can be get with injectIntl - // intl: store.dispatch(getIntl()), + intl, }; // Switch off the native scroll restoration behavior and handle it manually diff --git a/src/main.server.tsx b/src/main.server.tsx index 021a6b4..e76b0bc 100644 --- a/src/main.server.tsx +++ b/src/main.server.tsx @@ -1,3 +1,4 @@ +import { InMemoryCache } from 'apollo-cache-inmemory'; import { HttpLink } from 'apollo-link-http'; import { graphiqlExpress, graphqlExpress } from 'apollo-server-express'; import * as BluebirdPromise from 'bluebird'; @@ -6,10 +7,10 @@ import * as chalk from 'chalk'; import * as cookieParser from 'cookie-parser'; import * as dotenv from 'dotenv'; import * as express from 'express'; -import { UnauthorizedError as Jwt401Error } from 'express-jwt'; // import * as expressGraphQL from 'express-graphql'; import * as expressJwt from 'express-jwt'; -import * as helmet from 'helmet'; +import { UnauthorizedError as Jwt401Error } from 'express-jwt'; +import gql from 'graphql-tag'; import * as jwt from 'jsonwebtoken'; import * as nodeFetch from 'node-fetch'; import * as path from 'path'; @@ -17,6 +18,7 @@ import * as PrettyError from 'pretty-error'; import * as React from 'react'; import { getDataFromTree } from 'react-apollo'; import * as ReactDOM from 'react-dom/server'; +import { IntlProvider } from 'react-intl'; import { Provider } from 'react-redux'; import { StaticRouter } from 'react-router'; import * as assets from './assets.json'; @@ -26,11 +28,8 @@ import { api, auth, locales, port } from './config'; import createApolloClient from './core/createApolloClient'; import passport from './core/passport'; import { requestLanguage } from './core/requestLanguage'; -import ServerInterface from './core/ServerInterface'; +import { ServerLink } from './core/ServerLink'; import createFetch from './createFetch'; -import { configureStore } from './reduxs/configureStore'; -import { setLocale } from './reduxs/intl/actions'; -import { setRuntimeVariable } from './reduxs/runtime/actions'; import Routes from './routes'; import ErrorPage from './routes/Error/ErrorPage'; import * as errorPageStyle from './routes/Error/ErrorPage.css'; @@ -140,15 +139,16 @@ app.get('/graphiql', graphiqlExpress({ endpointURL: '/graphql' })); app.get('*', async (req, res, next) => { const location = req.url; - const apolloClient = createApolloClient({ - link: new HttpLink({ - uri: '/graphql', - credentials: 'include', + const client = createApolloClient({ + link: new ServerLink({ + schema: Schema, + rootValue: { request: req }, }), // networkInterface: new ServerInterface({ // schema: Schema, // rootValue: { request: req }, // }), + cache: new InMemoryCache(), ssrMode: true, }); @@ -159,31 +159,24 @@ app.get('*', async (req, res, next) => { // apolloClient, }); - // const store = configureStore({ - // user: req.user || null, - // }, { - // history: null, - // cookie: req.headers.cookies, - // apolloClient, - // fetch, - // }); - - // store.dispatch(setRuntimeVariable({ - // name: 'initialNow', - // value: Date.now(), - // })); - - // store.dispatch(setRuntimeVariable({ - // name: 'availableLocales', - // value: locales, - // })); + const state = { + locales: { + availableLocales: locales, + }, + runtimeVariable: { + initialNow: Date.now(), + }, + }; + // Fetch locale's messages const locale = req.language; - // const intl = await store.dispatch( - // setLocale({ - // locale, - // }), - // ); + // TODO: messages: localeMessages + const intl = new IntlProvider({ + initialNow: Date.now(), + locale, + messages: {}, + defaultLocale: 'en-US', + }).getChildContext().intl; const css = new Set(); @@ -197,12 +190,10 @@ app.get('*', async (req, res, next) => { styles.forEach((style) => css.add(style._getCss())); }, fetch, - // store, - // storeSubscription: null, // Apollo Client for use with react-apollo - client: apolloClient, + client, // intl instance as it can be get with injectIntl - // intl, + intl, }; const component = ( From e46a0178c59b33e8c669ee7e0c98bf64bdd37213 Mon Sep 17 00:00:00 2001 From: Nuttapat Kirawittaya Date: Wed, 1 Nov 2017 16:31:49 +0700 Subject: [PATCH 04/34] Fix components decorators --- src/components/App/index.tsx | 53 +---- src/components/AsyncComponents/index.ts | 4 +- src/components/Header/Header.tsx | 8 +- src/components/Layout/Layout.tsx | 14 +- src/components/Layout/index.ts | 2 +- src/components/Link/index.ts | 4 +- src/components/Navigation/Navigation.tsx | 7 +- src/components/Navigation/index.ts | 4 +- src/routes/Home/Home.tsx | 17 +- src/routes/Home/async.ts | 6 +- src/routes/Home/index.ts | 2 +- src/routes/NotFound/NotFound.tsx | 2 +- src/routes/NotFound/async.ts | 4 +- src/routes/NotFound/index.ts | 2 +- tools/webpack.config.ts | 1 - yarn.lock | 275 +++-------------------- 16 files changed, 49 insertions(+), 356 deletions(-) diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 09a76af..e75f11c 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -2,19 +2,13 @@ import * as PropTypes from 'prop-types'; import * as React from 'react'; import { ApolloProvider } from 'react-apollo'; import { IntlProvider } from 'react-intl'; -import { Provider as ReduxProvider } from 'react-redux'; namespace App { export interface Context { insertCss: any; - // store: { - // subscribe: any; - // dispatch: any; - // getState: any; - // }; fetch: any; client: any; - // intl: any; + intl: any; } interface IProps extends React.Props { @@ -39,9 +33,6 @@ class App extends React.Component { insertCss: PropTypes.func.isRequired, // Universal HTTP client fetch: PropTypes.func.isRequired, - // Integrate Redux - // http://redux.js.org/docs/basics/UsageWithReact.html - ...(ReduxProvider as any).childContextTypes, // Apollo Client client: PropTypes.object.isRequired, // ReactIntl @@ -52,48 +43,6 @@ class App extends React.Component { return this.props.context; } - // public componentDidMount() { - // const store = this.props.context && this.props.context.store; - // if (store) { - // this.unsubscribe = store.subscribe(() => { - // const state = store.getState(); - // const newIntl = state.intl; - // if (this.intl !== newIntl) { - // this.intl = newIntl; - // if (__DEV__) { - // console.log('Intl changed — Force rendering'); - // } - // deepForceUpdate(this); - // } - // }); - // } - // } - - // public componentWillUnmount() { - // if (this.unsubscribe) { - // this.unsubscribe(); - // this.unsubscribe = null; - // } - // } - - // public render() { - // const store = this.props.context && this.props.context.store; - // const client = this.props.context && this.props.context.client; - // const state = store && store.getState(); - // this.intl = (state && state.intl) || {}; - // const { initialNow, locale, messages } = this.intl; - // const localeMessages = (messages && messages[locale]) || {}; - // return ( - // - // {React.Children.only(this.props.children)} - // - // ); - // } render() { // Here, we are at universe level, sure? ;-) const { client } = this.props.context; diff --git a/src/components/AsyncComponents/index.ts b/src/components/AsyncComponents/index.ts index e8be83c..dafc426 100644 --- a/src/components/AsyncComponents/index.ts +++ b/src/components/AsyncComponents/index.ts @@ -1,3 +1 @@ -import { asyncRoute } from './AsyncComponents'; - -export default asyncRoute; +export { asyncRoute as AsyncComponents } from './AsyncComponents'; diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index ef27c86..3473b40 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -1,9 +1,9 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles'; import * as React from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; -import LanguageSwitcher from '../LanguageSwitcher'; -import Link from '../Link'; -import Navigation from '../Navigation'; +// import LanguageSwitcher from '../LanguageSwitcher'; +import { Link } from '../Link'; +import { Navigation } from '../Navigation'; import * as s from './Header.css'; import * as logoUrl from './logo-small.png'; import * as logoUrl2x from './logo-small@2x.png'; @@ -39,7 +39,7 @@ export class Header extends React.Component<{}> { - + {/* */}

diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 95d7b75..3473904 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -1,8 +1,6 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles'; import * as React from 'react'; import { connect } from 'react-redux'; -import { State } from '../../reduxs'; -import { UserState } from '../../reduxs/user/reducers'; import { Header } from '../Header'; import { Main } from '../Main'; @@ -13,17 +11,9 @@ import * as s from './Layout.css'; // const MdAdd = require('react-icons/lib/md/add'); namespace Layout { - export interface IConnectState { - user: UserState; - } - - export type Props = IConnectState; + export type Props = any; } -const mapStateToProps = (state: State) => ({ - user: state.user, -}); - @withStyles(s) export class Layout extends React.Component { public render() { @@ -37,5 +27,3 @@ export class Layout extends React.Component { ); } } - -export default connect(mapStateToProps)(Layout); diff --git a/src/components/Layout/index.ts b/src/components/Layout/index.ts index 6c48fae..9fc685e 100644 --- a/src/components/Layout/index.ts +++ b/src/components/Layout/index.ts @@ -1 +1 @@ -export { default as Layout } from './Layout'; +export { Layout } from './Layout'; diff --git a/src/components/Link/index.ts b/src/components/Link/index.ts index a9936d4..61fe08c 100644 --- a/src/components/Link/index.ts +++ b/src/components/Link/index.ts @@ -1,3 +1 @@ -import { Link } from './Link'; - -export default Link; +export { Link } from './Link'; diff --git a/src/components/Navigation/Navigation.tsx b/src/components/Navigation/Navigation.tsx index 54d33f5..c8c06d7 100644 --- a/src/components/Navigation/Navigation.tsx +++ b/src/components/Navigation/Navigation.tsx @@ -3,7 +3,7 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles'; import * as React from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import * as l from '../Header/logo-small.png'; -import Link from '../Link'; +import { Link } from '../Link'; import * as s from './Navigation.css'; const messages = defineMessages({ @@ -34,7 +34,8 @@ const messages = defineMessages({ }, }); -class Navigation extends React.Component<{}> { +@withStyles(s) +export class Navigation extends React.Component<{}> { render() { return (
@@ -61,5 +62,3 @@ class Navigation extends React.Component<{}> { ); } } - -export default withStyles(s)(Navigation); diff --git a/src/components/Navigation/index.ts b/src/components/Navigation/index.ts index bb08810..61f39d1 100644 --- a/src/components/Navigation/index.ts +++ b/src/components/Navigation/index.ts @@ -1,3 +1 @@ -import Navigation from './Navigation'; - -export default Navigation; +export { Navigation } from './Navigation'; diff --git a/src/routes/Home/Home.tsx b/src/routes/Home/Home.tsx index 3f275e4..b152dfe 100644 --- a/src/routes/Home/Home.tsx +++ b/src/routes/Home/Home.tsx @@ -3,23 +3,13 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles'; import * as React from 'react'; import { connect } from 'react-redux'; import { Route } from 'react-router-dom'; -import { compose } from 'redux'; -import { State } from '../../reduxs'; -import { UserState } from '../../reduxs/user/reducers'; import * as s from './Home.css'; export namespace Home { - export interface IConnectState { - user: UserState; - } - - export type Props = IConnectState; + export type Props = any; } -const mapStateToProps = ({ user }: State) => ({ - user, -}); - +@withStyles(s) export class Home extends React.Component { public render() { return

@@ -27,6 +17,3 @@ export class Home extends React.Component {

; } } - -const WithStylesHome = withStyles(s)(Home); -export default connect(mapStateToProps)(Home); diff --git a/src/routes/Home/async.ts b/src/routes/Home/async.ts index fc8ce98..f08c046 100644 --- a/src/routes/Home/async.ts +++ b/src/routes/Home/async.ts @@ -1,5 +1,3 @@ -import AsyncComponents from '../../components/AsyncComponents'; +import { AsyncComponents } from '../../components/AsyncComponents'; -export const Home = AsyncComponents(() => { - return import('./Home'); -}); +export const Home = AsyncComponents(() => import('./Home').then((module) => module.Home)); diff --git a/src/routes/Home/index.ts b/src/routes/Home/index.ts index c2d92a5..af9c1c6 100644 --- a/src/routes/Home/index.ts +++ b/src/routes/Home/index.ts @@ -1 +1 @@ -export { default as Home } from './Home'; +export { Home } from './Home'; diff --git a/src/routes/NotFound/NotFound.tsx b/src/routes/NotFound/NotFound.tsx index e863d3a..e394a07 100644 --- a/src/routes/NotFound/NotFound.tsx +++ b/src/routes/NotFound/NotFound.tsx @@ -5,7 +5,7 @@ interface INotFound extends React.Props { title: string; } -export default class NotFound extends React.Component { +export class NotFound extends React.Component { constructor(props) { super(props); } diff --git a/src/routes/NotFound/async.ts b/src/routes/NotFound/async.ts index 4dad689..b9275fa 100644 --- a/src/routes/NotFound/async.ts +++ b/src/routes/NotFound/async.ts @@ -1,3 +1,3 @@ -import AsyncComponents from '../../components/AsyncComponents'; +import { AsyncComponents } from '../../components/AsyncComponents'; -export const NotFound = AsyncComponents(() => import('./NotFound')); +export const NotFound = AsyncComponents(() => import('./NotFound').then((module) => module.NotFound)); diff --git a/src/routes/NotFound/index.ts b/src/routes/NotFound/index.ts index 4d20aa9..1099c21 100644 --- a/src/routes/NotFound/index.ts +++ b/src/routes/NotFound/index.ts @@ -1 +1 @@ -export { default as NotFound } from './NotFound'; +export { NotFound } from './NotFound'; diff --git a/tools/webpack.config.ts b/tools/webpack.config.ts index 6ba1546..48577b4 100644 --- a/tools/webpack.config.ts +++ b/tools/webpack.config.ts @@ -1,7 +1,6 @@ import * as AssetsPlugin from 'assets-webpack-plugin'; // import { CheckerPlugin, TsConfigPathsPlugin } from 'awesome-typescript-loader'; import * as cssnano from 'cssnano'; -import * as extend from 'extend'; import * as ExtractTextPlugin from 'extract-text-webpack-plugin'; import * as path from 'path'; import * as webpack from 'webpack'; diff --git a/yarn.lock b/yarn.lock index 6a87c3e..4fe622f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -304,10 +304,10 @@ redux "^3.6.0" "@types/redux-thunk@^2.1.0": - version "2.1.32" - resolved "https://registry.yarnpkg.com/@types/redux-thunk/-/redux-thunk-2.1.32.tgz#27fac368ced9ea170bf15e5fa4a21d9201f73102" + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/redux-thunk/-/redux-thunk-2.1.0.tgz#bc2b6e972961831afb82a9bf4f06726e351f9416" dependencies: - redux "^3.6.0" + redux-thunk "*" "@types/reflect-metadata@0.0.4": version "0.0.4" @@ -525,6 +525,13 @@ apollo-link-http@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.0.0.tgz#0450be89ae7e080722383c302f07135d364bc749" +apollo-link-state@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/apollo-link-state/-/apollo-link-state-0.0.2.tgz#c1debee2c756a3b0fc5e00d2ce6f1279928be035" + dependencies: + apollo-utilities "^1.0.1" + graphql-anywhere "^4.0.0" + apollo-link@1.0.0, apollo-link@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.0.0.tgz#3d334285789c217f95712ebce434d56ce7f3e991" @@ -565,7 +572,7 @@ apollo-utilities@^0.2.0-beta.0: version "0.2.0-rc.0" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-0.2.0-rc.0.tgz#5ac93a839c5688e8f655dc7d5789a5d878f4351f" -apollo-utilities@^1.0.0: +apollo-utilities@^1.0.0, apollo-utilities@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.1.tgz#34b4df0bd6ed71d0afaa7c62489173dca5d07e92" @@ -1935,10 +1942,6 @@ camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" -camelize@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" - caniuse-api@^1.5.2: version "1.6.1" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" @@ -2009,10 +2012,6 @@ chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" -change-emitter@^0.1.2: - version "0.1.6" - resolved "https://registry.yarnpkg.com/change-emitter/-/change-emitter-0.1.6.tgz#e8b2fe3d7f1ab7d69a32199aff91ea6931409515" - chokidar@1.7.0, chokidar@^1.6.0, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -2250,12 +2249,6 @@ content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" -content-security-policy-builder@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/content-security-policy-builder/-/content-security-policy-builder-1.1.0.tgz#d91f1b076236c119850c7dee9924bf55e05772b3" - dependencies: - dashify "^0.2.0" - content-type@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" @@ -2520,14 +2513,6 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -dasherize@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dasherize/-/dasherize-2.0.0.tgz#6d809c9cd0cf7bb8952d80fc84fa13d47ddb1308" - -dashify@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/dashify/-/dashify-0.2.2.tgz#6a07415a01c91faf4a32e38d9dfba71f61cb20fe" - date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" @@ -2588,15 +2573,11 @@ decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" -deep-diff@^0.3.5: - version "0.3.8" - resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" - deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" -deep-extend@^0.4.0, deep-extend@~0.4.0: +deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" @@ -2709,10 +2690,6 @@ dns-packet@^1.0.1: ip "^1.1.0" safe-buffer "^5.0.1" -dns-prefetch-control@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz#60ddb457774e178f1f9415f0cabb0e85b0b300b2" - dns-txt@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" @@ -2771,10 +2748,6 @@ domutils@1.5.1: dom-serializer "0" domelementtype "1" -dont-sniff-mimetype@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz#5932890dc9f4e2f19e5eb02a20026e5e5efc8f58" - dotenv@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" @@ -2816,10 +2789,6 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -ejs@^2.3.4: - version "2.5.6" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88" - ejs@^2.5.6: version "2.5.7" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" @@ -3110,10 +3079,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -exenv@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" - expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -3144,10 +3109,6 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expect-ct@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.1.0.tgz#52735678de18530890d8d7b95f0ac63640958094" - express-jwt@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/express-jwt/-/express-jwt-5.3.0.tgz#3d90cd65802e6336252f19e6a3df3e149e0c5ea0" @@ -3277,7 +3238,7 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" -extend@^3.0.1, extend@~3.0.0: +extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -3325,10 +3286,6 @@ fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" -fastclick@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/fastclick/-/fastclick-1.0.6.tgz#161625b27b1a5806405936bda9a2c1926d06be6a" - fastparse@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" @@ -3345,9 +3302,9 @@ faye-websocket@~0.11.0: dependencies: websocket-driver ">=0.5.1" -fbjs@^0.8.1, fbjs@^0.8.9: - version "0.8.12" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04" +fbjs@^0.8.16: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" dependencies: core-js "^1.0.0" isomorphic-fetch "^2.1.1" @@ -3357,9 +3314,9 @@ fbjs@^0.8.1, fbjs@^0.8.9: setimmediate "^1.0.5" ua-parser-js "^0.7.9" -fbjs@^0.8.16: - version "0.8.16" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" +fbjs@^0.8.9: + version "0.8.12" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04" dependencies: core-js "^1.0.0" isomorphic-fetch "^2.1.1" @@ -3542,10 +3499,6 @@ fragment-cache@^0.2.0, fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -frameguard@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/frameguard/-/frameguard-3.0.0.tgz#7bcad469ee7b96e91d12ceb3959c78235a9272e9" - fresh@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" @@ -3867,37 +3820,6 @@ hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" -helmet-csp@2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/helmet-csp/-/helmet-csp-2.6.0.tgz#c1f5595afbc5f83e5f1e6c15f842f07a10f6ea04" - dependencies: - camelize "1.0.0" - content-security-policy-builder "1.1.0" - dasherize "2.0.0" - lodash.reduce "4.6.0" - platform "1.3.4" - -helmet@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/helmet/-/helmet-3.9.0.tgz#7b2cf015a2d109bca83ede7924420799c0e67dee" - dependencies: - dns-prefetch-control "0.1.0" - dont-sniff-mimetype "1.0.0" - expect-ct "0.1.0" - frameguard "3.0.0" - helmet-csp "2.6.0" - hide-powered-by "1.0.0" - hpkp "2.0.0" - hsts "2.1.0" - ienoopen "1.0.0" - nocache "2.0.0" - referrer-policy "1.1.0" - x-xss-protection "1.0.0" - -hide-powered-by@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hide-powered-by/-/hide-powered-by-1.0.0.tgz#4a85ad65881f62857fc70af7174a1184dccce32b" - history@^4.7.2: version "4.7.2" resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b" @@ -3920,15 +3842,11 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" -hoist-non-react-statics@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" - hoist-non-react-statics@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.2.0.tgz#b099ca82f3640b1244309c8a526a2bd60ad9d7d9" -hoist-non-react-statics@^2.2.1, hoist-non-react-statics@^2.2.2, hoist-non-react-statics@^2.3.0: +hoist-non-react-statics@^2.2.2, hoist-non-react-statics@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0" @@ -3958,14 +3876,6 @@ hpack.js@^2.1.6: readable-stream "^2.0.1" wbuf "^1.1.0" -hpkp@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hpkp/-/hpkp-2.0.0.tgz#10e142264e76215a5d30c44ec43de64dee6d1672" - -hsts@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hsts/-/hsts-2.1.0.tgz#cbd6c918a2385fee1dd5680bfb2b3a194c0121cc" - html-comment-regex@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" @@ -4070,18 +3980,10 @@ ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" -ienoopen@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ienoopen/-/ienoopen-1.0.0.tgz#346a428f474aac8f50cf3784ea2d0f16f62bda6b" - immutable@3.8.1, immutable@^3.7.6: version "3.8.1" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2" -immutable@^3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" - import-local@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8" @@ -4187,7 +4089,7 @@ intl@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde" -invariant@^2.0.0, invariant@^2.1.1, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2: +invariant@^2.1.1, invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" dependencies: @@ -4694,7 +4596,7 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@0.2.x, loader-utils@^0.2.16: +loader-utils@^0.2.16: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: @@ -4727,7 +4629,7 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash-es@^4.2.0, lodash-es@^4.2.1: +lodash-es@^4.2.1: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" @@ -4822,7 +4724,7 @@ lodash.istypedarray@^3.0.0: version "3.0.6" resolved "https://registry.yarnpkg.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz#c9a477498607501d8e8494d283b87c39281cef62" -lodash.keys@^3.0.0, lodash.keys@^3.1.2: +lodash.keys@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" dependencies: @@ -4869,10 +4771,6 @@ lodash.pick@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" -lodash.reduce@4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" - lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" @@ -5119,7 +5017,7 @@ minimatch@3.0.3: dependencies: brace-expansion "^1.0.0" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: @@ -5242,10 +5140,6 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" -nocache@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.0.0.tgz#202b48021a0c4cbde2df80de15a17443c8b43980" - node-fetch@^1.0.1: version "1.7.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.1.tgz#899cb3d0a3c92f952c47f1b876f4c8aeabd400d5" @@ -5473,16 +5367,6 @@ obuf@^1.0.0, obuf@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e" -offline-plugin@^4.8.4: - version "4.8.4" - resolved "https://registry.yarnpkg.com/offline-plugin/-/offline-plugin-4.8.4.tgz#1084c59f6606bded5ee5a6bf6208e2b9f5bdd339" - dependencies: - deep-extend "^0.4.0" - ejs "^2.3.4" - loader-utils "0.2.x" - minimatch "^3.0.3" - slash "^1.0.0" - on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -5759,10 +5643,6 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -5795,10 +5675,6 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" -platform@1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.4.tgz#6f0fb17edaaa48f21442b3a975c063130f1c3ebd" - pleeease-filters@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pleeease-filters/-/pleeease-filters-4.0.0.tgz#6632b2fb05648d2758d865384fbced79e1ccaec7" @@ -6400,12 +6276,6 @@ querystringify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" -raf@^3.3.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/raf/-/raf-3.3.2.tgz#0c13be0b5b49b46f76d6669248d527cf2b02fe27" - dependencies: - performance-now "^2.1.0" - randomatic@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" @@ -6504,38 +6374,6 @@ react-error-overlay@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-3.0.0.tgz#c2bc8f4d91f1375b3dad6d75265d51cd5eeaf655" -react-grounding@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/react-grounding/-/react-grounding-0.0.3.tgz#de0c44bae45546cf7f50df41b74c57d39a0bfd5b" - dependencies: - react-headroom "^2.1.0" - recompose "^0.20.2" - -react-headroom@^2.1.0: - version "2.1.6" - resolved "https://registry.yarnpkg.com/react-headroom/-/react-headroom-2.1.6.tgz#637a5323d77845120dd41cc0aaadbf4786ed674a" - dependencies: - prop-types "^15.5.8" - raf "^3.3.0" - shallowequal "^0.2.2" - -react-headroom@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/react-headroom/-/react-headroom-2.2.2.tgz#5ddea3bc87cd54be38f6f98c3fde4527e2a5fb0f" - dependencies: - prop-types "^15.5.8" - raf "^3.3.0" - shallowequal "^0.2.2" - -react-helmet@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-5.2.0.tgz#a81811df21313a6d55c5f058c4aeba5d6f3d97a7" - dependencies: - deep-equal "^1.0.1" - object-assign "^4.1.1" - prop-types "^15.5.4" - react-side-effect "^1.1.0" - react-hot-loader@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-3.1.1.tgz#e06db8cd0841c41e3ab0b395b2b774126fc8914e" @@ -6575,17 +6413,6 @@ react-proxy@^3.0.0-alpha.0: dependencies: lodash "^4.6.1" -react-redux@^5.0.6: - version "5.0.6" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.0.6.tgz#23ed3a4f986359d68b5212eaaa681e60d6574946" - dependencies: - hoist-non-react-statics "^2.2.1" - invariant "^2.0.0" - lodash "^4.2.0" - lodash-es "^4.2.0" - loose-envify "^1.1.0" - prop-types "^15.5.10" - react-router-dom@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d" @@ -6609,13 +6436,6 @@ react-router@^4.2.0: prop-types "^15.5.4" warning "^3.0.0" -react-side-effect@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.1.3.tgz#512c25abe0dec172834c4001ec5c51e04d41bc5c" - dependencies: - exenv "^1.2.1" - shallowequal "^1.0.1" - react-transition-group@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10" @@ -6714,15 +6534,6 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" -recompose@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/recompose/-/recompose-0.20.2.tgz#113d6ac7e29ca664cfffec16b681ddddf15250bc" - dependencies: - change-emitter "^0.1.2" - fbjs "^0.8.1" - hoist-non-react-statics "^1.0.0" - symbol-observable "^0.2.4" - recursive-readdir@2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.1.tgz#90ef231d0778c5ce093c9a48d74e5c5422d13a99" @@ -6766,17 +6577,11 @@ reduce-function-call@^1.0.1: dependencies: balanced-match "^0.4.2" -redux-logger@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf" - dependencies: - deep-diff "^0.3.5" - -redux-thunk@^2.1.0: +redux-thunk@*: version "2.2.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.2.0.tgz#e615a16e16b47a19a515766133d1e3e99b7852e5" -redux@^3.6.0, redux@^3.7.2: +redux@^3.6.0: version "3.7.2" resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b" dependencies: @@ -6785,10 +6590,6 @@ redux@^3.6.0, redux@^3.7.2: loose-envify "^1.1.0" symbol-observable "^1.0.3" -referrer-policy@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.1.0.tgz#35774eb735bf50fb6c078e83334b472350207d79" - regenerate@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" @@ -6938,10 +6739,6 @@ requires-port@1.0.x, requires-port@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" -reselect@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" - resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -7360,16 +7157,6 @@ shallow-clone@^0.1.2: lazy-cache "^0.2.3" mixin-object "^2.0.1" -shallowequal@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-0.2.2.tgz#1e32fd5bcab6ad688a4812cb0cc04efc75c7014e" - dependencies: - lodash.keys "^3.1.2" - -shallowequal@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.0.2.tgz#1561dbdefb8c01408100319085764da3fcf83f8f" - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -7798,10 +7585,6 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" -symbol-observable@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" - symbol-observable@^1.0.2, symbol-observable@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" @@ -8488,10 +8271,6 @@ wtf-8@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a" -x-xss-protection@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/x-xss-protection/-/x-xss-protection-1.0.0.tgz#898afb93869b24661cf9c52f9ee8db8ed0764dd9" - xmlhttprequest-ssl@1.5.3: version "1.5.3" resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz#185a888c04eca46c3e4070d99f7b49de3528992d" From ac9b4734a9a8318f003de5c21ae1a7260b93dcec Mon Sep 17 00:00:00 2001 From: Nuttapat Kirawittaya Date: Mon, 22 Jan 2018 15:35:31 +0700 Subject: [PATCH 05/34] Update from mms-bunnoi project --- package.json | 8 +- seeds/mongo-seed.ts | 14 + src/Global.d.ts | 21 +- src/apollo/index.ts | 37 ++ src/apollo/intl/IntlQuery.gql | 6 + src/apollo/intl/LocaleQuery.gql | 5 + src/apollo/intl/SetLocaleMutation.gql | 3 + src/apollo/intl/index.ts | 72 +++ src/components/App/index.tsx | 73 ++- src/components/Html/index.tsx | 8 +- src/components/Layout/Layout.tsx | 4 - src/components/Main/Main.css | 11 - src/components/variables.css | 14 - src/config.ts | 16 +- src/core/ServerInterface.ts | 43 -- src/core/ServerLink.ts | 33 +- src/core/UnionInputType.ts | 201 ++++++++ src/core/createApolloClient.ts | 26 - src/core/requestLanguage.ts | 117 ----- src/createFetch.ts | 39 -- src/local/index.ts | 24 - src/main.client.tsx | 105 ++-- src/main.server.tsx | 257 ++++++---- src/main.socket.ts | 55 ++ src/routes/index.tsx | 9 - src/schema/index.ts | 4 +- src/schema/models/index.ts | 2 +- src/schema/schema.gql | 3 +- src/schema/types/Mutation/resolver.ts | 49 ++ src/schema/types/Mutation/typeDef.gql | 11 + src/schema/types/Subscription/index.ts | 7 + src/schema/types/Subscription/resolver.ts | 24 + src/schema/types/Subscription/typeDef.gql | 4 + src/schema/types/index.ts | 17 +- src/schema/types/pubsub.ts | 12 + tools/deploy.ts | 125 +++++ tools/jest.preprocessor.js | 36 -- tools/lib/cp.ts | 24 + tools/lib/fs.ts | 23 +- tools/postcss.config.js | 2 + tools/seeds.ts | 13 + tools/start.ts | 72 ++- tools/webpack.config.ts | 128 +++-- yarn.lock | 583 +++++++++++++++------- 44 files changed, 1607 insertions(+), 733 deletions(-) create mode 100644 seeds/mongo-seed.ts create mode 100644 src/apollo/index.ts create mode 100644 src/apollo/intl/IntlQuery.gql create mode 100644 src/apollo/intl/LocaleQuery.gql create mode 100644 src/apollo/intl/SetLocaleMutation.gql create mode 100644 src/apollo/intl/index.ts delete mode 100644 src/core/ServerInterface.ts create mode 100644 src/core/UnionInputType.ts delete mode 100644 src/core/createApolloClient.ts delete mode 100644 src/core/requestLanguage.ts delete mode 100644 src/createFetch.ts delete mode 100644 src/local/index.ts create mode 100644 src/main.socket.ts create mode 100644 src/schema/types/Subscription/index.ts create mode 100644 src/schema/types/Subscription/resolver.ts create mode 100644 src/schema/types/Subscription/typeDef.gql create mode 100644 src/schema/types/pubsub.ts create mode 100644 tools/deploy.ts delete mode 100644 tools/jest.preprocessor.js create mode 100644 tools/lib/cp.ts create mode 100644 tools/seeds.ts diff --git a/package.json b/package.json index b5c68ee..36a217c 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,10 @@ "apollo-link": "^1.0.0", "apollo-link-http": "^1.0.0", "apollo-link-state": "^0.0.2", + "apollo-link-ws": "^1.0.4", "apollo-server-express": "^1.2.0", + "apollo-upload-client": "^7.0.0-alpha.3", + "apollo-upload-server": "^4.0.0-alpha.3", "autoprefixer": "^7.1.6", "babel-polyfill": "^6.26.0", "bcp47": "^1.1.2", @@ -32,10 +35,12 @@ "dotenv": "^4.0.0", "express": "^4.16.2", "express-jwt": "^5.3.0", + "express-request-language": "^1.1.15", "extract-text-webpack-plugin": "^3.0.2", "fontfaceobserver": "^2.0.13", "graphql": "^0.11.7", "graphql-date": "^1.0.3", + "graphql-redis-subscriptions": "^1.4.0", "graphql-subscriptions": "^0.5.4", "graphql-tag": "^2.5.0", "graphql-tools": "^2.6.1", @@ -66,7 +71,8 @@ "sequelize": "^4.20.1", "sequelize-typescript": "^0.5.0", "serialize-javascript": "^1.4.0", - "serve-favicon": "^2.4.5" + "serve-favicon": "^2.4.5", + "subscriptions-transport-ws": "^0.9.5" }, "devDependencies": { "@types/babel-core": "^6.25.3", diff --git a/seeds/mongo-seed.ts b/seeds/mongo-seed.ts new file mode 100644 index 0000000..f5f6d8e --- /dev/null +++ b/seeds/mongo-seed.ts @@ -0,0 +1,14 @@ +import generate from 'babel-generator'; +import { ObjectID as id } from 'mongodb'; +import { Database } from '../src/schema/models'; +// tslint:disable-next-line:no-var-requires +const m = require('casual'); + +// Pass generator as callback +const array_of = (times, generator) => { + return Array.apply(null, Array(times)).map(() => generator()); +}; +export async function seed(database: Database) { + // Clear database + await database.connection.dropDatabase(); +} diff --git a/src/Global.d.ts b/src/Global.d.ts index a53422a..3984233 100644 --- a/src/Global.d.ts +++ b/src/Global.d.ts @@ -11,7 +11,6 @@ declare var __DEV__: boolean; declare interface Window { // A hack for the Redux DevTools Chrome extension. - __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: (f: F) => F; __INITIAL_STATE__?: any; __APOLLO_STATE__?: any; devToolsExtension?: any; @@ -20,7 +19,7 @@ declare interface Window { RSK_ENTRY: any; App: { apiUrl: string, - state: any, + apollo: any, lang: string, }; } @@ -39,10 +38,10 @@ declare module 'gaze' { export = _; } -// tslint:disable-next-line -// interface ObjectConstructor { -// assign(target: any, ...sources: any[]): any; -// } +declare module 'gaze' { + const _: any; + export = _; +} declare module '*.gql' { const _: DocumentNode; @@ -59,6 +58,11 @@ declare module '*.css' { export = _; } +declare module '*.scss' { + const _: any; + export = _; +} + declare module '*.jpg' { const _: any; export = _; @@ -69,6 +73,11 @@ declare module '*.png' { export = _; } +declare module '*.svg' { + const _: any; + export = _; +} + declare module 'isomorphic-style-loader/lib/withStyles' { export declare type CompositeComponent

= React.ComponentClass

| React.StatelessComponent

; // export interface ComponentDecorator { diff --git a/src/apollo/index.ts b/src/apollo/index.ts new file mode 100644 index 0000000..aee0c5c --- /dev/null +++ b/src/apollo/index.ts @@ -0,0 +1,37 @@ +import { ApolloCache } from 'apollo-cache'; +import { InMemoryCache } from 'apollo-cache-inmemory/lib/inMemoryCache'; +import { ApolloClient } from 'apollo-client'; +import { ApolloLink } from 'apollo-link'; +import { withClientState } from 'apollo-link-state'; +import { state as intl } from './intl'; + +interface IOptions { + link: ApolloLink; + ssrMode?: boolean; + cache: ApolloCache; + ssrForceFetchDelay?: number; +} + +export const createApolloClient = ({ link, ...options }: IOptions) => { + const update = (query, updater) => (result, variables, { cache }: { cache: InMemoryCache }) => { + const data = updater(cache.readQuery({ query, variables }), variables); + cache.writeQuery({ query, variables, data }); + return null; + }; + const local = withClientState({ + Query: { + todos: () => [], + ...intl.Query, + }, + Mutation: { + ...intl.Mutation, + }, + }); + + const client = new ApolloClient({ + ...options, + link: local.concat(link), + }); + + return client; +}; diff --git a/src/apollo/intl/IntlQuery.gql b/src/apollo/intl/IntlQuery.gql new file mode 100644 index 0000000..e2e008b --- /dev/null +++ b/src/apollo/intl/IntlQuery.gql @@ -0,0 +1,6 @@ +query intl ($locale:String!) { + intl (locale:$locale) { + id + message + } +} diff --git a/src/apollo/intl/LocaleQuery.gql b/src/apollo/intl/LocaleQuery.gql new file mode 100644 index 0000000..f4a376b --- /dev/null +++ b/src/apollo/intl/LocaleQuery.gql @@ -0,0 +1,5 @@ +query locale { + locale @client + initialNow @client + availableLocales @client +} diff --git a/src/apollo/intl/SetLocaleMutation.gql b/src/apollo/intl/SetLocaleMutation.gql new file mode 100644 index 0000000..aa55b98 --- /dev/null +++ b/src/apollo/intl/SetLocaleMutation.gql @@ -0,0 +1,3 @@ +mutation SetLocale($locale: String) { + setLocale(locale: $locale) @client +} \ No newline at end of file diff --git a/src/apollo/intl/index.ts b/src/apollo/intl/index.ts new file mode 100644 index 0000000..6e805b1 --- /dev/null +++ b/src/apollo/intl/index.ts @@ -0,0 +1,72 @@ +import { InMemoryCache } from 'apollo-cache-inmemory'; +import { ApolloClient } from 'apollo-client'; +import { IntlProvider } from 'react-intl'; +import * as INTLQUERY from './IntlQuery.gql'; +import * as LOCALEQUERY from './LocaleQuery.gql'; +import * as SETLOCALEMUTATION from './SetLocaleMutation.gql'; + +export interface IntlQuery { + intl: Array<{ + id: string; + message: string; + }>; +} + +export interface LocaleQuery { + locale: string; + initialNow: number; + availableLocales: string[]; +} + +export function getIntlContext(cache: InMemoryCache) { + const { locale, initialNow } = cache.readQuery({ query: LOCALEQUERY }); + const { intl } = cache.readQuery({ + query: INTLQUERY, + variables: { locale }, + }); + + const messages = intl.reduce((msgs, msg) => { + msgs[msg.id] = msg.message; + return msgs; + }, {}); + + const provider = new IntlProvider({ + initialNow, + locale, + messages, + defaultLocale: 'en-US', + }); + + return provider.getChildContext().intl; +} + +export function setLocale(client: ApolloClient) { + client.watchQuery({ query: LOCALEQUERY }).subscribe({ + next: ({ data }) => { + const { locale } = data; + client.mutate({ mutation: SETLOCALEMUTATION, variables: { locale } }); + }, + }); +} + +export const state = { + Query: { + locale: () => 'en-US', + initialNow: () => Date.now(), + }, + Mutation: { + setLocale(result, variables, { cache }: { cache: InMemoryCache }) { + const { locale } = variables; + const { availableLocales, initialNow } = cache.readQuery({ query: LOCALEQUERY }); + + cache.writeQuery({ query: LOCALEQUERY, variables, data: { locale, initialNow, availableLocales } }); + + if (process.env.BROWSER) { + const maxAge = 3650 * 24 * 3600; // 10 years in seconds + document.cookie = `lang=${locale};path=/;max-age=${maxAge}`; + } + + return null; + }, + }, +}; diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index e75f11c..905ff4b 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -1,13 +1,17 @@ +import { ApolloClient } from 'apollo-client'; import * as PropTypes from 'prop-types'; import * as React from 'react'; import { ApolloProvider } from 'react-apollo'; import { IntlProvider } from 'react-intl'; +import { IntlQuery, LocaleQuery } from '../../apollo/intl'; +import * as INTLQUERY from '../../apollo/intl/IntlQuery.gql'; +import * as LOCALEQUERY from '../../apollo/intl/LocaleQuery.gql'; namespace App { export interface Context { + // TODO: define type insertCss: any; - fetch: any; - client: any; + client: ApolloClient; intl: any; } @@ -16,6 +20,11 @@ namespace App { } export type Props = IProps; + + export interface State { + // TODO: define type + intl: any; + } } class App extends React.Component { @@ -27,12 +36,18 @@ class App extends React.Component { messages?: string, }; + constructor(props) { + super(props); + + this.state = { + intl: props.context.intl, + }; + } + static childContextTypes = { // Enables critical path CSS rendering // https://github.com/kriasoft/isomorphic-style-loader insertCss: PropTypes.func.isRequired, - // Universal HTTP client - fetch: PropTypes.func.isRequired, // Apollo Client client: PropTypes.object.isRequired, // ReactIntl @@ -40,14 +55,56 @@ class App extends React.Component { }; public getChildContext() { - return this.props.context; + return { + ...this.props.context, + ...this.state, + }; + } + + public componentDidMount() { + const s = this.setState.bind(this); + const { client } = this.props.context; + + this.unsubscribe = client.watchQuery({ + query: LOCALEQUERY, + }).subscribe({ + next({ data }) { + const { locale, initialNow } = data; + // TODO: fetchPolicy network-only to manage some way + client.query({ + query: INTLQUERY, + variables: { locale }, + fetchPolicy: 'network-only', + }) + .then(({ data: x }) => { + const messages = x.intl.reduce((msgs, msg) => { + msgs[msg.id] = msg.message; + return msgs; + }, {}); + + s({ + intl: new IntlProvider({ + initialNow, + locale, + messages, + defaultLocale: 'en-US', + }).getChildContext().intl, + }); + }); + }, + }).unsubscribe; + } + + public componentWillUnmount() { + if (this.unsubscribe) { + this.unsubscribe(); + this.unsubscribe = null; + } } render() { - // Here, we are at universe level, sure? ;-) const { client } = this.props.context; - // NOTE: If you need to add or modify header, footer etc. of the app, - // please do that inside the Layout component. + return ( {this.props.children} diff --git a/src/components/Html/index.tsx b/src/components/Html/index.tsx index 7c97f96..ab2f358 100644 --- a/src/components/Html/index.tsx +++ b/src/components/Html/index.tsx @@ -13,7 +13,7 @@ export namespace Html { scripts?: string[]; app: { apiUrl?: string, - // state?: any, + apollo?: any, lang: string, }; children: string; @@ -22,7 +22,7 @@ export namespace Html { } export class Html extends React.Component { - render() { + public render() { const { title, description, styles, scripts, app, children } = this.props; return ( @@ -34,7 +34,7 @@ export class Html extends React.Component { - {scripts.map((script) => + {scripts && scripts.map((script) => , )} @@ -51,7 +51,7 @@ export class Html extends React.Component {