From f2687a7828c12b172012791a940c0c71156e1785 Mon Sep 17 00:00:00 2001 From: snoop Date: Thu, 20 Jul 2017 18:21:36 +0900 Subject: [PATCH 1/5] move sensorlist --- src/ts/@overflow/app/router/index.tsx | 2 +- .../@overflow/app/views/{ => monitoring}/sensor/SensorList.tsx | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/ts/@overflow/app/views/{ => monitoring}/sensor/SensorList.tsx (100%) diff --git a/src/ts/@overflow/app/router/index.tsx b/src/ts/@overflow/app/router/index.tsx index 0285830..e9ef123 100644 --- a/src/ts/@overflow/app/router/index.tsx +++ b/src/ts/@overflow/app/router/index.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { Route, Switch } from 'react-router-dom'; import SignIn from '../views/member/SignIn'; -import SensorList from '../views/sensor/SensorList'; +import SensorList from '../views/monitoring/sensor/SensorList'; import { SignUp } from '@overflow/member/react/components/SignUp'; // import { SignIn } from '@overflow/member/react/components/SignIn';; diff --git a/src/ts/@overflow/app/views/sensor/SensorList.tsx b/src/ts/@overflow/app/views/monitoring/sensor/SensorList.tsx similarity index 100% rename from src/ts/@overflow/app/views/sensor/SensorList.tsx rename to src/ts/@overflow/app/views/monitoring/sensor/SensorList.tsx From e0f91c03a015ce07d0c47e512a09c8fcdcce7ee8 Mon Sep 17 00:00:00 2001 From: snoop Date: Thu, 20 Jul 2017 18:30:54 +0900 Subject: [PATCH 2/5] remove file --- src/ts/@overflow/app/views/monitoring/sensor/List.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/ts/@overflow/app/views/monitoring/sensor/List.tsx diff --git a/src/ts/@overflow/app/views/monitoring/sensor/List.tsx b/src/ts/@overflow/app/views/monitoring/sensor/List.tsx deleted file mode 100644 index e69de29..0000000 From f7504d9951767320845df0a2bc4f820458c5ea2d Mon Sep 17 00:00:00 2001 From: crusader Date: Thu, 20 Jul 2017 18:46:42 +0900 Subject: [PATCH 3/5] ing --- package.json | 12 +- public/index.html | 2 +- src/ts/@overflow/app/config/index.ts | 29 ++++ src/ts/@overflow/app/index.tsx | 137 +++++++++++++++--- src/ts/@overflow/app/router/index.tsx | 5 + src/ts/@overflow/commons/context/index.ts | 11 ++ .../commons/context/redux/action/lifecycle.ts | 24 +++ .../commons/context/redux/saga/index.ts | 25 ++++ src/ts/@overflow/commons/platform/index.ts | 16 +- .../commons/websocket/WebSocketRPC.ts | 81 +++++++---- .../probe/react/components/ProbeDetail.tsx | 2 - 11 files changed, 285 insertions(+), 59 deletions(-) create mode 100644 src/ts/@overflow/app/config/index.ts create mode 100644 src/ts/@overflow/commons/context/redux/action/lifecycle.ts create mode 100644 src/ts/@overflow/commons/context/redux/saga/index.ts diff --git a/package.json b/package.json index b13c904..7d2f3b1 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,12 @@ "@types/history": "^4.6.0", "@types/jest": "^19.2.4", "@types/prop-types": "^15.5.1", - "@types/react": "^15.0.32", + "@types/react": "^15.0.38", "@types/react-addons-test-utils": "^0.14.19", "@types/react-dom": "^15.5.1", - "@types/react-redux": "^4.4.45", - "@types/react-router": "^4.0.12", - "@types/react-router-dom": "^4.0.5", + "@types/react-redux": "^4.4.46", + "@types/react-router": "^4.0.14", + "@types/react-router-dom": "^4.0.7", "@types/react-tap-event-plugin": "^0.0.30", "@types/redux": "^3.6.0", "awesome-typescript-loader": "^3.1.3", @@ -71,8 +71,8 @@ "react-dom": "^15.6.1", "react-immutable-proptypes": "^2.1.0", "react-redux": "^5.0.5", - "react-router": "^4.1.1", - "react-router-dom": "^4.1.1", + "react-router": "^4.1.2", + "react-router-dom": "^4.1.2", "react-router-redux": "next", "react-tap-event-plugin": "^2.0.1", "redux": "^3.7.1", diff --git a/public/index.html b/public/index.html index 1a631af..e09ea73 100644 --- a/public/index.html +++ b/public/index.html @@ -16,7 +16,7 @@ -
+
\ No newline at end of file diff --git a/src/ts/@overflow/app/config/index.ts b/src/ts/@overflow/app/config/index.ts new file mode 100644 index 0000000..24ced6b --- /dev/null +++ b/src/ts/@overflow/app/config/index.ts @@ -0,0 +1,29 @@ +// Container Configuration +export interface ContainerConfig { + placeholderID: string; +} +const containerConfig: ContainerConfig = { + placeholderID: 'appContainer', +}; + +// RPC Server Configuration +export interface RPCConfig { + url: string; +} +const rpcConfig: RPCConfig = { + url: 'ws://127.0.0.1:18081/rpc', +}; + + +// Configuration +export interface Config { + container: ContainerConfig; + rpc: RPCConfig; +} + +const config: Config = { + container: containerConfig, + rpc: rpcConfig, +}; + +export default config; diff --git a/src/ts/@overflow/app/index.tsx b/src/ts/@overflow/app/index.tsx index 7bced01..94f49cf 100644 --- a/src/ts/@overflow/app/index.tsx +++ b/src/ts/@overflow/app/index.tsx @@ -5,11 +5,19 @@ import { fork } from 'redux-saga/effects'; import { Provider } from 'react-redux'; import { ConnectedRouter } from 'react-router-redux'; import * as injectTapEventPlugin from 'react-tap-event-plugin'; +import { Store } from 'redux'; +import createSagaMiddleware, { SagaMiddleware } from 'redux-saga'; import Platform from '@overflow/commons/platform'; +import AppContext from '@overflow/commons/context'; +import * as AppContextLifecycleActions from '@overflow/commons/context/redux/action/lifecycle'; +import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC'; +import { History } from 'history'; import { store, sagaMiddleware, history } from './redux/store'; +import appConfig, { Config } from './config'; + import sagas from './redux/saga'; // import routes from './router'; @@ -17,30 +25,117 @@ import {Layout} from './views/layout/Layout'; injectTapEventPlugin(); -function* app(): any { - const appContainer: HTMLElement = yield Platform.getAppContainer('react-placeholder'); +const rpcURL = 'ws://127.0.0.1:18081/rpc'; - ReactDOM.render( -
-

