diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 624d876..93fd321 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -17,6 +17,7 @@ import { MessagesComponent } from './messages/messages.component'; import { WebSocketService } from './services/websocket.service'; import { TerminalComponent } from './terminal/terminal.component'; import { FSMUpdateService } from './services/fsmupdate.service'; +import { ProcessManagerService } from './services/processmanager.service'; import { AppRoutingModule } from './app-routing.module'; @@ -42,7 +43,8 @@ import { AppRoutingModule } from './app-routing.module'; MarkdownService, WebSocketService, TerminadoService, - FSMUpdateService + FSMUpdateService, + ProcessManagerService ], bootstrap: [ AppComponent diff --git a/src/app/services/processcommand.ts b/src/app/services/processcommand.ts new file mode 100644 index 0000000..f275533 --- /dev/null +++ b/src/app/services/processcommand.ts @@ -0,0 +1,4 @@ +export class ProcessCommand { + command: string; + process_name: string; +} diff --git a/src/app/services/processmanager.service.ts b/src/app/services/processmanager.service.ts new file mode 100644 index 0000000..3e948a6 --- /dev/null +++ b/src/app/services/processmanager.service.ts @@ -0,0 +1,39 @@ +import { Injectable } from '@angular/core'; + +import { WebSocketService } from './websocket.service'; +import { ProcessCommand } from './processcommand'; +import { filter } from 'rxjs/operators'; + + +@Injectable() +export class ProcessManagerService { + key = 'processmanager'; + process_name: string; + + constructor(private webSocketService: WebSocketService) {} + + init() { + this.webSocketService.connect(); + } + + subscribeCallback(process_name: string, callback: (event: any) => void) { + this.webSocketService.observeKey(this.key) + .pipe(filter(message => message.data.process_name === process_name)).subscribe(callback); + } + + sendCommand(command: string, process_name: string) { + this.webSocketService.send(this.key, {'command': command, 'process_name': process_name}); + } + + startProcess(process_name: string) { + this.sendCommand('start', process_name); + } + + stopProcess(process_name: string) { + this.sendCommand('stop', process_name); + } + + restartProcess(process_name: string) { + this.sendCommand('restart', process_name); + } +} diff --git a/src/app/webide/webide.component.html b/src/app/webide/webide.component.html index 9054c88..5a2a2a6 100644 --- a/src/app/webide/webide.component.html +++ b/src/app/webide/webide.component.html @@ -3,7 +3,7 @@ class="btn btn-secondary" [class.active]="filename === file" [class.disabled]="filename === file" - (click)="selectCode(file); requestCode()" + (click)="sendCodeContents(); selectCode(file); requestCode()" [disabled]="filename === file"> {{file}} @@ -23,8 +23,8 @@ type="submit" class="btn btn-secondary" [class.btn-success]="saveButtonState === 'SAVED'" - [class.btn-warning]="saveButtonState === 'SAVING'" + [class.btn-info]="saveButtonState === 'SAVING'" [class.disabled]="saveButtonState === 'SAVING'" >Save! - Saved! - Saving... + Done! +
Reloading...
diff --git a/src/app/webide/webide.component.scss b/src/app/webide/webide.component.scss index 0ad49f6..daf91d9 100644 --- a/src/app/webide/webide.component.scss +++ b/src/app/webide/webide.component.scss @@ -7,3 +7,21 @@ .btn-secondary { border-radius: 0; } + +.loader { + border: 2px solid #ffffff; + border-radius: 50%; + border-top: 2px solid #212529; + width: 15px; + height: 15px; + animation: spin 2s linear infinite; + display: inline-block; + margin-right: 5px; + position: relative; + top: 2px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/src/app/webide/webide.component.ts b/src/app/webide/webide.component.ts index b4d542e..2180d8e 100644 --- a/src/app/webide/webide.component.ts +++ b/src/app/webide/webide.component.ts @@ -14,6 +14,7 @@ import 'brace/mode/sql'; import 'brace/theme/monokai'; import { SourceCode } from './source-code'; import { WebSocketService } from '../services/websocket.service'; +import { ProcessManagerService } from '../services/processmanager.service'; const modelist = brace.acequire('ace/ext/modelist'); @@ -35,15 +36,18 @@ export class WebideComponent implements OnInit { command_handlers = { 'reload': this.reloadHandler.bind(this), 'read': this.readHandler.bind(this), 'select': this.selectHandler.bind(this), - 'write': this.writeHandler.bind(this)}; + 'write': () => {}}; constructor(private webSocketService: WebSocketService, - private changeDetectorRef: ChangeDetectorRef) { } + private changeDetectorRef: ChangeDetectorRef, + private processManagerService: ProcessManagerService) { } ngOnInit() { this.webSocketService.connect(); this.subscribeWS(); this.requestCode(); + this.processManagerService.init(); + this.processManagerService.subscribeCallback('login', (event) => { this.setButtonStateSaved(); }); } subscribeWS() { @@ -72,7 +76,7 @@ export class WebideComponent implements OnInit { this.updateFileData(data); } - writeHandler(data: SourceCode) { + setButtonStateSaved() { this.saveButtonState = 'SAVED'; } @@ -81,11 +85,16 @@ export class WebideComponent implements OnInit { } sendCode() { + this.sendCodeContents(); + this.saveButtonState = 'SAVING'; + this.processManagerService.restartProcess('login'); + } + + sendCodeContents() { this.webSocketService.send(this.key_id, { 'command': 'write', 'content': this.code }); - this.saveButtonState = 'SAVING'; } requestCode() {