diff --git a/babel.config.js b/babel.config.js index 9666cf3..3665a32 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,9 +1,14 @@ /* eslint-env node */ module.exports = { presets: [ + [ + '@babel/preset-typescript', + { + allowDeclareFields: true, + }, + ], '@babel/preset-react', - '@babel/preset-typescript', - ['@babel/preset-env'], + '@babel/preset-env', ], plugins: [ '@babel/plugin-syntax-dynamic-import', diff --git a/package.json b/package.json index c8d6468..9c42f5d 100644 --- a/package.json +++ b/package.json @@ -88,8 +88,8 @@ }, "dependencies": {}, "devDependencies": { - "@babel/cli": "^7.7.4", - "@babel/core": "^7.7.4", + "@babel/cli": "^7.7.5", + "@babel/core": "^7.7.5", "@babel/node": "^7.7.4", "@babel/plugin-proposal-class-properties": "^7.7.4", "@babel/plugin-proposal-decorators": "^7.7.4", @@ -102,16 +102,16 @@ "@babel/plugin-proposal-logical-assignment-operators": "^7.7.4", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4", "@babel/plugin-proposal-numeric-separator": "^7.7.4", - "@babel/plugin-proposal-optional-chaining": "^7.7.4", + "@babel/plugin-proposal-optional-chaining": "^7.7.5", "@babel/plugin-proposal-pipeline-operator": "^7.7.4", "@babel/plugin-proposal-throw-expressions": "^7.7.4", "@babel/plugin-syntax-dynamic-import": "^7.7.4", "@babel/plugin-syntax-import-meta": "^7.7.4", - "@babel/plugin-transform-runtime": "^7.7.4", - "@babel/preset-env": "^7.7.4", + "@babel/plugin-transform-runtime": "^7.7.6", + "@babel/preset-env": "^7.7.6", "@babel/preset-react": "^7.7.4", "@babel/preset-typescript": "^7.7.4", - "@babel/runtime-corejs3": "^7.7.4", + "@babel/runtime-corejs3": "^7.7.6", "@storybook/addon-actions": "^5.2.8", "@storybook/addon-links": "^5.2.8", "@storybook/addon-viewport": "^5.2.8", @@ -123,7 +123,7 @@ "@typescript-eslint/parser": "^2.9.0", "babel-loader": "^8.0.0", "babel-plugin-react-intl": "^5.1.8", - "core-js": "3.4.3", + "core-js": "3.5.0", "csp-webpack-plugin": "^2.0.2", "css-loader": "^3.2.0", "cssnano": "^4.1.10", @@ -159,7 +159,7 @@ "sitemap-webpack-plugin": "^0.6.0", "speed-measure-webpack-plugin": "^1.3.1", "style-loader": "^1.0.0", - "typescript": "^3.7.2", + "typescript": "^3.7.3", "unexpected": "^11.8.1", "unexpected-sinon": "^10.5.1", "url-loader": "^2.2.0", diff --git a/packages/app/components/profile/Context.tsx b/packages/app/components/profile/Context.tsx new file mode 100644 index 0000000..bfe41ab --- /dev/null +++ b/packages/app/components/profile/Context.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { FormModel } from 'app/components/ui/form'; + +export interface ProfileContext { + userId: number; + onSubmit: (options: { + form: FormModel; + sendData: () => Promise; + }) => Promise; + goToProfile: () => Promise; +} + +const Context = React.createContext({ + userId: 0, + async onSubmit() {}, + async goToProfile() {}, +}); +Context.displayName = 'ProfileContext'; + +export const { Provider, Consumer } = Context; + +export default Context; diff --git a/packages/app/components/profile/multiFactorAuth/MfaDisable.tsx b/packages/app/components/profile/multiFactorAuth/MfaDisable.tsx index f6bd921..c9730b6 100644 --- a/packages/app/components/profile/multiFactorAuth/MfaDisable.tsx +++ b/packages/app/components/profile/multiFactorAuth/MfaDisable.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import PropTypes from 'prop-types'; import logger from 'app/services/logger'; import { disable as disableMFA } from 'app/services/api/mfa'; import { FormModel } from 'app/components/ui/form'; +import Context from '../Context'; import MfaDisableForm from './disableForm/MfaDisableForm'; import MfaStatus from './status/MfaStatus'; @@ -16,9 +16,8 @@ export default class MfaDisable extends React.Component< showForm: boolean; } > { - static contextTypes = { - userId: PropTypes.number.isRequired, - }; + static contextType = Context; + /* TODO: use declare */ context: React.ContextType; state = { showForm: false, diff --git a/packages/app/components/profile/multiFactorAuth/MfaEnable.tsx b/packages/app/components/profile/multiFactorAuth/MfaEnable.tsx index 9c290d8..2f818f0 100644 --- a/packages/app/components/profile/multiFactorAuth/MfaEnable.tsx +++ b/packages/app/components/profile/multiFactorAuth/MfaEnable.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { Button, FormModel } from 'app/components/ui/form'; import styles from 'app/components/profile/profileForm.scss'; import Stepper from 'app/components/ui/stepper'; @@ -9,6 +8,7 @@ import logger from 'app/services/logger'; import { getSecret, enable as enableMFA } from 'app/services/api/mfa'; import { Form } from 'app/components/ui/form'; +import Context from '../Context'; import Instructions from './instructions'; import KeyForm from './keyForm'; import Confirmation from './confirmation'; @@ -33,15 +33,14 @@ interface State { } export default class MfaEnable extends React.PureComponent { + static contextType = Context; + /* TODO: use declare */ context: React.ContextType; + static defaultProps = { confirmationForm: new FormModel(), step: 0, }; - static contextTypes = { - userId: PropTypes.number.isRequired, - }; - state = { isLoading: false, activeStep: this.props.step, diff --git a/packages/app/pages/profile/ChangeEmailPage.tsx b/packages/app/pages/profile/ChangeEmailPage.tsx index 11fa38b..6804989 100644 --- a/packages/app/pages/profile/ChangeEmailPage.tsx +++ b/packages/app/pages/profile/ChangeEmailPage.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { RouteComponentProps, Redirect } from 'react-router-dom'; import FormModel from 'app/components/ui/form/FormModel'; @@ -12,6 +11,7 @@ import { confirmNewEmail, } from 'app/services/api/accounts'; import { RootState } from 'app/reducers'; +import Context from 'app/components/profile/Context'; interface RouteParams { step: 'step1' | 'step2' | 'step3'; @@ -24,11 +24,8 @@ interface Props extends RouteComponentProps { } class ChangeEmailPage extends React.Component { - static contextTypes = { - userId: PropTypes.number.isRequired, - onSubmit: PropTypes.func.isRequired, - goToProfile: PropTypes.func.isRequired, - }; + static contextType = Context; + /* TODO: use declare */ context: React.ContextType; render() { const { step = 'step1', code } = this.props.match.params; diff --git a/packages/app/pages/profile/ChangePasswordPage.tsx b/packages/app/pages/profile/ChangePasswordPage.tsx index d2769fb..03b087a 100644 --- a/packages/app/pages/profile/ChangePasswordPage.tsx +++ b/packages/app/pages/profile/ChangePasswordPage.tsx @@ -1,24 +1,19 @@ import React from 'react'; import { connect } from 'react-redux'; -import PropTypes from 'prop-types'; import { changePassword } from 'app/services/api/accounts'; import { FormModel } from 'app/components/ui/form'; import ChangePassword from 'app/components/profile/changePassword/ChangePassword'; import { User } from 'app/components/user'; import { updateUser } from 'app/components/user/actions'; +import Context from 'app/components/profile/Context'; -type OwnProps = {}; - -type Props = OwnProps & { +interface Props { updateUser: (fields: Partial) => void; -}; +} class ChangePasswordPage extends React.Component { - static contextTypes = { - userId: PropTypes.number.isRequired, - onSubmit: PropTypes.func.isRequired, - goToProfile: PropTypes.func.isRequired, - }; + static contextType = Context; + /* TODO: use declare */ context: React.ContextType; form = new FormModel(); diff --git a/packages/app/pages/profile/ChangeUsernamePage.tsx b/packages/app/pages/profile/ChangeUsernamePage.tsx index 08e1e75..723d0c2 100644 --- a/packages/app/pages/profile/ChangeUsernamePage.tsx +++ b/packages/app/pages/profile/ChangeUsernamePage.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React from 'react'; import { connect } from 'react-redux'; import { updateUser } from 'app/components/user/actions'; @@ -6,6 +5,7 @@ import { RootState } from 'app/reducers'; import { changeUsername } from 'app/services/api/accounts'; import { FormModel } from 'app/components/ui/form'; import ChangeUsername from 'app/components/profile/changeUsername/ChangeUsername'; +import Context from 'app/components/profile/Context'; type Props = { username: string; @@ -13,11 +13,8 @@ type Props = { }; class ChangeUsernamePage extends React.Component { - static contextTypes = { - userId: PropTypes.number.isRequired, - onSubmit: PropTypes.func.isRequired, - goToProfile: PropTypes.func.isRequired, - }; + static contextType = Context; + /* TODO: use declare */ context: React.ContextType; form = new FormModel(); diff --git a/packages/app/pages/profile/MultiFactorAuthPage.tsx b/packages/app/pages/profile/MultiFactorAuthPage.tsx index cc2f299..6fd0b11 100644 --- a/packages/app/pages/profile/MultiFactorAuthPage.tsx +++ b/packages/app/pages/profile/MultiFactorAuthPage.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { RouteComponentProps, Redirect } from 'react-router-dom'; -import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import MultiFactorAuth, { MfaStep, @@ -8,6 +7,7 @@ import MultiFactorAuth, { import { FormModel } from 'app/components/ui/form'; import { User } from 'app/components/user'; import { RootState } from 'app/reducers'; +import Context from 'app/components/profile/Context'; interface Props extends RouteComponentProps<{ @@ -17,10 +17,8 @@ interface Props } class MultiFactorAuthPage extends React.Component { - static contextTypes = { - onSubmit: PropTypes.func.isRequired, - goToProfile: PropTypes.func.isRequired, - }; + static contextType = Context; + /* TODO: use declare */ context: React.ContextType; render() { const { diff --git a/packages/app/pages/profile/ProfilePage.tsx b/packages/app/pages/profile/ProfilePage.tsx index 6a2cbe5..5af588b 100644 --- a/packages/app/pages/profile/ProfilePage.tsx +++ b/packages/app/pages/profile/ProfilePage.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { Route, Switch, Redirect } from 'react-router-dom'; import { connect } from 'react-redux'; import { fetchUserData } from 'app/components/user/actions'; @@ -15,6 +14,7 @@ import ChangeEmailPage from 'app/pages/profile/ChangeEmailPage'; import MultiFactorAuthPage from 'app/pages/profile/MultiFactorAuthPage'; import { FormModel } from 'app/components/ui/form'; import { RootState } from 'app/reducers'; +import { Provider } from 'app/components/profile/Context'; import styles from './profile.scss'; @@ -23,61 +23,61 @@ interface Props { onSubmit: (options: { form: FormModel; sendData: () => Promise; - }) => void; + }) => Promise; fetchUserData: () => Promise; } class ProfilePage extends React.Component { - static childContextTypes = { - userId: PropTypes.number, - onSubmit: PropTypes.func, - goToProfile: PropTypes.func, - }; - - getChildContext() { - return { - userId: this.props.userId, - onSubmit: this.props.onSubmit, - goToProfile: () => this.props.fetchUserData().then(this.goToProfile), - }; - } - render() { + const { userId, onSubmit } = this.props; + return (
- - - - - - - - - - + + + + + + + + + + + -
- -
+
+ +
+
); } - goToProfile = () => browserHistory.push('/'); + goToProfile = async () => { + await this.props.fetchUserData(); + + browserHistory.push('/'); + }; } export default connect( diff --git a/yarn.lock b/yarn.lock index a3471b8..e88c551 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@babel/cli@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.7.4.tgz#38804334c8db40209f88c69a5c90998e60cca18b" - integrity sha512-O7mmzaWdm+VabWQmxuM8hqNrWGGihN83KfhPUzp2lAW4kzIMwBxujXkZbD4fMwKMYY9FXTbDvXsJqU+5XHXi4A== +"@babel/cli@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.7.5.tgz#25702cc65418efc06989af3727897b9f4c8690b6" + integrity sha512-y2YrMGXM3NUyu1Myg0pxg+Lx6g8XhEyvLHYNRwTBV6fDek3H7Io6b7N/LXscLs4HWn4HxMdy7f2rM1rTMp2mFg== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" @@ -32,7 +32,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@7.7.4", "@babel/core@^7.1.0", "@babel/core@^7.7.4": +"@babel/core@7.7.4", "@babel/core@^7.1.0": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.4.tgz#37e864532200cb6b50ee9a4045f5f817840166ab" integrity sha512-+bYbx56j4nYBmpsWtnPUsKW3NdnYxbqyfrP2w9wILBuHzdfIKz9prieZK0DFPyIzkjYVUe4QkusGL07r5pXznQ== @@ -52,7 +52,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.0.0", "@babel/core@^7.0.1", "@babel/core@^7.4.5": +"@babel/core@^7.0.0", "@babel/core@^7.0.1", "@babel/core@^7.4.5", "@babel/core@^7.7.5": version "7.7.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.5.tgz#ae1323cd035b5160293307f50647e83f8ba62f7e" integrity sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw== @@ -508,7 +508,7 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-catch-binding" "^7.7.4" -"@babel/plugin-proposal-optional-chaining@7.7.4", "@babel/plugin-proposal-optional-chaining@^7.7.4": +"@babel/plugin-proposal-optional-chaining@7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.7.4.tgz#3f04c2de1a942cbd3008324df8144b9cbc0ca0ba" integrity sha512-JmgaS+ygAWDR/STPe3/7y0lNlHgS+19qZ9aC06nYLwQ/XB7c0q5Xs+ksFU3EDnp9EiEsO0dnRAOKeyLHTZuW3A== @@ -516,6 +516,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-syntax-optional-chaining" "^7.7.4" +"@babel/plugin-proposal-optional-chaining@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.7.5.tgz#f0835f044cef85b31071a924010a2a390add11d4" + integrity sha512-sOwFqT8JSchtJeDD+CjmWCaiFoLxY4Ps7NjvwHC/U7l4e9i5pTRNt8nDMIFSOUL+ncFbYSwruHM8WknYItWdXw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-chaining" "^7.7.4" + "@babel/plugin-proposal-pipeline-operator@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.7.4.tgz#d61724b4f207b0a7c08e9182e8e36fda2d93e384" @@ -967,7 +975,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-runtime@7.7.4", "@babel/plugin-transform-runtime@^7.7.4": +"@babel/plugin-transform-runtime@7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.4.tgz#51fe458c1c1fa98a8b07934f4ed38b6cd62177a6" integrity sha512-O8kSkS5fP74Ad/8pfsCMGa8sBRdLxYoSReaARRNSz3FbFQj3z/QUvoUmJ28gn9BO93YfnXc3j+Xyaqe8cKDNBQ== @@ -977,6 +985,16 @@ resolve "^1.8.1" semver "^5.5.1" +"@babel/plugin-transform-runtime@^7.7.6": + version "7.7.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.7.6.tgz#4f2b548c88922fb98ec1c242afd4733ee3e12f61" + integrity sha512-tajQY+YmXR7JjTwRvwL4HePqoL3DYxpYXIHKVvrOIvJmeHe2y1w4tz5qz9ObUDC9m76rCzIMPyn4eERuwA4a4A== + dependencies: + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-plugin-utils" "^7.0.0" + resolve "^1.8.1" + semver "^5.5.1" + "@babel/plugin-transform-shorthand-properties@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.7.4.tgz#74a0a9b2f6d67a684c6fbfd5f0458eb7ba99891e" @@ -1031,7 +1049,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/preset-env@7.7.4", "@babel/preset-env@^7.7.4": +"@babel/preset-env@7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.4.tgz#ccaf309ae8d1ee2409c85a4e2b5e280ceee830f8" integrity sha512-Dg+ciGJjwvC1NIe/DGblMbcGq1HOtKbw8RLl4nIjlfcILKEOkWT/vRqPpumswABEBVudii6dnVwrBtzD7ibm4g== @@ -1145,7 +1163,7 @@ js-levenshtein "^1.1.3" semver "^5.5.0" -"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.7.1": +"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.7.1", "@babel/preset-env@^7.7.6": version "7.7.6" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.6.tgz#39ac600427bbb94eec6b27953f1dfa1d64d457b2" integrity sha512-k5hO17iF/Q7tR9Jv8PdNBZWYW6RofxhnxKjBMc0nG4JTaWvOTiPoO/RLFwAKcA4FpmuBFm6jkoqaRJLGi0zdaQ== @@ -1240,10 +1258,10 @@ pirates "^4.0.0" source-map-support "^0.5.16" -"@babel/runtime-corejs3@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.7.4.tgz#f861adc1cecb9903dfd66ea97917f02ff8d79888" - integrity sha512-BBIEhzk8McXDcB3IbOi8zQPzzINUp4zcLesVlBSOcyGhzPUU8Xezk5GAG7Sy5GVhGmAO0zGd2qRSeY2g4Obqxw== +"@babel/runtime-corejs3@^7.7.6": + version "7.7.6" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.7.6.tgz#5b1044ea11b659d288f77190e19c62da959ed9a3" + integrity sha512-NrRUehqG0sMSCaP+0XV/vOvvjNl4BQOWq3Qys1Q2KTEm5tGMo9h0dHnIzeKerj0a7SIB8LP5kYg/T1raE3FoKQ== dependencies: core-js-pure "^3.0.0" regenerator-runtime "^0.13.2" @@ -4721,10 +4739,10 @@ core-js-pure@^3.0.1: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.4.8.tgz#a4415834383784e81974cd34321daf36a6d2366e" integrity sha512-K9iPNbLDZ0Epojwd8J3lhodmrLHYvxb07H3DaFme1ne4TIlFq/ufiyPC40rc3OX6NCaVa0zaSu+VV6BVDR2wiA== -core-js@3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.4.3.tgz#09ea102412a368d5f73d24f082e41ac90c633a49" - integrity sha512-BVvHidX8uAmLCYPfLpXTEex7jz1uZJ1mW+shhIsBdA716O8Fg6TOwSgenSyO/bvEtnGdOTpKRZPSh4bSVI1k9w== +core-js@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.5.0.tgz#66df8e49be4bd775e6f952a9d083b756ad41c1ed" + integrity sha512-Ifh3kj78gzQ7NAoJXeTu+XwzDld0QRIwjBLRqAMhuLhP3d2Av5wmgE9ycfnvK6NAEjTkQ1sDPeoEZAWO3Hx1Uw== core-js@^1.0.0: version "1.2.7" @@ -14370,10 +14388,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb" - integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ== +typescript@^3.7.3: + version "3.7.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.3.tgz#b36840668a16458a7025b9eabfad11b66ab85c69" + integrity sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw== ua-parser-js@^0.7.18: version "0.7.20"