diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f9c19cd3..bf50c45d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -161,6 +161,7 @@ import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/c import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component'; import { EmptyTemplatesListComponent } from './components/preferences/common/empty-templates-list/empty-templates-list.component'; import { SymbolsMenuComponent } from './components/preferences/common/symbols-menu/symbols-menu.component'; +import { SearchFilter } from './filters/searchFilter.pipe'; if (environment.production) { Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', { @@ -261,7 +262,8 @@ if (environment.production) { CopyIouTemplateComponent, CopyDockerTemplateComponent, EmptyTemplatesListComponent, - SymbolsMenuComponent + SymbolsMenuComponent, + SearchFilter ], imports: [ BrowserModule, diff --git a/src/app/components/preferences/common/symbols/symbols.component.html b/src/app/components/preferences/common/symbols/symbols.component.html index 3eb0f2cb..0b2858b7 100644 --- a/src/app/components/preferences/common/symbols/symbols.component.html +++ b/src/app/components/preferences/common/symbols/symbols.component.html @@ -1,6 +1,7 @@ +

-
+
diff --git a/src/app/components/preferences/common/symbols/symbols.component.spec.ts b/src/app/components/preferences/common/symbols/symbols.component.spec.ts index f6e81158..5646d491 100644 --- a/src/app/components/preferences/common/symbols/symbols.component.spec.ts +++ b/src/app/components/preferences/common/symbols/symbols.component.spec.ts @@ -8,6 +8,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { SymbolsComponent } from './symbols.component'; import { SymbolService } from '../../../../services/symbol.service'; import { HttpClientModule } from '@angular/common/http'; +import { SearchFilter } from '../../../../filters/searchFilter.pipe'; export class MockedSymbolService { public list() { @@ -29,7 +30,8 @@ describe('Symbols component', () => { } ], declarations: [ - SymbolsComponent + SymbolsComponent, + SearchFilter ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/components/preferences/common/symbols/symbols.component.ts b/src/app/components/preferences/common/symbols/symbols.component.ts index c9ea926c..f33407d3 100644 --- a/src/app/components/preferences/common/symbols/symbols.component.ts +++ b/src/app/components/preferences/common/symbols/symbols.component.ts @@ -16,6 +16,7 @@ export class SymbolsComponent implements OnInit { symbols: Symbol[] = []; isSelected: string = ''; + searchText: string = ''; constructor( private symbolService: SymbolService diff --git a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html index 8695a4e3..ee5951e0 100644 --- a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html +++ b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.html @@ -87,9 +87,12 @@ -
+
+ + +
diff --git a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.scss b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.scss index 16e9201b..e69de29b 100644 --- a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.scss +++ b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.scss @@ -1,30 +0,0 @@ -.form-field { - width: 100%; -} - -.radio-button { - width: 50%; - padding-top: 20px; - padding-bottom: 30px; -} - -.radio-group { - margin-bottom: 20px; -} - -.buttons-bar { - padding-top: 20px; -} - -.nonvisible { - display: none; -} - -.file-button { - width: 18%; -} - -.file-name-form-field { - padding-left: 2%; - width: 80%; -} diff --git a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts index 256a6294..cb7be90f 100644 --- a/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts +++ b/src/app/components/preferences/docker/add-docker-template/add-docker-template.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { ToasterService } from '../../../../services/toaster.service'; import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; @@ -15,7 +15,7 @@ import { DockerImage } from '../../../../models/docker/docker-image'; @Component({ selector: 'app-add-docker-template', templateUrl: './add-docker-template.component.html', - styleUrls: ['./add-docker-template.component.scss'] + styleUrls: ['./add-docker-template.component.scss', '../../preferences.component.scss'] }) export class AddDockerTemplateComponent implements OnInit { server: Server; @@ -80,12 +80,16 @@ export class AddDockerTemplateComponent implements OnInit { this.newImageSelected = value === "newImage"; } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + } + addTemplate() { if (!this.virtualMachineForm.invalid && !this.containerNameForm.invalid && !this.networkAdaptersForm.invalid) { this.dockerTemplate.template_id = uuid(); this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => { - this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + this.goBack(); }); } else { this.toasterService.error(`Fill all required fields`); diff --git a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html index 54e7516c..6cea160e 100644 --- a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html +++ b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.html @@ -6,14 +6,19 @@
- - -
-
+
+ + + +
+
+
+ +
diff --git a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.scss b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.scss index 16e9201b..e69de29b 100644 --- a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.scss +++ b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.scss @@ -1,30 +0,0 @@ -.form-field { - width: 100%; -} - -.radio-button { - width: 50%; - padding-top: 20px; - padding-bottom: 30px; -} - -.radio-group { - margin-bottom: 20px; -} - -.buttons-bar { - padding-top: 20px; -} - -.nonvisible { - display: none; -} - -.file-button { - width: 18%; -} - -.file-name-form-field { - padding-left: 2%; - width: 80%; -} diff --git a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts index 96f3d511..e2e32b84 100644 --- a/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts +++ b/src/app/components/preferences/docker/copy-docker-template/copy-docker-template.component.ts @@ -1,30 +1,37 @@ import { Component, OnInit } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { ToasterService } from '../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; import { DockerTemplate } from '../../../../models/templates/docker-template'; import { DockerService } from '../../../../services/docker.service'; +import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-copy-docker-template', templateUrl: './copy-docker-template.component.html', - styleUrls: ['./copy-docker-template.component.scss'] + styleUrls: ['./copy-docker-template.component.scss', '../../preferences.component.scss'] }) export class CopyDockerTemplateComponent implements OnInit { server: Server; templateName: string = ''; dockerTemplate: DockerTemplate; + templateNameForm: FormGroup; constructor( private route: ActivatedRoute, private serverService: ServerService, private dockerService: DockerService, private toasterService: ToasterService, - private router: Router - ) {} + private router: Router, + private formBuilder: FormBuilder + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required) + }); + } ngOnInit() { const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -40,13 +47,17 @@ export class CopyDockerTemplateComponent implements OnInit { }); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + } + addTemplate() { - if (this.templateName) { + if (!this.templateNameForm.invalid) { this.dockerTemplate.template_id = uuid(); this.dockerTemplate.name = this.templateName; this.dockerService.addTemplate(this.server, this.dockerTemplate).subscribe((template: DockerTemplate) => { - this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + this.goBack(); }); } else { this.toasterService.error(`Fill all required fields`); diff --git a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html index 12f36d2c..d603fb36 100644 --- a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html +++ b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.html @@ -12,54 +12,56 @@ General settings - - - - - - - - - - {{category[0]}} - - - - - - -

- - - - - - - - - - {{type}} - - - - - Auto start console - - - - - {{resolution}} - - - - - - - - - +
+ + + + + + + + + + {{category[0]}} + + + + + + +

+ + + + + + + + + + {{type}} + + + + + Auto start console + + + + + {{resolution}} + + + + + + + + + +
Environment
- + @@ -70,7 +72,7 @@
Extra hosts
- + @@ -80,22 +82,15 @@ Usage - + -
- - -
-
-
-

Symbol selection

- +
+ +
-
- -
+ diff --git a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.scss b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.scss index 89cba97a..e69de29b 100644 --- a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.scss +++ b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.scss @@ -1,63 +0,0 @@ -.row { - width: 100%; - margin-left: 0px; -} - -.select { - width: 100%; -} - -.nonvisible { - display: none; -} - -.file-button { - width: 18%; -} - -.file-name-form-field { - padding-right: 2%; - width: 80%; -} - -.configButton { - width: 100%; - margin-bottom: 10px; -} - -.configHideButton { - margin-left: 80%; - width: 20%; - margin-bottom: 10px; -} - -.shadowed { - display: none; - transition: 0.25s; -} - -.top-button { - height: 36px; - margin-top: 22px -} - -.symbolSelectionButton { - width: 100%; -} - -.nonshadowed { - opacity: 0; - transition: 0.25s; -} - -th { - border: 0px!important; -} - -th.mat-header-cell { - padding-bottom: 15px; -} - -td.mat-cell { - padding-top: 15px; -} diff --git a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts index 4e311df6..625ff091 100644 --- a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts +++ b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.spec.ts @@ -68,6 +68,10 @@ describe('DockerTemplateDetailsComponent', () => { it('should call save template', () => { spyOn(mockedDockerService, 'saveTemplate').and.returnValue(of({} as DockerTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['adapter'].setValue(1); + component.generalSettingsForm.controls['symbol'].setValue('symbol path'); component.onSave(); diff --git a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts index 1902fc3c..18ffaa61 100644 --- a/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts +++ b/src/app/components/preferences/docker/docker-template-details/docker-template-details.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; import { ToasterService } from '../../../../services/toaster.service'; @@ -7,12 +7,13 @@ import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; import { DockerTemplate } from '../../../../models/templates/docker-template'; import { DockerService } from '../../../../services/docker.service'; import { DockerConfigurationService } from '../../../../services/docker-configuration.service'; +import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-docker-template-details', templateUrl: './docker-template-details.component.html', - styleUrls: ['./docker-template-details.component.scss'] + styleUrls: ['./docker-template-details.component.scss', '../../preferences.component.scss'] }) export class DockerTemplateDetailsComponent implements OnInit { server: Server; @@ -26,13 +27,24 @@ export class DockerTemplateDetailsComponent implements OnInit { adapters: CustomAdapter[] = []; displayedColumns: string[] = ['adapter_number', 'port_name']; + generalSettingsForm: FormGroup; + constructor( private route: ActivatedRoute, private serverService: ServerService, private dockerService: DockerService, private toasterService: ToasterService, - private configurationService: DockerConfigurationService - ){} + private configurationService: DockerConfigurationService, + private formBuilder: FormBuilder, + private router: Router + ){ + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + adapter: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required) + }); + } ngOnInit(){ const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -53,10 +65,18 @@ export class DockerTemplateDetailsComponent implements OnInit { this.consoleResolutions = this.configurationService.getConsoleResolutions(); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'docker', 'templates']); + } + onSave(){ - this.dockerService.saveTemplate(this.server, this.dockerTemplate).subscribe((savedTemplate: DockerTemplate) => { - this.toasterService.success("Changes saved"); - }); + if (this.generalSettingsForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + this.dockerService.saveTemplate(this.server, this.dockerTemplate).subscribe((savedTemplate: DockerTemplate) => { + this.toasterService.success("Changes saved"); + }); + } } chooseSymbol() { diff --git a/src/app/components/preferences/docker/docker-templates/docker-templates.component.html b/src/app/components/preferences/docker/docker-templates/docker-templates.component.html index 3d2b2a88..c760a4fa 100644 --- a/src/app/components/preferences/docker/docker-templates/docker-templates.component.html +++ b/src/app/components/preferences/docker/docker-templates/docker-templates.component.html @@ -2,6 +2,7 @@

Docker container templates

+
@@ -9,8 +10,8 @@
- - {{template.name}} +
+ {{template.name}} @@ -22,7 +23,7 @@ content_copyCopy - +
diff --git a/src/app/components/preferences/docker/docker-templates/docker-templates.component.scss b/src/app/components/preferences/docker/docker-templates/docker-templates.component.scss index b0726321..e69de29b 100644 --- a/src/app/components/preferences/docker/docker-templates/docker-templates.component.scss +++ b/src/app/components/preferences/docker/docker-templates/docker-templates.component.scss @@ -1,12 +0,0 @@ -.top-button { - height: 36px; - margin-top: 22px -} - -.name { - width: 95%; -} - -.menu-button { - width: 5%; -} diff --git a/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts b/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts index e5d48cf2..4ca6e1c3 100644 --- a/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts +++ b/src/app/components/preferences/docker/docker-templates/docker-templates.component.ts @@ -1,8 +1,7 @@ import { Component, OnInit, ViewChild } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; -import { switchMap } from 'rxjs/operators'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; import { DockerTemplate } from '../../../../models/templates/docker-template'; import { DockerService } from '../../../../services/docker.service'; @@ -11,7 +10,7 @@ import { DockerService } from '../../../../services/docker.service'; @Component({ selector: 'app-docker-templates', templateUrl: './docker-templates.component.html', - styleUrls: ['./docker-templates.component.scss'] + styleUrls: ['./docker-templates.component.scss', '../../preferences.component.scss'] }) export class DockerTemplatesComponent implements OnInit { server: Server; diff --git a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts index 2aad69b6..00fde8ff 100644 --- a/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts +++ b/src/app/components/preferences/dynamips/ios-templates/ios-templates.component.ts @@ -34,7 +34,6 @@ export class IosTemplatesComponent implements OnInit { } getTemplates() { - this.iosTemplates = []; this.iosService.getTemplates(this.server).subscribe((templates: IosTemplate[]) => { this.iosTemplates = templates.filter((elem) => elem.template_type === 'dynamips'); }); diff --git a/src/app/components/preferences/preferences.component.scss b/src/app/components/preferences/preferences.component.scss index b9f070fc..ffe18d4f 100644 --- a/src/app/components/preferences/preferences.component.scss +++ b/src/app/components/preferences/preferences.component.scss @@ -31,6 +31,16 @@ display: none; } +.configButton { + width: 100%; +} + +.configHideButton { + margin-left: 80%; + width: 20%; + margin-bottom: 10px; +} + .symbolSelectionButton { width: 100%; } diff --git a/src/app/components/preferences/preferences.component.ts b/src/app/components/preferences/preferences.component.ts index 5d36c142..78ecb2f8 100644 --- a/src/app/components/preferences/preferences.component.ts +++ b/src/app/components/preferences/preferences.component.ts @@ -1,7 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, ParamMap } from '@angular/router'; -import { ServerService } from '../../services/server.service'; -import { switchMap } from 'rxjs/operators'; +import { ActivatedRoute } from '@angular/router'; @Component({ diff --git a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html index 5949f1f0..cf51b441 100644 --- a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html +++ b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.html @@ -8,7 +8,7 @@
-
+ - + + formControlName="binary" > {{binary.path}} @@ -57,11 +57,11 @@ - + Existing image New image - +

-
+
+ + +
diff --git a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.scss b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.scss index 16e9201b..e69de29b 100644 --- a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.scss +++ b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.scss @@ -1,30 +0,0 @@ -.form-field { - width: 100%; -} - -.radio-button { - width: 50%; - padding-top: 20px; - padding-bottom: 30px; -} - -.radio-group { - margin-bottom: 20px; -} - -.buttons-bar { - padding-top: 20px; -} - -.nonvisible { - display: none; -} - -.file-button { - width: 18%; -} - -.file-name-form-field { - padding-left: 2%; - width: 80%; -} diff --git a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts index 329ab3ae..3afd6b0b 100644 --- a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts +++ b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.spec.ts @@ -79,9 +79,10 @@ describe('AddQemuVmTemplateComponent', () => { it('should call add template', () => { spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); - component.firstStepForm.controls['templateName'].setValue('template name'); - component.secondStepForm.controls['ramMemory'].setValue(0); - component.fourthStepForm.controls['fileName'].setValue('file name'); + component.nameForm.controls['templateName'].setValue('template name'); + component.memoryForm.controls['binary'].setValue('binary'); + component.memoryForm.controls['ramMemory'].setValue(0); + component.diskForm.controls['fileName'].setValue('file name'); component.chosenImage = 'path'; component.selectedBinary = { path: 'path', @@ -97,9 +98,10 @@ describe('AddQemuVmTemplateComponent', () => { it('should not call add template when template name is empty', () => { spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); - component.firstStepForm.controls['templateName'].setValue(''); - component.secondStepForm.controls['ramMemory'].setValue(0); - component.fourthStepForm.controls['fileName'].setValue('file name'); + component.nameForm.controls['templateName'].setValue(''); + component.memoryForm.controls['binary'].setValue('binary'); + component.memoryForm.controls['ramMemory'].setValue(0); + component.diskForm.controls['fileName'].setValue('file name'); component.chosenImage = 'path'; component.selectedBinary = { path: 'path', @@ -115,8 +117,9 @@ describe('AddQemuVmTemplateComponent', () => { it('should not call add template when ram is not set', () => { spyOn(mockedQemuService, 'addTemplate').and.returnValue(of({} as QemuTemplate)); - component.firstStepForm.controls['templateName'].setValue('template name'); - component.fourthStepForm.controls['fileName'].setValue('file name'); + component.nameForm.controls['templateName'].setValue('template name'); + component.memoryForm.controls['binary'].setValue('binary'); + component.diskForm.controls['fileName'].setValue('file name'); component.chosenImage = 'path'; component.selectedBinary = { path: 'path', diff --git a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts index 170cdc76..0522fe91 100644 --- a/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts +++ b/src/app/components/preferences/qemu/add-qemu-vm-template/add-qemu-vm-template.component.ts @@ -16,7 +16,7 @@ import { QemuConfigurationService } from '../../../../services/qemu-configuratio @Component({ selector: 'app-add-qemu-virtual-machine-template', templateUrl: './add-qemu-vm-template.component.html', - styleUrls: ['./add-qemu-vm-template.component.scss'] + styleUrls: ['./add-qemu-vm-template.component.scss', '../../preferences.component.scss'] }) export class AddQemuVmTemplateComponent implements OnInit { server: Server; @@ -30,9 +30,9 @@ export class AddQemuVmTemplateComponent implements OnInit { chosenImage: string = ''; qemuTemplate: QemuTemplate; - firstStepForm: FormGroup; - secondStepForm: FormGroup; - fourthStepForm: FormGroup; + nameForm: FormGroup; + memoryForm: FormGroup; + diskForm: FormGroup; constructor( private route: ActivatedRoute, @@ -46,15 +46,16 @@ export class AddQemuVmTemplateComponent implements OnInit { ) { this.qemuTemplate = new QemuTemplate(); - this.firstStepForm = this.formBuilder.group({ + this.nameForm = this.formBuilder.group({ templateName: new FormControl('', Validators.required) }); - this.secondStepForm = this.formBuilder.group({ + this.memoryForm = this.formBuilder.group({ + binary: new FormControl('', Validators.required), ramMemory: new FormControl('', Validators.required) }); - this.fourthStepForm = this.formBuilder.group({ + this.diskForm = this.formBuilder.group({ fileName: new FormControl('', Validators.required) }); } @@ -88,8 +89,12 @@ export class AddQemuVmTemplateComponent implements OnInit { this.chosenImage = event.target.files[0].name; } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + } + addTemplate() { - if (!this.firstStepForm.invalid && !this.secondStepForm.invalid && (this.selectedImage || this.chosenImage)) { + if (!this.nameForm.invalid && !this.memoryForm.invalid && (this.selectedImage || this.chosenImage)) { this.qemuTemplate.ram = this.ramMemory; this.qemuTemplate.qemu_path = this.selectedBinary.path; if (this.newImageSelected) { @@ -100,7 +105,7 @@ export class AddQemuVmTemplateComponent implements OnInit { this.qemuTemplate.template_id = uuid(); this.qemuService.addTemplate(this.server, this.qemuTemplate).subscribe((template: QemuTemplate) => { - this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + this.goBack(); }); } else { this.toasterService.error(`Fill all required fields`); diff --git a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html index 2f0e703c..c1c8866d 100644 --- a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html +++ b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.html @@ -5,15 +5,20 @@
-
- - -
-
+ +
+ + + +
+
+
+ +
diff --git a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.scss b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.scss index 16e9201b..e69de29b 100644 --- a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.scss +++ b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.scss @@ -1,30 +0,0 @@ -.form-field { - width: 100%; -} - -.radio-button { - width: 50%; - padding-top: 20px; - padding-bottom: 30px; -} - -.radio-group { - margin-bottom: 20px; -} - -.buttons-bar { - padding-top: 20px; -} - -.nonvisible { - display: none; -} - -.file-button { - width: 18%; -} - -.file-name-form-field { - padding-left: 2%; - width: 80%; -} diff --git a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts index 127fd31a..2327f843 100644 --- a/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts +++ b/src/app/components/preferences/qemu/copy-qemu-vm-template/copy-qemu-vm-template.component.ts @@ -1,25 +1,26 @@ import { Component, OnInit } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { QemuService } from '../../../../services/qemu.service'; import { QemuBinary } from '../../../../models/qemu/qemu-binary'; import { ToasterService } from '../../../../services/toaster.service'; import { QemuTemplate } from '../../../../models/templates/qemu-template'; import { v4 as uuid } from 'uuid'; +import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-copy-qemu-virtual-machine-template', templateUrl: './copy-qemu-vm-template.component.html', - styleUrls: ['./copy-qemu-vm-template.component.scss'] + styleUrls: ['./copy-qemu-vm-template.component.scss', '../../preferences.component.scss'] }) export class CopyQemuVmTemplateComponent implements OnInit { server: Server; qemuBinaries: QemuBinary[] = []; templateName: string = ''; qemuTemplate: QemuTemplate; - + nameForm: FormGroup; constructor( private route: ActivatedRoute, @@ -27,7 +28,12 @@ export class CopyQemuVmTemplateComponent implements OnInit { private qemuService: QemuService, private toasterService: ToasterService, private router: Router, - ) {} + private formBuilder: FormBuilder + ) { + this.nameForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required) + }); + } ngOnInit() { const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -43,13 +49,17 @@ export class CopyQemuVmTemplateComponent implements OnInit { }); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + } + addTemplate() { - if (this.templateName) { + if (!this.nameForm.invalid) { this.qemuTemplate.template_id = uuid(); this.qemuTemplate.name = this.templateName; this.qemuService.addTemplate(this.server, this.qemuTemplate).subscribe((template: QemuTemplate) => { - this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + this.goBack(); }); } else { this.toasterService.error(`Fill all required fields`); diff --git a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html index a508084a..e51ed81c 100644 --- a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html +++ b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.html @@ -12,44 +12,46 @@ General settings - - - - - - - - - -

- +
+ + + + + + + + + +
+

+ {{category[0]}} - + - + - + {{binary.path}} - + {{priority[0]}} - + {{option[0]}} @@ -79,10 +81,10 @@ HDA (Primary Master) - + - + {{interface}} @@ -97,10 +99,10 @@ HDB (Primary Slave) - + - + {{interface}} @@ -115,10 +117,10 @@ HDC (Secondary Master) - + - + {{interface}} @@ -133,10 +135,10 @@ HDD (Secondary Slave) - + - + {{interface}} @@ -153,6 +155,7 @@
+ -
@@ -174,29 +176,29 @@ Network - + - + - + - + - + - + {{type[1]}} ({{type[0]}}) -
+
Use the legacy networking mode @@ -214,6 +216,7 @@
+ -
+ -
- +
@@ -255,6 +257,7 @@
+ -
@@ -280,10 +282,10 @@ Activate CPU throttling - + - + {{priority}} @@ -298,7 +300,7 @@ Additional settings - + @@ -313,12 +315,15 @@ Usage - + -
+
+ + +
@@ -355,19 +360,10 @@
-
-
+
+ +
-
-
-
-

Symbol selection

- -
-
-
- -
-
+ diff --git a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.scss b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.scss index 89cba97a..e69de29b 100644 --- a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.scss +++ b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.scss @@ -1,63 +0,0 @@ -.row { - width: 100%; - margin-left: 0px; -} - -.select { - width: 100%; -} - -.nonvisible { - display: none; -} - -.file-button { - width: 18%; -} - -.file-name-form-field { - padding-right: 2%; - width: 80%; -} - -.configButton { - width: 100%; - margin-bottom: 10px; -} - -.configHideButton { - margin-left: 80%; - width: 20%; - margin-bottom: 10px; -} - -.shadowed { - display: none; - transition: 0.25s; -} - -.top-button { - height: 36px; - margin-top: 22px -} - -.symbolSelectionButton { - width: 100%; -} - -.nonshadowed { - opacity: 0; - transition: 0.25s; -} - -th { - border: 0px!important; -} - -th.mat-header-cell { - padding-bottom: 15px; -} - -td.mat-cell { - padding-top: 15px; -} diff --git a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts index f60f5889..06be2401 100644 --- a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts +++ b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.spec.ts @@ -76,6 +76,9 @@ describe('QemuVmTemplateDetailsComponent', () => { it('should call save template', () => { spyOn(mockedQemuService, 'saveTemplate').and.returnValue(of({} as QemuTemplate)); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); component.onSave(); diff --git a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts index 03c4d77e..14f1edf6 100644 --- a/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts +++ b/src/app/components/preferences/qemu/qemu-vm-template-details/qemu-vm-template-details.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { QemuService } from '../../../../services/qemu.service'; import { Server } from '../../../../models/server'; @@ -8,12 +8,13 @@ import { QemuBinary } from '../../../../models/qemu/qemu-binary'; import { ToasterService } from '../../../../services/toaster.service'; import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; import { QemuConfigurationService } from '../../../../services/qemu-configuration.service'; +import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms'; @Component({ selector: 'app-qemu-virtual-machine-template-details', templateUrl: './qemu-vm-template-details.component.html', - styleUrls: ['./qemu-vm-template-details.component.scss'] + styleUrls: ['./qemu-vm-template-details.component.scss', '../../preferences.component.scss'] }) export class QemuVmTemplateDetailsComponent implements OnInit { server: Server; @@ -34,13 +35,23 @@ export class QemuVmTemplateDetailsComponent implements OnInit { adapters: CustomAdapter[] = []; displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type']; + generalSettingsForm: FormGroup; + constructor( private route: ActivatedRoute, private serverService: ServerService, private qemuService: QemuService, private toasterService: ToasterService, - private configurationService: QemuConfigurationService - ){} + private configurationService: QemuConfigurationService, + private formBuilder: FormBuilder, + private router: Router + ){ + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required) + }); + } ngOnInit(){ const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -97,19 +108,31 @@ export class QemuVmTemplateDetailsComponent implements OnInit { this.qemuTemplate.bios_image = event.target.files[0].name; } + cancelConfigureCustomAdapters(){ + this.isConfiguratorOpened = !this.isConfiguratorOpened; + } + configureCustomAdapters(){ this.isConfiguratorOpened = !this.isConfiguratorOpened; this.qemuTemplate.custom_adapters = this.adapters; } - onSave(){ - if (!this.activateCpuThrottling){ - this.qemuTemplate.cpu_throttling = 0; - } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'qemu', 'templates']); + } - this.qemuService.saveTemplate(this.server, this.qemuTemplate).subscribe((savedTemplate: QemuTemplate) => { - this.toasterService.success("Changes saved"); - }); + onSave(){ + if (this.generalSettingsForm.invalid) { + this.toasterService.error(`Fill all required fields`); + } else { + if (!this.activateCpuThrottling){ + this.qemuTemplate.cpu_throttling = 0; + } + + this.qemuService.saveTemplate(this.server, this.qemuTemplate).subscribe((savedTemplate: QemuTemplate) => { + this.toasterService.success("Changes saved"); + }); + } } chooseSymbol() { @@ -117,6 +140,7 @@ export class QemuVmTemplateDetailsComponent implements OnInit { } symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; this.qemuTemplate.symbol = chosenSymbol; } } diff --git a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html index e3ed16dc..40274315 100644 --- a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html +++ b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.html @@ -2,6 +2,7 @@

QEMU VM templates

+
@@ -9,8 +10,8 @@
- - {{template.name}} +
+ {{template.name}} @@ -22,7 +23,7 @@ content_copyCopy - +
diff --git a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.scss b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.scss index b0726321..e69de29b 100644 --- a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.scss +++ b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.scss @@ -1,12 +0,0 @@ -.top-button { - height: 36px; - margin-top: 22px -} - -.name { - width: 95%; -} - -.menu-button { - width: 5%; -} diff --git a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts index 1350d19a..09fefcb4 100644 --- a/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts +++ b/src/app/components/preferences/qemu/qemu-vm-templates/qemu-vm-templates.component.ts @@ -1,8 +1,7 @@ import { Component, OnInit, ViewChild } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; -import { switchMap } from 'rxjs/operators'; import { QemuTemplate } from '../../../../models/templates/qemu-template'; import { QemuService } from '../../../../services/qemu.service'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @@ -11,7 +10,7 @@ import { DeleteTemplateComponent } from '../../common/delete-template-component/ @Component({ selector: 'app-qemu-virtual-machines-templates', templateUrl: './qemu-vm-templates.component.html', - styleUrls: ['./qemu-vm-templates.component.scss'] + styleUrls: ['./qemu-vm-templates.component.scss', '../../preferences.component.scss'] }) export class QemuVmTemplatesComponent implements OnInit { server: Server; @@ -34,13 +33,8 @@ export class QemuVmTemplatesComponent implements OnInit { } getTemplates() { - this.qemuTemplates = []; this.qemuService.getTemplates(this.server).subscribe((qemuTemplates: QemuTemplate[]) => { - qemuTemplates.forEach((template) => { - if ((template.template_type === 'qemu') && !template.builtin) { - this.qemuTemplates.push(template); - } - }); + this.qemuTemplates = qemuTemplates.filter((elem) => elem.template_type === 'dynamips'); }); } diff --git a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html index c4262f18..ca621a17 100644 --- a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html +++ b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.html @@ -5,19 +5,26 @@
- - - - {{vm.vmname}} - - -
- - Use as a linked base VM (experimental) - -
+ +
+ + + + {{vm.vmname}} + + + +
+ + Use as a linked base VM (experimental) + +
+
+ + +
diff --git a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.scss b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.scss index 9c2173c2..e69de29b 100644 --- a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.scss +++ b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.scss @@ -1,3 +0,0 @@ -.form-field { - width: 100%; -} diff --git a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts index 7fb56e75..b0edb631 100644 --- a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts +++ b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.spec.ts @@ -16,6 +16,7 @@ import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-temp import { AddVirtualBoxTemplateComponent } from './add-virtual-box-template.component'; import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; export class MockedVirtualBoxService { public addTemplate(server: Server, virtualBoxTemplate: VirtualBoxTemplate) { @@ -38,7 +39,7 @@ describe('AddVirtualBoxTemplateComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], + imports: [FormsModule, ReactiveFormsModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], providers: [ { provide: ActivatedRoute, useValue: activatedRoute @@ -95,6 +96,7 @@ describe('AddVirtualBoxTemplateComponent', () => { component.virtualBoxTemplate = {} as VirtualBoxTemplate; component.selectedVM = template; component.server = {id: 1} as Server; + component.vmForm.controls['vm'].setValue('virtual machine'); component.addTemplate(); diff --git a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts index 71433807..aa48d497 100644 --- a/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts +++ b/src/app/components/preferences/virtual-box/add-virtual-box-template/add-virtual-box-template.component.ts @@ -1,26 +1,27 @@ import { Component, OnInit } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; -import { switchMap } from 'rxjs/operators'; import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { VirtualBoxVm } from '../../../../models/virtualBox/virtual-box-vm'; import { ToasterService } from '../../../../services/toaster.service'; import { TemplateMocksService } from '../../../../services/template-mocks.service'; import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; import { v4 as uuid } from 'uuid'; +import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-add-virtual-box-template', templateUrl: './add-virtual-box-template.component.html', - styleUrls: ['./add-virtual-box-template.component.scss'] + styleUrls: ['./add-virtual-box-template.component.scss', '../../preferences.component.scss'] }) export class AddVirtualBoxTemplateComponent implements OnInit { server: Server; virtualMachines: VirtualBoxVm[]; selectedVM: VirtualBoxVm; virtualBoxTemplate: VirtualBoxTemplate; + vmForm: FormGroup; constructor( private route: ActivatedRoute, @@ -28,8 +29,13 @@ export class AddVirtualBoxTemplateComponent implements OnInit { private virtualBoxService: VirtualBoxService, private toasterService: ToasterService, private templateMocksService: TemplateMocksService, - private router: Router - ) {} + private router: Router, + private formBuilder: FormBuilder + ) { + this.vmForm = this.formBuilder.group({ + vm: new FormControl('', Validators.required) + }); + } ngOnInit() { const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -46,15 +52,19 @@ export class AddVirtualBoxTemplateComponent implements OnInit { }); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'virtualbox', 'templates']); + } + addTemplate() { - if (this.selectedVM) { + if (!this.vmForm.invalid) { this.virtualBoxTemplate.name = this.selectedVM.vmname; this.virtualBoxTemplate.vmname = this.selectedVM.vmname; this.virtualBoxTemplate.ram = this.selectedVM.ram; this.virtualBoxTemplate.template_id = uuid(); - this.virtualBoxService.addTemplate(this.server, this.virtualBoxTemplate).subscribe((template: VirtualBoxTemplate) => { - this.router.navigate(['/server', this.server.id, 'preferences', 'virtualbox', 'templates']); + this.virtualBoxService.addTemplate(this.server, this.virtualBoxTemplate).subscribe(() => { + this.goBack(); }); } else { this.toasterService.error(`Fill all required fields`); diff --git a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html index aa0039b3..99fc0198 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html +++ b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.html @@ -12,43 +12,45 @@ General settings - - - - - - - - - -

- - - - {{category[0]}} - - - - - - - {{type}} - - - - - Auto start console - - - - - - - - {{option[0]}} - - - +
+ + + + + + + + + +

+ + + + {{category[0]}} + + + + + + + {{type}} + + + + + Auto start console + + + + + + + + {{option[0]}} + + + +
Start VM in headless mode
@@ -62,26 +64,28 @@ Network - - - - - - - - - - - - - - - - {{type}} - - - -
+
+ + + + + + + + + + + + + + + + {{type}} + + + +
+
Allow GNS3 to use any configured VirtualBox adapter @@ -92,12 +96,15 @@ Usage - + -
+
+ + +
@@ -134,19 +141,10 @@
-
-
+
+ +
-
-
-
-

Symbol selection

- -
-
-
- -
-
+ diff --git a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.scss b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.scss index 88579891..e69de29b 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.scss +++ b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.scss @@ -1,50 +0,0 @@ -.row { - width: 100%; - margin-left: 0px; -} - -.select { - width: 100%; -} - -.configButton { - width: 100%; - margin-bottom: 10px; -} - -.configHideButton { - margin-left: 80%; - width: 20%; - margin-bottom: 10px; -} - -.shadowed { - display: none; - transition: 0.25s; -} - -.top-button { - height: 36px; - margin-top: 22px -} - -.symbolSelectionButton { - width: 100%; -} - -.nonshadowed { - opacity: 0; - transition: 0.25s; -} - -th { - border: 0px!important; -} - -th.mat-header-cell { - padding-bottom: 15px; -} - -td.mat-cell { - padding-top: 15px; -} diff --git a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts index 2255ed7e..80d3b056 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-template-details/virtual-box-template-details.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; import { ToasterService } from '../../../../services/toaster.service'; @@ -13,7 +13,7 @@ import { VirtualBoxConfigurationService } from '../../../../services/virtual-box @Component({ selector: 'app-virtual-box-template-details', templateUrl: './virtual-box-template-details.component.html', - styleUrls: ['./virtual-box-template-details.component.scss'] + styleUrls: ['./virtual-box-template-details.component.scss', '../../preferences.component.scss'] }) export class VirtualBoxTemplateDetailsComponent implements OnInit { server: Server; @@ -29,14 +29,31 @@ export class VirtualBoxTemplateDetailsComponent implements OnInit { displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type']; isConfiguratorOpened: boolean = false; + generalSettingsForm: FormGroup; + networkForm: FormGroup + constructor( private route: ActivatedRoute, private serverService: ServerService, private virtualBoxService: VirtualBoxService, private toasterService: ToasterService, private formBuilder: FormBuilder, - private virtualBoxConfigurationService: VirtualBoxConfigurationService - ) {} + private virtualBoxConfigurationService: VirtualBoxConfigurationService, + private router: Router + ) { + this.generalSettingsForm = this.formBuilder.group({ + templateName: new FormControl('', Validators.required), + defaultName: new FormControl('', Validators.required), + symbol: new FormControl('', Validators.required), + ram: new FormControl('', Validators.required) + }); + + this.networkForm = this.formBuilder.group({ + adapters: new FormControl('', Validators.required), + nameFormat: new FormControl('', Validators.required), + size: new FormControl('', Validators.required) + }); + } ngOnInit() { const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -75,6 +92,14 @@ export class VirtualBoxTemplateDetailsComponent implements OnInit { this.virtualBoxTemplate.custom_adapters = this.adapters; } + cancelConfigureCustomAdapters(){ + this.isConfiguratorOpened = !this.isConfiguratorOpened; + } + + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'virtualbox', 'templates']); + } + onSave() { this.virtualBoxService.saveTemplate(this.server, this.virtualBoxTemplate).subscribe((virtualBoxTemplate: VirtualBoxTemplate) => { this.toasterService.success("Changes saved"); @@ -86,6 +111,7 @@ export class VirtualBoxTemplateDetailsComponent implements OnInit { } symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; this.virtualBoxTemplate.symbol = chosenSymbol; } } diff --git a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html index 0607f12c..4b699752 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html +++ b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.html @@ -2,6 +2,7 @@

VirtualBox VM templates

+
@@ -9,12 +10,12 @@
- - {{template.name}} +
+ {{template.name}} - +
diff --git a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.scss b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.scss index e6125a7a..e69de29b 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.scss +++ b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.scss @@ -1,12 +0,0 @@ -.top-button { - height: 36px; - margin-top: 22px -} - -.name { - width: 90%; -} - -.delete-button { - width: 10%; -} diff --git a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts index 43e15a1b..d84edafc 100644 --- a/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts +++ b/src/app/components/preferences/virtual-box/virtual-box-templates/virtual-box-templates.component.ts @@ -1,8 +1,7 @@ import { Component, OnInit, ViewChild } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; -import { switchMap } from 'rxjs/operators'; import { VirtualBoxTemplate } from '../../../../models/templates/virtualbox-template'; import { VirtualBoxService } from '../../../../services/virtual-box.service'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @@ -12,7 +11,7 @@ import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; @Component({ selector: 'app-virtual-box-templates', templateUrl: './virtual-box-templates.component.html', - styleUrls: ['./virtual-box-templates.component.scss'] + styleUrls: ['./virtual-box-templates.component.scss', '../../preferences.component.scss'] }) export class VirtualBoxTemplatesComponent implements OnInit { server: Server; @@ -34,13 +33,8 @@ export class VirtualBoxTemplatesComponent implements OnInit { } getTemplates(){ - this.virtualBoxTemplates = []; this.virtualBoxService.getTemplates(this.server).subscribe((virtualBoxTemplates: VirtualBoxTemplate[]) => { - virtualBoxTemplates.forEach((template) => { - if ((template.template_type === 'virtualbox') && !template.builtin) { - this.virtualBoxTemplates.push(template); - } - }); + this.virtualBoxTemplates = virtualBoxTemplates.filter((elem) => elem.template_type === 'virtualbox'); }); } diff --git a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html index eb23d858..6fea2574 100644 --- a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html +++ b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.html @@ -5,19 +5,26 @@
- - - - {{vm.vmname}} - - -
- - Use as a linked base VM (experimental) - -
+ +
+ + + + {{vm.vmname}} + + +
+ + Use as a linked base VM (experimental) + +
+
+
+ + +
diff --git a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.scss b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.scss index 9c2173c2..e69de29b 100644 --- a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.scss +++ b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.scss @@ -1,3 +0,0 @@ -.form-field { - width: 100%; -} diff --git a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts index 3164f180..dd2ccabe 100644 --- a/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts +++ b/src/app/components/preferences/vmware/add-vmware-template/add-vmware-template.component.ts @@ -1,26 +1,27 @@ import { Component, OnInit } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; -import { switchMap } from 'rxjs/operators'; import { ToasterService } from '../../../../services/toaster.service'; import { TemplateMocksService } from '../../../../services/template-mocks.service'; import { v4 as uuid } from 'uuid'; import { VmwareVm } from '../../../../models/vmware/vmware-vm'; import { VmwareTemplate } from '../../../../models/templates/vmware-template'; import { VmwareService } from '../../../../services/vmware.service'; +import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-add-vmware-template', templateUrl: './add-vmware-template.component.html', - styleUrls: ['./add-vmware-template.component.scss'] + styleUrls: ['./add-vmware-template.component.scss', '../../preferences.component.scss'] }) export class AddVmwareTemplateComponent implements OnInit { server: Server; virtualMachines: VmwareVm[]; selectedVM: VmwareVm; vmwareTemplate: VmwareTemplate; + templateNameForm: FormGroup; constructor( private route: ActivatedRoute, @@ -28,8 +29,13 @@ export class AddVmwareTemplateComponent implements OnInit { private vmwareService: VmwareService, private toasterService: ToasterService, private templateMocksService: TemplateMocksService, - private router: Router - ) {} + private router: Router, + private formBuilder: FormBuilder + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl(null, [Validators.required]) + }); + } ngOnInit() { const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -46,14 +52,18 @@ export class AddVmwareTemplateComponent implements OnInit { }); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vmware', 'templates']); + } + addTemplate() { - if (this.selectedVM) { + if (!this.templateNameForm.invalid) { this.vmwareTemplate.name = this.selectedVM.vmname; this.vmwareTemplate.vmx_path = this.selectedVM.vmx_path; this.vmwareTemplate.template_id = uuid(); - this.vmwareService.addTemplate(this.server, this.vmwareTemplate).subscribe((template: VmwareTemplate) => { - this.router.navigate(['/server', this.server.id, 'preferences', 'vmware', 'templates']); + this.vmwareService.addTemplate(this.server, this.vmwareTemplate).subscribe(() => { + this.goBack(); }); } else { this.toasterService.error(`Fill all required fields`); diff --git a/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts b/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts index 740e744b..6358173d 100644 --- a/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts +++ b/src/app/components/preferences/vmware/add-vmware-template/add-vmware.component.template.spec.ts @@ -17,6 +17,7 @@ import { VmwareTemplate } from '../../../../models/templates/vmware-template'; import { AddVmwareTemplateComponent } from './add-vmware-template.component'; import { VmwareService } from '../../../../services/vmware.service'; import { VmwareVm } from '../../../../models/vmware/vmware-vm'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; export class MockedVmwareService { public addTemplate(server: Server, vmwareTemplate: VmwareTemplate) { @@ -39,7 +40,7 @@ describe('AddVmwareTemplateComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], + imports: [FormsModule, ReactiveFormsModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], providers: [ { provide: ActivatedRoute, useValue: activatedRoute @@ -76,6 +77,7 @@ describe('AddVmwareTemplateComponent', () => { component.vmwareTemplate = {} as VmwareTemplate; component.selectedVM = template; component.server = {id: 1} as Server; + component.templateNameForm.controls['templateName'].setValue('template name'); component.addTemplate(); diff --git a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html index 0bab714e..77a3be34 100644 --- a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html +++ b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.html @@ -12,30 +12,30 @@ General settings -
- + + - + - + -

- +

+ Auto start console - + - + - + - + - + - + {{type}} -
+
Allow GNS3 to override non custom VMware adapter @@ -118,13 +118,14 @@ Usage - +
-
+ +
@@ -162,19 +163,10 @@ -
-
+
+ +
-
-
-
-

Symbol selection

- -
-
-
- -
-
+ diff --git a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.scss b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.scss index 88579891..e69de29b 100644 --- a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.scss +++ b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.scss @@ -1,50 +0,0 @@ -.row { - width: 100%; - margin-left: 0px; -} - -.select { - width: 100%; -} - -.configButton { - width: 100%; - margin-bottom: 10px; -} - -.configHideButton { - margin-left: 80%; - width: 20%; - margin-bottom: 10px; -} - -.shadowed { - display: none; - transition: 0.25s; -} - -.top-button { - height: 36px; - margin-top: 22px -} - -.symbolSelectionButton { - width: 100%; -} - -.nonshadowed { - opacity: 0; - transition: 0.25s; -} - -th { - border: 0px!important; -} - -th.mat-header-cell { - padding-bottom: 15px; -} - -td.mat-cell { - padding-top: 15px; -} diff --git a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts index 37312b9c..75cdd50c 100644 --- a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts +++ b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.spec.ts @@ -68,9 +68,9 @@ describe('VmwareTemplateDetailsComponent', () => { it('should call save template', () => { spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); component.onSave(); @@ -79,9 +79,9 @@ describe('VmwareTemplateDetailsComponent', () => { it('should not call save template when template name is empty', () => { spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.inputForm.controls['templateName'].setValue(''); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['templateName'].setValue(''); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); component.onSave(); @@ -90,9 +90,9 @@ describe('VmwareTemplateDetailsComponent', () => { it('should not call save template when default name is empty', () => { spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue(''); - component.inputForm.controls['symbol'].setValue('symbol'); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue(''); + component.generalSettingsForm.controls['symbol'].setValue('symbol'); component.onSave(); @@ -101,9 +101,9 @@ describe('VmwareTemplateDetailsComponent', () => { it('should not call save template when symbol path is empty', () => { spyOn(mockedVmwareService, 'saveTemplate').and.returnValue(of({} as VmwareTemplate)); - component.inputForm.controls['templateName'].setValue('template name'); - component.inputForm.controls['defaultName'].setValue('default name'); - component.inputForm.controls['symbol'].setValue(''); + component.generalSettingsForm.controls['templateName'].setValue('template name'); + component.generalSettingsForm.controls['defaultName'].setValue('default name'); + component.generalSettingsForm.controls['symbol'].setValue(''); component.onSave(); diff --git a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts index 4a960806..3fddcf30 100644 --- a/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts +++ b/src/app/components/preferences/vmware/vmware-template-details/vmware-template-details.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; import { ToasterService } from '../../../../services/toaster.service'; @@ -13,12 +13,12 @@ import { CustomAdapter } from '../../../../models/qemu/qemu-custom-adapter'; @Component({ selector: 'app-vmware-template-details', templateUrl: './vmware-template-details.component.html', - styleUrls: ['./vmware-template-details.component.scss'] + styleUrls: ['./vmware-template-details.component.scss', '../../preferences.component.scss'] }) export class VmwareTemplateDetailsComponent implements OnInit { server: Server; vmwareTemplate: VmwareTemplate; - inputForm: FormGroup; + generalSettingsForm: FormGroup; adapters: CustomAdapter[] = []; displayedColumns: string[] = ['adapter_number', 'port_name', 'adapter_type']; @@ -36,9 +36,10 @@ export class VmwareTemplateDetailsComponent implements OnInit { private vmwareService: VmwareService, private toasterService: ToasterService, private formBuilder: FormBuilder, - private vmwareConfigurationService: VmwareConfigurationService + private vmwareConfigurationService: VmwareConfigurationService, + private router: Router ) { - this.inputForm = this.formBuilder.group({ + this.generalSettingsForm = this.formBuilder.group({ templateName: new FormControl('', Validators.required), defaultName: new FormControl('', Validators.required), symbol: new FormControl('', Validators.required) @@ -65,8 +66,12 @@ export class VmwareTemplateDetailsComponent implements OnInit { this.networkTypes = this.vmwareConfigurationService.getNetworkTypes(); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vmware', 'templates']); + } + onSave() { - if (this.inputForm.invalid) { + if (this.generalSettingsForm.invalid) { this.toasterService.error(`Fill all required fields`); } else { this.vmwareService.saveTemplate(this.server, this.vmwareTemplate).subscribe((vmwareTemplate: VmwareTemplate) => { @@ -75,6 +80,10 @@ export class VmwareTemplateDetailsComponent implements OnInit { } } + cancelConfigureCustomAdapters(){ + this.isConfiguratorOpened = !this.isConfiguratorOpened; + } + configureCustomAdapters() { this.isConfiguratorOpened = !this.isConfiguratorOpened; this.adapters = []; diff --git a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.html b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.html index e41f5d98..2651f909 100644 --- a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.html +++ b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.html @@ -2,6 +2,7 @@

VMware VM templates

+
@@ -9,12 +10,12 @@
- - {{template.name}} +
+ {{template.name}} - +
diff --git a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.scss b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.scss index e6125a7a..e69de29b 100644 --- a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.scss +++ b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.scss @@ -1,12 +0,0 @@ -.top-button { - height: 36px; - margin-top: 22px -} - -.name { - width: 90%; -} - -.delete-button { - width: 10%; -} diff --git a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts index 8deb63e4..1e6e4e51 100644 --- a/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts +++ b/src/app/components/preferences/vmware/vmware-templates/vmware-templates.component.ts @@ -1,19 +1,16 @@ import { Component, OnInit, ViewChild } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { VmwareTemplate } from '../../../../models/templates/vmware-template'; import { VmwareService } from '../../../../services/vmware.service'; -import { MatDialog } from '@angular/material'; -import { DeleteConfirmationDialogComponent } from '../../common/delete-confirmation-dialog/delete-confirmation-dialog.component'; -import { ToasterService } from '../../../../services/toaster.service'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @Component({ selector: 'app-vmware-templates', templateUrl: './vmware-templates.component.html', - styleUrls: ['./vmware-templates.component.scss'] + styleUrls: ['./vmware-templates.component.scss', '../../preferences.component.scss'] }) export class VmwareTemplatesComponent implements OnInit { server: Server; diff --git a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html index 3d61ea21..b9d5566c 100644 --- a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html +++ b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.html @@ -5,10 +5,15 @@
- - - + + + + + + +
+
diff --git a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.scss b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.scss index 00630795..e69de29b 100644 --- a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.scss +++ b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.scss @@ -1,3 +0,0 @@ -.row { - width: 100%; -} diff --git a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts index 0bc0b254..3b59d322 100644 --- a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts +++ b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.spec.ts @@ -16,6 +16,7 @@ import { TemplateMocksService } from '../../../../services/template-mocks.servic import { MockedToasterService } from '../../../../services/toaster.service.spec'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; import { MockedActivatedRoute } from '../../preferences.component.spec'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; export class MockedVpcsService { public addTemplate(server: Server, vpcsTemplate: VpcsTemplate) { @@ -34,7 +35,7 @@ describe('AddVpcsTemplateComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - imports: [MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], + imports: [FormsModule, ReactiveFormsModule, MatIconModule, MatToolbarModule, MatMenuModule, MatCheckboxModule, CommonModule, NoopAnimationsModule, RouterTestingModule.withRoutes([])], providers: [ { provide: ActivatedRoute, useValue: activatedRoute @@ -64,6 +65,7 @@ describe('AddVpcsTemplateComponent', () => { it('should call add template', () => { spyOn(mockedVpcsService, 'addTemplate').and.returnValue(of({} as VpcsTemplate)); component.templateName = "sample name"; + component.templateNameForm.controls['templateName'].setValue('template name'); component.server = {id: 1} as Server; component.addTemplate(); diff --git a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts index a695c0d8..62158587 100644 --- a/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts +++ b/src/app/components/preferences/vpcs/add-vpcs-template/add-vpcs-template.component.ts @@ -1,23 +1,24 @@ import { Component, OnInit } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; -import { switchMap } from 'rxjs/operators'; import { VpcsService } from '../../../../services/vpcs.service'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; import { ToasterService } from '../../../../services/toaster.service'; import { v4 as uuid } from 'uuid'; import { TemplateMocksService } from '../../../../services/template-mocks.service'; +import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-add-vpcs-template', templateUrl: './add-vpcs-template.component.html', - styleUrls: ['./add-vpcs-template.component.scss'] + styleUrls: ['./add-vpcs-template.component.scss', '../../preferences.component.scss'] }) export class AddVpcsTemplateComponent implements OnInit { server: Server; templateName: string = ''; + templateNameForm: FormGroup constructor( private route: ActivatedRoute, @@ -25,8 +26,13 @@ export class AddVpcsTemplateComponent implements OnInit { private vpcsService: VpcsService, private router: Router, private toasterService: ToasterService, - private templateMocksService: TemplateMocksService - ) {} + private templateMocksService: TemplateMocksService, + private formBuilder: FormBuilder + ) { + this.templateNameForm = this.formBuilder.group({ + templateName: new FormControl(null, [Validators.required]) + }); + } ngOnInit() { const server_id = this.route.snapshot.paramMap.get("server_id"); @@ -35,8 +41,12 @@ export class AddVpcsTemplateComponent implements OnInit { }); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vpcs', 'templates']); + } + addTemplate() { - if (this.templateName) { + if (!this.templateNameForm.invalid) { let vpcsTemplate: VpcsTemplate; this.templateMocksService.getVpcsTemplate().subscribe((template: VpcsTemplate) => { @@ -46,8 +56,8 @@ export class AddVpcsTemplateComponent implements OnInit { vpcsTemplate.template_id = uuid(), vpcsTemplate.name = this.templateName, - this.vpcsService.addTemplate(this.server, vpcsTemplate).subscribe((vpcsTemplate) => { - this.router.navigate(['/server', this.server.id, 'preferences', 'vpcs', 'templates']); + this.vpcsService.addTemplate(this.server, vpcsTemplate).subscribe(() => { + this.goBack(); }); } else { this.toasterService.error(`Fill all required fields`); diff --git a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts index 2d7581ec..641746b1 100644 --- a/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts +++ b/src/app/components/preferences/vpcs/vpcs-preferences/vpcs-preferences.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { Server } from '../../../../models/server'; -import { switchMap } from 'rxjs/operators'; import { ServerService } from '../../../../services/server.service'; diff --git a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html index 08009d7e..fa2601a3 100644 --- a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html +++ b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.html @@ -5,77 +5,68 @@
-
- - - - - - - - - - - - -

- - + + + + + + + + + + + + + +

+ + + + {{category[0]}} + + + + + + + {{type}} + + + + - - {{category[0]}} - -
-
- - - - {{type}} - - - - - Auto start console - -
+ [(ngModel)]="vpcsTemplate.console_auto_start"> + Auto start console + + +
-
+ +
- -
-
-
-

Symbol selection

- - -
-
-
- -
-
+ diff --git a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.scss b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.scss index c20e763d..e69de29b 100644 --- a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.scss +++ b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.scss @@ -1,22 +0,0 @@ -.row { - width: 100%; - margin-left: 0px; -} - -.select { - width: 100%; -} - -.top-button { - height: 36px; - margin-top: 22px -} - -.shadowed { - display: none; - transition: 0.25s; -} - -.symbolSelectionButton { - width: 100%; -} diff --git a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts index 281d1b3b..6b23a04b 100644 --- a/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts +++ b/src/app/components/preferences/vpcs/vpcs-template-details/vpcs-template-details.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { Server } from '../../../../models/server'; import { ToasterService } from '../../../../services/toaster.service'; @@ -12,16 +12,13 @@ import { VpcsConfigurationService } from '../../../../services/vpcs-configuratio @Component({ selector: 'app-vpcs-template-details', templateUrl: './vpcs-template-details.component.html', - styleUrls: ['./vpcs-template-details.component.scss','../../preferences.component.scss'] + styleUrls: ['./vpcs-template-details.component.scss', '../../preferences.component.scss'] }) export class VpcsTemplateDetailsComponent implements OnInit { server: Server; vpcsTemplate: VpcsTemplate; inputForm: FormGroup; - isSymbolSelectionOpened: boolean = false; - copyOfSymbol: string; - consoleTypes: string[] = []; categories = []; @@ -31,7 +28,8 @@ export class VpcsTemplateDetailsComponent implements OnInit { private vpcsService: VpcsService, private toasterService: ToasterService, private formBuilder: FormBuilder, - private vpcsConfigurationService: VpcsConfigurationService + private vpcsConfigurationService: VpcsConfigurationService, + private router: Router ) { this.inputForm = this.formBuilder.group({ templateName: new FormControl('', Validators.required), @@ -59,6 +57,10 @@ export class VpcsTemplateDetailsComponent implements OnInit { this.categories = this.vpcsConfigurationService.getCategories(); } + goBack() { + this.router.navigate(['/server', this.server.id, 'preferences', 'vpcs', 'templates']); + } + onSave() { if (this.inputForm.invalid) { this.toasterService.error(`Fill all required fields`); @@ -70,16 +72,11 @@ export class VpcsTemplateDetailsComponent implements OnInit { } chooseSymbol() { - this.copyOfSymbol = this.vpcsTemplate.symbol; this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; } - cancelChooseSymbol() { - this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; - this.vpcsTemplate.symbol = this.copyOfSymbol; - } - symbolChanged(chosenSymbol: string) { + this.isSymbolSelectionOpened = !this.isSymbolSelectionOpened; this.vpcsTemplate.symbol = chosenSymbol; } } diff --git a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html index dfb847a4..63e5ea13 100644 --- a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html +++ b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.html @@ -2,6 +2,7 @@

VPCS node templates

+
@@ -9,12 +10,12 @@
- - {{template.name}} +
+ {{template.name}} - +
diff --git a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.scss b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.scss index e6125a7a..e69de29b 100644 --- a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.scss +++ b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.scss @@ -1,12 +0,0 @@ -.top-button { - height: 36px; - margin-top: 22px -} - -.name { - width: 90%; -} - -.delete-button { - width: 10%; -} diff --git a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts index 47207978..fb91b3e1 100644 --- a/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts +++ b/src/app/components/preferences/vpcs/vpcs-templates/vpcs-templates.component.ts @@ -1,19 +1,16 @@ import { Component, OnInit, ViewChild } from "@angular/core"; import { Server } from '../../../../models/server'; -import { ActivatedRoute, ParamMap } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { ServerService } from '../../../../services/server.service'; import { VpcsService } from '../../../../services/vpcs.service'; import { VpcsTemplate } from '../../../../models/templates/vpcs-template'; -import { MatDialog } from '@angular/material'; -import { DeleteConfirmationDialogComponent } from '../../common/delete-confirmation-dialog/delete-confirmation-dialog.component'; -import { ToasterService } from '../../../../services/toaster.service'; import { DeleteTemplateComponent } from '../../common/delete-template-component/delete-template.component'; @Component({ selector: 'app-vpcs-templates', templateUrl: './vpcs-templates.component.html', - styleUrls: ['./vpcs-templates.component.scss'] + styleUrls: ['./vpcs-templates.component.scss', '../../preferences.component.scss'] }) export class VpcsTemplatesComponent implements OnInit { server: Server; @@ -35,13 +32,8 @@ export class VpcsTemplatesComponent implements OnInit { } getTemplates() { - this.vpcsTemplates = []; this.vpcsService.getTemplates(this.server).subscribe((vpcsTemplates: VpcsTemplate[]) => { - vpcsTemplates.forEach((template) => { - if ((template.template_type === 'vpcs') && !template.builtin) { - this.vpcsTemplates.push(template); - } - }); + this.vpcsTemplates = vpcsTemplates.filter((elem) => elem.template_type === 'vpcs'); }); } diff --git a/src/app/filters/searchFilter.pipe.spec.ts b/src/app/filters/searchFilter.pipe.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/filters/searchFilter.pipe.ts b/src/app/filters/searchFilter.pipe.ts new file mode 100644 index 00000000..5177a825 --- /dev/null +++ b/src/app/filters/searchFilter.pipe.ts @@ -0,0 +1,17 @@ +import { Pipe, PipeTransform } from '@angular/core'; + + +@Pipe({ + name: 'filenamefilter' +}) +export class SearchFilter implements PipeTransform { + transform(items: any[], searchText: string): any[] { + if(!items) return []; + if(!searchText) return items; + + searchText = searchText.toLowerCase(); + return items.filter( item => { + return item.filename.toLowerCase().includes(searchText); + }); + } +}