diff --git a/packages/cra-template-typescript/template.json b/packages/cra-template-typescript/template.json
index bdff039e051..9fbaa1796b8 100644
--- a/packages/cra-template-typescript/template.json
+++ b/packages/cra-template-typescript/template.json
@@ -39,6 +39,7 @@
"react-redux": "7.x",
"react-router-dom": "5.x",
"redux": "4.x",
+ "redux-promise-listener": "1.x",
"redux-saga": "1.x",
"redux-sentry-middleware": "0.x",
"reselect": "4.x"
diff --git a/packages/cra-template-typescript/template/src/modules/auth/components/Login.tsx b/packages/cra-template-typescript/template/src/modules/auth/components/Login.tsx
index aef49c844b5..ca0a100ef6f 100644
--- a/packages/cra-template-typescript/template/src/modules/auth/components/Login.tsx
+++ b/packages/cra-template-typescript/template/src/modules/auth/components/Login.tsx
@@ -1,5 +1,5 @@
import firewall from '../HOC/firewall';
-import LoginForm from '../containers/LoginForm';
+import LoginForm from './LoginForm';
import AuthContent from './AuthContent';
export default firewall(AuthContent, LoginForm);
diff --git a/packages/cra-template-typescript/template/src/modules/auth/components/LoginForm.tsx b/packages/cra-template-typescript/template/src/modules/auth/components/LoginForm.tsx
index 42200cb6919..76739d33bbf 100644
--- a/packages/cra-template-typescript/template/src/modules/auth/components/LoginForm.tsx
+++ b/packages/cra-template-typescript/template/src/modules/auth/components/LoginForm.tsx
@@ -1,43 +1,61 @@
-import React from "react";
-import { Form } from "redux-form";
-import { Button } from "antd";
-import { TextField } from "@ackee/mateus";
-import { FormattedMessage } from "react-intl";
-
-interface LoginFormProps {
- handleSubmit: () => void;
- submitting: boolean;
- error?: string;
-}
-
-function LoginForm({ handleSubmit, submitting, error = '' }: LoginFormProps) {
+import React from 'react';
+import { FormattedMessage, useIntl } from 'react-intl';
+import { Form, Field } from 'react-final-form';
+
+import { useSubmitForm, validatorsWithMessage, composeValidators, translate } from 'modules/form';
+
+import { types } from '../services/actions';
+import { LoginFormField } from '../types';
+
+const { required, email } = validatorsWithMessage;
+
+const validators = {
+ [LoginFormField.EMAIL]: composeValidators(required, email),
+ [LoginFormField.PASSWORD]: required,
+};
+
+const LoginForm = () => {
+ const { formatMessage } = useIntl();
+ const onSubmit = useSubmitForm(types.login);
+
return (
-
+
+ )}
+ />
);
-}
+};
export default LoginForm;
diff --git a/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/LoginForm.ts b/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/LoginForm.ts
deleted file mode 100644
index 74873a36f08..00000000000
--- a/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/LoginForm.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { compose } from "redux";
-import { reduxForm } from "redux-form";
-import { connect } from "react-redux";
-import { injectIntl } from "react-intl";
-import { submitForm } from "@ackee/mateus";
-
-import config from "config";
-
-import LoginForm from '../../components/LoginForm';
-import { loginForm } from '../../services/actions';
-
-import validate from './LoginForm.validate';
-
-export default compose>(
- connect(null, {
- // TODO: bug in @ackee/mateus types - loginForm is action crater not an actual action
- // @ts-ignore
- onSubmit: submitForm(config.forms.login, loginForm),
- }),
- injectIntl,
- reduxForm({
- form: config.forms.login,
- validate,
- }),
-)(LoginForm);
diff --git a/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/LoginForm.validate.ts b/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/LoginForm.validate.ts
deleted file mode 100644
index 89a038de639..00000000000
--- a/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/LoginForm.validate.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { LoginFormField } from "../../config";
-import type { LoginFormValues } from "../../config";
-
-export default function validate(values: LoginFormValues, { intl }) {
- const errors: Partial> = {};
-
- if (!values.email) {
- errors.email = 'Required';
- }
- if (!values.password) {
- errors.password = 'Required';
- }
-
- return errors;
-}
diff --git a/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/index.ts b/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/index.ts
deleted file mode 100644
index 1195444e543..00000000000
--- a/packages/cra-template-typescript/template/src/modules/auth/containers/LoginForm/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './LoginForm';
diff --git a/packages/cra-template-typescript/template/src/modules/auth/services/actions/index.ts b/packages/cra-template-typescript/template/src/modules/auth/services/actions/index.ts
index 6c4b578eff3..d94388ea77b 100644
--- a/packages/cra-template-typescript/template/src/modules/auth/services/actions/index.ts
+++ b/packages/cra-template-typescript/template/src/modules/auth/services/actions/index.ts
@@ -1,2 +1,5 @@
-export { default as types } from './types';
-export * from './login';
+import * as types from './types';
+
+export { default as login } from './login';
+
+export { types };
diff --git a/packages/cra-template-typescript/template/src/modules/auth/services/actions/login.ts b/packages/cra-template-typescript/template/src/modules/auth/services/actions/login.ts
index 0fea3ecfe46..1a1300e51c3 100644
--- a/packages/cra-template-typescript/template/src/modules/auth/services/actions/login.ts
+++ b/packages/cra-template-typescript/template/src/modules/auth/services/actions/login.ts
@@ -1,5 +1,5 @@
-import types from './types';
+import { createFormActions } from 'react-final-form-redux-submit';
-export const loginForm = () => ({
- type: types.LOGIN_FORM,
-});
+import { login as loginTypes } from './types';
+
+export default createFormActions(loginTypes);
diff --git a/packages/cra-template-typescript/template/src/modules/auth/services/actions/types.ts b/packages/cra-template-typescript/template/src/modules/auth/services/actions/types.ts
index 9333a2f2ed9..61df17d7450 100644
--- a/packages/cra-template-typescript/template/src/modules/auth/services/actions/types.ts
+++ b/packages/cra-template-typescript/template/src/modules/auth/services/actions/types.ts
@@ -1,11 +1,3 @@
-import { createAsyncType } from "@ackee/redux-utils";
+import { createFormActionTypes } from 'react-final-form-redux-submit';
-const asyncType = createAsyncType({
- modulePrefix: 'auth',
-});
-
-export default {
- ...asyncType({
- types: ['LOGIN_FORM'],
- }),
-};
+export const login = createFormActionTypes('LOGIN_FORM');
diff --git a/packages/cra-template-typescript/template/src/modules/auth/services/sagas/loginForm.ts b/packages/cra-template-typescript/template/src/modules/auth/services/sagas/loginForm.ts
index 9a9dbd6dfa9..ca1a263af79 100644
--- a/packages/cra-template-typescript/template/src/modules/auth/services/sagas/loginForm.ts
+++ b/packages/cra-template-typescript/template/src/modules/auth/services/sagas/loginForm.ts
@@ -1,28 +1,21 @@
-import * as Petrus from "@ackee/petrus";
-import * as sagaEffects from "redux-saga/effects";
+import { LOGIN_SUCCESS, LOGIN_FAILURE, loginRequest } from '@ackee/petrus';
+import { put, take, takeLeading } from 'redux-saga/effects';
-import { types } from '../actions';
+import { types, login } from '../actions';
-const { put, take, takeEvery } = sagaEffects;
+function* handleLoginForm(action: ReturnType) {
+ yield put(loginRequest(action.payload));
-function* handleLoginForm(action) {
- yield action.startSubmit();
+ const result = yield take([LOGIN_SUCCESS, LOGIN_FAILURE]);
- yield put(Petrus.loginRequest(action.data));
-
- const result = yield take([Petrus.LOGIN_SUCCESS, Petrus.LOGIN_FAILURE]);
-
- let payload;
-
- if (result.type === Petrus.LOGIN_FAILURE) {
- payload = {
- _error: 'Login failed',
- };
+ if (result.type === LOGIN_SUCCESS) {
+ yield put(login.submitSuccess());
+ } else {
+ console.error(result.error);
+ yield put(login.submitFailure('login.failed'));
}
-
- yield action.stopSubmit(payload);
}
-export default function*() {
- yield takeEvery(types.LOGIN_FORM, handleLoginForm);
+export default function* () {
+ yield takeLeading(types.login.SUBMIT, handleLoginForm);
}
diff --git a/packages/cra-template-typescript/template/src/modules/auth/types.ts b/packages/cra-template-typescript/template/src/modules/auth/types.ts
index d69153282db..a301a04f4cd 100644
--- a/packages/cra-template-typescript/template/src/modules/auth/types.ts
+++ b/packages/cra-template-typescript/template/src/modules/auth/types.ts
@@ -1,5 +1,10 @@
-export type User = {email: string};
+export type User = { email: string };
export interface PetrusEntitiesState {
user: null | User;
-}
\ No newline at end of file
+}
+
+export enum LoginFormField {
+ EMAIL = 'email',
+ PASSWORD = 'password',
+}
diff --git a/packages/cra-template-typescript/template/src/modules/core/modules/redux/config/enhancer.ts b/packages/cra-template-typescript/template/src/modules/core/modules/redux/config/enhancer.ts
index 1f12e06e47d..67bce094633 100644
--- a/packages/cra-template-typescript/template/src/modules/core/modules/redux/config/enhancer.ts
+++ b/packages/cra-template-typescript/template/src/modules/core/modules/redux/config/enhancer.ts
@@ -1,9 +1,5 @@
import { applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga';
-// TODO: replace with use-form-module
-// @use-auth-module-begin
-import createReduxPromiseListener from 'redux-promise-listener';
-// @use-auth-module-end
import { routerMiddlewareWithHistory } from 'modules/core/modules/router';
import { sentryMiddleware } from 'modules/core/modules/sentry';
@@ -13,16 +9,16 @@ import * as Log from 'config/loglevel';
import * as Consts from 'constants/index';
import type { StoreEnhancer } from 'redux';
+// @use-form-module-begin
+import promiseListener from './promiseListener';
+// @use-form-module-end
+
declare global {
interface Window {
__REDUX_DEVTOOLS_EXTENSION__: any;
}
}
-// @use-auth-module-begin
-export const promiseListener = createReduxPromiseListener();
-// @use-auth-module-end
-
export default function configureEnhancer() {
const sagaMiddleware = createSagaMiddleware({
onError: Log.error,
@@ -31,9 +27,9 @@ export default function configureEnhancer() {
const middlewares = [
routerMiddlewareWithHistory,
sagaMiddleware,
- // @use-auth-module-begin
+ // @use-form-module-begin
promiseListener.middleware,
- // @use-auth-module-end
+ // @use-form-module-end
sentryMiddleware,
];
const enhancerArgs = [applyMiddleware(...middlewares)];
diff --git a/packages/cra-template-typescript/template/src/modules/core/modules/redux/config/promiseListener.ts b/packages/cra-template-typescript/template/src/modules/core/modules/redux/config/promiseListener.ts
new file mode 100644
index 00000000000..86ae354011f
--- /dev/null
+++ b/packages/cra-template-typescript/template/src/modules/core/modules/redux/config/promiseListener.ts
@@ -0,0 +1,5 @@
+// @use-form-module-begin
+import createReduxPromiseListener from 'redux-promise-listener';
+
+export default createReduxPromiseListener();
+// @use-form-module-end
diff --git a/packages/cra-template-typescript/template/src/modules/form/hooks/useSubmitForm.ts b/packages/cra-template-typescript/template/src/modules/form/hooks/useSubmitForm.ts
index 6755169c5b5..c1fdb9fc537 100644
--- a/packages/cra-template-typescript/template/src/modules/form/hooks/useSubmitForm.ts
+++ b/packages/cra-template-typescript/template/src/modules/form/hooks/useSubmitForm.ts
@@ -1,5 +1,5 @@
import { createSubmitFormHook } from 'react-final-form-redux-submit';
-import { promiseListener } from 'modules/core/modules/redux';
+import promiseListener from 'modules/core/modules/redux/config/promiseListener';
const useSubmitForm = createSubmitFormHook(promiseListener);
diff --git a/packages/cra-template-typescript/template/src/services/reducers/index.ts b/packages/cra-template-typescript/template/src/services/reducers/index.ts
index b4796a44298..7ade5ba41c6 100644
--- a/packages/cra-template-typescript/template/src/services/reducers/index.ts
+++ b/packages/cra-template-typescript/template/src/services/reducers/index.ts
@@ -1,4 +1,3 @@
-import { reducer as formReducer } from 'redux-form';
// @use-auth-module-begin
import { reducer as auth } from 'modules/auth';
// @use-auth-module-end
@@ -10,7 +9,6 @@ const reducers = {
// @use-auth-module-begin
auth,
// @use-auth-module-end
- form: formReducer,
};
export default reducers;
diff --git a/packages/cra-template-typescript/template/src/services/sagas/index.ts b/packages/cra-template-typescript/template/src/services/sagas/index.ts
index d5e55f265c5..0e46e5e9bb7 100644
--- a/packages/cra-template-typescript/template/src/services/sagas/index.ts
+++ b/packages/cra-template-typescript/template/src/services/sagas/index.ts
@@ -1,6 +1,5 @@
import { all } from 'redux-saga/effects';
-import { submitFormSaga } from '@ackee/mateus';
// @use-auth-module-begin
import { saga as auth } from 'modules/auth';
// @use-auth-module-end
@@ -10,6 +9,5 @@ export default function* appSaga() {
// @use-auth-module-begin
auth(),
// @use-auth-module-end
- submitFormSaga(),
]);
}
diff --git a/packages/react-scripts/custom/scripts/init/useAuthModule/applyAnswer.js b/packages/react-scripts/custom/scripts/init/useAuthModule/applyAnswer.js
index cdb4dd50f54..93101e43bb3 100644
--- a/packages/react-scripts/custom/scripts/init/useAuthModule/applyAnswer.js
+++ b/packages/react-scripts/custom/scripts/init/useAuthModule/applyAnswer.js
@@ -21,7 +21,7 @@ const createPrettierFormatter = async templatePath => {
}
const mergedOptions = {
- parser: 'babel',
+ parser: 'typescript',
...options,
};
@@ -29,9 +29,9 @@ const createPrettierFormatter = async templatePath => {
};
// {/* ... */} or // ...
-const BEGIN = /(\/\/|\{\/\*) @use-auth-module-begin(\s\*\/}$)?/gm;
-const END = /(\/\/|\{\/\*) @use-auth-module-end(\s\*\/}$)?/gm;
-const BEGIN_OR_END = /(\/\/|\{\/\*) @use-auth-module-(begin|end)(\s\*\/}$)?/gm;
+const BEGIN = /(\/\/|\{\/\*) @use-(auth|form)-module-begin(\s\*\/}$)?/gm;
+const END = /(\/\/|\{\/\*) @use-(auth|form)-module-end(\s\*\/}$)?/gm;
+const BEGIN_OR_END = /(\/\/|\{\/\*) @use-(auth|form)-module-(begin|end)(\s\*\/}$)?/gm;
/**
* get content that is outside of @use-auth-module-begin and @use-auth-module-end comments
diff --git a/packages/react-scripts/custom/scripts/init/useAuthModule/getDependencies.js b/packages/react-scripts/custom/scripts/init/useAuthModule/getDependencies.js
index 9704e73c48f..5cf0c2f6969 100644
--- a/packages/react-scripts/custom/scripts/init/useAuthModule/getDependencies.js
+++ b/packages/react-scripts/custom/scripts/init/useAuthModule/getDependencies.js
@@ -8,19 +8,26 @@ module.exports = templatePath => {
return {
files: [
- resolveTemplateSrc('config/antonio/index.js'),
- resolveTemplateSrc('services/sagas/modules/index.js'),
- resolveTemplateSrc('services/sagas/index.js'),
- resolveTemplateSrc('services/reducers/index.js'),
- resolveTemplateSrc('modules/application/dependencies.js'),
- resolveTemplateSrc('modules/application/components/App.jsx'),
- resolveTemplateSrc('modules/core/modules/sentry/config/index.js'),
- resolveTemplateSrc('modules/core/modules/sentry/dependencies.js'),
- resolveTemplateSrc('modules/sharedDependencies.js'),
+ resolveTemplateSrc('config/antonio/index.ts'),
+ resolveTemplateSrc('services/sagas/modules/index.ts'),
+ resolveTemplateSrc('services/sagas/index.ts'),
+ resolveTemplateSrc('services/reducers/index.ts'),
+ resolveTemplateSrc('modules/application/components/App.tsx'),
+ resolveTemplateSrc('modules/core/modules/sentry/config/index.ts'),
+ resolveTemplateSrc('modules/core/modules/redux/config/enhancers.ts'),
+ resolveTemplateSrc(
+ 'modules/core/modules/redux/config/promiseListener.ts'
+ ),
],
directories: [resolveTemplateSrc('modules/auth')],
packageJson: {
- dependencies: ['@ackee/petrus'],
+ dependencies: [
+ '@ackee/petrus',
+ 'final-form',
+ 'react-final-form',
+ 'react-final-form-redux-submit',
+ 'redux-promise-listener',
+ ],
},
};
};
diff --git a/packages/react-scripts/custom/scripts/init/useAuthModule/index.js b/packages/react-scripts/custom/scripts/init/useAuthModule/index.js
index 820c037c0da..6e1fc924850 100644
--- a/packages/react-scripts/custom/scripts/init/useAuthModule/index.js
+++ b/packages/react-scripts/custom/scripts/init/useAuthModule/index.js
@@ -14,4 +14,6 @@ module.exports = async props => {
});
await applyAnswer(result.useAuthModule, props);
+
+ return result.useAuthModule;
};