Rest Request redux

This commit is contained in:
geek 2017-09-04 18:59:29 +09:00
parent 2c0d212a41
commit 1a6e90300a
19 changed files with 439 additions and 34 deletions

View File

@ -48,9 +48,12 @@ import NotificationReadAllUnconfirmedReducer from '@overflow/notification/redux/
import NotificationReadAllReducer from '@overflow/notification/redux/reducer/read_all'; import NotificationReadAllReducer from '@overflow/notification/redux/reducer/read_all';
import NotificationReadCountReducer from '@overflow/notification/redux/reducer/read_unconfirmed_count'; import NotificationReadCountReducer from '@overflow/notification/redux/reducer/read_unconfirmed_count';
import ForgotPassword from '@overflow/member/redux/reducer/forgotPassword';
import AuthCrawlerRegistReducer from '@overflow/auth/redux/reducer/regist'; import AuthCrawlerRegistReducer from '@overflow/auth/redux/reducer/regist';
import AsyncRequest from '@overflow/app/redux/saga/AsyncRequest'; import AsyncRequest from '@overflow/app/redux/saga/AsyncRequest';
import AsyncRestRequest from '@overflow/app/redux/saga/AsyncRestRequest';
// Container Configuration // Container Configuration
export interface ContainerConfig { export interface ContainerConfig {
@ -121,9 +124,11 @@ const reduxConfig: ReduxConfig = {
NotificationReadAllReducer, NotificationReadAllReducer,
NotificationReadCountReducer, NotificationReadCountReducer,
AuthCrawlerRegistReducer, AuthCrawlerRegistReducer,
ForgotPassword,
], ],
sagaWatchers: [ sagaWatchers: [
AsyncRequest, AsyncRequest,
AsyncRestRequest,
], ],
}; };

View File

@ -0,0 +1,18 @@
import Action from '@overflow/commons/redux/Action';
import AsyncRestRequestSendingPayload from '../payload/AsyncRestRequestSendingPayload';
// Action Type
export type SENDING = '@overflow/app/async/rest/SENDING';
export const SENDING: SENDING = '@overflow/app/async/rest/SENDING';
// Action Creater
export type sending = (complete: boolean) => Action<AsyncRestRequestSendingPayload>;
export const sending: sending = (complete: boolean): Action<AsyncRestRequestSendingPayload> => {
return {
type: SENDING,
payload: {
complete: complete,
},
};
};

View File

@ -0,0 +1,5 @@
export interface AsyncRestRequestSendingPayload {
complete: boolean;
}
export default AsyncRestRequestSendingPayload;

View File

@ -0,0 +1,20 @@
import Action from '@overflow/commons/redux/Action';
import { ReducersMapObject } from 'redux';
import AsyncRestRequestSendingPayload from '../payload/AsyncRestRequestSendingPayload';
import * as AsyncRestRequestSendingActions from '../action/asyncRestRequestSending';
import AsyncRestRequestSendingState, {
defaultState as AsyncRestRequestSendingDefaultState,
} from '../state/AsyncRestRequestSending';
const reducer: ReducersMapObject = {
[AsyncRestRequestSendingActions.SENDING]: (state: AsyncRestRequestSendingState = AsyncRestRequestSendingDefaultState,
action: Action<AsyncRestRequestSendingPayload>): AsyncRestRequestSendingState => {
return {
complete: action.payload.complete,
};
},
};
export default reducer;

View File