Loading...

-
, - appContainer, - ); - sagaMiddleware.run(sagas); +class App { + private config: Config; + private container: HTMLElement; + private context: AppContext; + private rpcClient: WebSocketRPC; + private store: Store; + private sagaMiddleware: SagaMiddleware; + private history: History; + + public constructor() { + this.config = appConfig; + this.sagaMiddleware = sagaMiddleware; + this.store = store; + } + + public async start(): Promise { + try { + this.container = await Platform.getAppContainer(this.config.container.placeholderID); + this.displayLoading(); + + this.context = await this.initContext(); + // this.rpcClient = await this.initRpcClient(); + await this.initSagaEffect(); + + this.store.dispatch(AppContextLifecycleActions.initialized()); + + this.displayApp(); + } catch (e) { + this.displayError(e); + } + } + + public initContext(): Promise { + const appContext = new Promise(resolve => { + const context = AppContext.getContext(); + resolve(context); + }); + + return appContext; + } + + public initRpcClient(): Promise { + const rpcClient = new Promise((resolve, reject) => { + let client = new WebSocketRPC(this.config.rpc.url); + client.initialize() + .then(() => { + resolve(client); + }) + .catch((err: any) => { + reject(err); + }); + }); + + return rpcClient; + } + + public initSagaEffect(): Promise { + const rpcClient = new Promise(resolve => { + this.sagaMiddleware.run(sagas); + resolve(); + }); + + return rpcClient; + } + + + private displayLoading(): void { + ReactDOM.render( +
+

Loading...

+
, + this.container, + ); + } + + private displayError(e: Error): void { + ReactDOM.render( +
+

{e.message}

+
, + this.container, + ); + } + + + private displayApp(): void { + ReactDOM.render( +
, + this.container, + ); + } - ReactDOM.render( -
, - appContainer, - ); } -sagaMiddleware.run(app); +let app = new App(); +app.start(); diff --git a/src/ts/@overflow/app/router/index.tsx b/src/ts/@overflow/app/router/index.tsx index e9ef123..5cef490 100644 --- a/src/ts/@overflow/app/router/index.tsx +++ b/src/ts/@overflow/app/router/index.tsx @@ -16,6 +16,11 @@ import { PWChange } from '@overflow/member/react/components/PWChange'; import { TableExampleSortable } from '@overflow/temp/react/components/TableExampleSortable'; +interface AppRouter { + +} + + const routes = ( {/* diff --git a/src/ts/@overflow/commons/context/index.ts b/src/ts/@overflow/commons/context/index.ts index 9d4f7d1..fbaa4f8 100644 --- a/src/ts/@overflow/commons/context/index.ts +++ b/src/ts/@overflow/commons/context/index.ts @@ -15,12 +15,23 @@ class AppContext { return null; } + public static put(instance: T): void { + + + return null; + } + public static getContext(): AppContext { if (null === AppContext.context) { AppContext.context = new AppContext(); } return AppContext.context; } + + public static destroy(): void { + console.log('AppContext has been destroyed.'); + } + } export default AppContext; diff --git a/src/ts/@overflow/commons/context/redux/action/lifecycle.ts b/src/ts/@overflow/commons/context/redux/action/lifecycle.ts new file mode 100644 index 0000000..c8f7e66 --- /dev/null +++ b/src/ts/@overflow/commons/context/redux/action/lifecycle.ts @@ -0,0 +1,24 @@ +import Action from '@overflow/commons/redux/Action'; + +// Action Type +export type INITIALIZED = '@overflow/commons/context/INITIALIZED'; +export type WILL_DESTROY = '@overflow/commons/context/WILL_DESTROY'; + +export const INITIALIZED: INITIALIZED = '@overflow/commons/context/INITIALIZED'; +export const WILL_DESTROY: WILL_DESTROY = '@overflow/commons/context/WILL_DESTROY'; + +// Action Creater +export type initialized = () => Action; +export type willDestroy = () => Action; + +export const initialized: initialized = (): Action => { + return { + type: INITIALIZED, + }; +}; + +export const willDestroy: willDestroy = (): Action => { + return { + type: WILL_DESTROY, + }; +}; diff --git a/src/ts/@overflow/commons/context/redux/saga/index.ts b/src/ts/@overflow/commons/context/redux/saga/index.ts new file mode 100644 index 0000000..11620f1 --- /dev/null +++ b/src/ts/@overflow/commons/context/redux/saga/index.ts @@ -0,0 +1,25 @@ + +import { SagaIterator } from 'redux-saga'; +import { call, fork, take } from 'redux-saga/effects'; + +import * as LifecycleActions from '../action/lifecycle'; + +import AppContext from '../../'; + + +function _destroy(): Promise { + return new Promise(resolve => { + AppContext.destroy(); + resolve(); + }); +} + +function* destroy(): SagaIterator { + yield take(LifecycleActions.WILL_DESTROY); + yield call(_destroy); +} + + +export default function* root(): SagaIterator { + yield fork(destroy); +} diff --git a/src/ts/@overflow/commons/platform/index.ts b/src/ts/@overflow/commons/platform/index.ts index a77284f..3a85eeb 100644 --- a/src/ts/@overflow/commons/platform/index.ts +++ b/src/ts/@overflow/commons/platform/index.ts @@ -1,7 +1,9 @@ +import AppContext from '../context'; + abstract class Platform { - public static * getAppContainer(containerId: string): IterableIterator> { - const appContainer = yield new Promise(resolve => { + public static getAppContainer(containerId: string): Promise { + const appContainer = new Promise(resolve => { document.addEventListener('DOMContentLoaded', () => { resolve(document.getElementById(containerId)); }); @@ -9,6 +11,16 @@ abstract class Platform { return appContainer; } + + public static * getAppContext(): IterableIterator> { + const appContext = yield new Promise(resolve => { + const context = AppContext.getContext(); + resolve(context); + }); + + return appContext; + } + } export default Platform; diff --git a/src/ts/@overflow/commons/websocket/WebSocketRPC.ts b/src/ts/@overflow/commons/websocket/WebSocketRPC.ts index 7886fc1..db1836c 100644 --- a/src/ts/@overflow/commons/websocket/WebSocketRPC.ts +++ b/src/ts/@overflow/commons/websocket/WebSocketRPC.ts @@ -9,9 +9,7 @@ import { RPCRequest, RPCResponse, } from './protocol/rpc'; -import injectable from '../context/decorator/injectable'; -export type OnConnectFunc = () => void; export type OnDisconnectFunc = () => void; export type OnResponseFunc = (response: any) => void; @@ -22,28 +20,42 @@ interface RequestQueue { reject: (reason?: any) => void; } -@injectable() +enum WebSocketStatus { + NOT_CONNECT = 1, + WILL_CONNECT, + CONNECTED, + WILL_DISCONNECT, +} + +enum WebSocketReadyState { + CONNECTING = 0, + OPEN = 1, + CLOSING = 2, + CLOSED = 3, +} + + export default class WebSocketRPC { private url: string; + private connStatus: WebSocketStatus; private conn: WebSocket; private isReady: boolean; private requestID: ID_TYPE = 0; - private onConnectListeners: OnConnectFunc[] = []; private onDisconnectListeners: OnDisconnectFunc[] = []; private onResponseListeners: Map; private requestQueue: Map; + /** * name */ public constructor(url: string) { this.isReady = false; + this.connStatus = WebSocketStatus.NOT_CONNECT; this.url = url; this.onResponseListeners = new Map(); this.requestQueue = new Map(); - - this.initialize(); } public Call(method: string, params: any[]): Promise { @@ -59,33 +71,49 @@ export default class WebSocketRPC { }); } - - public OnConnect(cb: OnConnectFunc): void { - if (this.isReady) { - cb(); - } - this.onConnectListeners.push(cb); - } - public OnDisconnect(cb: OnDisconnectFunc): void { this.onDisconnectListeners.push(cb); } - private initialize(): void { - this.conn = new WebSocket(this.url); - this.conn.onopen = (e: Event): any => { - this.fireOnConnect(); + public initialize(): Promise { + return new Promise((resolve, reject) => { + try { + this.conn = new WebSocket(this.url); + } catch(e) { + console.log(e); + } + this.connStatus = WebSocketStatus.WILL_CONNECT; + this.conn.onopen = (ev: Event): any => { + this.connStatus = WebSocketStatus.CONNECTED; + this.attachCallback(); + resolve(); + this.isReady = true; + return null; + }; + + this.conn.onerror = (ev: Event): any => { + this.connStatus = WebSocketStatus.NOT_CONNECT; + reject(new Error('Cannot connect to API Server.')); + return null; + }; + }); + } + + private attachCallback(): void { + this.conn.onopen = (ev: Event): any => { + this.connStatus = WebSocketStatus.CONNECTED; this.isReady = true; return null; }; - this.conn.onclose = (e: CloseEvent): any => { + this.conn.onclose = (ev: CloseEvent): any => { + this.connStatus = WebSocketStatus.NOT_CONNECT; this.fireOnDisconnect(); return null; }; - this.conn.onmessage = (e: MessageEvent): any => { - let response: ProtocolResponse = JSON.parse(e.data); + this.conn.onmessage = (ev: MessageEvent): any => { + let response: ProtocolResponse = JSON.parse(ev.data); let res: RPCResponse = JSON.parse(response.getBody()); const requestID = response.getID(); const error = response.getError(); @@ -105,16 +133,15 @@ export default class WebSocketRPC { // perhaps sever side send message } - this.fireOnMessage(e); + this.fireOnMessage(ev); }; + this.conn.onerror = (ev: Event): any => { + console.log(ev); + return null; + }; } - private fireOnConnect(): void { - for (let i = 0; i < this.onConnectListeners.length; i++) { - this.onConnectListeners[i](); - } - } private fireOnDisconnect(): void { for (let i = 0; i < this.onDisconnectListeners.length; i++) { diff --git a/src/ts/@overflow/probe/react/components/ProbeDetail.tsx b/src/ts/@overflow/probe/react/components/ProbeDetail.tsx index 533eb29..b331d77 100644 --- a/src/ts/@overflow/probe/react/components/ProbeDetail.tsx +++ b/src/ts/@overflow/probe/react/components/ProbeDetail.tsx @@ -9,7 +9,6 @@ import { Button, import { TargetTable } from '@overflow/temp/react/components/Targets'; import Probe from '@overflow/probe/api/model/Probe'; - export interface StateProps { probe: Probe; } @@ -45,7 +44,6 @@ export class ProbeDetail extends React.Component { } } - export class ProbeBasicInfo extends React.Component { constructor(props: Props, context: State) { From c5561a915e129adc6d1dffe96731887d3aed29a2 Mon Sep 17 00:00:00 2001 From: snoop Date: Thu, 20 Jul 2017 19:04:35 +0900 Subject: [PATCH 4/5] fixed sensor --- src/ts/@overflow/sensor/react/SensorDetail.tsx | 9 +++++---- .../sensor/react/components/SensorDetail.tsx | 4 ++-- .../sensor/react/components/SensorList.tsx | 5 +++-- src/ts/@overflow/sensor/redux/state/Read.ts | 16 +++++++++++++--- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/ts/@overflow/sensor/react/SensorDetail.tsx b/src/ts/@overflow/sensor/react/SensorDetail.tsx index f2d3754..7c2a594 100644 --- a/src/ts/@overflow/sensor/react/SensorDetail.tsx +++ b/src/ts/@overflow/sensor/react/SensorDetail.tsx @@ -4,21 +4,22 @@ import { SensorDetailStateProps, SensorDetailDispatchProps, } from './components/SensorDetail'; -import State from '../redux/state/ReadAllByTarget'; +import State from '../redux/state/Read'; -import * as ReadAllByTargetActions from '../redux/action/read_all_by_target'; +import * as ReadActions from '../redux/action/read'; import Target from '@overflow/target/api/model/Target'; import Sensor from '@overflow/sensor/api/model/Sensor'; export function mapStateToProps(state: any): SensorDetailStateProps { return { + sensor:state.sensor, }; } export function mapDispatchToProps(dispatch: Dispatch): SensorDetailDispatchProps { return { - onReadAllByTarget: (target: Target) => { - dispatch(ReadAllByTargetActions.request(target)); + onRead: (id: number) => { + dispatch(ReadActions.request(id)); }, }; } diff --git a/src/ts/@overflow/sensor/react/components/SensorDetail.tsx b/src/ts/@overflow/sensor/react/components/SensorDetail.tsx index 9e76b40..89b841d 100644 --- a/src/ts/@overflow/sensor/react/components/SensorDetail.tsx +++ b/src/ts/@overflow/sensor/react/components/SensorDetail.tsx @@ -11,7 +11,7 @@ export interface SensorDetailStateProps { } export interface SensorDetailDispatchProps { - + onRead?(id: number): void; } @@ -31,7 +31,7 @@ export class SensorDetail extends React.Component); + // return (); + return (); } return ( diff --git a/src/ts/@overflow/sensor/redux/state/Read.ts b/src/ts/@overflow/sensor/redux/state/Read.ts index 5c15c15..45212ae 100644 --- a/src/ts/@overflow/sensor/redux/state/Read.ts +++ b/src/ts/@overflow/sensor/redux/state/Read.ts @@ -1,3 +1,13 @@ -/** - * Created by geek on 17. 7. 3. - */ +import Sensor from '../../api/model/Sensor'; + +export interface State { + readonly isGetSensor: boolean; + readonly error?: Error; +} + +export const defaultState: State = { + isGetSensor: undefined, + error: undefined, +}; + +export default State; From 99277b75e42b86b3212c6ac0051d0db73536ef43 Mon Sep 17 00:00:00 2001 From: geek Date: Thu, 20 Jul 2017 19:17:46 +0900 Subject: [PATCH 5/5] discovery view create discovery component modify --- .../@overflow/discovery/react/Discovery.tsx | 21 +++++++++++++++++++ .../discovery/react/components/Discovery.tsx | 9 ++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/ts/@overflow/discovery/react/Discovery.tsx b/src/ts/@overflow/discovery/react/Discovery.tsx index e69de29..1446b40 100644 --- a/src/ts/@overflow/discovery/react/Discovery.tsx +++ b/src/ts/@overflow/discovery/react/Discovery.tsx @@ -0,0 +1,21 @@ +import { connect, Dispatch } from 'react-redux'; +import { + Discovery, + StateProps as DiscoveryStateProps, + DispatchProps as DiscoveryDispatchProps, +} from './components/Discovery'; + + +export function mapStateToProps(state: any): DiscoveryStateProps { + return { + + }; +} + +export function mapDispatchToProps(dispatch: Dispatch): DiscoveryDispatchProps { + return { + + }; +} + +export default connect(mapStateToProps, mapDispatchToProps)(Discovery); diff --git a/src/ts/@overflow/discovery/react/components/Discovery.tsx b/src/ts/@overflow/discovery/react/components/Discovery.tsx index ed7baa2..28f89d0 100644 --- a/src/ts/@overflow/discovery/react/components/Discovery.tsx +++ b/src/ts/@overflow/discovery/react/components/Discovery.tsx @@ -9,10 +9,15 @@ import { import { DiscoveryProbe } from './DiscoveryProbe'; import { DiscoveryTable } from './DiscoveryTable'; -export interface Props { - +export interface StateProps { } +export interface DispatchProps { + +} + +export type Props = StateProps & DispatchProps; + export interface State { startPopup:boolean; probeTemp: any;