Merge pull request #42 from avatao-content/api-rework

Api rework
This commit is contained in:
therealkrispet 2019-08-08 16:29:27 +02:00 committed by GitHub
commit 9d6a819606
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 201 additions and 250 deletions

View File

@ -3,11 +3,16 @@
import { Component, OnInit } from '@angular/core';
import { WebSocketService } from '../services/websocket.service';
import { ConsoleContentCommand, RewriteContentCommand, ShowLiveLogsCommand } from '../message-types/console-commands';
import { WebSocketMessage } from '../message-types/websocket-message';
import {
ConsoleReadMessage,
ConsoleWriteMessage,
ConsoleLiveLogsMessage,
ConsoleRewriteContentMessage
} from '../message-types/console-messages';
import { config } from '../config';
import { ProcessLogService } from '../services/processlog.service';
import { LogMessage } from '../message-types/log-message';
import { CommandMessage } from '../message-types/command-message';
@Component({
selector: 'app-console',
@ -19,10 +24,10 @@ export class ConsoleComponent implements OnInit {
rewriteContentWithProcessLogsOnDeploy: string = config.console.rewriteContentWithProcessLogsOnDeploy;
command_handlers = {
'write': this.writeHandler.bind(this),
'read': this.readHandler.bind(this),
'showLiveLogs': this.showLiveLogsHandler.bind(this),
'rewriteContentWithProcessLogsOnDeploy': this.rewriteContentWithProcessLogsOnDeployHandler.bind(this)
'console.read': this.readHandler.bind(this),
'console.write': this.writeHandler.bind(this),
'console.showLiveLogs': this.showLiveLogsHandler.bind(this),
'console.rewriteContentWithProcessLogsOnDeploy': this.rewriteContentWithProcessLogsOnDeployHandler.bind(this)
};
constructor(private webSocketService: WebSocketService,
@ -30,18 +35,18 @@ export class ConsoleComponent implements OnInit {
ngOnInit() {
this.webSocketService.connect();
this.webSocketService.observeKey<CommandMessage>('console').subscribe(
(event) => this.command_handlers[event.data.command](event.data)
this.webSocketService.observeKey<WebSocketMessage>('console').subscribe(
message => this.command_handlers[message.key](message)
);
this.processLogService.newLogs.subscribe((data) => this.newLogsHandler(data));
}
writeHandler(data: ConsoleContentCommand) {
this.setContent(data.content);
readHandler(message: ConsoleReadMessage) {
this.sendContent(this.console_content);
}
readHandler(data: ConsoleContentCommand) {
this.sendContent(this.console_content);
writeHandler(message: ConsoleWriteMessage) {
this.setContent(message.value);
}
newLogsHandler(logs: LogMessage) {
@ -53,12 +58,12 @@ export class ConsoleComponent implements OnInit {
}
}
showLiveLogsHandler(data: ShowLiveLogsCommand) {
this.processLogService.showLiveLogs = data.value;
showLiveLogsHandler(message: ConsoleLiveLogsMessage) {
this.processLogService.showLiveLogs = message.value;
}
rewriteContentWithProcessLogsOnDeployHandler(data: RewriteContentCommand) {
this.rewriteContentWithProcessLogsOnDeploy = data.value;
rewriteContentWithProcessLogsOnDeployHandler(message: ConsoleRewriteContentMessage) {
this.rewriteContentWithProcessLogsOnDeploy = message.value;
}
setContent(content: string) {
@ -66,9 +71,9 @@ export class ConsoleComponent implements OnInit {
}
sendContent(content: string) {
this.webSocketService.send('console', {
'command': 'read',
'content': content
this.webSocketService.sendJSON({
'key': 'console.content',
'value': content
});
}
}

View File

@ -5,11 +5,11 @@ import { Component, OnDestroy, OnInit, ChangeDetectorRef, ElementRef, ViewChild
import { DeploymentNotificationService } from '../services/deployment-notification.service';
import { Subscription } from 'rxjs';
import { WebSocketService } from '../services/websocket.service';
import { HideMessagesCommand, LayoutCommand, TerminalMenuItemCommand } from '../message-types/dashboard-commands';
import { WebSocketMessage } from '../message-types/websocket-message';
import { HideMessagesMessage, LayoutMessage, TerminalMenuItemMessage } from '../message-types/dashboard-messages';
import { config } from '../config';
import { ProcessLogService } from '../services/processlog.service';
import { LogMessage } from '../message-types/log-message';
import { CommandMessage } from '../message-types/command-message';
import { HttpClient } from '@angular/common/http';
import { delay, retryWhen, tap } from 'rxjs/operators';
@ -35,11 +35,11 @@ export class DashboardComponent implements OnInit, OnDestroy {
iframeReloadSubscription: Subscription;
command_handlers = {
'layout': this.layoutHandler.bind(this),
'hideMessages': this.hideMessagesHandler.bind(this),
'terminalMenuItem': this.terminalMenuItemHandler.bind(this),
'reloadFrontend': this.reloadFrontendHandlder.bind(this),
'reloadIframe': this.reloadIframeHandler.bind(this)
'dashboard.layout': this.layoutHandler.bind(this),
'dashboard.hideMessages': this.hideMessagesHandler.bind(this),
'dashboard.terminalMenuItem': this.terminalMenuItemHandler.bind(this),
'dashboard.reloadFrontend': this.reloadFrontendHandlder.bind(this),
'dashboard.reloadIframe': this.reloadIframeHandler.bind(this)
};
constructor(private deploymentNotificationService: DeploymentNotificationService,
@ -57,8 +57,8 @@ export class DashboardComponent implements OnInit, OnDestroy {
}
initCommandHandling() {
this.webSocketService.observeKey<CommandMessage>('dashboard').subscribe((event) => {
this.command_handlers[event.data.command](event.data);
this.webSocketService.observeKey<WebSocketMessage>('dashboard').subscribe(message => {
this.command_handlers[message.key](message);
this.changeDetectorRef.detectChanges();
});
}
@ -80,11 +80,8 @@ export class DashboardComponent implements OnInit, OnDestroy {
if (config.dashboard.triggerFirstFSMStep) {
setTimeout(() => {
this.webSocketService.sendJSON({
'key': 'fsm',
'data': {
'command': 'trigger',
'value': config.dashboard.triggerFirstFSMStep
}
'key': 'fsm.step',
'trigger': config.dashboard.triggerFirstFSMStep
});
});
}
@ -96,27 +93,27 @@ export class DashboardComponent implements OnInit, OnDestroy {
}
}
layoutHandler(data: LayoutCommand) {
if (config.dashboard.enabledLayouts.includes(data.value)) {
this.setLayout(data.value);
layoutHandler(message: LayoutMessage) {
if (config.dashboard.enabledLayouts.includes(message.value)) {
this.setLayout(message.value);
} else {
console.log('Invalid ide layout "' + data.value + '" received!');
console.log('Invalid ide layout "' + message.value + '" received!');
}
}
hideMessagesHandler(data: HideMessagesCommand) {
this.hideMessages = data.value;
hideMessagesHandler(message: HideMessagesMessage) {
this.hideMessages = message.value;
}
terminalMenuItemHandler(data: TerminalMenuItemCommand) {
this.selectTerminalMenuItem(data.value);
terminalMenuItemHandler(message: TerminalMenuItemMessage) {
this.selectTerminalMenuItem(message.value);
}
reloadFrontendHandlder(data: CommandMessage) {
reloadFrontendHandlder(message: WebSocketMessage) {
setTimeout(() => window.location.reload(), 2000);
}
reloadIframeHandler(data: CommandMessage) {
reloadIframeHandler(message: WebSocketMessage) {
setTimeout(() => this.reloadIframeNoSubmit(), 200);
}

View File

@ -10,9 +10,9 @@
[class.disabled]="filename === file"
[disabled]="filename === file"
[class.tao-tab-btn-saved]="filename === file && codeState === CodeState.SAVED">
<span *ngIf="filename !== file">{{file}}</span>
<span *ngIf="filename !== file">{{pathBasename(file)}}</span>
<span *ngIf="filename === file"
[class.underline]="codeState === CodeState.DIRTY">{{file}}</span>
[class.underline]="codeState === CodeState.DIRTY">{{pathBasename(file)}}</span>
</button>
</div>
@ -39,6 +39,6 @@
<ngx-monaco-editor [(ngModel)]="code"
class="tfw-ide-editor"
(ngModelChange)="editorWriteHanlder()"
(keyup)="editorWriteHandler()"
[options]="editorOptions"
></ngx-monaco-editor>

View File

@ -3,16 +3,15 @@
import { ChangeDetectorRef, Component, EventEmitter, OnInit, Output } from '@angular/core';
import { IDECommand } from '../message-types/ide-command';
import { WebSocketService } from '../services/websocket.service';
import { WebSocketMessage } from '../message-types/websocket-message';
import { IDEMessage } from '../message-types/ide-message';
import { ProcessManagerService } from '../services/processmanager.service';
import { DeploymentNotificationService } from '../services/deployment-notification.service';
import { config } from '../config';
import { CommandMessage } from '../message-types/command-message';
import { LanguageMap } from './language-map';
import { filter, first } from 'rxjs/operators';
enum DeployButtonState {
DEPLOYED,
DEPLOYING,
@ -20,13 +19,11 @@ enum DeployButtonState {
TODEPLOY
}
enum CodeState {
SAVED,
DIRTY
}
@Component({
selector: 'app-ide',
templateUrl: './ide.component.html',
@ -36,10 +33,8 @@ export class IdeComponent implements OnInit {
CodeState = CodeState;
DeployButtonState = DeployButtonState;
key_id = 'ide';
files: string[];
filename = '';
directory = '';
code: string = config.ide.defaultCode;
codeState = CodeState.SAVED;
@ -58,11 +53,9 @@ export class IdeComponent implements OnInit {
@Output() newLogs = new EventEmitter<any>();
command_handlers = {
'reload': this.reloadHandler.bind(this),
'read': this.readHandler.bind(this),
'select': this.selectHandler.bind(this),
'write': this.writeHandler.bind(this),
'selectdir': this.selectdirHandler.bind(this)
'ide.reload': this.reloadHandler.bind(this),
'ide.read': this.readHandler.bind(this),
'ide.write': this.writeHandler.bind(this),
};
constructor(private webSocketService: WebSocketService,
@ -80,17 +73,14 @@ export class IdeComponent implements OnInit {
}
subscribeWS() {
this.webSocketService.observeKey<CommandMessage>(this.key_id).subscribe((event) => {
this.command_handlers[event.data.command](event.data);
this.webSocketService.observeKey<WebSocketMessage>('ide').subscribe(message => {
this.command_handlers[message.key](message);
this.changeDetectorRef.detectChanges();
});
}
subscribeFirstLanguageDetection() {
this.webSocketService.observeKey<CommandMessage>(this.key_id).pipe(
filter(message => message.data.command === 'read'),
first()
).subscribe(
this.webSocketService.observeKey<IDEMessage>('ide.read').pipe(first()).subscribe(
() => this.autoDetectEditorLanguageIfEnabled(this.filename)
);
}
@ -99,18 +89,18 @@ export class IdeComponent implements OnInit {
this.processManagerService.init();
this.processManagerService.subscribeCallback(
config.ide.deployProcessName,
(event) => {
message => {
this.deploymentNotificationService.deploying.next(false);
this.newLogs.emit({
stdout: event.data.stdout,
stderr: event.data.stderr
stdout: message.stdout,
stderr: message.stderr
});
}
);
this.processManagerService.subscribeSuccessCallback(
config.ide.deployProcessName,
(event) => this.setDeployButtonState(DeployButtonState.DEPLOYED)
message => this.setDeployButtonState(DeployButtonState.DEPLOYED)
);
this.processManagerService.subscribeErrorCallback(
@ -119,36 +109,24 @@ export class IdeComponent implements OnInit {
);
}
updateFileData(data: IDECommand) {
this.filename = data.filename;
this.directory = data.directory;
this.code = (data.content != null) ? data.content : this.code;
this.files = data.files;
}
selectHandler(data: IDECommand) {
this.updateFileData(data);
this.autoDetectEditorLanguageIfEnabled(this.filename);
}
reloadHandler(data: CommandMessage) {
reloadHandler(message: WebSocketMessage) {
this.requestCode();
}
readHandler(data: IDECommand) {
readHandler(message: IDEMessage) {
if (this.codeState === CodeState.SAVED) {
this.updateFileData(data);
if (this.filename != message.filename) {
this.filename = message.filename;
}
this.code = (message.content != null) ? message.content : this.code;
this.files = message.files;
}
}
writeHandler(data: CommandMessage) {
writeHandler(message: IDEMessage) {
this.setCodeState(CodeState.SAVED);
}
selectdirHandler(data: IDECommand) {
this.updateFileData(data);
}
autoDetectEditorLanguageIfEnabled(filename: string) {
if (!config.ide.autoDetectFileLanguage) {
return;
@ -181,11 +159,12 @@ export class IdeComponent implements OnInit {
if (this.codeState === CodeState.DIRTY) {
this.sendCodeContents();
}
this.selectCode(file);
this.filename = file;
this.requestCode();
this.autoDetectEditorLanguageIfEnabled(this.filename);
}
editorWriteHanlder() {
editorWriteHandler() {
this.setCodeState(CodeState.DIRTY);
this.setDeployButtonState(DeployButtonState.TODEPLOY);
this.resetAutoSaveCountdown();
@ -211,23 +190,22 @@ export class IdeComponent implements OnInit {
}
}
pathBasename(path: string) {
return path.split('/').reverse()[0];
}
sendCodeContents() {
this.webSocketService.send(this.key_id, {
'command': 'write',
this.webSocketService.sendJSON({
'key': 'ide.write',
'filename': this.filename,
'content': this.code
});
}
requestCode() {
this.webSocketService.send(this.key_id, {
'command': 'read'
});
}
selectCode(filename: string) {
this.webSocketService.send(this.key_id, {
'command': 'select',
'filename': filename
this.webSocketService.sendJSON({
'key': 'ide.read',
'filename': this.filename
});
}
}

View File

@ -0,0 +1,23 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { WebSocketMessage } from './websocket-message';
export interface MessageConfig extends WebSocketMessage {
originator?: string;
}
export interface MessageMetadata {
originator?: string;
timestamp?: Date;
}
export interface MessageData extends MessageMetadata {
message: string;
}
export interface Message extends MessageData, WebSocketMessage {}
export interface MessageQueue extends WebSocketMessage {
value: Array<MessageData>;
}

View File

@ -1,6 +0,0 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
export interface CommandMessage {
readonly command: string;
}

View File

@ -1,13 +0,0 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { CommandMessage } from './command-message';
import { SetValueCommand } from './set-value-command';
export interface ConsoleContentCommand extends CommandMessage {
content?: string;
}
export interface ShowLiveLogsCommand extends CommandMessage, SetValueCommand<boolean> {}
export interface RewriteContentCommand extends CommandMessage, SetValueCommand<string> {}

View File

@ -0,0 +1,15 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { SetValueCommand } from './set-value-command';
import { WebSocketMessage } from './websocket-message';
export interface ConsoleReadMessage extends WebSocketMessage {}
export interface ConsoleWriteMessage extends WebSocketMessage {
value: string;
}
export interface ConsoleLiveLogsMessage extends WebSocketMessage, SetValueCommand<boolean> {}
export interface ConsoleRewriteContentMessage extends WebSocketMessage, SetValueCommand<string> {}

View File

@ -1,11 +0,0 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { CommandMessage } from './command-message';
import { SetValueCommand } from './set-value-command';
export interface LayoutCommand extends CommandMessage, SetValueCommand<string> {}
export interface HideMessagesCommand extends CommandMessage, SetValueCommand<boolean> {}
export interface TerminalMenuItemCommand extends CommandMessage, SetValueCommand<string> {}

View File

@ -0,0 +1,11 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { SetValueCommand } from './set-value-command';
import { WebSocketMessage } from './websocket-message';
export interface LayoutMessage extends WebSocketMessage, SetValueCommand<string> {}
export interface HideMessagesMessage extends WebSocketMessage, SetValueCommand<boolean> {}
export interface TerminalMenuItemMessage extends WebSocketMessage, SetValueCommand<string> {}

View File

@ -1,7 +1,9 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
export class FSMUpdate {
import { WebSocketMessage } from './websocket-message';
export interface FSMUpdateMessage extends WebSocketMessage {
current_state: string;
valid_transitions: object;
}

View File

@ -1,11 +1,10 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { CommandMessage } from './command-message';
import { WebSocketMessage } from './websocket-message';
export interface IDECommand extends CommandMessage {
export interface IDEMessage extends WebSocketMessage {
filename: string;
content?: string;
files: string[];
directory: string;
files?: string[];
}

View File

@ -1,7 +0,0 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
export class MessageMetadata {
originator: string;
timestamp?: Date;
}

View File

@ -1,8 +0,0 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { MessagesMessage } from './messages-message';
export class MessageQueueMessage {
messages: Array<MessagesMessage>;
}

View File

@ -1,7 +0,0 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { CommandMessage } from './command-message';
import { SetValueCommand } from './set-value-command';
export interface MessagesControlCommand extends CommandMessage, SetValueCommand<boolean> {}

View File

@ -1,8 +0,0 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { MessageMetadata } from './message-metadata';
export class MessagesMessage extends MessageMetadata {
message: string;
}

View File

@ -1,7 +1,7 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { CommandMessage } from './command-message';
import { LogMessage } from './log-message';
import { WebSocketMessage } from './websocket-message';
export interface ProcessLogCommand extends CommandMessage, LogMessage {}
export interface ProcessLogMessage extends WebSocketMessage, LogMessage {}

View File

@ -1,10 +1,10 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { CommandMessage } from './command-message';
import { LogMessage } from './log-message';
import { WebSocketMessage } from './websocket-message';
export interface ProcessCommand extends CommandMessage, LogMessage {
process_name: string;
export interface ProcessMessage extends WebSocketMessage, LogMessage {
name: string;
error?: string;
}

View File

@ -1,8 +1,6 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
import { CommandMessage } from './command-message';
export interface SetValueCommand<T> extends CommandMessage {
export interface SetValueCommand<T> {
value: T;
}

View File

@ -1,8 +1,6 @@
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
// All Rights Reserved. See LICENSE file for details.
export class WebSocketMessage<T> {
export interface WebSocketMessage {
key: string;
trigger?: string;
data: T;
}

View File

@ -17,11 +17,4 @@
<div class="jumping-circle" id="jc2"></div>
<div class="jumping-circle" id="jc3"></div>
</div>
<div class="tfw-next-button">
<button *ngIf="showNextButton"
(click)="stepFSM()"
class="tao-btn-rainbow">
Next
</button>
</div>
</div>

View File

@ -2,14 +2,11 @@
// All Rights Reserved. See LICENSE file for details.
import { ChangeDetectorRef, Component, OnInit, EventEmitter, Output } from '@angular/core';
import { MessageConfig, MessageData, Message, MessageQueue } from '../message-types/bot-messages';
import { MarkdownService } from '../services/markdown.service';
import { WebSocketService } from '../services/websocket.service';
import { MessagesMessage } from '../message-types/messages-message';
import { MessagesControlCommand } from '../message-types/messages-control-command';
import { config } from '../config';
import { CommandMessage } from '../message-types/command-message';
import { MessageQueueMessage } from '../message-types/message-queue-message';
import { Subject, Observer, BehaviorSubject } from 'rxjs';
@Component({
@ -19,15 +16,17 @@ import { Subject, Observer, BehaviorSubject } from 'rxjs';
})
export class MessagesComponent implements OnInit {
@Output() newMessageEvent: EventEmitter<any> = new EventEmitter();
newMessage: Subject<MessagesMessage> = new Subject<MessagesMessage>();
newMessage: Subject<MessageData> = new Subject<MessageData>();
messageInQueue = true;
messages: MessagesMessage[] = [];
originator: string = 'avataobot';
messages: MessageData[] = [];
messageQueueAttender: MessageQueueAttender;
showNextButton: boolean = config.messages.showNextButton;
command_handlers = {
'showNextButton': this.showButtonHandler.bind(this)
'message.queue': this.handleQueueMessage.bind(this),
'message.config': this.configureMessages.bind(this),
'message.send': () => {}
};
constructor(
@ -40,7 +39,7 @@ export class MessagesComponent implements OnInit {
ngOnInit() {
this.newMessage.subscribe(
(message) => {
message => {
this.writeMessage(message);
this.newMessageEvent.emit();
});
@ -49,45 +48,43 @@ export class MessagesComponent implements OnInit {
);
this.websocketService.connect();
this.websocketService.observeKey<MessagesMessage>('message').subscribe(
(event) => this.newMessage.next(event.data)
this.websocketService.observeKey<Message>('message.send').subscribe(
message => this.newMessage.next(message)
);
this.websocketService.observeKey<MessageQueueMessage>('queueMessages').subscribe(
(event) => this.handleQueueMessage(event.data)
);
this.websocketService.observeKey<CommandMessage>('messagecontrol').subscribe(
(event) => this.command_handlers[event.data.command](event.data)
this.websocketService.observeKey<MessageQueue>('message').subscribe(
message => this.command_handlers[message.key](message)
);
}
writeMessage(message: MessagesMessage) {
writeMessage(message: MessageData) {
this.transformMessage(message);
this.messages.push(message);
this.changeDetectorRef.detectChanges();
}
transformMessage(message: MessagesMessage) {
transformMessage(message: MessageData) {
message.message = this.convertMarkdownToHTML(message.message);
if (!message.originator) {
message.originator = this.originator;
}
if (!message.timestamp) {
message.timestamp = new Date();
}
}
handleQueueMessage(data: MessageQueueMessage) {
this.messageQueueAttender.queueMessages(data.messages);
handleQueueMessage(message: MessageQueue) {
this.messageQueueAttender.queueMessages(message.value);
}
configureMessages(message: MessageConfig) {
if (message.originator) {
this.originator = message.originator;
}
}
convertMarkdownToHTML(text: string) {
return this.markdownService.convertToHtml(text);
}
showButtonHandler(data: MessagesControlCommand) {
this.showNextButton = data.value;
}
stepFSM() {
this.websocketService.sendJSON({key: '', trigger: 'step_next'});
}
}
@ -96,14 +93,14 @@ class MessageQueueAttender {
private readonly charPerSecond: number;
private lastMessageLength = 0;
private queue: MessagesMessage[] = [];
private queue: MessageData[] = [];
constructor(private messageEmitter: Observer<MessagesMessage>, wordPerMinute: number = config.messages.messageQueueWPM) {
constructor(private messageEmitter: Observer<MessageData>, wordPerMinute: number = config.messages.messageQueueWPM) {
const charPerMinute = wordPerMinute * 5;
this.charPerSecond = charPerMinute / 60;
}
queueMessages(messages: Array<MessagesMessage>) {
queueMessages(messages: Array<MessageData>) {
this.queue = this.queue.concat(messages);
this.attendQueue();
}

View File

@ -4,7 +4,7 @@
import { Injectable } from '@angular/core';
import { WebSocketService } from './websocket.service';
import { FSMUpdate } from '../message-types/fsm-update';
import { FSMUpdateMessage } from '../message-types/fsm-update-message';
@Injectable()
export class FSMUpdateService {
@ -14,9 +14,9 @@ export class FSMUpdateService {
constructor(private websocketService: WebSocketService) {}
public init(): void {
this.websocketService.observeKey<FSMUpdate>('FSMUpdate').subscribe((event) => {
this.current_state = event.data.current_state;
this.valid_transitions = event.data.valid_transitions;
this.websocketService.observeKey<FSMUpdateMessage>('fsm.update').subscribe(message => {
this.current_state = message.current_state;
this.valid_transitions = message.valid_transitions;
});
}

View File

@ -3,25 +3,20 @@
import { Injectable } from '@angular/core';
import { WebSocketService } from './websocket.service';
import { ProcessLogCommand } from '../message-types/process-log-command';
import { LogMessage } from '../message-types/log-message';
import { ProcessLogMessage } from '../message-types/process-log-message';
import { config } from '../config';
import { BehaviorSubject } from 'rxjs';
import { LogMessage } from '../message-types/log-message';
import { CommandMessage } from '../message-types/command-message';
@Injectable()
export class ProcessLogService {
newLogs = new BehaviorSubject<LogMessage>(config.console.defaultLogs);
showLiveLogs = config.console.showLiveLogs;
command_handlers = {
'new_log': this.newLogsHandler.bind(this)
};
constructor(private webSocketService: WebSocketService) {
this.webSocketService.connect();
this.webSocketService.observeKey<CommandMessage>('processlog').subscribe(
(event) => this.command_handlers[event.data.command](event.data)
this.webSocketService.observeKey<ProcessLogMessage>('process.log.new').subscribe(
message => this.newLogsHandler(message)
);
}
@ -31,11 +26,11 @@ export class ProcessLogService {
}
}
newLogsHandler(data: ProcessLogCommand) {
newLogsHandler(message: ProcessLogMessage) {
if (this.showLiveLogs) {
this.newLogs.next({
stdout: data.stdout,
stderr: data.stderr
stdout: message.stdout,
stderr: message.stderr
});
}
}

View File

@ -4,14 +4,11 @@
import { Injectable } from '@angular/core';
import { WebSocketService } from './websocket.service';
import { ProcessCommand } from '../message-types/process-command';
import { ProcessMessage } from '../message-types/process-message';
import { filter } from 'rxjs/operators';
import { WebSocketMessage } from '../message-types/websocket-message';
@Injectable()
export class ProcessManagerService {
key = 'processmanager';
process_name: string;
constructor(private webSocketService: WebSocketService) {}
@ -20,25 +17,21 @@ export class ProcessManagerService {
this.webSocketService.connect();
}
subscribeCallback(process_name: string, callback: (event: WebSocketMessage<ProcessCommand>) => void) {
subscribeCallback(process_name: string, callback: (message: ProcessMessage) => void) {
this.observeProcessMessage(process_name).subscribe(callback);
}
subscribeSuccessCallback(process_name: string, callback: (event: WebSocketMessage<ProcessCommand>) => void) {
this.observeProcessMessage(process_name).pipe(filter(message => !('error' in message.data))).subscribe(callback);
subscribeSuccessCallback(process_name: string, callback: (message: ProcessMessage) => void) {
this.observeProcessMessage(process_name).pipe(filter(message => !('error' in message))).subscribe(callback);
}
subscribeErrorCallback(process_name: string, callback: (event: WebSocketMessage<ProcessCommand>) => void) {
this.observeProcessMessage(process_name).pipe(filter(message => 'error' in message.data)).subscribe(callback);
subscribeErrorCallback(process_name: string, callback: (message: ProcessMessage) => void) {
this.observeProcessMessage(process_name).pipe(filter(message => 'error' in message)).subscribe(callback);
}
observeProcessMessage(process_name: string) {
return this.webSocketService.observeKey<ProcessCommand>(this.key)
.pipe(filter(message => message.data.process_name === process_name));
}
sendCommand(command: string, process_name: string) {
this.webSocketService.send(this.key, {'command': command, 'process_name': process_name});
return this.webSocketService.observeKey<ProcessMessage>('process')
.pipe(filter(message => message.name === process_name));
}
startProcess(process_name: string) {
@ -52,4 +45,11 @@ export class ProcessManagerService {
restartProcess(process_name: string) {
this.sendCommand('restart', process_name);
}
sendCommand(command: string, process_name: string) {
this.webSocketService.sendJSON({
'key': 'process.'+command,
'name': process_name
});
}
}

View File

@ -19,7 +19,7 @@ function jsonWebsocketConnect(url: string, input: Observable<object>, protocols?
@Injectable()
export class WebSocketService {
private uplink: QueueingSubject<object>;
public downlink: Observable<WebSocketMessage<undefined>>;
public downlink: Observable<WebSocketMessage>;
constructor() {}
@ -33,14 +33,14 @@ export class WebSocketService {
wsproto + window.location.host + '/ws',
this.uplink = new QueueingSubject<object>()
).messages.pipe(
map(message => <WebSocketMessage<undefined>> message),
map(message => <WebSocketMessage> message),
share()
);
console.log('ws connected');
}
public observeKey<T>(key: string): Observable<WebSocketMessage<T>> {
return this.downlink.pipe(filter(message => message.key === key));
public observeKey<T extends WebSocketMessage>(key: string): Observable<T> {
return this.downlink.pipe(filter(message => message.key.startsWith(key)), map(message => <T> message));
}
public send(key: string, data?: any, trigger?: any): void {