@ -0,0 +1,121 @@
import { SagaIterator } from 'redux-saga';
import { call, Effect, fork, put, takeEvery } from 'redux-saga/effects';
import Action from '@overflow/commons/redux/Action';
import SagaWatcher from '@overflow/commons/redux/saga/SagaWatcher';
import * as AsyncRestRequestActions from '@overflow/commons/redux/action/asyncRestRequest';
import AsyncRestRequestPayload from '@overflow/commons/redux/payload/AsyncRestRequestPayload';
import * as AppAsyncRestRequestSendingActions from '../action/asyncRestRequestSending';
export class AsyncRestRequest implements SagaWatcher {
// private _webSocketRPC: WebSocketRPC;
//
// public setWebSocketRPC(webSocketRPC: WebSocketRPC): void {
// this._webSocketRPC = webSocketRPC;
// }
private * request(action: Action<AsyncRestRequestPayload>): SagaIterator {
const {entry, method, requestType, args} = action.payload;
console.log(JSON.stringify(args));
try {
yield put(AppAsyncRestRequestSendingActions.sending(false));
let result = yield call(
fetch,
'http://192.168.1.103:19080/account/' + entry,
{
method: method,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(args),
},
);
// let result = yield call(this.fetchApi2, entry, method, args);
// let result = yield call({context: this, fn: this.fetchApi2}, entry, method, args);
yield put(AsyncRestRequestActions.requestSuccess(requestType, result));
} catch (e) {
yield put(AsyncRestRequestActions.requestFailure(requestType, e));
} finally {
yield put(AppAsyncRestRequestSendingActions.sending(true));
}
}
public * watch(): SagaIterator {
yield takeEvery(AsyncRestRequestActions.REQUEST, this.request);
}
public fetchApi2(uri: string, method:string, args:any): any {
return fetch(
'http://192.168.1.103:19080/account/' + uri, {
method: method,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(args),
},
)
.then((response) => {
return (response.status === 200) ? response.json() : Promise.reject('logon');
});
// .catch(err => {
// Promise.reject(err);
// });
}
public fetchApi(uri: string, method:string, args:any): Promise<any> {
return fetch(
'http://192.168.1.103:19080/account/' + uri, {
method: method,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(args),
},
);
// .then((response:any) => {
// console.log(response);
// return response;
// })
// .then((json:any) => {
// return json;
// })
// .catch(err => {
// return err;
// });
}
//
// let d: any = await fetch('http://192.168.1.103:19080/account/forgot_password', {
// method: 'POST',
// headers: {
// // 'Content-Type': 'text/plain; charset=utf-8',
// 'Accept': 'application/json',
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({
// signinId: 'geek@loafle.com',
// }),
//
// }).then((respnse:any) => {
// console.log(respnse);
// return respnse.json();
// }).then((resData:any) => {
// console.log('resdata' + resData);
// return resData;
// }).catch(err => {
// console.log('eee' + err);
// });
}
export default AsyncRestRequest;

View File

@ -0,0 +1,9 @@
export interface State {
complete: boolean;
}
export const defaultState: State = {
complete: false,
};
export default State;

View File

@ -11,6 +11,7 @@ import SignIn from '../member/SignIn';
import SignUp from '../member/SignUp'; import SignUp from '../member/SignUp';
import PWConfirm from '../member/PWConfirm'; import PWConfirm from '../member/PWConfirm';
import Modify from '../member/Modify'; import Modify from '../member/Modify';
import ResetPassword from '../member/ResetPassword';
export interface Props extends RouteComponentProps<any> { export interface Props extends RouteComponentProps<any> {
} }
@ -38,6 +39,7 @@ class AccountLayout extends React.Component<Props, State> {
<Route path={`${this.props.match.url}/signup`} component={SignUp}/> <Route path={`${this.props.match.url}/signup`} component={SignUp}/>
<Route path={`${this.props.match.url}/pw_confirm`} component={PWConfirm}/> <Route path={`${this.props.match.url}/pw_confirm`} component={PWConfirm}/>
<Route path={`${this.props.match.url}/modify`} component={Modify}/> <Route path={`${this.props.match.url}/modify`} component={Modify}/>
<Route path={`${this.props.match.url}/reset_password`} component={ResetPassword}/>
</Switch> </Switch>
</Segment> </Segment>
</Grid.Column> </Grid.Column>

View File

@ -0,0 +1,26 @@
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import ResetPasswordContainer from '@overflow/member/react/ResetPassword';
export interface Props {
}
export interface State {
}
class ResetPassword extends React.Component<RouteComponentProps<Props>, object> {
public constructor(props?: RouteComponentProps<Props>, context?: State) {
super(props, context);
}
public render(): JSX.Element {
return (
<ResetPasswordContainer/>
);
}
}
export default ResetPassword;

View File

@ -2,8 +2,8 @@ import Action from '@overflow/commons/redux/Action';
import AsyncRequestPayload from '../payload/AsyncRequestPayload'; import AsyncRequestPayload from '../payload/AsyncRequestPayload';
// Action Type // Action Type
export type REQUEST = '@overflow/commons/anync/REQUEST'; export type REQUEST = '@overflow/commons/async/REQUEST';
export const REQUEST: REQUEST = '@overflow/commons/anync/REQUEST'; export const REQUEST: REQUEST = '@overflow/commons/async/REQUEST';
// Action Creater // Action Creater
export type request = (service: string, method: string, requestType: string, ...args: any[]) => Action<AsyncRequestPayload>; export type request = (service: string, method: string, requestType: string, ...args: any[]) => Action<AsyncRequestPayload>;

View File

@ -0,0 +1,37 @@
import Action from '@overflow/commons/redux/Action';
import AsyncRestRequestPayload from '../payload/AsyncRestRequestPayload';
// Action Type
export type REQUEST = '@overflow/commons/async/rest/REQUEST';
export const REQUEST: REQUEST = '@overflow/commons/async/rest/REQUEST';
// Action Creater
export type request = (entry: string, method: string, requestType: string, ...args: any[]) => Action<AsyncRestRequestPayload>;
export type requestSuccess = (requestType: string, result: any) => Action<any>;
export type requestFailure = (requestType: string, error: any) => Action<any>;
export const request: request = (entry: string, method: string, requestType: string, ...args: any[]): Action<AsyncRestRequestPayload> => {
return {
type: REQUEST,
payload: {
entry: entry,
method: method,
requestType: requestType,
args: args,
},
};
};
export const requestSuccess: requestSuccess = (requestType: string, result: any): Action<any> => {
return {
type: `${requestType}/SUCCESS`,
payload: result,
};
};
export const requestFailure: requestFailure = (requestType: string, error: Error): Action<any> => {
return {
type: `${requestType}/FAILURE`,
error: error,
};
};

View File

@ -0,0 +1,10 @@
import Action from '@overflow/commons/redux/Action';
interface AsyncRestRequestPayload {
entry: string;
method: string;
requestType: string;
args?: any[];
}
export default AsyncRestRequestPayload;

View File

@ -0,0 +1,28 @@
import { connect, Dispatch } from 'react-redux';
import {
ResetPassword,
StateProps as ResetPasswordStateProps,
DispatchProps as ResetPasswordDispatchProps,
Props as ResetPasswordProps,
} from './components/ResetPassword';
// import ResetPasswordState from '../redux/state/ResetPassword';
//
// import * as ResetPasswordActions from '../redux/action/reset_password';
// import { push as routerPush } from 'react-router-redux';
// import * as asyncRequestActions from '@overflow/commons/redux/action/asyncRequest';
export function mapStateToProps(state: any): ResetPasswordStateProps {
return {
};
}
export function mapDispatchToProps(dispatch: Dispatch<any>): ResetPasswordDispatchProps {
return {
// onConfirmPassword: (pass: string) => {
// dispatch(asyncRequestActions.request('MemberService', 'signin', ResetPasswordActions.REQUEST, 'overflow@loafle.com', pass));
// },
};
}
export default connect(mapStateToProps, mapDispatchToProps)(ResetPassword);

View File

@ -8,8 +8,11 @@ import {
import SignInState from '../redux/state/SignIn'; import SignInState from '../redux/state/SignIn';
import * as signinActions from '../redux/action/signIn'; import * as signinActions from '../redux/action/signIn';
import * as forgotPasswordAction from '../redux/action/forgot_password';
import { push as routerPush } from 'react-router-redux'; import { push as routerPush } from 'react-router-redux';
import * as asyncRequestActions from '@overflow/commons/redux/action/asyncRequest'; import * as asyncRequestActions from '@overflow/commons/redux/action/asyncRequest';
import * as asyncRestRequestAction from '@overflow/commons/redux/action/asyncRestRequest';
export function mapStateToProps(state: SignInState, ownProps?: SignInStateProps): SignInStateProps { export function mapStateToProps(state: SignInState, ownProps?: SignInStateProps): SignInStateProps {
console.log(state.error); console.log(state.error);
@ -28,6 +31,9 @@ export function mapDispatchToProps(dispatch: Dispatch<any>, ownProps?: any): Sig
onRedirectHome: () => { onRedirectHome: () => {
dispatch(routerPush('/')); dispatch(routerPush('/'));
}, },
onForgotPassword: (email:string) => {
dispatch(asyncRestRequestAction.request('/forgot_password', 'POST', forgotPasswordAction.REQUEST, {signinId:email}));
},
}; };
} }

View File

@ -0,0 +1,62 @@
import *as React from 'react';
import {
Input,
InputOnChangeData,
Button,
Form,
ButtonProps,
} from 'semantic-ui-react';
export interface StateProps {
}
export interface DispatchProps {
}
export type Props = StateProps & DispatchProps;
export interface State {
pw: string;
pwConfirm: string;
}
export class ResetPassword extends React.Component<Props, State> {
constructor(props: Props, context: State) {
super(props, context);
this.state = {
pw:null,
pwConfirm:null,
};
}
public render(): JSX.Element {
return (
<Form>
<Form.Input placeholder='Password' type='password' onChange={
(event: React.SyntheticEvent<HTMLInputElement>, data: InputOnChangeData) => {
this.setState({ pw: data.value });
}} />
<Form.Input placeholder='Password Confirm' type='password' onChange={
(event: React.SyntheticEvent<HTMLInputElement>, data: InputOnChangeData) => {
this.setState({ pwConfirm: data.value });
}} />
<Form.Group>
<Button primary fluid style={{margin:'7'}} onClick={this.PWConfirmClick}> Submit </Button>
<Button fluid style={{margin:'7'}}> Cancel </Button>
</Form.Group>
</Form>
);
}
private PWConfirmClick(event: React.SyntheticEvent<HTMLButtonElement>, data: ButtonProps):void {
if (this.state.pw !== this.state.pwConfirm) {
alert('Password Not Equal');
return;
}
// Todo Password Reset Fetch Communication
}
}

View File

@ -24,6 +24,7 @@ export interface StateProps {
export interface DispatchProps { export interface DispatchProps {
onSignIn?(signinId: string, signinPw: string ): void; onSignIn?(signinId: string, signinPw: string ): void;
onForgotPassword?(email:string): void;
onSignUp?(): void; onSignUp?(): void;
onResetPassword?():void; onResetPassword?():void;
onRedirectHome():void; onRedirectHome():void;
@ -81,7 +82,10 @@ export class SignIn extends React.Component<Props, State> {
Enter email address Enter email address
<Grid centered> <Grid centered>
<Grid.Column mobile={14} tablet={10} computer={10}> <Grid.Column mobile={14} tablet={10} computer={10}>
<Input fluid placeholder='Email' /> <Input fluid placeholder='Email' onChange={
(event: React.SyntheticEvent<HTMLInputElement>, data: InputOnChangeData) => {
this.setState({ email: data.value });
}} />
</Grid.Column> </Grid.Column>
</Grid> </Grid>
</Modal.Content> </Modal.Content>
@ -121,40 +125,41 @@ export class SignIn extends React.Component<Props, State> {
sendComPopup: true, sendComPopup: true,
}); });
this.props.onForgotPassword(this.state.email);
// Todo Ajax // Todo Ajax
this.testhttp(); // this.testhttp();
} }
private async testhttp() { // private async testhttp() {
// let httpc: httpm.HttpClient = new httpm.HttpClient('vsts-node-api'); // // let httpc: httpm.HttpClient = new httpm.HttpClient('vsts-node-api');
// let res:httpm.HttpClientResponse = await httpc.get('http://192.168.1.103:19080/forgot_password?'); // // let res:httpm.HttpClientResponse = await httpc.get('http://192.168.1.103:19080/forgot_password?');
// let body: string = await res.readBody(); // // let body: string = await res.readBody();
// console.log(body, res.message); // // console.log(body, res.message);
//
let d: any = await fetch('http://192.168.1.103:19080/account/forgot_password', { // let d: any = await fetch('http://192.168.1.103:19080/account/forgot_password', {
method: 'POST', // method: 'POST',
headers: { // headers: {
// 'Content-Type': 'text/plain; charset=utf-8', // // 'Content-Type': 'text/plain; charset=utf-8',
'Accept': 'application/json', // 'Accept': 'application/json',
'Content-Type': 'application/json', // 'Content-Type': 'application/json',
}, // },
body: JSON.stringify({ // body: JSON.stringify({
signinId: 'geek@loafle.com', // signinId: 'geek@loafle.com',
}), // }),
//
}).then((respnse:any) => { // }).then((respnse:any) => {
console.log(respnse); // console.log(respnse);
return respnse.json(); // return respnse.json();
}).then((resData:any) => { // }).then((resData:any) => {
console.log('resdata' + resData); // console.log('resdata' + resData);
return resData; // return resData;
}).catch(err => { // }).catch(err => {
console.log('eee' + err); // console.log('eee' + err);
}); // });
// let re: any = await d.json(); // // let re: any = await d.json();
//
// console.log(d); // // console.log(d);
} // }
private signInClick(event: React.SyntheticEvent<HTMLButtonElement>, data: ButtonProps):void { private signInClick(event: React.SyntheticEvent<HTMLButtonElement>, data: ButtonProps):void {
this.props.onSignIn(this.state.email, this.state.pass); this.props.onSignIn(this.state.email, this.state.pass);

View File

@ -0,0 +1,8 @@
// Action Type
export type REQUEST = '@overflow/member/forgot_password/REQUEST';
export type REQUEST_SUCCESS = '@overflow/member/forgot_password/REQUEST/SUCCESS';
export type REQUEST_FAILURE = '@overflow/member/forgot_password/REQUEST/FAILURE';
export const REQUEST: REQUEST = '@overflow/member/forgot_password/REQUEST';
export const REQUEST_SUCCESS: REQUEST_SUCCESS = '@overflow/member/forgot_password/REQUEST/SUCCESS';
export const REQUEST_FAILURE: REQUEST_FAILURE = '@overflow/member/forgot_password/REQUEST/FAILURE';

View File

@ -0,0 +1,5 @@
interface ForgotPasswordPayload {
email: string;
}
export default ForgotPasswordPayload;

View File

@ -0,0 +1,26 @@
import Action from '@overflow/commons/redux/Action';
import { ReducersMapObject } from 'redux';
import Member from '@overflow/member/api/model/Member';
import * as ForgotPasswordTypes from '../action/forgot_password';
import ForgotPasswordState, { defaultState as forgotDefaultState } from '../state/ForgotPassword';
const reducer: ReducersMapObject = {
[ForgotPasswordTypes.REQUEST_SUCCESS]: (state: ForgotPasswordState = forgotDefaultState, action: Action<Member>): ForgotPasswordState => {
return {
...state,
isSendMail: true,
};
},
[ForgotPasswordTypes.REQUEST_FAILURE]: (state: ForgotPasswordState = forgotDefaultState, action: Action<Error>): ForgotPasswordState => {
if (action.error.name === 'SignInPwNotMatchException') {
//
}
return {
...state,
error: new Error('ForgotPassword Error'),
};
},
};
export default reducer;

View File

@ -0,0 +1,12 @@
export interface State {
readonly isSendMail: boolean;
readonly error?: Error;
}
export const defaultState: State = {
isSendMail: undefined,
error: undefined,
};
export default State;