mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-05-05 18:18:29 +00:00
I added install appliances confirmation dialog, Unit test cases for upload and delete file and suggested changes.
This commit is contained in:
parent
147cae1313
commit
c86769dd4f
@ -274,7 +274,7 @@ import { UserService } from './services/user.service';
|
|||||||
import { LoggedUserComponent } from './components/users/logged-user/logged-user.component';
|
import { LoggedUserComponent } from './components/users/logged-user/logged-user.component';
|
||||||
import { ImageManagerComponent } from './components/image-manager/image-manager.component';
|
import { ImageManagerComponent } from './components/image-manager/image-manager.component';
|
||||||
import { AddImageDialogComponent } from './components/image-manager/add-image-dialog/add-image-dialog.component';
|
import { AddImageDialogComponent } from './components/image-manager/add-image-dialog/add-image-dialog.component';
|
||||||
import { DeleteallfilesDialogComponent } from './components/image-manager/deleteallfiles-dialog/deleteallfiles-dialog.component';
|
import { DeleteAllImageFilesDialogComponent } from './components/image-manager/deleteallfiles-dialog/deleteallfiles-dialog.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -465,7 +465,7 @@ import { DeleteallfilesDialogComponent } from './components/image-manager/delete
|
|||||||
ProjectReadmeComponent,
|
ProjectReadmeComponent,
|
||||||
ImageManagerComponent,
|
ImageManagerComponent,
|
||||||
AddImageDialogComponent,
|
AddImageDialogComponent,
|
||||||
DeleteallfilesDialogComponent,
|
DeleteAllImageFilesDialogComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -1,27 +1,70 @@
|
|||||||
<div class="row" style="display: flex;">
|
<div *ngIf="!isInstallAppliance">
|
||||||
<div class="col-md-6">
|
<div class="row">
|
||||||
<mat-label>Please Select Image</mat-label>
|
<div class="col-md-10">
|
||||||
|
<h5>Would you like to automatically install appliances for this image?</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 txt-align">
|
<div class="col-md-2 txt-align">
|
||||||
<input type="file" accept=".qcow2, .bin,.image,.qcow2,.vmdk,.img" multiple #file class="non-visible"
|
<button mat-button (click)="dialogRef.close()">
|
||||||
(change)="uploadImageFile($event)" />
|
<mat-icon>close</mat-icon>
|
||||||
<button mat-raised-button color="primary" (click)="file.click()" class="file-button">Browse</button>
|
</button>
|
||||||
</div>
|
|
||||||
<div class="col-md-2 txt-align">
|
|
||||||
<button mat-button (click)="dialogRef.close()">
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row" *ngFor="let img of selectFile; let i = index">
|
|
||||||
<mat-title> {{i+1}}. {{img?.name}} </mat-title>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<div *ngIf="uploadedFile">
|
|
||||||
<mat-progress-bar mode="indeterminate" [value]="uploadProgress" aria-valuemin="0" aria-valuemax="100">
|
|
||||||
</mat-progress-bar>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<mat-radio-group name="install_appliances" class="choose-instal-appliance" [value]="install_appliance" (change)="selectInstallApplianceOption($event)">
|
||||||
|
<mat-radio-button value="true" class="instal-appliances-button" [checked]="install_appliance">
|
||||||
|
Yes
|
||||||
|
</mat-radio-button>
|
||||||
|
<mat-radio-button value="false" class="instal-appliances-button" [checked]="!install_appliance">
|
||||||
|
No
|
||||||
|
</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button color="primary" (click)="isInstallAppliance =!isInstallAppliance">Next</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div *ngIf="!isExistImage && isInstallAppliance">
|
||||||
|
<div class="row" style="display: flex;">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h5>Please Select image</h5>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 txt-align">
|
||||||
|
<input type="file" accept=".qcow2, .bin,.image,.qcow2,.vmdk,.img,.tmp" multiple #file class="non-visible"
|
||||||
|
(change)="uploadImageFile($event)" />
|
||||||
|
<button mat-raised-button color="primary" (click)="file.click()" class="file-button">Browse</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 txt-align">
|
||||||
|
<button mat-button (click)="dialogRef.close()">
|
||||||
|
<mat-icon>close</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" *ngFor="let img of selectFile; let i = index">
|
||||||
|
<mat-title> {{i+1}}. {{img?.name}} </mat-title>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div *ngIf="uploadedFile">
|
||||||
|
<mat-progress-bar mode="indeterminate" [value]="uploadProgress" aria-valuemin="0" aria-valuemax="100">
|
||||||
|
</mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="isExistImage">
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<div *ngIf="uploadFileMessage.length > 0">
|
||||||
|
<p class="uploaded-text">Uploaded image details</p>
|
||||||
|
<p *ngFor="let uploadFile of uploadFileMessage; let i = index" [ngClass]="{'uploaded-error-text': uploadFile?.error?.message}">{{i+1}}. {{uploadFile?.filename ?? uploadFile?.error?.message}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button color="primary" (click)="dialogRef.close(false)">Close</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -21,7 +21,7 @@
|
|||||||
top: 0px;
|
top: 0px;
|
||||||
}
|
}
|
||||||
.mat-toolbar-single-row {
|
.mat-toolbar-single-row {
|
||||||
height: auto !important;
|
height: auto;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
@ -59,7 +59,25 @@
|
|||||||
}
|
}
|
||||||
.txt-align{
|
.txt-align{
|
||||||
text-align: end;
|
text-align: end;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
.uploaded-text{
|
||||||
|
color: #0ca8c7;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
.uploaded-error-text{
|
||||||
|
color: #d52435;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choose-instal-appliance {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin: 15px 0px 11px 0px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instal-appliances-button {
|
||||||
|
margin: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,14 +1,53 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
|
import { MatDialog, MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
|
import { ImageManagerService } from 'app/services/image-manager.service';
|
||||||
|
import { ServerService } from '../../../services/server.service';
|
||||||
|
import { MockedServerService } from '../../../services/server.service.spec';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { Server } from '../../../models/server';
|
||||||
|
|
||||||
import { AddImageDialogComponent } from './add-image-dialog.component';
|
import { AddImageDialogComponent } from './add-image-dialog.component';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { ToasterService } from 'app/services/toaster.service';
|
||||||
|
import { MockedToasterService } from 'app/services/toaster.service.spec';
|
||||||
|
|
||||||
|
export class MockedImageManagerService {
|
||||||
|
public getImages(server: Server) {
|
||||||
|
return of();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
describe('AddImageDialogComponent', () => {
|
describe('AddImageDialogComponent', () => {
|
||||||
let component: AddImageDialogComponent;
|
let component: AddImageDialogComponent;
|
||||||
let fixture: ComponentFixture<AddImageDialogComponent>;
|
let fixture: ComponentFixture<AddImageDialogComponent>;
|
||||||
|
|
||||||
|
let mockedServerService = new MockedServerService();
|
||||||
|
let mockedImageManagerService = new MockedImageManagerService()
|
||||||
|
let mockedToasterService = new MockedToasterService()
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ AddImageDialogComponent ]
|
imports:[
|
||||||
|
MatIconModule,
|
||||||
|
MatToolbarModule,
|
||||||
|
MatMenuModule,
|
||||||
|
MatCheckboxModule,
|
||||||
|
MatDialogModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: ServerService, useValue: mockedServerService },
|
||||||
|
{ provide: ImageManagerService, useValue: mockedImageManagerService },
|
||||||
|
{ provide: MAT_DIALOG_DATA, useValue: {} },
|
||||||
|
{ provide: MatDialogRef, useValue: {} },
|
||||||
|
{ provide: ToasterService, useValue: mockedToasterService },
|
||||||
|
],
|
||||||
|
declarations: [ AddImageDialogComponent ],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,9 @@ import { animate, state, style, transition, trigger } from '@angular/animations'
|
|||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
import { Server } from '../../../models/server';
|
import { Server } from '../../../models/server';
|
||||||
import { ImageManagerService } from '../../../services/image-manager.service';
|
import { ImageManagerService } from '../../../services/image-manager.service';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
import { ImageData } from '../../../models/images';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-add-image-dialog',
|
selector: 'app-add-image-dialog',
|
||||||
@ -21,10 +23,11 @@ import { Observable } from 'rxjs';
|
|||||||
export class AddImageDialogComponent implements OnInit {
|
export class AddImageDialogComponent implements OnInit {
|
||||||
server: Server;
|
server: Server;
|
||||||
uploadedFile: boolean = false;
|
uploadedFile: boolean = false;
|
||||||
uploadProgress: number = 0;
|
isExistImage: boolean = false;
|
||||||
|
isInstallAppliance: boolean = false
|
||||||
|
install_appliance: boolean = false
|
||||||
selectFile: any = [];
|
selectFile: any = [];
|
||||||
|
uploadFileMessage: ImageData = []
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
@ -37,34 +40,28 @@ export class AddImageDialogComponent implements OnInit {
|
|||||||
this.server = this.data
|
this.server = this.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectInstallApplianceOption(ev) {
|
||||||
|
this.install_appliance = ev.value
|
||||||
|
}
|
||||||
|
|
||||||
async uploadImageFile(event) {
|
async uploadImageFile(event) {
|
||||||
for (let imgFile of event.target.files) {
|
for (let imgFile of event.target.files) {
|
||||||
this.selectFile.push(imgFile)
|
this.selectFile.push(imgFile)
|
||||||
}
|
}
|
||||||
|
await this.upload()
|
||||||
await this.upload().subscribe((_) => {
|
|
||||||
console.log(_)
|
|
||||||
this.dialogRef.close('file uploaded');
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// files uploading
|
// files uploading
|
||||||
upload() {
|
upload() {
|
||||||
return new Observable<any>(observe => {
|
const calls = [];
|
||||||
this.selectFile.forEach((img, i) => {
|
this.uploadedFile = true;
|
||||||
let resCount = 1
|
this.selectFile.forEach(imgElement => {
|
||||||
try {
|
calls.push(this.imageService.uploadedImage(this.server, this.install_appliance, imgElement.name, imgElement).pipe(catchError(error => of(error))))
|
||||||
resCount = resCount + i
|
});
|
||||||
this.uploadedFile = true;
|
Observable.forkJoin(calls).subscribe(responses => {
|
||||||
this.imageService.uploadedImage(this.server, img.name, img)
|
this.uploadFileMessage = responses
|
||||||
.subscribe(() => {
|
this.uploadedFile = false;
|
||||||
this.selectFile.length == resCount ? observe.next() : ''
|
this.isExistImage = true;
|
||||||
}, (error) => {
|
});
|
||||||
observe.error(error)
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div *ngIf="!isDelete">
|
<div *ngIf="!isDelete && !isUsedFiles">
|
||||||
<h1 mat-dialog-title>Do you want delete all files ?.</h1>
|
<h1 mat-dialog-title>Do you want delete all files ?.</h1>
|
||||||
<div mat-dialog-content >
|
<div mat-dialog-content>
|
||||||
<p>Your selected files</p>
|
<p>Your selected files</p>
|
||||||
<p *ngFor="let file of deleteData?.deleteFilesPaths; let i = index">{{i+1}}. {{file?.filename}}</p>
|
<p *ngFor="let file of deleteData?.deleteFilesPaths; let i = index">{{i+1}}. {{file?.filename}}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -9,11 +9,26 @@
|
|||||||
<button mat-button mat-dialog-close cdkFocusInitial>Cancel</button>
|
<button mat-button mat-dialog-close cdkFocusInitial>Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="isDelete">
|
<div *ngIf="isDelete && !isUsedFiles">
|
||||||
<h1 align="center" mat-dialog-title>Please wait.</h1>
|
<h1 align="center" mat-dialog-title>Please wait.</h1>
|
||||||
|
|
||||||
<div mat-dialog-content align="center">
|
<div mat-dialog-content align="center">
|
||||||
<mat-spinner color="accent"></mat-spinner>
|
<mat-spinner color="accent"></mat-spinner>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="isDelete && isUsedFiles">
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<div *ngIf="deleteFliesDetails.length > 0">
|
||||||
|
<h5>Images can't be deleted because image used in one or more template.</h5>
|
||||||
|
<p *ngFor="let message of deleteFliesDetails; let i = index" [ngClass]="{'deleted-error-text': message?.error?.message}"><span *ngIf="message !=null">{{i+1}}. {{message?.error?.message}}</span></p>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="fileNotDeleted.length > 0">
|
||||||
|
<h5 class="delete-text">{{fileNotDeleted.length}} Images deleted successfully.</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button color="primary" (click)="dialogRef.close(false)">Close</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -0,0 +1,11 @@
|
|||||||
|
.delete-text{
|
||||||
|
color: #0ca8c7;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleted-error-text{
|
||||||
|
color: #d52435;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,20 +1,60 @@
|
|||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
|
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
|
import { ToasterService } from 'app/services/toaster.service';
|
||||||
|
import { MockedToasterService } from 'app/services/toaster.service.spec';
|
||||||
|
import { Server } from 'http';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { ImageManagerService } from '../../../services/image-manager.service';
|
||||||
|
import { ServerService } from '../../../services/server.service';
|
||||||
|
import { MockedServerService } from '../../../services/server.service.spec';
|
||||||
|
import { ImageManagerComponent } from '../image-manager.component';
|
||||||
|
|
||||||
import { DeleteallfilesDialogComponent } from './deleteallfiles-dialog.component';
|
import { DeleteAllImageFilesDialogComponent } from './deleteallfiles-dialog.component';
|
||||||
|
|
||||||
describe('DeleteallfilesDialogComponent', () => {
|
export class MockedImageManagerService {
|
||||||
let component: DeleteallfilesDialogComponent;
|
public deleteALLFile(server: Server, image_path) {
|
||||||
let fixture: ComponentFixture<DeleteallfilesDialogComponent>;
|
return of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('DeleteAllImageFilesDialogComponent', () => {
|
||||||
|
let component: DeleteAllImageFilesDialogComponent;
|
||||||
|
let fixture: ComponentFixture<DeleteAllImageFilesDialogComponent>;
|
||||||
|
let mockedServerService = new MockedServerService();
|
||||||
|
let mockedImageManagerService = new MockedImageManagerService()
|
||||||
|
let mockedToasterService = new MockedToasterService()
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ DeleteallfilesDialogComponent ]
|
imports: [
|
||||||
|
MatIconModule,
|
||||||
|
MatToolbarModule,
|
||||||
|
MatMenuModule,
|
||||||
|
MatCheckboxModule,
|
||||||
|
MatDialogModule,
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: ServerService, useValue: mockedServerService },
|
||||||
|
{ provide: ImageManagerService, useValue: mockedImageManagerService },
|
||||||
|
{ provide: MAT_DIALOG_DATA, useValue: {} },
|
||||||
|
{ provide: MatDialogRef, useValue: {} },
|
||||||
|
{ provide: ToasterService, useValue: mockedToasterService },
|
||||||
|
|
||||||
|
],
|
||||||
|
declarations: [DeleteAllImageFilesDialogComponent,
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(DeleteallfilesDialogComponent);
|
fixture = TestBed.createComponent(DeleteAllImageFilesDialogComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
@ -1,19 +1,25 @@
|
|||||||
import { Component, Inject, OnInit } from '@angular/core';
|
import { Component, Inject, OnInit } from '@angular/core';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
import { ImageManagerService } from '@services/image-manager.service';
|
import { ImageManagerService } from '../../../services/image-manager.service';
|
||||||
import { ToasterService } from '@services/toaster.service';
|
import { ToasterService } from '../../../services/toaster.service';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
import { ImageData } from '../../../models/images';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-deleteallfiles-dialog',
|
selector: 'app-deleteallfiles-dialog',
|
||||||
templateUrl: './deleteallfiles-dialog.component.html',
|
templateUrl: './deleteallfiles-dialog.component.html',
|
||||||
styleUrls: ['./deleteallfiles-dialog.component.scss']
|
styleUrls: ['./deleteallfiles-dialog.component.scss']
|
||||||
})
|
})
|
||||||
export class DeleteallfilesDialogComponent implements OnInit {
|
export class DeleteAllImageFilesDialogComponent implements OnInit {
|
||||||
isDelete: boolean = false;
|
isDelete: boolean = false;
|
||||||
|
isUsedFiles: boolean = false;
|
||||||
|
deleteFliesDetails: ImageData = []
|
||||||
|
fileNotDeleted: ImageData = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(MAT_DIALOG_DATA) public deleteData: any,
|
@Inject(MAT_DIALOG_DATA) public deleteData: any,
|
||||||
public dialogRef: MatDialogRef<DeleteallfilesDialogComponent>,
|
public dialogRef: MatDialogRef<DeleteAllImageFilesDialogComponent>,
|
||||||
private imageService: ImageManagerService,
|
private imageService: ImageManagerService,
|
||||||
private toasterService: ToasterService
|
private toasterService: ToasterService
|
||||||
) { }
|
) { }
|
||||||
@ -23,30 +29,21 @@ export class DeleteallfilesDialogComponent implements OnInit {
|
|||||||
|
|
||||||
async deleteAll() {
|
async deleteAll() {
|
||||||
this.isDelete = true
|
this.isDelete = true
|
||||||
await this.delete().subscribe((_) => {
|
await this.deleteFile()
|
||||||
this.dialogRef.close(true);
|
|
||||||
this.isDelete = false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
delete() {
|
|
||||||
return new Observable<any>(observe => {
|
deleteFile() {
|
||||||
this.deleteData.deleteFilesPaths.forEach((_, i) => {
|
const calls = [];
|
||||||
let imgDeleteCount = 1
|
this.deleteData.deleteFilesPaths.forEach(pathElement => {
|
||||||
try {
|
calls.push(this.imageService.deleteFile(this.deleteData.server, pathElement.filename).pipe(catchError(error => of(error))))
|
||||||
imgDeleteCount = imgDeleteCount + i
|
});
|
||||||
this.imageService.deleteImage(this.deleteData.server, _.filename).subscribe(
|
Observable.forkJoin(calls).subscribe(responses => {
|
||||||
() => {
|
this.deleteFliesDetails = responses.filter(x => x !== null)
|
||||||
this.deleteData.deleteFilesPaths.length === imgDeleteCount ? observe.next() : ''
|
this.fileNotDeleted = responses.filter(x => x === null)
|
||||||
},
|
this.isUsedFiles = true;
|
||||||
(error) => {
|
this.isDelete = true
|
||||||
this.toasterService.error(error)
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
this.toasterService.error(error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
36
src/app/components/image-manager/image-database-file.ts
Normal file
36
src/app/components/image-manager/image-database-file.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import { DataSource, SelectionModel } from '@angular/cdk/collections';
|
||||||
|
import { MatSort } from '@angular/material/sort';
|
||||||
|
import { BehaviorSubject, Observable, Subscription, merge } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { Image } from '../../models/images';
|
||||||
|
|
||||||
|
|
||||||
|
export class imageDatabase {
|
||||||
|
dataChange: BehaviorSubject<Image[]> = new BehaviorSubject<Image[]>([]);
|
||||||
|
get data(): Image[] {
|
||||||
|
return this.dataChange.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addImages(fileData: Image[]) {
|
||||||
|
this.dataChange.next(fileData);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class imageDataSource extends DataSource<Image> {
|
||||||
|
constructor(private serverDatabase: imageDatabase) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(): Observable<Image[]> {
|
||||||
|
return merge(this.serverDatabase.dataChange).pipe(
|
||||||
|
map(() => {
|
||||||
|
return this.serverDatabase.data;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect() { }
|
||||||
|
}
|
@ -21,7 +21,7 @@
|
|||||||
<mat-table #table [dataSource]="dataSource">
|
<mat-table #table [dataSource]="dataSource">
|
||||||
<ng-container matColumnDef="select">
|
<ng-container matColumnDef="select">
|
||||||
<mat-header-cell *matHeaderCellDef>
|
<mat-header-cell *matHeaderCellDef>
|
||||||
<mat-checkbox (change)="$event ? masterToggle() : null" [checked]="selection.hasValue() && isAllSelected()"
|
<mat-checkbox (change)="$event ? selectAllImages() : null" [checked]="selection.hasValue() && isAllSelected()"
|
||||||
[indeterminate]="selection.hasValue() && !isAllSelected()">
|
[indeterminate]="selection.hasValue() && !isAllSelected()">
|
||||||
</mat-checkbox>
|
</mat-checkbox>
|
||||||
</mat-header-cell>
|
</mat-header-cell>
|
||||||
@ -49,14 +49,15 @@
|
|||||||
<mat-header-cell *matHeaderCellDef> Image Size </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef> Image Size </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row"> {{ (row.image_size/1000000).toFixed()}} MB </mat-cell>
|
<mat-cell *matCellDef="let row"> {{ (row.image_size/1000000).toFixed()}} MB </mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="delete" >
|
<ng-container matColumnDef="delete" >
|
||||||
<mat-header-cell *matHeaderCellDef>
|
<mat-header-cell *matHeaderCellDef>
|
||||||
<button mat-fab color="primary" *ngIf="selection.hasValue() && isAllSelected()" class="fb-btn" (click)="deleteAllFiles()" aria-label="Example icon button with a delete icon">
|
<button mat-button *ngIf="selection.hasValue() && isAllSelected()" (click)="deleteAllFiles()" aria-label="Example icon button with a delete icon">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-header-cell>
|
</mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row" >
|
<mat-cell *matCellDef="let row" >
|
||||||
<button mat-fab color="primary" *ngIf="selection.isSelected(row)" class="fb-btn" (click)="deleteFile(row.path)" aria-label="Example icon button with a delete icon">
|
<button mat-button *ngIf="selection.isSelected(row)" (click)="deleteFile(row.path)" aria-label="Example icon button with a delete icon">
|
||||||
<mat-icon>delete</mat-icon>
|
<mat-icon>delete</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
|
@ -10,11 +10,6 @@
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fb-btn{
|
|
||||||
background-color: #263238 !important;
|
|
||||||
box-shadow: none !important;
|
|
||||||
height: 45px;
|
|
||||||
}
|
|
||||||
mat-header-cell, mat-cell {
|
mat-header-cell, mat-cell {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,74 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||||
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
|
import { ImageManagerService } from 'app/services/image-manager.service';
|
||||||
|
import { ServerService } from 'app/services/server.service';
|
||||||
|
import { MockedServerService } from 'app/services/server.service.spec';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { Server } from '../../models/server';
|
||||||
|
|
||||||
import { ImageManagerComponent } from './image-manager.component';
|
import { ImageManagerComponent } from './image-manager.component';
|
||||||
|
import { Image } from '../../models/images';
|
||||||
|
import { ProgressService } from 'app/common/progress/progress.service';
|
||||||
|
import { MockedProgressService } from '../project-map/project-map.component.spec';
|
||||||
|
import { MockedActivatedRoute } from '../preferences/preferences.component.spec';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { MockedVersionService } from '../../services/version.service.spec';
|
||||||
|
import { VersionService } from 'app/services/version.service';
|
||||||
|
import { ToasterService } from 'app/services/toaster.service';
|
||||||
|
import { MockedToasterService } from 'app/services/toaster.service.spec';
|
||||||
|
|
||||||
|
export class MockedImageManagerService {
|
||||||
|
public getImages(server: Server) {
|
||||||
|
return of();
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteFile(server: Server, image_path) {
|
||||||
|
return of();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
describe('ImageManagerComponent', () => {
|
describe('ImageManagerComponent', () => {
|
||||||
let component: ImageManagerComponent;
|
let component: ImageManagerComponent;
|
||||||
let fixture: ComponentFixture<ImageManagerComponent>;
|
let fixture: ComponentFixture<ImageManagerComponent>;
|
||||||
|
|
||||||
|
let mockedServerService = new MockedServerService();
|
||||||
|
let mockedImageManagerService = new MockedImageManagerService()
|
||||||
|
let mockedProgressService = new MockedProgressService()
|
||||||
|
let mockedVersionService = new MockedVersionService()
|
||||||
|
let mockedToasterService = new MockedToasterService()
|
||||||
|
let activatedRoute = new MockedActivatedRoute().get();
|
||||||
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
declarations: [ ImageManagerComponent ]
|
imports: [
|
||||||
|
MatIconModule,
|
||||||
|
MatToolbarModule,
|
||||||
|
MatMenuModule,
|
||||||
|
MatCheckboxModule,
|
||||||
|
MatDialogModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: ActivatedRoute,
|
||||||
|
useValue: activatedRoute,
|
||||||
|
},
|
||||||
|
{ provide: ServerService, useValue: mockedServerService },
|
||||||
|
{ provide: ImageManagerService, useValue: mockedImageManagerService },
|
||||||
|
{ provide: ProgressService, useValue: mockedProgressService },
|
||||||
|
{ provide: VersionService, useValue: mockedVersionService },
|
||||||
|
{ provide: ToasterService, useValue: mockedToasterService },
|
||||||
|
],
|
||||||
|
declarations: [ImageManagerComponent],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA],
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -22,4 +80,17 @@ describe('ImageManagerComponent', () => {
|
|||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should call save images', () => {
|
||||||
|
spyOn(mockedImageManagerService, 'getImages').and.returnValue(of({} as Image));
|
||||||
|
component.getImages()
|
||||||
|
expect(mockedImageManagerService.getImages).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete image', () => {
|
||||||
|
spyOn(mockedImageManagerService, 'deleteFile').and.returnValue(of({} as Image));
|
||||||
|
component.deleteFile('image_path')
|
||||||
|
expect(mockedImageManagerService.deleteFile).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ServerService } from '../../services/server.service';
|
import { ServerService } from '../../services/server.service';
|
||||||
import { VersionService } from '../../services/version.service';
|
import { VersionService } from '../../services/version.service';
|
||||||
import { ProgressService } from 'app/common/progress/progress.service';
|
import { ProgressService } from 'app/common/progress/progress.service';
|
||||||
import { Images } from '../../models/images';
|
import { Image } from '../../models/images';
|
||||||
import { Server } from '../../models/server';
|
import { Server } from '../../models/server';
|
||||||
import { ImageManagerService } from "../../services/image-manager.service";
|
import { ImageManagerService } from "../../services/image-manager.service";
|
||||||
import { Version } from '../../models/version';
|
|
||||||
import { DataSource, SelectionModel } from '@angular/cdk/collections';
|
import { DataSource, SelectionModel } from '@angular/cdk/collections';
|
||||||
import { MatSort } from '@angular/material/sort';
|
|
||||||
import { BehaviorSubject, Observable, Subscription, merge } from 'rxjs';
|
|
||||||
import { map } from 'rxjs/operators';
|
|
||||||
import { AddImageDialogComponent } from './add-image-dialog/add-image-dialog.component';
|
import { AddImageDialogComponent } from './add-image-dialog/add-image-dialog.component';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ToasterService } from '../../services/toaster.service';
|
import { ToasterService } from '../../services/toaster.service';
|
||||||
import { NotificationService } from '@services/notification.service';
|
import { DeleteAllImageFilesDialogComponent } from './deleteallfiles-dialog/deleteallfiles-dialog.component';
|
||||||
import { DeleteallfilesDialogComponent } from './deleteallfiles-dialog/deleteallfiles-dialog.component';
|
import { imageDataSource, imageDatabase } from "./image-database-file";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-image-manager',
|
selector: 'app-image-manager',
|
||||||
@ -30,7 +26,7 @@ export class ImageManagerComponent implements OnInit {
|
|||||||
isAllDelete: boolean = false
|
isAllDelete: boolean = false
|
||||||
selection = new SelectionModel(true, []);
|
selection = new SelectionModel(true, []);
|
||||||
|
|
||||||
displayedColumns = ['select', 'filename', 'image_type', 'image_size', 'delete'];
|
displayedColumns = ['select', 'filename', 'image_type', 'image_size','delete'];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private imageService: ImageManagerService,
|
private imageService: ImageManagerService,
|
||||||
@ -50,33 +46,36 @@ export class ImageManagerComponent implements OnInit {
|
|||||||
if (server.authToken) {
|
if (server.authToken) {
|
||||||
this.getImages()
|
this.getImages()
|
||||||
}
|
}
|
||||||
this.versionService.get(this.server).subscribe((version: Version) => {
|
// this.versionService.get(this.server).subscribe((version: Version) => {
|
||||||
this.version = version.version;
|
// this.version = version.version;
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
this.dataSource = new imageDataSource(this.imageDatabase);
|
this.dataSource = new imageDataSource(this.imageDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
getImages() {
|
getImages() {
|
||||||
this.imageService.getSavedImgList(this.server).subscribe(
|
this.imageService.getImages(this.server).subscribe(
|
||||||
(images: Images[]) => {
|
(images: Image[]) => {
|
||||||
this.imageDatabase.addImages(images)
|
this.imageDatabase.addImages(images)
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
this.progressService.setError(error);
|
this.toasterService.error(error.error.message)
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteFile(path) {
|
deleteFile(path) {
|
||||||
this.imageService.deleteImage(this.server, path).subscribe(
|
this.imageService.deleteFile(this.server, path).subscribe(
|
||||||
(res) => {
|
(res) => {
|
||||||
this.getImages()
|
this.getImages()
|
||||||
this.unChecked()
|
this.unChecked()
|
||||||
this.toasterService.success('File deleted');
|
this.toasterService.success('File deleted');
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
this.toasterService.error(error)
|
this.getImages()
|
||||||
|
this.unChecked()
|
||||||
|
this.toasterService.error(error.error.message)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -87,7 +86,7 @@ export class ImageManagerComponent implements OnInit {
|
|||||||
return numSelected === numRows;
|
return numSelected === numRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
masterToggle() {
|
selectAllImages() {
|
||||||
this.isAllSelected() ? this.unChecked() : this.allChecked()
|
this.isAllSelected() ? this.unChecked() : this.allChecked()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,30 +101,30 @@ export class ImageManagerComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addImageDialog() {
|
public addImageDialog() {
|
||||||
console.log(this.server)
|
|
||||||
const dialogRef = this.dialog.open(AddImageDialogComponent, {
|
const dialogRef = this.dialog.open(AddImageDialogComponent, {
|
||||||
width: '750px',
|
width: '600px',
|
||||||
maxHeight: '550px',
|
maxHeight: '550px',
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
disableClose: true,
|
disableClose: true,
|
||||||
data: this.server
|
data: this.server
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((answer: string) => {
|
dialogRef.afterClosed().subscribe((isAddes: boolean) => {
|
||||||
if (answer) {
|
if (isAddes) {
|
||||||
this.getImages()
|
this.getImages()
|
||||||
this.toasterService.success('File added');
|
this.unChecked()
|
||||||
} else {
|
} else {
|
||||||
|
this.getImages()
|
||||||
|
this.unChecked()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAllFiles() {
|
deleteAllFiles() {
|
||||||
console.log(this.server)
|
const dialogRef = this.dialog.open(DeleteAllImageFilesDialogComponent, {
|
||||||
const dialogRef = this.dialog.open(DeleteallfilesDialogComponent, {
|
width: '500px',
|
||||||
width: '400px',
|
maxHeight: '650px',
|
||||||
maxHeight: '350px',
|
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
disableClose: true,
|
disableClose: true,
|
||||||
data: {
|
data: {
|
||||||
@ -140,38 +139,11 @@ export class ImageManagerComponent implements OnInit {
|
|||||||
this.getImages()
|
this.getImages()
|
||||||
this.toasterService.success('All files deleted');
|
this.toasterService.success('All files deleted');
|
||||||
} else {
|
} else {
|
||||||
|
this.unChecked()
|
||||||
|
this.getImages()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class imageDatabase {
|
|
||||||
dataChange: BehaviorSubject<Images[]> = new BehaviorSubject<Images[]>([]);
|
|
||||||
get data(): Images[] {
|
|
||||||
return this.dataChange.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public addImages(fliesData: Images[]) {
|
|
||||||
this.dataChange.next(fliesData);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export class imageDataSource extends DataSource<Images> {
|
|
||||||
constructor(private serverDatabase: imageDatabase) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(): Observable<Images[]> {
|
|
||||||
return merge(this.serverDatabase.dataChange).pipe(
|
|
||||||
map(() => {
|
|
||||||
return this.serverDatabase.data;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnect() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class Images {
|
export class Image {
|
||||||
filename: string;
|
filename: string;
|
||||||
path: string;
|
path: string;
|
||||||
image_type: string;
|
image_type: string;
|
||||||
@ -7,4 +7,8 @@ export class Images {
|
|||||||
checksum_algorithm: string;
|
checksum_algorithm: string;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ImageData {
|
||||||
|
|
||||||
}
|
}
|
@ -1,16 +1,60 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||||
|
import { inject, TestBed } from '@angular/core/testing';
|
||||||
|
import { AppTestingModule } from 'app/testing/app-testing/app-testing.module';
|
||||||
|
import { Server } from '../models/server';
|
||||||
|
import { HttpServer } from './http-server.service';
|
||||||
|
import { getTestServer } from './testing';
|
||||||
|
|
||||||
import { ImageManagerService } from './image-manager.service';
|
import { ImageManagerService } from './image-manager.service';
|
||||||
|
import { Image } from "../models/images";
|
||||||
|
|
||||||
describe('ImageManagerService', () => {
|
describe('ImageManagerService', () => {
|
||||||
let service: ImageManagerService;
|
let httpClient: HttpClient;
|
||||||
|
let httpTestingController: HttpTestingController;
|
||||||
|
let httpServer: HttpServer;
|
||||||
|
let server: Server;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({});
|
TestBed.configureTestingModule({
|
||||||
service = TestBed.inject(ImageManagerService);
|
imports: [HttpClientTestingModule, AppTestingModule],
|
||||||
|
providers: [HttpServer, ImageManagerService],
|
||||||
|
});
|
||||||
|
|
||||||
|
httpClient = TestBed.get(HttpClient);
|
||||||
|
httpTestingController = TestBed.get(HttpTestingController);
|
||||||
|
httpServer = TestBed.get(HttpServer);
|
||||||
|
server = getTestServer();
|
||||||
|
// service = TestBed.inject(ImageManagerService);
|
||||||
|
});
|
||||||
|
afterEach(() => {
|
||||||
|
httpTestingController.verify();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
|
it('should be get Images', inject([ImageManagerService], (service: ImageManagerService) => {
|
||||||
|
service.getImages(server).subscribe();
|
||||||
|
const req = httpTestingController.expectOne('http://127.0.0.1:3080/v3/images');
|
||||||
|
expect(req.request.method).toEqual('GET');
|
||||||
expect(service).toBeTruthy();
|
expect(service).toBeTruthy();
|
||||||
});
|
}));
|
||||||
|
|
||||||
|
it('should add image', inject([ImageManagerService], (service: ImageManagerService) => {
|
||||||
|
let install_appliance = true
|
||||||
|
const image: Image = {
|
||||||
|
filename: '',
|
||||||
|
path: '',
|
||||||
|
image_type: '',
|
||||||
|
image_size: 0,
|
||||||
|
checksum: '',
|
||||||
|
checksum_algorithm: '',
|
||||||
|
created_at: '',
|
||||||
|
updated_at: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
service.uploadedImage(server, install_appliance, image.filename, image).subscribe();
|
||||||
|
const req = httpTestingController.expectOne('http://127.0.0.1:3080/v3/images/upload/?install_appliances=true');
|
||||||
|
expect(req.request.method).toEqual('POST');
|
||||||
|
expect(req.request.body).toEqual(image);
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Server } from '../models/server';
|
import { Server } from '../models/server';
|
||||||
import { HttpServer } from './http-server.service';
|
import { HttpServer } from './http-server.service';
|
||||||
import { merge, Observable, Subscription } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { Images } from "../models/images";
|
import { Image } from "../models/images";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -11,13 +11,14 @@ export class ImageManagerService {
|
|||||||
|
|
||||||
constructor(private httpServer: HttpServer) { }
|
constructor(private httpServer: HttpServer) { }
|
||||||
|
|
||||||
getSavedImgList(server: Server) {
|
getImages(server: Server) {
|
||||||
return this.httpServer.get<Images[]>(server, '/images') as Observable<Images[]>;
|
return this.httpServer.get<Image[]>(server, '/images') as Observable<Image[]>;
|
||||||
}
|
}
|
||||||
uploadedImage(server:Server, image_path, flie){
|
|
||||||
return this.httpServer.post<Images[]>(server, `/images/upload/${image_path}?install_appliances=true`,flie) as Observable<Images[]>;
|
uploadedImage(server:Server, install_appliance, image_path, flie){
|
||||||
|
return this.httpServer.post<Image[]>(server, `/images/upload/${image_path}?install_appliances=${install_appliance}`,flie) as Observable<Image[]>;
|
||||||
}
|
}
|
||||||
deleteImage(server:Server, image_path){
|
deleteFile(server:Server, image_path){
|
||||||
return this.httpServer.delete<Images[]>(server, `/images/${image_path}`) as Observable<Images[]>;
|
return this.httpServer.delete<Image[]>(server, `/images/${image_path}`) as Observable<Image[]>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user