Merge branch 'master' of https://git.loafle.net/overflow/overflow_app
This commit is contained in:
commit
1cdc1306de
|
@ -1,5 +1,8 @@
|
||||||
import { ReducersMapObject } from 'redux';
|
import { ReducersMapObject } from 'redux';
|
||||||
|
import { SagaWatcher } from '@overflow/commons/redux-saga';
|
||||||
|
|
||||||
import signInReducer from '@overflow/member/redux/reducer/signIn';
|
import signInReducer from '@overflow/member/redux/reducer/signIn';
|
||||||
|
import signInSagaWatchers from '@overflow/member/redux/saga/signIn';
|
||||||
|
|
||||||
// Container Configuration
|
// Container Configuration
|
||||||
export interface ContainerConfig {
|
export interface ContainerConfig {
|
||||||
|
@ -21,17 +24,23 @@ const rpcConfig: RPCConfig = {
|
||||||
export interface ReduxConfig {
|
export interface ReduxConfig {
|
||||||
state: ReduxState;
|
state: ReduxState;
|
||||||
reducerMaps: ReducersMapObject[];
|
reducerMaps: ReducersMapObject[];
|
||||||
|
sagaWarchers: (SagaWatcher[])[];
|
||||||
}
|
}
|
||||||
export interface ReduxState {
|
export interface ReduxState {
|
||||||
|
|
||||||
}
|
}
|
||||||
const reduxState: ReduxState = {};
|
const reduxState: ReduxState = {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const reduxConfig: ReduxConfig = {
|
const reduxConfig: ReduxConfig = {
|
||||||
state: reduxState,
|
state: reduxState,
|
||||||
reducerMaps: [
|
reducerMaps: [
|
||||||
signInReducer,
|
signInReducer,
|
||||||
],
|
],
|
||||||
|
sagaWarchers: [
|
||||||
|
signInSagaWatchers,
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,15 @@ import {
|
||||||
|
|
||||||
import createSagaMiddleware, {
|
import createSagaMiddleware, {
|
||||||
SagaMiddleware,
|
SagaMiddleware,
|
||||||
|
SagaIterator,
|
||||||
} from 'redux-saga';
|
} from 'redux-saga';
|
||||||
|
|
||||||
|
import {
|
||||||
|
fork,
|
||||||
|
} from 'redux-saga/effects';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createHashHistory,
|
createHashHistory,
|
||||||
History,
|
History,
|
||||||
|
@ -39,12 +46,10 @@ import AppContext from '@overflow/commons/context';
|
||||||
import * as AppContextLifecycleActions from '@overflow/commons/context/redux/action/lifecycle';
|
import * as AppContextLifecycleActions from '@overflow/commons/context/redux/action/lifecycle';
|
||||||
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
|
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
|
||||||
import ReducerContext from '@overflow/commons/redux/ReducerContext';
|
import ReducerContext from '@overflow/commons/redux/ReducerContext';
|
||||||
|
import { SagaWatcher } from '@overflow/commons/redux-saga';
|
||||||
|
|
||||||
import appConfig, { Config, ReduxState } from './config';
|
import appConfig, { Config, ReduxState } from './config';
|
||||||
|
|
||||||
import sagas from './redux/saga';
|
|
||||||
// import routes from './router';
|
|
||||||
|
|
||||||
import App from './views/App';
|
import App from './views/App';
|
||||||
|
|
||||||
injectTapEventPlugin();
|
injectTapEventPlugin();
|
||||||
|
@ -82,6 +87,7 @@ class Application {
|
||||||
|
|
||||||
this.context = await this.initContext();
|
this.context = await this.initContext();
|
||||||
// this.rpcClient = await this.initRpcClient();
|
// this.rpcClient = await this.initRpcClient();
|
||||||
|
// this.context.put(this.rpcClient);
|
||||||
|
|
||||||
await this.initRedux();
|
await this.initRedux();
|
||||||
|
|
||||||
|
@ -141,13 +147,21 @@ class Application {
|
||||||
Application.useReduxDevTools ? compose(middleware, window.devToolsExtension()) : middleware,
|
Application.useReduxDevTools ? compose(middleware, window.devToolsExtension()) : middleware,
|
||||||
);
|
);
|
||||||
// saga
|
// saga
|
||||||
this.sagaMiddleware.run(sagas);
|
this.sagaMiddleware.run(this.initReduxSagaWarchers, this.config.redux.sagaWarchers);
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
return init;
|
return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private * initReduxSagaWarchers(sagaWarchers: (SagaWatcher[])[]): SagaIterator {
|
||||||
|
for (let sagaWarcher of sagaWarchers) {
|
||||||
|
for (let warcher of sagaWarcher) {
|
||||||
|
yield fork(warcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private displayLoading(): void {
|
private displayLoading(): void {
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<div style={{
|
<div style={{
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
import { SagaIterator } from 'redux-saga';
|
|
||||||
import { fork } from 'redux-saga/effects';
|
|
||||||
|
|
||||||
import { watchSignin as memberWatchSignin } from '@overflow/member/redux/saga/signIn';
|
|
||||||
|
|
||||||
export default function* sagas(): SagaIterator {
|
|
||||||
yield fork(memberWatchSignin);
|
|
||||||
}
|
|
|
@ -9,6 +9,7 @@ import Home from '../Home';
|
||||||
import ProbeList from '../../views/monitoring/probe/List';
|
import ProbeList from '../../views/monitoring/probe/List';
|
||||||
import TargetList from '../../views/infrastructure/target/List';
|
import TargetList from '../../views/infrastructure/target/List';
|
||||||
import SensorList from '../monitoring/sensor/List';
|
import SensorList from '../monitoring/sensor/List';
|
||||||
|
import NoauthList from '../../views/monitoring/probe/NoAuth';
|
||||||
import TitleBarContainer from '@overflow/app/views/layout/TitleBarContainer';
|
import TitleBarContainer from '@overflow/app/views/layout/TitleBarContainer';
|
||||||
|
|
||||||
export interface Props extends RouteComponentProps<any> {
|
export interface Props extends RouteComponentProps<any> {
|
||||||
|
@ -37,6 +38,7 @@ export class AppLayout extends React.Component<Props, State> {
|
||||||
<Route exact={true} path={`${this.props.match.url}probes`} component={ProbeList}/>
|
<Route exact={true} path={`${this.props.match.url}probes`} component={ProbeList}/>
|
||||||
<Route exact={true} path={`${this.props.match.url}targets`} component={TargetList}/>
|
<Route exact={true} path={`${this.props.match.url}targets`} component={TargetList}/>
|
||||||
<Route exact={true} path={`${this.props.match.url}sensors`} component={SensorList}/>
|
<Route exact={true} path={`${this.props.match.url}sensors`} component={SensorList}/>
|
||||||
|
<Route exact={true} path={`${this.props.match.url}noauth_probes`} component={NoauthList}/>
|
||||||
<Redirect to='/error/404' />
|
<Redirect to='/error/404' />
|
||||||
</Switch>
|
</Switch>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
|
@ -52,6 +52,7 @@ class LeftMenu extends React.Component<Props, State> {
|
||||||
</Menu.Header>
|
</Menu.Header>
|
||||||
<Menu.Menu>
|
<Menu.Menu>
|
||||||
<Menu.Item onClick={(e) => this.props.onChangeUrl('/probes')} style={{ 'marginLeft': '30px' }}>Probe</Menu.Item>
|
<Menu.Item onClick={(e) => this.props.onChangeUrl('/probes')} style={{ 'marginLeft': '30px' }}>Probe</Menu.Item>
|
||||||
|
<Menu.Item onClick={(e) => this.props.onChangeUrl('/noauth_probes')} style={{ 'marginLeft': '30px' }}>NoauthProbe</Menu.Item>
|
||||||
<Menu.Item href='#/' style={{ 'marginLeft': '30px' }}>Sensors</Menu.Item>
|
<Menu.Item href='#/' style={{ 'marginLeft': '30px' }}>Sensors</Menu.Item>
|
||||||
</Menu.Menu>
|
</Menu.Menu>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import TitleBarContainer from './TitleBarContainer';
|
||||||
import LeftMenu from './LeftMenu';
|
import LeftMenu from './LeftMenu';
|
||||||
|
|
||||||
import ProbeDetail from '../../views/monitoring/probe/Detail';
|
import ProbeDetail from '../../views/monitoring/probe/Detail';
|
||||||
|
import ProbeHost from '../../views/monitoring/probe/Host';
|
||||||
import ProbeHistory from '../../views/monitoring/probe/History';
|
import ProbeHistory from '../../views/monitoring/probe/History';
|
||||||
import TargetList from '../../views/infrastructure/target/List';
|
import TargetList from '../../views/infrastructure/target/List';
|
||||||
|
|
||||||
|
@ -32,6 +33,10 @@ export class ProbeDetailLayout extends React.Component<Props, State> {
|
||||||
'name': 'Info',
|
'name': 'Info',
|
||||||
'path': this.state.currUrl,
|
'path': this.state.currUrl,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'name': 'Host',
|
||||||
|
'path': this.state.currUrl + '/host',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'name': 'History',
|
'name': 'History',
|
||||||
'path': this.state.currUrl + '/history',
|
'path': this.state.currUrl + '/history',
|
||||||
|
@ -49,6 +54,7 @@ export class ProbeDetailLayout extends React.Component<Props, State> {
|
||||||
<TitleBarContainer sub={sub} location={this.props.location.pathname}/>
|
<TitleBarContainer sub={sub} location={this.props.location.pathname}/>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact={true} path={`${this.props.match.url}/:id`} component={ProbeDetail} />
|
<Route exact={true} path={`${this.props.match.url}/:id`} component={ProbeDetail} />
|
||||||
|
<Route exact={true} path={`${this.props.match.url}/:id/host`} component={ProbeHost} />
|
||||||
<Route exact={true} path={`${this.props.match.url}/:id/history`} component={ProbeHistory} />
|
<Route exact={true} path={`${this.props.match.url}/:id/history`} component={ProbeHistory} />
|
||||||
<Route exact={true} path={`${this.props.match.url}/:id/targets`} component={TargetList} />
|
<Route exact={true} path={`${this.props.match.url}/:id/targets`} component={TargetList} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
26
src/ts/@overflow/app/views/monitoring/probe/Host.tsx
Normal file
26
src/ts/@overflow/app/views/monitoring/probe/Host.tsx
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { RouteComponentProps } from 'react-router';
|
||||||
|
import ProbeHostContainer from '@overflow/probe/react/ProbeHost';
|
||||||
|
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
|
||||||
|
import AppContext from '@overflow/commons/context';
|
||||||
|
import inject from '@overflow/commons/context/decorator/inject';
|
||||||
|
|
||||||
|
class ProbeHost extends React.Component<RouteComponentProps<object>, object> {
|
||||||
|
@inject()
|
||||||
|
private client: WebSocketRPC;
|
||||||
|
|
||||||
|
public constructor(props?: RouteComponentProps<object>, context?: object) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
|
let con = AppContext.get<WebSocketRPC>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<ProbeHostContainer params={this.props.match.params}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default ProbeHost;
|
|
@ -10,9 +10,14 @@ abstract class Service {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected send(methodName: string, ...params: any[]): Promise<string> {
|
protected send<T>(methodName: string, ...params: any[]): Promise<T> {
|
||||||
return new Promise<string>(resolve => {
|
return this.webSocketRPC.Call(methodName, params)
|
||||||
resolve('');
|
.then(body => {
|
||||||
|
const o: T = JSON.parse(body);
|
||||||
|
return o;
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
throw e;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,4 @@ export const PARAM_TYPES = 'overflow:paramtypes';
|
||||||
export const DESIGN_PARAM_TYPES = 'design:paramtypes';
|
export const DESIGN_PARAM_TYPES = 'design:paramtypes';
|
||||||
|
|
||||||
// The type of the binding at design time
|
// The type of the binding at design time
|
||||||
export const INJECT_TAG = 'inject';
|
export const INJECT_TAG = '__inject__';
|
||||||
|
|
|
@ -5,13 +5,24 @@ export interface Config {
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const inject = (config?: Config) => {
|
const inject = (config?: Config) => {
|
||||||
return (target: Object, propertyKey: string | symbol, parameterIndex?: number): void => {
|
return (target: Object, propertyKey: string | symbol, parameterIndex?: number): void => {
|
||||||
if (typeof parameterIndex === 'number') {
|
if (typeof parameterIndex === 'number') {
|
||||||
// tagParameter(target, targetKey, index, metadata);
|
// tagParameter(target, targetKey, index, metadata);
|
||||||
} else {
|
} else {
|
||||||
let types = Reflect.getMetadata('design:type', target, propertyKey);
|
if (Reflect.hasOwnMetadata(METADATA.INJECT_TAG, target)) {
|
||||||
|
let meta = Reflect.getMetadata(METADATA.INJECT_TAG, target);
|
||||||
|
} else {
|
||||||
|
let meta: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let types = Reflect.getMetadata(METADATA.INJECT_TAG, target);
|
||||||
|
|
||||||
|
// Reflect.defineMetadata(METADATA.PARAM_TYPES, types, target);
|
||||||
|
|
||||||
|
console.log(types);
|
||||||
// tagProperty(target, targetKey, metadata);
|
// tagProperty(target, targetKey, metadata);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
|
import * as METADATA from './constants';
|
||||||
|
|
||||||
class AppContext {
|
class AppContext {
|
||||||
private static context: AppContext = null;
|
private static context: AppContext = null;
|
||||||
|
private instanceMap: Map<string, Function>;
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
|
this.instanceMap = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getService<T>(): T {
|
public put(instance: any, name?: string): void {
|
||||||
return null;
|
if (typeof name !== 'string') {
|
||||||
|
if (instance instanceof Function) {
|
||||||
|
name = (<Function>instance).name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.instanceMap.set(name, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getService<T>(clazz: {new(...args: any[]): T}): T {
|
||||||
|
let types = Reflect.getMetadata(METADATA.PARAM_TYPES, clazz);
|
||||||
|
|
||||||
|
let i = new clazz();
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static get<T>(): T {
|
public static get<T>(): T {
|
||||||
|
@ -15,10 +31,8 @@ class AppContext {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static put<T>(instance: T): void {
|
public static put(instance: any, name?: string): void {
|
||||||
|
AppContext.getContext().put(instance, name);
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getContext(): AppContext {
|
public static getContext(): AppContext {
|
||||||
|
|
3
src/ts/@overflow/commons/redux-saga/index.ts
Normal file
3
src/ts/@overflow/commons/redux-saga/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { SagaIterator } from 'redux-saga';
|
||||||
|
|
||||||
|
export type SagaWatcher = () => SagaIterator;
|
|
@ -6,7 +6,8 @@ interface ReducerItem<State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReducerContext {
|
class ReducerContext {
|
||||||
private static instance: ReducerContext = new ReducerContext();
|
private static readonly instance: ReducerContext = new ReducerContext();
|
||||||
|
private static readonly sagaActionKey: string = '@@redux-saga/SAGA_ACTION';
|
||||||
private reducerMap: Map<string, ReducerItem<any>[]>;
|
private reducerMap: Map<string, ReducerItem<any>[]>;
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
|
@ -26,7 +27,9 @@ class ReducerContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static reducer<State, A extends Action>(state: State, action: A): State {
|
public static reducer<State, A extends Action>(state: State, action: A): State {
|
||||||
const actionType = action.type;
|
const actionType: string = action.type;
|
||||||
|
const isSagaAction = action.hasOwnProperty(ReducerContext.sagaActionKey) ? action[ReducerContext.sagaActionKey] : false;
|
||||||
|
|
||||||
if (ReducerContext.getInstance().reducerMap.has(actionType)) {
|
if (ReducerContext.getInstance().reducerMap.has(actionType)) {
|
||||||
let reducerItems = ReducerContext.getInstance().reducerMap.get(actionType);
|
let reducerItems = ReducerContext.getInstance().reducerMap.get(actionType);
|
||||||
for (let reducerItem of reducerItems) {
|
for (let reducerItem of reducerItems) {
|
||||||
|
@ -34,8 +37,10 @@ class ReducerContext {
|
||||||
state = reducer(state, action);
|
state = reducer(state, action);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (-1 === actionType.indexOf('@@')) {
|
||||||
console.log(`Reducer for [${actionType}] is not exist in the context.`);
|
console.log(`Reducer for [${actionType}] is not exist in the context.`);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import Action from './Action';
|
|
||||||
import * as Redux from 'redux';
|
|
||||||
|
|
||||||
// export type Reducer<S> = <A extends Action>(state: S, action: A) => S;
|
|
||||||
|
|
||||||
// export interface ReducersMapObject {
|
|
||||||
// [key: string]: Reducer<any>;
|
|
||||||
// }
|
|
||||||
|
|
||||||
const createReducer = <State>(initialState: State, handlers: Redux.ReducersMapObject): Redux.Reducer<State> => {
|
|
||||||
return <A extends Action>(state: State = initialState, action: A): State => {
|
|
||||||
if (handlers[action.type]) {
|
|
||||||
return handlers[action.type](state, action);
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createReducer;
|
|
|
@ -58,10 +58,8 @@ export default class WebSocketRPC {
|
||||||
this.requestQueue = new Map();
|
this.requestQueue = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Call(method: string, params: any[]): Promise<any> {
|
public Call(method: string, params: any[]): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
|
||||||
return new Promise<any>((resolve, reject) => {
|
|
||||||
const requestID = this.getRequestID();
|
const requestID = this.getRequestID();
|
||||||
let request = new ProtocolRequest<ID_TYPE>(RPCProtocol, requestID);
|
let request = new ProtocolRequest<ID_TYPE>(RPCProtocol, requestID);
|
||||||
let req = new RPCRequest(method, params);
|
let req = new RPCRequest(method, params);
|
||||||
|
|
|
@ -12,12 +12,7 @@ export class MemberService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
public signin(signinId: string, signinPw: string): Promise<Member> {
|
public signin(signinId: string, signinPw: string): Promise<Member> {
|
||||||
return new Promise<Member>(resolve => {
|
return this.send<Member>('signin', [signinId, signinPw]);
|
||||||
const json = this.send('signin', [signinId, signinPw]);
|
|
||||||
let member: Member;
|
|
||||||
// member = ........(json);
|
|
||||||
resolve(member);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public signout(member: Member): Member {
|
public signout(member: Member): Member {
|
||||||
|
|
|
@ -9,13 +9,13 @@ import State from '../redux/state/SignIn';
|
||||||
import * as signinActions from '../redux/action/signIn';
|
import * as signinActions from '../redux/action/signIn';
|
||||||
|
|
||||||
|
|
||||||
export function mapStateToProps(state: any): SignInStateProps {
|
export function mapStateToProps(state: any, ownProps?: any): SignInStateProps {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapDispatchToProps(dispatch: Dispatch<any>): SigninDispatchProps {
|
export function mapDispatchToProps(dispatch: Dispatch<any>, ownProps?: any): SigninDispatchProps {
|
||||||
return {
|
return {
|
||||||
onSignIn: (signinId: string, signinPw: string) => {
|
onSignIn: (signinId: string, signinPw: string) => {
|
||||||
dispatch(signinActions.request(signinId, signinPw));
|
dispatch(signinActions.request(signinId, signinPw));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { SagaIterator } from 'redux-saga';
|
import { SagaIterator } from 'redux-saga';
|
||||||
import { call, Effect, fork, put, takeLatest } from 'redux-saga/effects';
|
import { call, Effect, fork, put, takeLatest } from 'redux-saga/effects';
|
||||||
|
|
||||||
|
import { SagaWatcher } from '@overflow/commons/redux-saga';
|
||||||
|
|
||||||
import AppContext from '@overflow/commons/context';
|
import AppContext from '@overflow/commons/context';
|
||||||
import Action from '@overflow/commons/redux/Action';
|
import Action from '@overflow/commons/redux/Action';
|
||||||
|
@ -18,7 +19,7 @@ function* signin(action: Action<SigninPayload>): SagaIterator {
|
||||||
// payload: {sendingRequest: true},
|
// payload: {sendingRequest: true},
|
||||||
// });
|
// });
|
||||||
|
|
||||||
const member = yield call(AppContext.getService<MemberService>().signin, signinId, signinPw);
|
const member = yield call(AppContext.getService(MemberService).signin, signinId, signinPw);
|
||||||
|
|
||||||
// if (responseBody.token === undefined) {
|
// if (responseBody.token === undefined) {
|
||||||
// throw new Error(MESSAGES.UNABLE_TO_FIND_TOKEN_IN_LOGIN_RESPONSE);
|
// throw new Error(MESSAGES.UNABLE_TO_FIND_TOKEN_IN_LOGIN_RESPONSE);
|
||||||
|
@ -34,6 +35,10 @@ function* signin(action: Action<SigninPayload>): SagaIterator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function* watchSignin(): SagaIterator {
|
function* watchSignin(): SagaIterator {
|
||||||
yield takeLatest(SigninActions.REQUEST, signin);
|
yield takeLatest(SigninActions.REQUEST, signin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sagaWatchers: SagaWatcher[] = [watchSignin];
|
||||||
|
|
||||||
|
export default sagaWatchers;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Table,
|
import {
|
||||||
|
Table,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Button,
|
Button,
|
||||||
Header,
|
Header,
|
||||||
|
@ -100,7 +101,7 @@ export class NoauthProbeList extends React.Component<any, any> {
|
||||||
alert(this.state.selected);
|
alert(this.state.selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public handleRowActive(id: string):boolean {
|
public handleRowActive(id: string): boolean {
|
||||||
if (this.state.selected.indexOf(id) === -1) {
|
if (this.state.selected.indexOf(id) === -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,6 @@ export class NoauthProbeList extends React.Component<any, any> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container fluid>
|
<Container fluid>
|
||||||
<Header as='h3' dividing>Noauth Probes</Header>
|
|
||||||
<Table celled selectable striped>
|
<Table celled selectable striped>
|
||||||
<Table.Header>
|
<Table.Header>
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
|
@ -140,10 +140,16 @@ export class NoauthProbeList extends React.Component<any, any> {
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
))}
|
))}
|
||||||
</Table.Body>
|
</Table.Body>
|
||||||
</Table>
|
<Table.Footer>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.HeaderCell colSpan='7'>
|
||||||
<Button primary floated={'right'} onClick={this.handleAccept.bind(this)}>Accept</Button>
|
<Button primary floated={'right'} onClick={this.handleAccept.bind(this)}>Accept</Button>
|
||||||
<Button floated={'right'} onClick={this.handleDeny.bind(this)}>Deny</Button>
|
<Button floated={'right'} onClick={this.handleDeny.bind(this)}>Deny</Button>
|
||||||
|
</Table.HeaderCell>
|
||||||
|
</Table.Row>
|
||||||
|
</Table.Footer>
|
||||||
|
</Table>
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {
|
||||||
DispatchProps as ProbeDetailDispatchProps,
|
DispatchProps as ProbeDetailDispatchProps,
|
||||||
} from './components/ProbeDetailInfo';
|
} from './components/ProbeDetailInfo';
|
||||||
import { push as routerPush } from 'react-router-redux';
|
import { push as routerPush } from 'react-router-redux';
|
||||||
import Probe from '@overflow/probe/api/model/Probe';
|
|
||||||
|
|
||||||
|
|
||||||
export function mapStateToProps(state: any, props: any): ProbeDetailStateProps {
|
export function mapStateToProps(state: any, props: any): ProbeDetailStateProps {
|
||||||
|
@ -16,9 +15,6 @@ export function mapStateToProps(state: any, props: any): ProbeDetailStateProps {
|
||||||
|
|
||||||
export function mapDispatchToProps(dispatch: Dispatch<any>): ProbeDetailDispatchProps {
|
export function mapDispatchToProps(dispatch: Dispatch<any>): ProbeDetailDispatchProps {
|
||||||
return {
|
return {
|
||||||
// onDiscoverySelect: ( id: string) => {
|
|
||||||
// dispatch(routerPush('/discovery/' + id ));
|
|
||||||
// },
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
src/ts/@overflow/probe/react/ProbeHost.tsx
Normal file
21
src/ts/@overflow/probe/react/ProbeHost.tsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { connect, Dispatch } from 'react-redux';
|
||||||
|
import {
|
||||||
|
ProbeHost,
|
||||||
|
StateProps as ProbeDetailStateProps,
|
||||||
|
DispatchProps as ProbeDetailDispatchProps,
|
||||||
|
} from './components/ProbeHost';
|
||||||
|
import { push as routerPush } from 'react-router-redux';
|
||||||
|
|
||||||
|
|
||||||
|
export function mapStateToProps(state: any, props: any): ProbeDetailStateProps {
|
||||||
|
return {
|
||||||
|
id: props.params.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapDispatchToProps(dispatch: Dispatch<any>): ProbeDetailDispatchProps {
|
||||||
|
return {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(ProbeHost);
|
|
@ -7,9 +7,8 @@ import {
|
||||||
Header,
|
Header,
|
||||||
Container,
|
Container,
|
||||||
} from 'semantic-ui-react';
|
} from 'semantic-ui-react';
|
||||||
// import { TargetTable } from '@overflow/target/react/components/TargetList';
|
|
||||||
import Probe from '@overflow/probe/api/model/Probe';
|
import Probe from '@overflow/probe/api/model/Probe';
|
||||||
import {Discovery} from '../../../discovery/react/components/Discovery';
|
import { Discovery } from '../../../discovery/react/components/Discovery';
|
||||||
|
|
||||||
export interface StateProps {
|
export interface StateProps {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -22,9 +21,8 @@ export interface DispatchProps {
|
||||||
export type Props = StateProps & DispatchProps;
|
export type Props = StateProps & DispatchProps;
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
probe: Probe;
|
probe: any; // todo. fix to Probe
|
||||||
id: string;
|
isDiscovery: boolean;
|
||||||
isDiscovery:boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,15 +32,41 @@ export class ProbeDetailInfo extends React.Component<Props, State> {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.state = {
|
this.state = {
|
||||||
probe: null,
|
probe: null,
|
||||||
id: '44',
|
|
||||||
isDiscovery: false,
|
isDiscovery: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillMount(): void {
|
public componentWillMount(): void {
|
||||||
|
|
||||||
|
// todo. getting probe by probeId
|
||||||
|
let p = {
|
||||||
|
'id': '11',
|
||||||
|
'status': {
|
||||||
|
'name': 'STARTED',
|
||||||
|
},
|
||||||
|
'domain': {
|
||||||
|
'name': 'insanity\'s domain',
|
||||||
|
},
|
||||||
|
'displayName': '192.168.1.105\'s probe',
|
||||||
|
'network': {
|
||||||
|
'cidr': '192.168.1.0/24',
|
||||||
|
'ip': '192.168.1.105',
|
||||||
|
'mac': 'ab:cd:ef:gh:ij',
|
||||||
|
},
|
||||||
|
'targetCount': '20',
|
||||||
|
'sensorCount': '30',
|
||||||
|
'probeKey': '1AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
||||||
|
'description': 'description1111111111',
|
||||||
|
'createDate': '2017-01-01',
|
||||||
|
'authorizeDate': '2017-01-01',
|
||||||
|
'restartDate': '2017-01-01',
|
||||||
|
'authorizeMember': {
|
||||||
|
'name': 'insanity',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
probe: null,
|
probe: p,
|
||||||
id: '44',
|
|
||||||
isDiscovery: false,
|
isDiscovery: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -53,18 +77,18 @@ export class ProbeDetailInfo extends React.Component<Props, State> {
|
||||||
|
|
||||||
public handleDiscovery = (event: any, data: any): void => {
|
public handleDiscovery = (event: any, data: any): void => {
|
||||||
console.log(event);
|
console.log(event);
|
||||||
// let probeId = String(this.state.id);
|
this.setState({ isDiscovery: true });
|
||||||
// this.props.onDiscoverySelect(this.state.id);
|
}
|
||||||
// if (this.state.isDiscovery) {
|
|
||||||
// this.setState({isDiscovery: false});
|
|
||||||
// } else {
|
|
||||||
// this.setState({isDiscovery: true});
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
public renderDiscovery(): JSX.Element {
|
||||||
|
if (this.state.isDiscovery) {
|
||||||
|
return <Discovery />;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public showStartStopBtn(): JSX.Element {
|
public showStartStopBtn(): JSX.Element {
|
||||||
return <Button content='Stop' icon='stop' labelPosition='left' negative/>;
|
return <Button content='Stop' icon='stop' labelPosition='left' negative />;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): JSX.Element {
|
||||||
|
@ -74,65 +98,62 @@ export class ProbeDetailInfo extends React.Component<Props, State> {
|
||||||
<Table.Body>
|
<Table.Body>
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Cell collapsing>
|
<Table.Cell collapsing>
|
||||||
<Header size='small'>Domain</Header>
|
<Header size='small'>Name</Header>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>todo</Table.Cell>
|
<Table.Cell>{this.state.probe.displayName}</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Cell collapsing>
|
<Table.Cell collapsing>
|
||||||
<Header size='small'>Status</Header>
|
<Header size='small'>Status</Header>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>todo</Table.Cell>
|
<Table.Cell>{this.state.probe.status.name}</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Cell collapsing>
|
<Table.Cell collapsing>
|
||||||
<Header size='small'>Host IP</Header>
|
<Header size='small'>Created at</Header>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>todo</Table.Cell>
|
<Table.Cell>{this.state.probe.createDate}</Table.Cell>
|
||||||
</Table.Row>
|
|
||||||
<Table.Row>
|
|
||||||
<Table.Cell collapsing>
|
|
||||||
<Header size='small'>Host Name</Header>
|
|
||||||
</Table.Cell>
|
|
||||||
<Table.Cell>todo</Table.Cell>
|
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Cell collapsing>
|
<Table.Cell collapsing>
|
||||||
<Header size='small'>Authorized at</Header>
|
<Header size='small'>Authorized at</Header>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>todo</Table.Cell>
|
<Table.Cell>{this.state.probe.authorizeDate}</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.Cell collapsing>
|
||||||
|
<Header size='small'>Authorized by</Header>
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell>{this.state.probe.authorizeMember.name}</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.Cell collapsing>
|
||||||
|
<Header size='small'>Uptime</Header>
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell>todo.</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.Cell collapsing>
|
<Table.Cell collapsing>
|
||||||
<Header size='small'>Description</Header>
|
<Header size='small'>Description</Header>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>todo</Table.Cell>
|
<Table.Cell>{this.state.probe.description}</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
</Table.Body>
|
</Table.Body>
|
||||||
<Table.Footer>
|
<Table.Footer>
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.HeaderCell colSpan='2'>
|
<Table.HeaderCell colSpan='2'>
|
||||||
{this.showStartStopBtn()}
|
{this.showStartStopBtn()}
|
||||||
<Button content='Discovery' icon='search' labelPosition='left' floated={'right'} positive onClick={this.handleDiscovery}/>
|
<Button content='Discovery' icon='search' labelPosition='left' floated={'right'} positive onClick={this.handleDiscovery} />
|
||||||
</Table.HeaderCell>
|
</Table.HeaderCell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
</Table.Footer>
|
</Table.Footer>
|
||||||
|
|
||||||
</Table>
|
</Table>
|
||||||
{/* {this.showStartStopBtn()} */}
|
{/* {this.showStartStopBtn()} */}
|
||||||
|
{this.renderDiscovery()}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private showDiscovery = ():JSX.Element => {
|
|
||||||
if (!this.state.isDiscovery) {
|
|
||||||
this.setState({isDiscovery:true});
|
|
||||||
return <Discovery/>;
|
|
||||||
} else {
|
|
||||||
this.setState({isDiscovery:false});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
57
src/ts/@overflow/probe/react/components/ProbeHost.tsx
Normal file
57
src/ts/@overflow/probe/react/components/ProbeHost.tsx
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Table,
|
||||||
|
Label,
|
||||||
|
Segment,
|
||||||
|
Header,
|
||||||
|
Container,
|
||||||
|
} from 'semantic-ui-react';
|
||||||
|
import Probe from '@overflow/probe/api/model/Probe';
|
||||||
|
|
||||||
|
export interface StateProps {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DispatchProps {
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Props = StateProps & DispatchProps;
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
probe: any; // todo. fix to Probe
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class ProbeHost extends React.Component<Props, State> {
|
||||||
|
|
||||||
|
constructor(props: Props, context: State) {
|
||||||
|
super(props, context);
|
||||||
|
this.state = {
|
||||||
|
probe: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentWillMount(): void {
|
||||||
|
console.log(this.props.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<Table celled={false}>
|
||||||
|
<Table.Body>
|
||||||
|
<Table.Row>
|
||||||
|
<Table.Cell collapsing>
|
||||||
|
<Header size='small'>Name</Header>
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell>todo</Table.Cell>
|
||||||
|
</Table.Row>
|
||||||
|
</Table.Body>
|
||||||
|
</Table>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,47 +36,60 @@ export class ProbeList extends React.Component<Props, State> {
|
||||||
this.data = [
|
this.data = [
|
||||||
{
|
{
|
||||||
'id': '11',
|
'id': '11',
|
||||||
'metaProbeStatus': {
|
'status': {
|
||||||
'name': 'STARTED',
|
'name': 'STARTED',
|
||||||
},
|
},
|
||||||
'domain': {
|
'domain': {
|
||||||
'name': 'asus',
|
'name': 'insanity\'s domain',
|
||||||
},
|
},
|
||||||
|
'displayName': '192.168.1.105\'s probe',
|
||||||
|
'network': {
|
||||||
|
'cidr': '192.168.1.0/24',
|
||||||
|
'ip': '192.168.1.105',
|
||||||
|
'mac': 'ab:cd:ef:gh:ij',
|
||||||
|
},
|
||||||
|
'targetCount': '20',
|
||||||
|
'sensorCount': '30',
|
||||||
'probeKey': '1AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
'probeKey': '1AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
||||||
'description': 'description1111111111',
|
'description': 'description1111111111',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'id': '22',
|
'id': '22',
|
||||||
'metaProbeStatus': {
|
'status': {
|
||||||
'name': 'STOPPED',
|
|
||||||
},
|
|
||||||
'domain': {
|
|
||||||
'name': 'ottugi',
|
|
||||||
},
|
|
||||||
'probeKey': '2AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
|
||||||
'description': 'description22222222',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'id': '33',
|
|
||||||
'metaProbeStatus': {
|
|
||||||
'name': 'STOPPED',
|
|
||||||
},
|
|
||||||
'domain': {
|
|
||||||
'name': 'lg',
|
|
||||||
},
|
|
||||||
'probeKey': '3AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
|
||||||
'description': 'description33333',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'id': '44',
|
|
||||||
'metaProbeStatus': {
|
|
||||||
'name': 'STARTED',
|
'name': 'STARTED',
|
||||||
},
|
},
|
||||||
'domain': {
|
'domain': {
|
||||||
'name': 'apple',
|
'name': 'insanity\'s domain',
|
||||||
},
|
},
|
||||||
'probeKey': '4AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
'displayName': '192.168.1.105\'s probe',
|
||||||
'description': 'description4444',
|
'network': {
|
||||||
|
'cidr': '192.168.1.0/24',
|
||||||
|
'ip': '192.168.1.105',
|
||||||
|
'mac': 'ab:cd:ef:gh:ij',
|
||||||
|
},
|
||||||
|
'targetCount': '20',
|
||||||
|
'sensorCount': '30',
|
||||||
|
'probeKey': '1AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
||||||
|
'description': 'description1111111111',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': '33',
|
||||||
|
'status': {
|
||||||
|
'name': 'STARTED',
|
||||||
|
},
|
||||||
|
'domain': {
|
||||||
|
'name': 'insanity\'s domain',
|
||||||
|
},
|
||||||
|
'displayName': '192.168.1.105\'s probe',
|
||||||
|
'network': {
|
||||||
|
'cidr': '192.168.1.0/24',
|
||||||
|
'ip': '192.168.1.105',
|
||||||
|
'mac': 'ab:cd:ef:gh:ij',
|
||||||
|
},
|
||||||
|
'targetCount': '20',
|
||||||
|
'sensorCount': '30',
|
||||||
|
'probeKey': '1AGBLKDFJ2452ASDGFL2KWJLKSDJ',
|
||||||
|
'description': 'description1111111111',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -131,6 +144,7 @@ export class ProbeList extends React.Component<Props, State> {
|
||||||
<Table.Row>
|
<Table.Row>
|
||||||
<Table.HeaderCell textAlign={'center'}>Name</Table.HeaderCell>
|
<Table.HeaderCell textAlign={'center'}>Name</Table.HeaderCell>
|
||||||
<Table.HeaderCell textAlign={'center'}>CIDR</Table.HeaderCell>
|
<Table.HeaderCell textAlign={'center'}>CIDR</Table.HeaderCell>
|
||||||
|
<Table.HeaderCell textAlign={'center'}>IP</Table.HeaderCell>
|
||||||
<Table.HeaderCell textAlign={'center'}>Status</Table.HeaderCell>
|
<Table.HeaderCell textAlign={'center'}>Status</Table.HeaderCell>
|
||||||
<Table.HeaderCell textAlign={'center'}>Target Count</Table.HeaderCell>
|
<Table.HeaderCell textAlign={'center'}>Target Count</Table.HeaderCell>
|
||||||
<Table.HeaderCell textAlign={'center'}>Sensor Count</Table.HeaderCell>
|
<Table.HeaderCell textAlign={'center'}>Sensor Count</Table.HeaderCell>
|
||||||
|
@ -156,16 +170,17 @@ export class ProbeList extends React.Component<Props, State> {
|
||||||
private renderRows(): (JSX.Element | JSX.Element[]) {
|
private renderRows(): (JSX.Element | JSX.Element[]) {
|
||||||
if (this.state.list.length === 0) {
|
if (this.state.list.length === 0) {
|
||||||
return <Table.Row error >
|
return <Table.Row error >
|
||||||
<Table.Cell textAlign='center' colSpan='5'>No results found.</Table.Cell>
|
<Table.Cell textAlign='center' colSpan='6'>No results found.</Table.Cell>
|
||||||
</Table.Row>;
|
</Table.Row>;
|
||||||
}
|
}
|
||||||
return this.state.list.map((probe: any, index: number) => (
|
return this.state.list.map((probe: any, index: number) => (
|
||||||
<Table.Row key={index} onClick={this.handleSelect.bind(this, probe)}>
|
<Table.Row key={index} onClick={this.handleSelect.bind(this, probe)}>
|
||||||
<Table.Cell >{probe.domain.name}</Table.Cell>
|
<Table.Cell >{probe.displayName}</Table.Cell>
|
||||||
<Table.Cell>{index}</Table.Cell>
|
<Table.Cell>{probe.network.cidr}</Table.Cell>
|
||||||
<Table.Cell negative={this.checkCellStatus(probe.metaProbeStatus)} textAlign={'center'}>{probe.metaProbeStatus.name}</Table.Cell>
|
<Table.Cell>{probe.network.ip}</Table.Cell>
|
||||||
<Table.Cell textAlign={'center'} >todo. {probe.targetCnt}</Table.Cell>
|
<Table.Cell negative={this.checkCellStatus(probe.status)} textAlign={'center'}>{probe.status.name}</Table.Cell>
|
||||||
<Table.Cell textAlign={'center'} >todo. {probe.sensorCnt}</Table.Cell>
|
<Table.Cell textAlign={'center'} >{probe.targetCount}</Table.Cell>
|
||||||
|
<Table.Cell textAlign={'center'} >{probe.sensorCount}</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user