Dialog for Qemu template name

This commit is contained in:
piotrpekala7 2020-09-08 12:07:38 +02:00
parent b32fdf4fc2
commit 87aa6c4b59
6 changed files with 186 additions and 7 deletions

View File

@ -279,6 +279,7 @@ import { ChangeHostnameActionComponent } from './components/project-map/context-
import { ChangeHostnameDialogComponent } from './components/project-map/change-hostname-dialog/change-hostname-dialog.component';
import { ApplianceInfoDialogComponent } from './components/project-map/new-template-dialog/appliance-info-dialog/appliance-info-dialog.component';
import { InformationDialogComponent } from './components/dialogs/information-dialog.component';
import { TemplateNameDialogComponent } from './components/project-map/new-template-dialog/template-name-dialog/template-name-dialog.component';
@NgModule({
declarations: [
@ -462,7 +463,8 @@ import { InformationDialogComponent } from './components/dialogs/information-dia
ChangeHostnameActionComponent,
ChangeHostnameDialogComponent,
ApplianceInfoDialogComponent,
InformationDialogComponent
InformationDialogComponent,
TemplateNameDialogComponent
],
imports: [
BrowserModule,

View File

@ -29,6 +29,7 @@ import { Template } from '../../../models/template';
import { ComputeService } from '../../../services/compute.service';
import { InformationDialogComponent } from '../../../components/dialogs/information-dialog.component';
import { ProgressService } from '../../../common/progress/progress.service';
import { TemplateNameDialogComponent } from './template-name-dialog/template-name-dialog.component';
@Component({
selector: 'app-new-template-dialog',
@ -78,6 +79,8 @@ export class NewTemplateDialogComponent implements OnInit {
private iosImages: Image[] = [];
private iouImages: Image[] = [];
private templates: Template[] = [];
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild('stepper', {static: true}) stepper: MatStepper;
@ -98,6 +101,10 @@ export class NewTemplateDialogComponent implements OnInit {
) {}
ngOnInit() {
this.templateService.list(this.server).subscribe((templates) => {
this.templates = templates;
});
this.computeService.getComputes(this.server).subscribe((computes) => {
computes.forEach(compute => {
if (compute.compute_id === 'vm') {
@ -423,6 +430,8 @@ export class NewTemplateDialogComponent implements OnInit {
}
createIouTemplate (image: Image) {
if (!this.validateTemplateName()) return;
let iouTemplate: IouTemplate = new IouTemplate();
iouTemplate.name = this.applianceToInstall.name;
iouTemplate.nvram = this.applianceToInstall.iou.nvram;
@ -447,6 +456,8 @@ export class NewTemplateDialogComponent implements OnInit {
}
createIosTemplate(image: Image) {
if (!this.validateTemplateName()) return;
let iosTemplate: IosTemplate = new IosTemplate();
iosTemplate.name = this.applianceToInstall.name;
iosTemplate.chassis = this.applianceToInstall.dynamips.chassis;
@ -479,6 +490,8 @@ export class NewTemplateDialogComponent implements OnInit {
}
createDockerTemplate() {
if (!this.validateTemplateName()) return;
let dockerTemplate: DockerTemplate = new DockerTemplate();
dockerTemplate.name = this.applianceToInstall.name;
dockerTemplate.adapters = this.applianceToInstall.docker.adapters;
@ -509,8 +522,8 @@ export class NewTemplateDialogComponent implements OnInit {
this.toasterService.error('Please select QEMU binary first');
return;
}
let qemuTemplate: QemuTemplate = new QemuTemplate();
qemuTemplate.name = this.applianceToInstall.name;
qemuTemplate.ram = this.applianceToInstall.qemu.ram;
qemuTemplate.adapters = this.applianceToInstall.qemu.adapters;
qemuTemplate.adapter_type = this.applianceToInstall.qemu.adapter_type;
@ -533,11 +546,58 @@ export class NewTemplateDialogComponent implements OnInit {
qemuTemplate.template_type = 'qemu';
qemuTemplate.usage = this.applianceToInstall.usage;
this.qemuService.addTemplate(this.server, qemuTemplate).subscribe((template) => {
this.templateService.newTemplateCreated.next(template as any as Template);
this.toasterService.success('Template added');
this.dialogRef.close();
});
if (this.templates.filter(t => t.name === this.applianceToInstall.name).length === 0) {
qemuTemplate.name = this.applianceToInstall.name;
this.qemuService.addTemplate(this.server, qemuTemplate).subscribe((template) => {
this.templateService.newTemplateCreated.next(template as any as Template);
this.toasterService.success('Template added');
this.dialogRef.close();
});
} else {
const dialogRef = this.dialog.open(TemplateNameDialogComponent, {
width: '400px',
height: '250px',
autoFocus: false,
disableClose: true
});
dialogRef.componentInstance.server = this.server;
dialogRef.afterClosed().subscribe((answer: string) => {
if (answer) {
qemuTemplate.name = answer;
this.qemuService.addTemplate(this.server, qemuTemplate).subscribe((template) => {
this.templateService.newTemplateCreated.next(template as any as Template);
this.toasterService.success('Template added');
this.dialogRef.close();
});
} else{
return false;
}
});
}
}
validateTemplateName() {
if (this.templates.filter(t => t.name === this.applianceToInstall.name).length === 0) {
return true;
} else {
const dialogRef = this.dialog.open(TemplateNameDialogComponent, {
width: '400px',
height: '300px',
autoFocus: false,
disableClose: true
});
dialogRef.componentInstance.server = this.server;
dialogRef.afterClosed().subscribe((answer: string) => {
if (answer) {
this.applianceToInstall.name = answer;
return true;
} else{
return false;
}
});
}
}
}

View File

@ -0,0 +1,26 @@
<h1 mat-dialog-title>Please enter name for the new template</h1>
<form [formGroup]="templateNameForm" class="file-name-form">
<mat-form-field class="file-name-form-field">
<input
matInput
(keydown)="onKeyDown($event)"
type="text"
formControlName="templateName"
[ngClass]="{ 'is-invalid': form.templateName?.errors }"
placeholder="Template name"
/>
<mat-error *ngIf="form.templateName?.touched && form.templateName?.errors && form.templateName?.errors.required"
>Template name is required</mat-error
>
<mat-error *ngIf="form.templateName?.errors && form.templateName?.errors.invalidName"
>Template name is incorrect</mat-error
>
<mat-error *ngIf="form.templateName?.errors && form.templateName?.errors.templateExist"
>Template with this name exists</mat-error
>
</mat-form-field>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()" color="accent">Cancel</button>
<button mat-button (click)="onAddClick()" tabindex="2" class="add-project-button" mat-raised-button color="primary">Add template</button>
</div>
</form>

View File

@ -0,0 +1,7 @@
.file-name-form-field {
width: 100%;
}
.project-snackbar {
background: #2196F3;
}

View File

@ -0,0 +1,70 @@
import { Component, OnInit, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { Server } from '../../../../models/server';
import { v4 as uuid } from 'uuid';
import { ProjectNameValidator } from '../../../projects/models/projectNameValidator';
import { ToasterService } from '../../../../services/toaster.service';
import { TemplateService } from '../../../../services/template.service';
import { templateNameAsyncValidator } from '../../../../validators/template-name-async-validator';
import { Template } from '../../../../models/template';
@Component({
selector: 'app-template-name-dialog',
templateUrl: './template-name-dialog.component.html',
styleUrls: ['./template-name-dialog.component.scss'],
providers: [ProjectNameValidator]
})
export class TemplateNameDialogComponent implements OnInit {
server: Server;
templateNameForm: FormGroup;
constructor(
public dialogRef: MatDialogRef<TemplateNameDialogComponent>,
private router: Router,
private dialog: MatDialog,
private toasterService: ToasterService,
private formBuilder: FormBuilder,
private templateNameValidator: ProjectNameValidator,
private templateService: TemplateService
) {}
ngOnInit() {
this.templateNameForm = this.formBuilder.group({
templateName: new FormControl(null, [Validators.required, this.templateNameValidator.get], [templateNameAsyncValidator(this.server, this.templateService)])
});
}
get form() {
return this.templateNameForm.controls;
}
onAddClick(): void {
if (this.templateNameForm.invalid) {
this.toasterService.error('Please enter correct name for new template');
return;
}
this.templateService.list(this.server).subscribe((templates: Template[]) => {
const templateName = this.templateNameForm.controls['templateName'].value;
let existingProject = templates.find(t => t.name === templateName);
if (existingProject) {
this.toasterService.error('Template with this name exists');
} else {
this.dialogRef.close(this.templateNameForm.controls['templateName'].value);
}
});
}
onNoClick(): void {
this.dialogRef.close();
}
onKeyDown(event) {
if (event.key === "Enter") {
this.onAddClick();
}
}
}

View File

@ -0,0 +1,14 @@
import { TemplateService } from '../services/template.service';
import { FormControl } from '@angular/forms';
import { timer } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Server } from '../models/server';
export const templateNameAsyncValidator = (server: Server, templateService: TemplateService) => {
return (control: FormControl) => {
return timer(500).pipe(
switchMap(() => templateService.list(server)),
map(response => (response.find(n => n.name === control.value) ? {templateExist: true} : null))
);
}
}