Redux
This commit is contained in:
parent
573671134c
commit
77b2c1ed7b
|
@ -3,7 +3,7 @@
|
|||
"version": "1.0.0",
|
||||
"description": "Node Hello Project",
|
||||
"main": "index.js",
|
||||
"repository": "https://git.loafle.net/prototype/hello.git",
|
||||
"repository": "https://git.loafle.net/overflow/overflow_app.git",
|
||||
"author": "LOAFLE (rnd@loafle.com)",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
@ -15,7 +15,7 @@
|
|||
"test:watch": "yarn run jest -- --watch",
|
||||
"jest": "PWD=$(pwd) NODE_ENV=test ./node_modules/.bin/jest -w 1 --coverage",
|
||||
"prebuild": "./node_modules/.bin/check-dependencies && yarn run clean",
|
||||
"build": "set NODE_ENV=production && ./node_modules/.bin/webpack --progress -profile --colors --config ./config/webpack/webpack.config.prod.js",
|
||||
"build": "set NODE_ENV=production && ./node_modules/.bin/webpack --progress --profile --colors --config ./config/webpack/webpack.config.prod.js",
|
||||
"lint": "./node_modules/.bin/tslint -c tslint.json 'src/ts/**/*.{ts,tsx}' && ./node_modules/.bin/sass-lint 'src/**/*.scss'",
|
||||
"stats": "set NODE_ENV=production && webpack --progress --config ./config/webpack/webpack.config.stats.js --profile --json > ./config/webpack/stats/stats.json"
|
||||
},
|
||||
|
@ -31,6 +31,7 @@
|
|||
"@types/react-router-dom": "^4.0.4",
|
||||
"@types/react-tap-event-plugin": "^0.0.30",
|
||||
"@types/redux": "^3.6.0",
|
||||
"@types/redux-actions": "^1.2.6",
|
||||
"awesome-typescript-loader": "^3.1.3",
|
||||
"check-dependencies": "^1.0.1",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
|
@ -55,8 +56,8 @@
|
|||
"tslint-loader": "^3.5.3",
|
||||
"tslint-react": "^3.0.0",
|
||||
"typescript": "^2.3.3",
|
||||
"webpack": "^2.6.0",
|
||||
"webpack-dev-server": "^2.4.5",
|
||||
"webpack": "^2.6.1",
|
||||
"webpack-dev-server": "^2.5.0",
|
||||
"webpack-merge": "^4.1.0",
|
||||
"webpack-visualizer-plugin": "^0.1.11"
|
||||
},
|
||||
|
|
8
src/ts/commons/redux/Action.ts
Normal file
8
src/ts/commons/redux/Action.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
interface Action<Payload = {}> {
|
||||
type: any;
|
||||
payload?: Payload;
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
|
||||
export default Action;
|
10
src/ts/commons/redux/Module.ts
Normal file
10
src/ts/commons/redux/Module.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import Action from './Action';
|
||||
|
||||
interface IModule<State, Payload> {
|
||||
Name: string;
|
||||
ActionTypes: {[key: string]: any};
|
||||
Actions: {[key: string]: any};
|
||||
Reducer: (state: State, action: Action<Payload>) => State;
|
||||
}
|
||||
|
||||
export default IModule;
|
55
src/ts/commons/util/immutable/Record.ts
Normal file
55
src/ts/commons/util/immutable/Record.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { Iterable, Map, Record as ImmutableRecord } from 'immutable';
|
||||
|
||||
export interface Record<T extends Record<T>> extends Map<string, any> {
|
||||
set: (prop: string, val: any) => T;
|
||||
delete: (key: string) => T;
|
||||
remove: (key: string) => T;
|
||||
clear: () => T;
|
||||
update: {
|
||||
(updater: (value: T) => any): T;
|
||||
(key: string, updater: (value: any) => any): T;
|
||||
(key: string, notSetValue: any, updater: (value: any) => any): T;
|
||||
};
|
||||
merge: (obj: any) => T;
|
||||
mergeWith: (
|
||||
merger: (previous?: any, next?: any, key?: string) => any,
|
||||
obj: any,
|
||||
) => T;
|
||||
mergeDeep: (obj: any) => T;
|
||||
mergeDeepWith: (
|
||||
merger: (previous?: any, next?: any, key?: string) => any,
|
||||
obj: any,
|
||||
) => T;
|
||||
setIn: (keyPath: any[] | Iterable<any, any>, value: any) => T;
|
||||
deleteIn: (keyPath: Array<any> | Iterable<any, any>) => T;
|
||||
removeIn: (keyPath: Array<any> | Iterable<any, any>) => T;
|
||||
updateIn: {
|
||||
(keyPath: any[] | Iterable<any, any>, updater: (value: any) => any): T;
|
||||
(
|
||||
keyPath: any[] | Iterable<any, any>,
|
||||
notSetValue: any,
|
||||
updater: (value: any) => any,
|
||||
): T
|
||||
};
|
||||
mergeIn: (keyPath: any[] | Iterable<any, any>, obj: any) => T;
|
||||
mergeDeepIn: (keyPath: any[] | Iterable<any, any>, obj: any) => T;
|
||||
withMutations: (mutator: (mutable: T) => any) => T;
|
||||
asMutable: () => T;
|
||||
asImmutable: () => T;
|
||||
}
|
||||
|
||||
export function makeRecordType<O, R extends Record<R> & O>
|
||||
(defaultVal: O, val: O = null, name?: string): R {
|
||||
|
||||
const RecordFactory = makeRecordFactory<O, R>(defaultVal, name);
|
||||
return val ? RecordFactory(val) : RecordFactory();
|
||||
}
|
||||
|
||||
export function makeRecordFactory<O, R extends Record<R> & O>
|
||||
(obj: O, name?: string): (val?: O) => R {
|
||||
|
||||
const iRecord = ImmutableRecord(obj, name);
|
||||
return (val: O = null) => {
|
||||
return new iRecord(val) as R;
|
||||
};
|
||||
}
|
|
@ -1,7 +1,32 @@
|
|||
class Starter {
|
||||
public static main(): void {
|
||||
console.log('Hello world.');
|
||||
}
|
||||
import * as member from 'member/redux';
|
||||
import { Action, createStore, combineReducers } from 'redux';
|
||||
|
||||
|
||||
export interface StateRecord {
|
||||
member: member.StateRecord;
|
||||
}
|
||||
|
||||
Starter.main();
|
||||
export interface IActionTypes {
|
||||
member: member.IActionTypes;
|
||||
}
|
||||
export const ActionTypes: IActionTypes = {
|
||||
member: member.ActionTypes,
|
||||
};
|
||||
|
||||
export interface IActions {
|
||||
member: member.IActions;
|
||||
}
|
||||
export const Actions: IActions = {
|
||||
member: member.Actions,
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const Reducers = combineReducers<StateRecord>({
|
||||
member: member.Reducers,
|
||||
});
|
||||
|
||||
|
||||
let store = createStore(Reducers);
|
||||
|
||||
console.log('');
|
||||
|
|
|
@ -2,11 +2,11 @@ import {MemberStatus} from './MemberStatus';
|
|||
|
||||
|
||||
export interface Member {
|
||||
id: number;
|
||||
id?: number;
|
||||
email: string;
|
||||
name: string;
|
||||
phone: string;
|
||||
companyName: string;
|
||||
createDate: Date;
|
||||
status: MemberStatus;
|
||||
createDate?: Date;
|
||||
status?: MemberStatus;
|
||||
}
|
|
@ -2,5 +2,5 @@ export enum MemberStatus {
|
|||
NOAUTH = 1,
|
||||
NORMAL = 2,
|
||||
DORMANCY = 3,
|
||||
WITHDRAWAL = 4
|
||||
WITHDRAWAL = 4,
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
import { Member } from 'member/api/model/Member';
|
||||
|
||||
export type REGIST = '@overflow/member/regist/REGIST';
|
||||
export const REGIST: REGIST = '@overflow/member/regist/REGIST';
|
||||
|
||||
export type RegistAction = {
|
||||
type: REGIST,
|
||||
by: Member
|
||||
};
|
||||
|
||||
function counterReducer(state = INITIAL_STATE, action:CounterAction = OtherAction) {
|
||||
switch (action.type) {
|
||||
case INCREMENT_COUNTER:
|
||||
return state.update({value: state.value + action.by});
|
||||
|
||||
case DECREMENT_COUNTER:
|
||||
return state.update({value: state.value - action.by});
|
||||
|
||||
case LOGOUT_USER:
|
||||
return INITIAL_STATE;
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
44
src/ts/member/redux/index.ts
Normal file
44
src/ts/member/redux/index.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { Action, combineReducers } from 'redux';
|
||||
|
||||
import * as signin from './signin';
|
||||
import * as signout from './signout';
|
||||
import * as signup from './signup';
|
||||
|
||||
export const ModuleName = 'member';
|
||||
|
||||
export interface StateRecord {
|
||||
signin: signin.StateRecord;
|
||||
signout: signout.StateRecord;
|
||||
signup: signup.StateRecord;
|
||||
}
|
||||
|
||||
export interface IActionTypes {
|
||||
signin: signin.IActionTypes;
|
||||
signout: signout.IActionTypes;
|
||||
signup: signup.IActionTypes;
|
||||
}
|
||||
export const ActionTypes: IActionTypes = {
|
||||
signin: signin.ActionTypes,
|
||||
signout: signout.ActionTypes,
|
||||
signup: signup.ActionTypes,
|
||||
};
|
||||
|
||||
export interface IActions {
|
||||
signin: signin.IActions;
|
||||
signout: signout.IActions;
|
||||
signup: signup.IActions;
|
||||
}
|
||||
export const Actions: IActions = {
|
||||
signin: signin.Actions,
|
||||
signout: signout.Actions,
|
||||
signup: signup.Actions,
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const Reducers = combineReducers<StateRecord>({
|
||||
signin: signin.Reducers,
|
||||
signout: signout.Reducers,
|
||||
signup: signup.Reducers,
|
||||
});
|
||||
|
90
src/ts/member/redux/signin/index.ts
Normal file
90
src/ts/member/redux/signin/index.ts
Normal file
|
@ -0,0 +1,90 @@
|
|||
import Action from 'commons/redux/Action';
|
||||
import { Record, makeRecordFactory } from 'commons/util/immutable/Record';
|
||||
|
||||
import { Member } from 'member/api/model/Member';
|
||||
|
||||
export const ModuleName = 'signin';
|
||||
|
||||
export type REQUEST = '@overflow/member/signin/REQUEST';
|
||||
export type REQUEST_SUCCESS = '@overflow/member/signin/REQUEST_SUCCESS';
|
||||
export type REQUEST_FAILURE = '@overflow/member/signin/REQUEST_FAILURE';
|
||||
|
||||
export interface SigninPayload {
|
||||
signinId: string;
|
||||
signinPw: string;
|
||||
}
|
||||
|
||||
export interface MemberPayload extends Member {
|
||||
}
|
||||
|
||||
export interface State {
|
||||
isAuthenticated: boolean;
|
||||
member?: Member;
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
export interface StateRecord extends Record<StateRecord>, State {
|
||||
}
|
||||
|
||||
const makeStateRecord = makeRecordFactory<State, StateRecord>({
|
||||
isAuthenticated: undefined,
|
||||
member: undefined,
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
export interface IActionTypes {
|
||||
REQUEST: REQUEST;
|
||||
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
||||
REQUEST_FAILURE: REQUEST_FAILURE;
|
||||
}
|
||||
export const ActionTypes: IActionTypes = {
|
||||
REQUEST: '@overflow/member/signin/REQUEST',
|
||||
REQUEST_SUCCESS: '@overflow/member/signin/REQUEST_SUCCESS',
|
||||
REQUEST_FAILURE: '@overflow/member/signin/REQUEST_FAILURE',
|
||||
};
|
||||
|
||||
export interface IActions {
|
||||
request: (signinId: string, signinPw: string) => Action<SigninPayload>;
|
||||
requestSuccess: (member: Member) => Action<Member>;
|
||||
requestFailure: (error: Error) => Action;
|
||||
}
|
||||
export const Actions: IActions = {
|
||||
request(signinId: string, signinPw: string): Action<SigninPayload> {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
payload: {
|
||||
signinId: signinId,
|
||||
signinPw: signinPw,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
requestSuccess(member: Member): Action<Member> {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
payload: member,
|
||||
};
|
||||
},
|
||||
|
||||
requestFailure(error: Error): Action {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
error: error,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export function Reducers(state: StateRecord = makeStateRecord(), action: Action<MemberPayload | Error>): StateRecord {
|
||||
switch (action.type) {
|
||||
case ActionTypes.REQUEST_SUCCESS:
|
||||
{
|
||||
return state.merge({isAuthenticated: true, member: action.payload});
|
||||
}
|
||||
case ActionTypes.REQUEST_FAILURE:
|
||||
{
|
||||
return state.merge({isAuthenticated: false, error: action.error});
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
70
src/ts/member/redux/signout/index.ts
Normal file
70
src/ts/member/redux/signout/index.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import Action from 'commons/redux/Action';
|
||||
import { Record, makeRecordFactory } from 'commons/util/immutable/Record';
|
||||
import { Member } from 'member/api/model/Member';
|
||||
export type REQUEST = '@overflow/member/signout/REQUEST';
|
||||
export type REQUEST_SUCCESS = '@overflow/member/signout/REQUEST_SUCCESS';
|
||||
export type REQUEST_FAILURE = '@overflow/member/signout/REQUEST_FAILURE';
|
||||
|
||||
export const ModuleName = 'signout';
|
||||
|
||||
export interface State {
|
||||
}
|
||||
|
||||
export interface StateRecord extends Record<StateRecord>, State {
|
||||
}
|
||||
|
||||
const makeStateRecord = makeRecordFactory<State, StateRecord>({
|
||||
});
|
||||
|
||||
|
||||
export interface IActionTypes {
|
||||
REQUEST: REQUEST;
|
||||
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
||||
REQUEST_FAILURE: REQUEST_FAILURE;
|
||||
}
|
||||
export const ActionTypes: IActionTypes = {
|
||||
REQUEST: '@overflow/member/signout/REQUEST',
|
||||
REQUEST_SUCCESS: '@overflow/member/signout/REQUEST_SUCCESS',
|
||||
REQUEST_FAILURE: '@overflow/member/signout/REQUEST_FAILURE',
|
||||
};
|
||||
|
||||
export interface IActions {
|
||||
request: () => Action;
|
||||
requestSuccess: () => Action;
|
||||
requestFailure: (error: Error) => Action;
|
||||
}
|
||||
export const Actions: IActions = {
|
||||
request(): Action {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
};
|
||||
},
|
||||
|
||||
requestSuccess(): Action {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
};
|
||||
},
|
||||
|
||||
requestFailure(error: Error): Action {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
error: error,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export function Reducers(state: StateRecord = makeStateRecord(), action: Action): StateRecord {
|
||||
switch (action.type) {
|
||||
case ActionTypes.REQUEST_SUCCESS:
|
||||
{
|
||||
return state.merge({isAuthenticated: true, member: action.payload});
|
||||
}
|
||||
case ActionTypes.REQUEST_FAILURE:
|
||||
{
|
||||
return state.merge({isAuthenticated: false, error: action.error});
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
81
src/ts/member/redux/signup/index.ts
Normal file
81
src/ts/member/redux/signup/index.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
import Action from 'commons/redux/Action';
|
||||
import { Record, makeRecordFactory } from 'commons/util/immutable/Record';
|
||||
import { Member } from 'member/api/model/Member';
|
||||
|
||||
export const ModuleName = 'signup';
|
||||
|
||||
export type REQUEST = '@overflow/member/signup/REQUEST';
|
||||
export type REQUEST_SUCCESS = '@overflow/member/signup/REQUEST_SUCCESS';
|
||||
export type REQUEST_FAILURE = '@overflow/member/signup/REQUEST_FAILURE';
|
||||
|
||||
export interface MemberPayload extends Member {
|
||||
}
|
||||
|
||||
export interface State {
|
||||
isRegistered: boolean;
|
||||
member?: Member;
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
export interface StateRecord extends Record<StateRecord>, State {
|
||||
}
|
||||
|
||||
const makeStateRecord = makeRecordFactory<State, StateRecord>({
|
||||
isRegistered: undefined,
|
||||
member: undefined,
|
||||
error: undefined,
|
||||
});
|
||||
|
||||
export interface IActionTypes {
|
||||
REQUEST: REQUEST;
|
||||
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
||||
REQUEST_FAILURE: REQUEST_FAILURE;
|
||||
}
|
||||
export const ActionTypes: IActionTypes = {
|
||||
REQUEST: '@overflow/member/signup/REQUEST',
|
||||
REQUEST_SUCCESS: '@overflow/member/signup/REQUEST_SUCCESS',
|
||||
REQUEST_FAILURE: '@overflow/member/signup/REQUEST_FAILURE',
|
||||
};
|
||||
|
||||
export interface IActions {
|
||||
request: (member: Member) => Action<MemberPayload>;
|
||||
requestSuccess: (member: Member) => Action<Member>;
|
||||
requestFailure: (error: Error) => Action;
|
||||
}
|
||||
export const Actions: IActions = {
|
||||
request(member: Member): Action<MemberPayload> {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
payload: member,
|
||||
};
|
||||
},
|
||||
|
||||
requestSuccess(member: Member): Action<Member> {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
payload: member,
|
||||
};
|
||||
},
|
||||
|
||||
requestFailure(error: Error): Action {
|
||||
return {
|
||||
type: ActionTypes.REQUEST,
|
||||
error: error,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export function Reducers(state: StateRecord = makeStateRecord(), action: Action<MemberPayload | Error>): StateRecord {
|
||||
switch (action.type) {
|
||||
case ActionTypes.REQUEST_SUCCESS:
|
||||
{
|
||||
return state.merge({isRegistered: true, member: action.payload});
|
||||
}
|
||||
case ActionTypes.REQUEST_FAILURE:
|
||||
{
|
||||
return state.merge({isRegistered: false, error: action.error});
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,7 @@
|
|||
"eofline": true,
|
||||
"forin": true,
|
||||
"indent": [true, 2, "spaces"],
|
||||
"interface-name": [true],
|
||||
"interface-name": [false],
|
||||
"jsdoc-format": true,
|
||||
"label-position": true,
|
||||
"max-line-length": [true, 140],
|
||||
|
|
Loading…
Reference in New Issue
Block a user