Merge pull request #1316 from GNS3/enhancement/1307

Add common process bar when uploading IOS and IOU images
This commit is contained in:
Jeremy Grossmann 2022-05-24 22:57:02 +07:00 committed by GitHub
commit 83fa40907e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 87 additions and 15 deletions

View File

@ -1,14 +1,14 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs'; import { BehaviorSubject, Subject } from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class UploadServiceService { export class UploadServiceService {
private countSource = new BehaviorSubject(0); private countSource = new Subject();
currentCount = this.countSource.asObservable(); currentCount = this.countSource.asObservable();
private cancelItem = new BehaviorSubject(false); private cancelItem = new Subject();
currentCancelItemDetails = this.cancelItem.asObservable(); currentCancelItemDetails = this.cancelItem.asObservable();
constructor() { } constructor() { }
@ -16,8 +16,8 @@ export class UploadServiceService {
processBarCount(processCount:number) { processBarCount(processCount:number) {
this.countSource.next(processCount) this.countSource.next(processCount)
} }
cancelFileUploading(){ cancelFileUploading(isCancel){
this.cancelItem.next(true) this.cancelItem.next(isCancel)
} }
} }

View File

@ -21,7 +21,7 @@ export class UploadingProcessbarComponent implements OnInit {
) { } ) { }
ngOnInit() { ngOnInit() {
this.subscription = this._US.currentCount.subscribe((count) => { this.subscription = this._US.currentCount.subscribe((count:number) => {
this.uploadProgress = count; this.uploadProgress = count;
if (this.uploadProgress === 100) { if (this.uploadProgress === 100) {
this.dismiss() this.dismiss()
@ -35,7 +35,7 @@ export class UploadingProcessbarComponent implements OnInit {
this._snackRef.dismiss(); this._snackRef.dismiss();
} }
cancelItem() { cancelItem() {
this._US.cancelFileUploading() this._US.cancelFileUploading(true)
} }
ngOnDestroy() { ngOnDestroy() {
this.subscription.unsubscribe(); this.subscription.unsubscribe();

View File

@ -1,7 +1,12 @@
import { Component, OnInit } from '@angular/core'; import { Location } from '@angular/common';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { UploadServiceService } from 'app/common/uploading-processbar/upload-service.service';
import { UploadingProcessbarComponent } from 'app/common/uploading-processbar/uploading-processbar.component';
import { FileItem, FileUploader, ParsedResponseHeaders } from 'ng2-file-upload'; import { FileItem, FileUploader, ParsedResponseHeaders } from 'ng2-file-upload';
import { Subscription } from 'rxjs';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { Compute } from '../../../../models/compute'; import { Compute } from '../../../../models/compute';
import { IosImage } from '../../../../models/images/ios-image'; import { IosImage } from '../../../../models/images/ios-image';
@ -19,7 +24,7 @@ import { ToasterService } from '../../../../services/toaster.service';
templateUrl: './add-ios-template.component.html', templateUrl: './add-ios-template.component.html',
styleUrls: ['./add-ios-template.component.scss', '../../preferences.component.scss'], styleUrls: ['./add-ios-template.component.scss', '../../preferences.component.scss'],
}) })
export class AddIosTemplateComponent implements OnInit { export class AddIosTemplateComponent implements OnInit, OnDestroy {
server: Server; server: Server;
iosTemplate: IosTemplate; iosTemplate: IosTemplate;
isEtherSwitchRouter: boolean = false; isEtherSwitchRouter: boolean = false;
@ -46,6 +51,8 @@ export class AddIosTemplateComponent implements OnInit {
ciscoUrl: string = 'https://cfn.cloudapps.cisco.com/ITDIT/CFN/jsp/SearchBySoftware.jsp'; ciscoUrl: string = 'https://cfn.cloudapps.cisco.com/ITDIT/CFN/jsp/SearchBySoftware.jsp';
uploader: FileUploader; uploader: FileUploader;
isLocalComputerChosen: boolean = true; isLocalComputerChosen: boolean = true;
uploadProgress:number = 0;
subscription: Subscription;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
@ -56,7 +63,9 @@ export class AddIosTemplateComponent implements OnInit {
private router: Router, private router: Router,
private templateMocksService: TemplateMocksService, private templateMocksService: TemplateMocksService,
private iosConfigurationService: IosConfigurationService, private iosConfigurationService: IosConfigurationService,
private computeService: ComputeService private computeService: ComputeService,
private uploadServiceService: UploadServiceService,
private snackBar : MatSnackBar,
) { ) {
this.iosTemplate = new IosTemplate(); this.iosTemplate = new IosTemplate();
@ -92,6 +101,16 @@ export class AddIosTemplateComponent implements OnInit {
this.getImages(); this.getImages();
this.toasterService.success('Image uploaded'); this.toasterService.success('Image uploaded');
}; };
this.uploader.onProgressItem = (progress: any) => {
this.uploadProgress = progress['progress'];
this.uploadServiceService.processBarCount(this.uploadProgress)
};
this.subscription = this.uploadServiceService.currentCancelItemDetails.subscribe((isCancel) => {
if (isCancel) {
this.cancelUploading()
}
})
const server_id = this.route.snapshot.paramMap.get('server_id'); const server_id = this.route.snapshot.paramMap.get('server_id');
this.serverService.get(parseInt(server_id, 10)).then((server: Server) => { this.serverService.get(parseInt(server_id, 10)).then((server: Server) => {
@ -137,7 +156,9 @@ export class AddIosTemplateComponent implements OnInit {
const itemToUpload = this.uploader.queue[0]; const itemToUpload = this.uploader.queue[0];
if ((itemToUpload as any).options) (itemToUpload as any).options.disableMultipart = true; ((itemToUpload as any).options.headers = [{ name: 'Authorization', value: 'Bearer ' + this.server.authToken }]) if ((itemToUpload as any).options) (itemToUpload as any).options.disableMultipart = true; ((itemToUpload as any).options.headers = [{ name: 'Authorization', value: 'Bearer ' + this.server.authToken }])
this.uploader.uploadItem(itemToUpload); this.uploader.uploadItem(itemToUpload);
this.snackBar.openFromComponent(UploadingProcessbarComponent, {
panelClass: 'uplaoding-file-snackabar',
});
} }
addTemplate() { addTemplate() {
@ -250,4 +271,16 @@ export class AddIosTemplateComponent implements OnInit {
onChassisChosen() { onChassisChosen() {
this.networkAdaptersForTemplate = []; this.networkAdaptersForTemplate = [];
} }
cancelUploading() {
this.uploader.clearQueue();
this.uploadServiceService.processBarCount(100)
this.toasterService.warning('Image upload cancelled');
// this.uploadServiceService.cancelFileUploading(false)
// window.location.reload()
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
} }

View File

@ -1,7 +1,11 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { UploadServiceService } from 'app/common/uploading-processbar/upload-service.service';
import { UploadingProcessbarComponent } from 'app/common/uploading-processbar/uploading-processbar.component';
import { FileItem, FileUploader, ParsedResponseHeaders } from 'ng2-file-upload'; import { FileItem, FileUploader, ParsedResponseHeaders } from 'ng2-file-upload';
import { Subscription } from 'rxjs';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { Compute } from '../../../../models/compute'; import { Compute } from '../../../../models/compute';
import { IouImage } from '../../../../models/iou/iou-image'; import { IouImage } from '../../../../models/iou/iou-image';
@ -18,7 +22,7 @@ import { ToasterService } from '../../../../services/toaster.service';
templateUrl: './add-iou-template.component.html', templateUrl: './add-iou-template.component.html',
styleUrls: ['./add-iou-template.component.scss', '../../preferences.component.scss'], styleUrls: ['./add-iou-template.component.scss', '../../preferences.component.scss'],
}) })
export class AddIouTemplateComponent implements OnInit { export class AddIouTemplateComponent implements OnInit, OnDestroy {
server: Server; server: Server;
iouTemplate: IouTemplate; iouTemplate: IouTemplate;
isRemoteComputerChosen: boolean = false; isRemoteComputerChosen: boolean = false;
@ -31,6 +35,8 @@ export class AddIouTemplateComponent implements OnInit {
templateNameForm: FormGroup; templateNameForm: FormGroup;
imageForm: FormGroup; imageForm: FormGroup;
isLocalComputerChosen: boolean = true; isLocalComputerChosen: boolean = true;
uploadProgress: number = 0
subscription: Subscription;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
@ -40,7 +46,9 @@ export class AddIouTemplateComponent implements OnInit {
private router: Router, private router: Router,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private templateMocksService: TemplateMocksService, private templateMocksService: TemplateMocksService,
private computeService: ComputeService private computeService: ComputeService,
private uploadServiceService: UploadServiceService,
private snackBar: MatSnackBar
) { ) {
this.iouTemplate = new IouTemplate(); this.iouTemplate = new IouTemplate();
@ -61,6 +69,11 @@ export class AddIouTemplateComponent implements OnInit {
this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => { this.uploader.onErrorItem = (item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) => {
this.toasterService.error('An error occured: ' + response); this.toasterService.error('An error occured: ' + response);
}; };
this.uploader.onProgressItem = (progress: any) => {
this.uploadProgress = progress['progress'];
this.uploadServiceService.processBarCount(this.uploadProgress)
};
this.uploader.onSuccessItem = ( this.uploader.onSuccessItem = (
item: FileItem, item: FileItem,
response: string, response: string,
@ -79,6 +92,13 @@ export class AddIouTemplateComponent implements OnInit {
this.iouTemplate = iouTemplate; this.iouTemplate = iouTemplate;
}); });
}); });
this.subscription = this.uploadServiceService.currentCancelItemDetails.subscribe((isCancel) => {
if (isCancel) {
this.cancelUploading()
}
})
} }
getImages() { getImages() {
@ -107,9 +127,20 @@ export class AddIouTemplateComponent implements OnInit {
const itemToUpload = this.uploader.queue[0]; const itemToUpload = this.uploader.queue[0];
if ((itemToUpload as any).options) (itemToUpload as any).options.disableMultipart = true; ((itemToUpload as any).options.headers = [{ name: 'Authorization', value: 'Bearer ' + this.server.authToken }]) if ((itemToUpload as any).options) (itemToUpload as any).options.disableMultipart = true; ((itemToUpload as any).options.headers = [{ name: 'Authorization', value: 'Bearer ' + this.server.authToken }])
this.uploader.uploadItem(itemToUpload); this.uploader.uploadItem(itemToUpload);
this.snackBar.openFromComponent(UploadingProcessbarComponent, {
panelClass: 'uplaoding-file-snackabar',
});
} }
cancelUploading() {
this.uploader.clearQueue();
this.uploadServiceService.processBarCount(100)
this.toasterService.warning('Image upload cancelled');
// this.uploadServiceService.cancelFileUploading(false)
// window.location.reload()
}
goBack() { goBack() {
@ -141,4 +172,8 @@ export class AddIouTemplateComponent implements OnInit {
this.toasterService.error(`Fill all required fields`); this.toasterService.error(`Fill all required fields`);
} }
} }
ngOnDestroy() {
this.subscription.unsubscribe();
}
} }

View File

@ -164,6 +164,8 @@ export class AddQemuVmTemplateComponent implements OnInit {
this.uploader.clearQueue(); this.uploader.clearQueue();
this.uploadServiceService.processBarCount(100) this.uploadServiceService.processBarCount(100)
this.toasterService.warning('Image Uploading canceled'); this.toasterService.warning('Image Uploading canceled');
this.uploadServiceService.cancelFileUploading(false)
} }
goBack() { goBack() {

View File

@ -429,7 +429,9 @@ export class NewTemplateDialogComponent implements OnInit {
cancelUploading() { cancelUploading() {
this.uploaderImage.clearQueue(); this.uploaderImage.clearQueue();
this.uploadServiceService.processBarCount(100) this.uploadServiceService.processBarCount(100)
this.toasterService.warning('Image imported canceled'); this.toasterService.warning('Image upload cancelled');
this.uploadServiceService.cancelFileUploading(false)
} }
checkImageFromVersion(image: string): boolean { checkImageFromVersion(image: string): boolean {