mirror of
https://github.com/avatao-content/frontend-tutorial-framework
synced 2024-12-05 02:01:32 +00:00
Merge branch 'message-types'
This commit is contained in:
commit
995feeeddd
43
README.md
43
README.md
@ -21,10 +21,25 @@ These APIs are documented in the [baseimage-tutorial-framework](https://github.c
|
||||
|
||||
## Configuration
|
||||
|
||||
Most of the time it is not necessary to edit the source code of our components as you can easily customise their behaviour through the `src/app/config.ts` config file.
|
||||
Generally it is unadvised to directly modify the source code of our pre-written components (this is hard for us to support and is prone to break).
|
||||
|
||||
The most notable setting available in this file is the enabling of different layouts, which allows the user and you to switch between them.
|
||||
Layouts describe which components are visible and where they are on the screen.
|
||||
For this reason most components are extensively configurable through the `src/app/config.ts` file.
|
||||
These configurations range from the enabling of different layouts to how frequently should our IDE save automatically.
|
||||
|
||||
Many configuration options are changeable dynamically using API messages sent from the backend, like so:
|
||||
|
||||
```
|
||||
{
|
||||
"key": ...component name...,
|
||||
"data":
|
||||
{
|
||||
"command": ...configuration key...,
|
||||
"value": ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Should you encounter any missing features, feel free to contact team TFW and we'll consider implementing them as configuration options (a common example would be making a configuration option dynamic).
|
||||
|
||||
### Terminal (webshell)
|
||||
|
||||
@ -41,6 +56,21 @@ You can write to it (and thus execute commands) and read what commands were exec
|
||||
|
||||
This enables you to pre-type or execute commands for the user and figure out what they are doing in the terminal.
|
||||
|
||||
### Console
|
||||
|
||||
Not unlike how a desktop IDE displays the output of your application, TFW provides a similar component as well.
|
||||
|
||||
The console can appear in place of the terminal and allows you to display the output of a supervisor process in real time.
|
||||
|
||||
This means that if you type `print('cats like cheese')` in your application code and run it, you will see `cats like cheese` appear on the console! Pretty neat, right?
|
||||
|
||||
You can control the displaying of process logs to the console using the `console.rewriteContentWithProcessLogsOnDeploy` key in `config.ts`.
|
||||
The value of `stdout` or `stderr` will cause the console to display the respective stream, while an empty string will disable any automatic output to the console altogether.
|
||||
|
||||
We recommend redirecting `stdout` and `stderr` to the same file and displaying the together.
|
||||
|
||||
The `console.showLiveLogs` key enables real time output from the standard stream you've selected.
|
||||
|
||||
### IDE (webIde)
|
||||
|
||||
This component is a simple text editor based on ACE.
|
||||
@ -120,10 +150,7 @@ The dashboard also exposes a frontend API to dynamically change layouts any time
|
||||
"data":
|
||||
{
|
||||
"command": "layout",
|
||||
"layout": ...,
|
||||
"hide_messages": ...
|
||||
"value": ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can use the `hide_messages` key to hide the message component (sadly it currently takes up the space it would occupy).
|
||||
```
|
@ -19,7 +19,7 @@ export const config = {
|
||||
'web-only'
|
||||
],
|
||||
iframeUrl: '/webservice',
|
||||
hide_messages: false
|
||||
hideMessages: false
|
||||
},
|
||||
ide: {
|
||||
route: 'ide',
|
||||
|
@ -1,9 +0,0 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export interface ConsoleCommand {
|
||||
command: string;
|
||||
content?: string;
|
||||
showLiveLogs?: boolean;
|
||||
rewriteContentWithProcessLogsOnDeploy?: string;
|
||||
}
|
@ -3,10 +3,11 @@
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { WebSocketService } from '../services/websocket.service';
|
||||
import { ConsoleCommand } from './console-command';
|
||||
import { ConsoleContentCommand, RewriteContentCommand, ShowLiveLogsCommand } from '../message-types/console-commands';
|
||||
import { config } from '../config';
|
||||
import { ProcessLogService } from '../services/processlog.service';
|
||||
import { LogMessage } from '../services/log.message';
|
||||
import { LogMessage } from '../message-types/log-message';
|
||||
import { CommandMessage } from '../message-types/command-message';
|
||||
|
||||
@Component({
|
||||
selector: 'app-console',
|
||||
@ -29,17 +30,17 @@ export class ConsoleComponent implements OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
this.webSocketService.connect();
|
||||
this.webSocketService.observeKey<ConsoleCommand>('console').subscribe(
|
||||
this.webSocketService.observeKey<CommandMessage>('console').subscribe(
|
||||
(event) => this.command_handlers[event.data.command](event.data)
|
||||
);
|
||||
this.processLogService.newLogs.subscribe((data) => this.newLogsHandler(data));
|
||||
}
|
||||
|
||||
writeHandler(data: ConsoleCommand) {
|
||||
writeHandler(data: ConsoleContentCommand) {
|
||||
this.setContent(data.content);
|
||||
}
|
||||
|
||||
readHandler(data: ConsoleCommand) {
|
||||
readHandler(data: ConsoleContentCommand) {
|
||||
this.sendContent(this.console_content);
|
||||
}
|
||||
|
||||
@ -52,12 +53,12 @@ export class ConsoleComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
showLiveLogsHandler(data: ConsoleCommand) {
|
||||
this.processLogService.showLiveLogs = data.showLiveLogs;
|
||||
showLiveLogsHandler(data: ShowLiveLogsCommand) {
|
||||
this.processLogService.showLiveLogs = data.value;
|
||||
}
|
||||
|
||||
rewriteContentWithProcessLogsOnDeployHandler(data: ConsoleCommand) {
|
||||
this.rewriteContentWithProcessLogsOnDeploy = data.rewriteContentWithProcessLogsOnDeploy;
|
||||
rewriteContentWithProcessLogsOnDeployHandler(data: RewriteContentCommand) {
|
||||
this.rewriteContentWithProcessLogsOnDeploy = data.value;
|
||||
}
|
||||
|
||||
setContent(content: string) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div [attr.class]="layout">
|
||||
<div class="tfw-grid-main-components">
|
||||
<div class="tfw-header"><app-header></app-header></div>
|
||||
<div [ngClass]="{'hide-attribute': hide_messages}" class="tfw-messages">
|
||||
<div [ngClass]="{'hide-attribute': hideMessages}" class="tfw-messages">
|
||||
<app-messages></app-messages>
|
||||
</div>
|
||||
<div class="tfw-web tao-grid-top-left"
|
||||
|
@ -5,10 +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 { LayoutCommand } from './layout-command';
|
||||
import { HideMessagesCommand, LayoutCommand, TerminalMenuItemCommand } from '../message-types/dashboard-commands';
|
||||
import { config } from '../config';
|
||||
import { ProcessLogService } from '../services/processlog.service';
|
||||
import { LogMessage } from '../services/log.message';
|
||||
import { LogMessage } from '../message-types/log-message';
|
||||
import { CommandMessage } from '../message-types/command-message';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
@ -18,16 +19,17 @@ import { LogMessage } from '../services/log.message';
|
||||
export class DashboardComponent implements OnInit, OnDestroy {
|
||||
deploying = false;
|
||||
deploymentNotificationSubscription: Subscription;
|
||||
layout: string = config.dashboard.currentLayout;
|
||||
hide_messages: boolean = config.dashboard.hide_messages;
|
||||
iframeUrl: string = config.dashboard.iframeUrl;
|
||||
@ViewChild('webiframe') webiframe: ElementRef;
|
||||
selectedTerminalMenuItem = config.dashboard.terminalOrConsole;
|
||||
|
||||
command_handlers = {'layout': this.layoutHandler.bind(this),
|
||||
'hide_messages': this.hideMessagesHandler.bind(this),
|
||||
'terminal_menu': this.terminalMenuSelectHandler.bind(this),
|
||||
'reload_frontend': this.reloadFrontendHandlder.bind(this)};
|
||||
layout: string = config.dashboard.currentLayout;
|
||||
hideMessages: boolean = config.dashboard.hideMessages;
|
||||
iframeUrl: string = config.dashboard.iframeUrl;
|
||||
selectedTerminalMenuItem: string = config.dashboard.terminalOrConsole;
|
||||
|
||||
command_handlers = {'layout': this.layoutHandler.bind(this),
|
||||
'hideMessages': this.hideMessagesHandler.bind(this),
|
||||
'terminalMenuItem': this.terminalMenuItemHandler.bind(this),
|
||||
'reloadFrontend': this.reloadFrontendHandlder.bind(this)};
|
||||
|
||||
constructor(private deploymentNotificationService: DeploymentNotificationService,
|
||||
private webSocketService: WebSocketService,
|
||||
@ -42,7 +44,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
initCommandHandling() {
|
||||
this.webSocketService.observeKey<LayoutCommand>('dashboard').subscribe((event) => {
|
||||
this.webSocketService.observeKey<CommandMessage>('dashboard').subscribe((event) => {
|
||||
this.command_handlers[event.data.command](event.data);
|
||||
this.changeDetectorRef.detectChanges();
|
||||
});
|
||||
@ -70,22 +72,22 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
layoutHandler(data: LayoutCommand) {
|
||||
if (config.dashboard.enabledLayouts.includes(data.layout)) {
|
||||
this.setLayout(data.layout);
|
||||
if (config.dashboard.enabledLayouts.includes(data.value)) {
|
||||
this.setLayout(data.value);
|
||||
} else {
|
||||
console.log('Invalid ide layout "' + data.layout + '" received!');
|
||||
console.log('Invalid ide layout "' + data.value + '" received!');
|
||||
}
|
||||
}
|
||||
|
||||
hideMessagesHandler(data: LayoutCommand) {
|
||||
this.hide_messages = data.hide_messages;
|
||||
hideMessagesHandler(data: HideMessagesCommand) {
|
||||
this.hideMessages = data.value;
|
||||
}
|
||||
|
||||
terminalMenuSelectHandler(data: LayoutCommand) {
|
||||
this.selectTerminalMenuItem(data.terminal_menu_item);
|
||||
terminalMenuItemHandler(data: TerminalMenuItemCommand) {
|
||||
this.selectTerminalMenuItem(data.value);
|
||||
}
|
||||
|
||||
reloadFrontendHandlder(data: LayoutCommand) {
|
||||
reloadFrontendHandlder(data: CommandMessage) {
|
||||
setTimeout(() => window.location.reload(), 2000);
|
||||
}
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export interface LayoutCommand {
|
||||
command: string;
|
||||
layout?: string;
|
||||
hide_messages?: boolean;
|
||||
terminal_menu_item?: string;
|
||||
}
|
@ -16,11 +16,12 @@ import 'brace/mode/python';
|
||||
import 'brace/mode/sql';
|
||||
|
||||
import 'brace/theme/cobalt';
|
||||
import { SourceCode } from './source-code';
|
||||
import { IDECommand } from '../message-types/ide-command';
|
||||
import { WebSocketService } from '../services/websocket.service';
|
||||
import { ProcessManagerService } from '../services/processmanager.service';
|
||||
import { DeploymentNotificationService } from '../services/deployment-notification.service';
|
||||
import { config } from '../config';
|
||||
import { CommandMessage } from '../message-types/command-message';
|
||||
|
||||
const modelist = brace.acequire('ace/ext/modelist');
|
||||
const langTools = brace.acequire('ace/ext/language_tools');
|
||||
@ -89,7 +90,7 @@ export class IdeComponent implements OnInit {
|
||||
}
|
||||
|
||||
subscribeWS() {
|
||||
this.webSocketService.observeKey<SourceCode>(this.key_id).subscribe((event) => {
|
||||
this.webSocketService.observeKey<CommandMessage>(this.key_id).subscribe((event) => {
|
||||
this.command_handlers[event.data.command](event.data);
|
||||
this.changeDetectorRef.detectChanges();
|
||||
});
|
||||
@ -119,7 +120,7 @@ export class IdeComponent implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
updateFileData(data: SourceCode) {
|
||||
updateFileData(data: IDECommand) {
|
||||
this.filename = data.filename;
|
||||
this.directory = data.directory;
|
||||
this.code = (data.content != null) ? data.content : this.code;
|
||||
@ -127,25 +128,25 @@ export class IdeComponent implements OnInit {
|
||||
this.files = data.files;
|
||||
}
|
||||
|
||||
selectHandler(data: SourceCode) {
|
||||
selectHandler(data: IDECommand) {
|
||||
this.updateFileData(data);
|
||||
}
|
||||
|
||||
reloadHandler(data: SourceCode) {
|
||||
reloadHandler(data: CommandMessage) {
|
||||
this.requestCode();
|
||||
}
|
||||
|
||||
readHandler(data: SourceCode) {
|
||||
readHandler(data: IDECommand) {
|
||||
if (this.codeState === CodeState.SAVED) {
|
||||
this.updateFileData(data);
|
||||
}
|
||||
}
|
||||
|
||||
writeHandler() {
|
||||
writeHandler(data: CommandMessage) {
|
||||
this.setCodeState(CodeState.SAVED);
|
||||
}
|
||||
|
||||
selectdirHandler(data: SourceCode) {
|
||||
selectdirHandler(data: IDECommand) {
|
||||
this.updateFileData(data);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export class MessageControl {
|
||||
command: string;
|
||||
next_visibility?: boolean;
|
||||
export interface CommandMessage {
|
||||
readonly command: string;
|
||||
}
|
13
src/app/message-types/console-commands.ts
Normal file
13
src/app/message-types/console-commands.ts
Normal file
@ -0,0 +1,13 @@
|
||||
// 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> {}
|
11
src/app/message-types/dashboard-commands.ts
Normal file
11
src/app/message-types/dashboard-commands.ts
Normal file
@ -0,0 +1,11 @@
|
||||
// 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> {}
|
@ -1,10 +1,11 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export interface SourceCode {
|
||||
import { CommandMessage } from './command-message';
|
||||
|
||||
export interface IDECommand extends CommandMessage {
|
||||
filename: string;
|
||||
content?: string;
|
||||
files: string[];
|
||||
directory: string;
|
||||
command: string;
|
||||
}
|
7
src/app/message-types/messages-control-command.ts
Normal file
7
src/app/message-types/messages-control-command.ts
Normal file
@ -0,0 +1,7 @@
|
||||
// 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> {}
|
@ -1,7 +1,7 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export class Message {
|
||||
export class MessagesMessage {
|
||||
originator: string;
|
||||
timestamp: Date;
|
||||
message: string;
|
10
src/app/message-types/process-command.ts
Normal file
10
src/app/message-types/process-command.ts
Normal file
@ -0,0 +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';
|
||||
|
||||
export interface ProcessCommand extends CommandMessage, LogMessage {
|
||||
process_name: string;
|
||||
error?: string;
|
||||
}
|
7
src/app/message-types/process-log-command.ts
Normal file
7
src/app/message-types/process-log-command.ts
Normal file
@ -0,0 +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';
|
||||
|
||||
export interface ProcessLogCommand extends CommandMessage, LogMessage {}
|
8
src/app/message-types/set-value-command.ts
Normal file
8
src/app/message-types/set-value-command.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// 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 {
|
||||
value: T;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export class WSMessage<T> {
|
||||
export class WebSocketMessage<T> {
|
||||
key: string;
|
||||
trigger?: string;
|
||||
data: T;
|
@ -5,9 +5,10 @@ import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||||
import { MarkdownService } from '../services/markdown.service';
|
||||
import { WebSocketService } from '../services/websocket.service';
|
||||
|
||||
import { Message } from './message';
|
||||
import { MessageControl } from './messagecontrol';
|
||||
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';
|
||||
|
||||
@Component({
|
||||
selector: 'app-messages',
|
||||
@ -15,9 +16,11 @@ import { config } from '../config';
|
||||
styleUrls: ['./messages.component.scss']
|
||||
})
|
||||
export class MessagesComponent implements OnInit {
|
||||
messages: Message[] = [];
|
||||
messages: MessagesMessage[] = [];
|
||||
showNextButton: boolean = config.messages.showNextButton;
|
||||
command_handlers = {'showbutton': this.showButton.bind(this)};
|
||||
command_handlers = {
|
||||
'showNextButton': this.showButtonHandler.bind(this)
|
||||
};
|
||||
|
||||
constructor(
|
||||
private markdownService: MarkdownService,
|
||||
@ -25,28 +28,28 @@ export class MessagesComponent implements OnInit {
|
||||
private changeDetectorRef: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
convert(text: string) {
|
||||
return this.markdownService.convertToHtml(text);
|
||||
}
|
||||
|
||||
showButton(data: MessageControl) {
|
||||
this.showNextButton = data.next_visibility;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.websocketService.connect();
|
||||
this.websocketService.observeKey<Message>('message').subscribe(
|
||||
this.websocketService.observeKey<MessagesMessage>('message').subscribe(
|
||||
(event) => {
|
||||
this.messages.push(event.data);
|
||||
event.data.message = this.convert(event.data.message);
|
||||
this.changeDetectorRef.detectChanges();
|
||||
});
|
||||
this.websocketService.observeKey<MessageControl>('messagecontrol').subscribe(
|
||||
this.websocketService.observeKey<CommandMessage>('messagecontrol').subscribe(
|
||||
(event) => {
|
||||
this.command_handlers[event.data.command](event.data);
|
||||
});
|
||||
}
|
||||
|
||||
convert(text: string) {
|
||||
return this.markdownService.convertToHtml(text);
|
||||
}
|
||||
|
||||
showButtonHandler(data: MessagesControlCommand) {
|
||||
this.showNextButton = data.value;
|
||||
}
|
||||
|
||||
stepFSM() {
|
||||
this.websocketService.sendJSON({key: '', trigger: 'step_next'});
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { WebSocketService } from './websocket.service';
|
||||
|
||||
import { FSMUpdate } from './fsmupdate';
|
||||
import { FSMUpdate } from '../message-types/fsm-update';
|
||||
|
||||
@Injectable()
|
||||
export class FSMUpdateService {
|
||||
|
@ -1,10 +0,0 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export interface ProcessCommand {
|
||||
command: string;
|
||||
process_name: string;
|
||||
error?: string;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// Copyright (C) 2018 Avatao.com Innovative Learning Kft.
|
||||
// All Rights Reserved. See LICENSE file for details.
|
||||
|
||||
export interface ProcessLogCommand {
|
||||
command: string;
|
||||
stdout: string;
|
||||
stderr: string;
|
||||
}
|
@ -3,10 +3,11 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { WebSocketService } from './websocket.service';
|
||||
import { ProcessLogCommand } from './processlog-command';
|
||||
import { ProcessLogCommand } from '../message-types/process-log-command';
|
||||
import { config } from '../config';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { LogMessage } from './log.message';
|
||||
import { LogMessage } from '../message-types/log-message';
|
||||
import { CommandMessage } from '../message-types/command-message';
|
||||
|
||||
@Injectable()
|
||||
export class ProcessLogService {
|
||||
@ -19,7 +20,7 @@ export class ProcessLogService {
|
||||
|
||||
constructor(private webSocketService: WebSocketService) {
|
||||
this.webSocketService.connect();
|
||||
this.webSocketService.observeKey<ProcessLogCommand>('processlog').subscribe(
|
||||
this.webSocketService.observeKey<CommandMessage>('processlog').subscribe(
|
||||
(event) => this.command_handlers[event.data.command](event.data)
|
||||
);
|
||||
}
|
||||
|
@ -4,9 +4,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { WebSocketService } from './websocket.service';
|
||||
import { ProcessCommand } from './processcommand';
|
||||
import { ProcessCommand } from '../message-types/process-command';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { WSMessage } from './wsmessage';
|
||||
import { WebSocketMessage } from '../message-types/websocket-message';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@ -20,15 +20,15 @@ export class ProcessManagerService {
|
||||
this.webSocketService.connect();
|
||||
}
|
||||
|
||||
subscribeCallback(process_name: string, callback: (event: WSMessage<ProcessCommand>) => void) {
|
||||
subscribeCallback(process_name: string, callback: (event: WebSocketMessage<ProcessCommand>) => void) {
|
||||
this.observeProcessMessage(process_name).subscribe(callback);
|
||||
}
|
||||
|
||||
subscribeSuccessCallback(process_name: string, callback: (event: WSMessage<ProcessCommand>) => void) {
|
||||
subscribeSuccessCallback(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: (event: WSMessage<ProcessCommand>) => void) {
|
||||
subscribeErrorCallback(process_name: string, callback: (event: WebSocketMessage<ProcessCommand>) => void) {
|
||||
this.observeProcessMessage(process_name).pipe(filter(message => 'error' in message.data)).subscribe(callback);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { QueueingSubject } from './queueing-subject';
|
||||
import { Observable } from 'rxjs';
|
||||
import websocketConnect from 'rxjs-websockets';
|
||||
import { filter, map, share } from 'rxjs/operators';
|
||||
import { WSMessage } from './wsmessage';
|
||||
import { WebSocketMessage } from '../message-types/websocket-message';
|
||||
|
||||
|
||||
function jsonWebsocketConnect(url: string, input: Observable<object>, protocols?: string | string[]) {
|
||||
@ -19,7 +19,7 @@ function jsonWebsocketConnect(url: string, input: Observable<object>, protocols?
|
||||
@Injectable()
|
||||
export class WebSocketService {
|
||||
private uplink: QueueingSubject<object>;
|
||||
public downlink: Observable<WSMessage<undefined>>;
|
||||
public downlink: Observable<WebSocketMessage<undefined>>;
|
||||
|
||||
constructor() {}
|
||||
|
||||
@ -33,13 +33,13 @@ export class WebSocketService {
|
||||
wsproto + window.location.host + '/ws',
|
||||
this.uplink = new QueueingSubject<object>()
|
||||
).messages.pipe(
|
||||
map(message => <WSMessage<undefined>> message),
|
||||
map(message => <WebSocketMessage<undefined>> message),
|
||||
share()
|
||||
);
|
||||
console.log('ws connected');
|
||||
}
|
||||
|
||||
public observeKey<T>(key: string): Observable<WSMessage<T>> {
|
||||
public observeKey<T>(key: string): Observable<WebSocketMessage<T>> {
|
||||
return this.downlink.pipe(filter(message => message.key === key));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user