diff --git a/src/ts/@overflow/app/router/index.tsx b/src/ts/@overflow/app/router/index.tsx
index 70ee64a..e5afd67 100644
--- a/src/ts/@overflow/app/router/index.tsx
+++ b/src/ts/@overflow/app/router/index.tsx
@@ -5,11 +5,124 @@ import Signin from '../views/member/Signin';
const routes = (
+
-
-
+
);
export default routes;
+
+const _routes = [
+ {
+ path: '/signin',
+ component: Signin,
+ },
+ {
+ path: '/signup',
+ component: Signup,
+ },
+ {
+ path: '/forgot_password',
+ component: ForgotPassword,
+ },
+ {
+ path: '/email_confirm',
+ component: EmailConfirm,
+ },
+ {
+ path: '/',
+ component: Home,
+ routes: [
+ {
+ path: '/monitoring',
+ component: Monitoring,
+ routes: [
+ {
+ path: '/probe',
+ component: Probe,
+ routes: [
+ {
+ path: '/list',
+ component: Probe,
+ },
+ {
+ path: '/noauth',
+ component: NoAuthProbe,
+ },
+ {
+ path: '/setup',
+ component: ProbeSetup,
+ },
+ ],
+ },
+ {
+ path: '/sensor',
+ component: Sensor,
+ },
+ ],
+ },
+ {
+ path: '/infrastructure',
+ component: ,
+ routes: [
+ {
+ path: '/maps',
+ component: InfrastructureMaps,
+ },
+ {
+ path: '/targets',
+ component: Targets,
+ },
+ ],
+ },
+ {
+ path: '/dashboard',
+ component: Dashboard,
+ },
+ {
+ path: '/metrics',
+ component: Metrics,
+ },
+ {
+ path: '/alerts',
+ component: Alerts,
+ },
+ {
+ path: '/history',
+ component: History,
+ },
+ {
+ path: '/settings',
+ component: Settings,
+ },
+ {
+ path: '/notifications',
+ component: Notifications,
+ },
+ {
+ path: '/account',
+ component: ,
+ routes: [
+ {
+ path: '/signout',
+ component: Signout,
+ },
+ {
+ path: '/profile',
+ component: Profile,
+ },
+ {
+ path: '/preferences',
+ component: Preferences,
+ },
+ {
+ path: '/help',
+ component: Help,
+ },
+ ],
+ },
+ ],
+ },
+];
diff --git a/src/ts/@overflow/app/views/Home.tsx b/src/ts/@overflow/app/views/Home.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/alert/Alert.tsx b/src/ts/@overflow/app/views/alert/Alert.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/dashboard/Dashboard.tsx b/src/ts/@overflow/app/views/dashboard/Dashboard.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/help/Help.tsx b/src/ts/@overflow/app/views/help/Help.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/history/History.tsx b/src/ts/@overflow/app/views/history/History.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/infrastructure/maps/Maps.tsx b/src/ts/@overflow/app/views/infrastructure/maps/Maps.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/infrastructure/target/List.tsx b/src/ts/@overflow/app/views/infrastructure/target/List.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/member/EmailConfirm.tsx b/src/ts/@overflow/app/views/member/EmailConfirm.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/member/ForgotPassword.tsx b/src/ts/@overflow/app/views/member/ForgotPassword.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/member/Signout.tsx b/src/ts/@overflow/app/views/member/Signout.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/member/Signup.tsx b/src/ts/@overflow/app/views/member/Signup.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/metric/Metric.tsx b/src/ts/@overflow/app/views/metric/Metric.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/monitoring/probe/List.tsx b/src/ts/@overflow/app/views/monitoring/probe/List.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/monitoring/probe/NoAuth.tsx b/src/ts/@overflow/app/views/monitoring/probe/NoAuth.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/monitoring/probe/Setup.tsx b/src/ts/@overflow/app/views/monitoring/probe/Setup.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/monitoring/sensor/List.tsx b/src/ts/@overflow/app/views/monitoring/sensor/List.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/notification/Notification.tsx b/src/ts/@overflow/app/views/notification/Notification.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/app/views/setting/Setting.tsx b/src/ts/@overflow/app/views/setting/Setting.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/commons/api/Client.ts b/src/ts/@overflow/commons/api/Client.ts
index de07fea..1d70be4 100644
--- a/src/ts/@overflow/commons/api/Client.ts
+++ b/src/ts/@overflow/commons/api/Client.ts
@@ -1,13 +1,256 @@
+export type OnConnectFunc = () => void;
+export type OnWebsocketDisconnectFunc = () => void;
+export type OnWebsocketNativeMessageFunc = (websocketMessage: string) => void;
+export type OnMessageFunc = (message: any) => void;
+
+enum MessageType {
+ STRING = 1,
+ INT,
+ BOOLEAN,
+ JSON,
+}
+
class Client {
- private wss: WebSocket;
+ private conn: WebSocket;
+ private isReady: boolean;
+ // events listeners
+ private connectListeners: OnConnectFunc[] = [];
+ private disconnectListeners: OnWebsocketDisconnectFunc[] = [];
+ private nativeMessageListeners: OnWebsocketNativeMessageFunc[] = [];
+ private messageListeners: { [event: string]: OnMessageFunc[] } = {};
+
+ constructor(endpoint: string, protocols?: string[]) {
+ // if (!window.WebSocket) {
+ // return;
+ // }
+
+ if (endpoint.indexOf('ws') === -1) {
+ endpoint = 'ws://' + endpoint;
+ }
+
+ if (protocols != null && protocols.length > 0) {
+ this.conn = new WebSocket(endpoint, protocols);
+ } else {
+ this.conn = new WebSocket(endpoint);
+ }
+
+ this.conn.onopen = ((evt: Event): any => {
+ this.fireConnect();
+ this.isReady = true;
+ return null;
+ });
+
+ this.conn.onclose = ((evt: Event): any => {
+ this.fireDisconnect();
+ return null;
+ });
+
+ this.conn.onmessage = ((evt: MessageEvent) => {
+ this.messageReceivedFromConn(evt);
+ });
+
+ this.conn.onerror = ((evt: MessageEvent) => {
+ this.errorReceivedFromConn(evt);
+ });
+ }
+
+ public OnConnect(fn: OnConnectFunc): void {
+ if (this.isReady) {
+ fn();
+ }
+ this.connectListeners.push(fn);
+ }
+ public OnDisconnect(fn: OnWebsocketDisconnectFunc): void {
+ this.disconnectListeners.push(fn);
+ }
+ public OnMessage(cb: OnWebsocketNativeMessageFunc): void {
+ this.nativeMessageListeners.push(cb);
+ }
+ public On(event: string, cb: OnMessageFunc): void {
+ if (this.messageListeners[event] == null || this.messageListeners[event] === undefined) {
+ this.messageListeners[event] = [];
+ }
+ this.messageListeners[event].push(cb);
+ }
+
+ //
+
+ // Ws Actions
+ public Disconnect(): void {
+ this.conn.close();
+ }
+
+ // EmitMessage sends a native websocket message
+ public EmitMessage(websocketMessage: string): void {
+ this.conn.send(websocketMessage);
+ }
+
+ protected fireConnect(): void {
+ for (let i = 0; i < this.connectListeners.length; i++) {
+ this.connectListeners[i]();
+ }
+ }
+
+ protected fireDisconnect(): void {
+ for (let i = 0; i < this.disconnectListeners.length; i++) {
+ this.disconnectListeners[i]();
+ }
+ }
+
+ protected fireNativeMessage(websocketMessage: string): void {
+ for (let i = 0; i < this.nativeMessageListeners.length; i++) {
+ this.nativeMessageListeners[i](websocketMessage);
+ }
+ }
+
+ protected fireMessage(event: string, message: any): void {
+ for (let key in this.messageListeners) {
+ if (this.messageListeners.hasOwnProperty(key)) {
+ if (key === event) {
+ for (let i = 0; i < this.messageListeners[key].length; i++) {
+ this.messageListeners[key][i](message);
+ }
+ }
+ }
+ }
+ }
+
+ // utils
+ private isNumber(obj: any): boolean {
+ return !isNaN(obj - 0) && obj !== null && obj !== '' && obj !== false;
+ }
+
+ private isString(obj: any): boolean {
+ return Object.prototype.toString.call(obj) === '[object String]';
+ }
+
+ private isBoolean(obj: any): boolean {
+ return typeof obj === 'boolean' ||
+ (typeof obj === 'object' && typeof obj.valueOf() === 'boolean');
+ }
+
+ private isJSON(obj: any): boolean {
+ return typeof obj === 'object';
+ }
+
+ //
+
+ // messages
+ private _msg(event: string, messageType: MessageType, dataMessage: string): string {
+
+ return websocketMessagePrefix + event + websocketMessageSeparator + String(websocketMessageType) + websocketMessageSeparator + dataMessage;
+ }
+
+ private encodeMessage(event: string, data: any): string {
+ let m = '';
+ let t: MessageType = MessageType.STRING;
+ if (this.isNumber(data)) {
+ t = MessageType.INT;
+ m = data.toString();
+ } else if (this.isBoolean(data)) {
+ t = MessageType.BOOLEAN;
+ m = data.toString();
+ } else if (this.isString(data)) {
+ t = MessageType.STRING;
+ m = data.toString();
+ } else if (this.isJSON(data)) {
+ // propably json-object
+ t = MessageType.JSON;
+ m = JSON.stringify(data);
+ } else {
+ console.log('Invalid, javascript-side should contains an empty second parameter.');
+ }
+
+ return this._msg(event, t, m);
+ }
+
+ private decodeMessage(event: string, websocketMessage: string): T | any {
+ // q-websocket-message;user;4;themarshaledstringfromajsonstruct
+ let skipLen = websocketMessagePrefixLen + websocketMessageSeparatorLen + event.length + 2;
+ if (websocketMessage.length < skipLen + 1) {
+ return null;
+ }
+ let websocketMessageType = parseInt(websocketMessage.charAt(skipLen - 2));
+ let theMessage = websocketMessage.substring(skipLen, websocketMessage.length);
+ if (websocketMessageType === MessageType.INT) {
+ return parseInt(theMessage);
+ } else if (websocketMessageType === MessageType.BOOLEAN) {
+ return Boolean(theMessage);
+ } else if (websocketMessageType === MessageType.STRING) {
+ return theMessage;
+ } else if (websocketMessageType === MessageType.JSON) {
+ return JSON.parse(theMessage);
+ } else {
+ return null; // invalid
+ }
+ }
+
+ private getWebsocketCustomEvent(websocketMessage: string): string {
+ if (websocketMessage.length < websocketMessagePrefixAndSepIdx) {
+ return '';
+ }
+ let s = websocketMessage.substring(websocketMessagePrefixAndSepIdx, websocketMessage.length);
+ let evt = s.substring(0, s.indexOf(websocketMessageSeparator));
+
+ return evt;
+ }
+
+ private getCustomMessage(event: string, websocketMessage: string): string {
+ let eventIdx = websocketMessage.indexOf(event + websocketMessageSeparator);
+ let s = websocketMessage.substring(eventIdx + event.length + websocketMessageSeparator.length + 2, websocketMessage.length);
+ return s;
+ }
+
+ //
+
+ // Ws Events
+
+ // messageReceivedFromConn this is the func which decides
+ // if it's a native websocket message or a custom qws message
+ // if native message then calls the fireNativeMessage
+ // else calls the fireMessage
+ //
+ // remember q gives you the freedom of native websocket messages if you don't want to use this client side at all.
+ private messageReceivedFromConn(evt: MessageEvent): void {
+ // check if qws message
+ let message = evt.data;
+ if (message.indexOf(websocketMessagePrefix) !== -1) {
+ let event = this.getWebsocketCustomEvent(message);
+ if (event !== '') {
+ // it's a custom message
+ this.fireMessage(event, this.getCustomMessage(event, message));
+ return;
+ }
+ }
+
+ // it's a native websocket message
+ this.fireNativeMessage(message);
+ }
+
+ // errorReceivedFromConn this is the func which decides
+ // if it's a native websocket message or a custom qws message
+ // if native message then calls the fireNativeMessage
+ // else calls the fireMessage
+ //
+ // remember q gives you the freedom of native websocket messages if you don't want to use this client side at all.
+ private errorReceivedFromConn(evt: MessageEvent): void {
+ // check if qws message
+ let message = evt.data;
+ if (message.indexOf(websocketMessagePrefix) !== -1) {
+ let event = this.getWebsocketCustomEvent(message);
+ if (event !== '') {
+ // it's a custom message
+ this.fireMessage(event, this.getCustomMessage(event, message));
+ return;
+ }
+ }
+
+ // it's a native websocket message
+ this.fireNativeMessage(message);
+ }
}
-export interface Protocol {
- serviceName: string;
- methodName: string;
- params?: string[];
-}
export default Client;
diff --git a/src/ts/@overflow/help/react/Help.tsx b/src/ts/@overflow/help/react/Help.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/src/ts/@overflow/help/react/components/Help.tsx b/src/ts/@overflow/help/react/components/Help.tsx
new file mode 100644
index 0000000..e69de29