From f106ca51da9eb2066ce12502eb27419de64bf733 Mon Sep 17 00:00:00 2001 From: Rajnikant Lodhi Date: Mon, 18 Jul 2022 12:29:52 +0530 Subject: [PATCH 1/9] Add cosmetic change --- src/app/components/projects/projects.component.html | 4 ++-- src/app/components/projects/projects.component.scss | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/app/components/projects/projects.component.html b/src/app/components/projects/projects.component.html index b19b140a..0ae7fd75 100644 --- a/src/app/components/projects/projects.component.html +++ b/src/app/components/projects/projects.component.html @@ -30,8 +30,8 @@ - Actions - + Actions + + + + +
+

Please wait.

+ +
+ + +
+
+ +
+
+
+
Project can't be deleted because image used in one or more template.
+

{{i+1}}. {{message?.error?.message}}

+
+
+
{{fileNotDeleted.length}} Projects deleted successfully.
+
+
+
+ +
+
\ No newline at end of file diff --git a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.scss b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts new file mode 100644 index 00000000..8acf87e4 --- /dev/null +++ b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConfirmationDeleteAllProjectsComponent } from './confirmation-delete-all-projects.component'; + +describe('ConfirmationDeleteAllProjectsComponent', () => { + let component: ConfirmationDeleteAllProjectsComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ ConfirmationDeleteAllProjectsComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ConfirmationDeleteAllProjectsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts new file mode 100644 index 00000000..19d4b136 --- /dev/null +++ b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts @@ -0,0 +1,48 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { ProjectService } from '@services/project.service'; +import { ToasterService } from '@services/toaster.service'; +import { Observable, of } from 'rxjs'; +import { catchError } from 'rxjs/operators'; + +@Component({ + selector: 'app-confirmation-delete-all-projects', + templateUrl: './confirmation-delete-all-projects.component.html', + styleUrls: ['./confirmation-delete-all-projects.component.scss'] +}) +export class ConfirmationDeleteAllProjectsComponent implements OnInit { + isDelete: boolean = false; + isUsedFiles: boolean = false; + deleteFliesDetails: any = [] + fileNotDeleted: any = [] + + constructor( + @Inject(MAT_DIALOG_DATA) public deleteData: any, + public dialogRef: MatDialogRef, + private projectService: ProjectService, + private toasterService: ToasterService + ) { } + + ngOnInit(): void { + } + + async deleteAll() { + this.isDelete = true + await this.deleteFile() + } + + deleteFile() { + const calls = []; + this.deleteData.deleteFilesPaths.forEach(project => { + calls.push(this.projectService.delete(this.deleteData.server, project.project_id).pipe(catchError(error => of(error)))) + }); + Observable.forkJoin(calls).subscribe(responses => { + this.deleteFliesDetails = responses.filter(x => x !== null) + this.fileNotDeleted = responses.filter(x => x === null) + this.isUsedFiles = true; + this.isDelete = true + }); + + } + +} diff --git a/src/app/components/projects/projects.component.html b/src/app/components/projects/projects.component.html index 0ae7fd75..65d92452 100644 --- a/src/app/components/projects/projects.component.html +++ b/src/app/components/projects/projects.component.html @@ -2,8 +2,8 @@

Projects

- - + @@ -22,6 +22,21 @@
+ + + + + + + + + + + + + Name @@ -52,22 +67,37 @@ + + + + + + + + + + diff --git a/src/app/components/projects/projects.component.ts b/src/app/components/projects/projects.component.ts index 606f5e16..f88065d8 100644 --- a/src/app/components/projects/projects.component.ts +++ b/src/app/components/projects/projects.component.ts @@ -1,9 +1,10 @@ -import { DataSource } from '@angular/cdk/collections'; +import { DataSource, SelectionModel } from '@angular/cdk/collections'; import { Component, OnInit, ViewChild } from '@angular/core'; import { MatBottomSheet } from '@angular/material/bottom-sheet'; import { MatDialog } from '@angular/material/dialog'; import { MatSort, MatSortable } from '@angular/material/sort'; import { ActivatedRoute, Router } from '@angular/router'; +import { ExportPortableProjectComponent } from '@components/export-portable-project/export-portable-project.component'; import { ElectronService } from 'ngx-electron'; import { BehaviorSubject, merge, Observable } from 'rxjs'; import { map } from 'rxjs//operators'; @@ -17,6 +18,7 @@ import { ToasterService } from '../../services/toaster.service'; import { AddBlankProjectDialogComponent } from './add-blank-project-dialog/add-blank-project-dialog.component'; import { ChooseNameDialogComponent } from './choose-name-dialog/choose-name-dialog.component'; import { ConfirmationBottomSheetComponent } from './confirmation-bottomsheet/confirmation-bottomsheet.component'; +import { ConfirmationDeleteAllProjectsComponent } from './confirmation-delete-all-projects/confirmation-delete-all-projects.component'; import { ImportProjectDialogComponent } from './import-project-dialog/import-project-dialog.component'; import { NavigationDialogComponent } from './navigation-dialog/navigation-dialog.component'; @@ -29,10 +31,12 @@ export class ProjectsComponent implements OnInit { server: Server; projectDatabase = new ProjectDatabase(); dataSource: ProjectDataSource; - displayedColumns = ['name', 'actions']; + displayedColumns = ['select', 'name', 'actions', 'delete']; settings: Settings; - + project: Project; searchText: string = ''; + isAllDelete: boolean = false; + selection = new SelectionModel(true, []); @ViewChild(MatSort, { static: true }) sort: MatSort; @@ -188,6 +192,70 @@ export class ProjectsComponent implements OnInit { } }); } + + deleteAllFiles() { + const dialogRef = this.dialog.open(ConfirmationDeleteAllProjectsComponent, { + width: '550px', + maxHeight: '650px', + autoFocus: false, + disableClose: true, + data: { + server: this.server, + deleteFilesPaths: this.selection.selected + } + }); + + dialogRef.afterClosed().subscribe((isAllfilesdeleted: boolean) => { + if (isAllfilesdeleted) { + this.unChecked() + this.refresh() + this.toasterService.success('All files deleted'); + } else { + this.unChecked() + this.refresh() + return false; + } + }); + } + + isAllSelected() { + const numSelected = this.selection.selected.length; + const numRows = this.projectDatabase.data.length; + return numSelected === numRows; + } + + selectAllImages() { + this.isAllSelected() ? this.unChecked() : this.allChecked(); + } + + unChecked() { + this.selection.clear(); + this.isAllDelete = false; + } + + allChecked() { + this.projectDatabase.data.forEach((row) => this.selection.select(row)); + this.isAllDelete = true; + } + +exportSelectProject(project: Project){ + this.project = project + if(this.project.project_id){ + this.exportPortableProjectDialog() + } + +} + exportPortableProjectDialog() { + const dialogRef = this.dialog.open(ExportPortableProjectComponent, { + width: '700px', + maxHeight: '850px', + autoFocus: false, + disableClose: true, + data: {serverDetails:this.server,projectDetails:this.project}, + }); + + dialogRef.afterClosed().subscribe((isAddes: boolean) => {}); + } } export class ProjectDatabase { @@ -208,6 +276,8 @@ export class ProjectDatabase { this.dataChange.next(this.data.slice()); } } + + } export class ProjectDataSource extends DataSource { diff --git a/src/app/layouts/default-layout/default-layout.component.html b/src/app/layouts/default-layout/default-layout.component.html index 5466a65c..348f07ae 100644 --- a/src/app/layouts/default-layout/default-layout.component.html +++ b/src/app/layouts/default-layout/default-layout.component.html @@ -19,6 +19,19 @@ + + + - diff --git a/src/app/layouts/default-layout/default-layout.component.ts b/src/app/layouts/default-layout/default-layout.component.ts index 223cb83b..b4c15303 100644 --- a/src/app/layouts/default-layout/default-layout.component.ts +++ b/src/app/layouts/default-layout/default-layout.component.ts @@ -1,15 +1,14 @@ import { Component, HostListener, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; -import { NavigationEnd } from '@angular/router'; -import { ActivatedRoute, ParamMap, Router } from '@angular/router'; -import { ServerService } from '../../services/server.service'; +import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { ElectronService } from 'ngx-electron'; import { Subscription } from 'rxjs'; import { ProgressService } from '../../common/progress/progress.service'; +import { Server } from '../../models/server'; import { RecentlyOpenedProjectService } from '../../services/recentlyOpenedProject.service'; import { ServerManagementService } from '../../services/server-management.service'; +import { ServerService } from '../../services/server.service'; import { ToasterService } from '../../services/toaster.service'; import { version } from './../../version'; -import { Server } from '../../models/server'; @Component({ selector: 'app-default-layout', @@ -39,8 +38,7 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy { private progressService: ProgressService, private router: Router, private serverService: ServerService, - private route: ActivatedRoute, - + private route: ActivatedRoute ) {} ngOnInit() { @@ -50,7 +48,7 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy { this.routeSubscription = this.router.events.subscribe((val) => { if (val instanceof NavigationEnd) this.checkIfUserIsLoginPage(); }); - + this.recentlyOpenedServerId = this.recentlyOpenedProjectService.getServerId(); this.recentlyOpenedProjectId = this.recentlyOpenedProjectService.getProjectId(); this.serverIdProjectList = this.recentlyOpenedProjectService.getServerIdProjectList(); @@ -74,21 +72,21 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy { } goToUserInfo() { - let serverId = this.router.url.split("/server/")[1].split("/")[0]; + let serverId = this.router.url.split('/server/')[1].split('/')[0]; this.serverService.get(+serverId).then((server: Server) => { this.router.navigate(['/server', server.id, 'loggeduser']); }); } goToDocumentation() { - let serverId = this.router.url.split("/server/")[1].split("/")[0]; + let serverId = this.router.url.split('/server/')[1].split('/')[0]; this.serverService.get(+serverId).then((server: Server) => { (window as any).open(`http://${server.host}:${server.port}/docs`); }); } checkIfUserIsLoginPage() { - if (this.router.url.includes("login")) { + if (this.router.url.includes('login')) { this.isLoginPage = true; } else { this.isLoginPage = false; @@ -96,10 +94,10 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy { } logout() { - let serverId = this.router.url.split("/server/")[1].split("/")[0]; + let serverId = this.router.url.split('/server/')[1].split('/')[0]; this.serverService.get(+serverId).then((server: Server) => { server.authToken = null; - this.serverService.update(server).then(val => this.router.navigate(['/server', server.id, 'login'])); + this.serverService.update(server).then((val) => this.router.navigate(['/server', server.id, 'login'])); }); } @@ -116,14 +114,22 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy { } goToPreferences() { + let controllerId = this.router.url.split('/server/')[1].split('/')[0]; this.router - .navigate(['/controller', this.controller.id, 'preferences']) + .navigate(['/server', controllerId, 'preferences']) .catch((error) => this.toasterService.error('Cannot navigate to the preferences')); } goToSystemStatus() { + let controllerId = this.router.url.split('/server/')[1].split('/')[0]; this.router - .navigate(['/controller', this.controller.id, 'systemstatus']) + .navigate(['/server', controllerId, 'systemstatus']) + .catch((error) => this.toasterService.error('Cannot navigate to the system status')); + } + goToImageManager() { + let controllerId = this.router.url.split('/server/')[1].split('/')[0]; + this.router + .navigate(['/server', controllerId, 'image-manager']) .catch((error) => this.toasterService.error('Cannot navigate to the system status')); } @@ -141,7 +147,6 @@ export class DefaultLayoutComponent implements OnInit, OnDestroy { window.close(); return false; } - ngOnDestroy() { this.serverStatusSubscription.unsubscribe(); From 845f1f1ad8841a144d5d62f58facb205400af221 Mon Sep 17 00:00:00 2001 From: Rajnikant Lodhi Date: Tue, 19 Jul 2022 18:18:46 +0530 Subject: [PATCH 4/9] I complete unit test case to confirmations for delete all project --- ...tion-delete-all-projects.component.spec.ts | 29 +++++++++++++++++++ ...firmation-delete-all-projects.component.ts | 4 +-- .../components/projects/projects.component.ts | 2 +- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts index 8acf87e4..0b9f4d37 100644 --- a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts +++ b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts @@ -1,13 +1,42 @@ 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 { MockedProjectService } from '../../../services/project.service.spec'; +import { MockedToasterService } from '../../../services/toaster.service.spec'; +import { ProjectService } from '../../../services/project.service'; +import { ServerService } from '../../../services/server.service'; +import { MockedServerService } from '../../../services/server.service.spec'; +import { ToasterService } from '../../../services/toaster.service'; import { ConfirmationDeleteAllProjectsComponent } from './confirmation-delete-all-projects.component'; describe('ConfirmationDeleteAllProjectsComponent', () => { let component: ConfirmationDeleteAllProjectsComponent; let fixture: ComponentFixture; + let mockedServerService = new MockedServerService(); + let mockedImageManagerService = new MockedProjectService() + let mockedToasterService = new MockedToasterService() beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [ + MatIconModule, + MatToolbarModule, + MatMenuModule, + MatCheckboxModule, + MatDialogModule, + ], + providers: [ + { provide: ServerService, useValue: mockedServerService }, + { provide: ProjectService, useValue: mockedImageManagerService }, + { provide: MAT_DIALOG_DATA, useValue: {} }, + { provide: MatDialogRef, useValue: {} }, + { provide: ToasterService, useValue: mockedToasterService }, + + ], declarations: [ ConfirmationDeleteAllProjectsComponent ] }) .compileComponents(); diff --git a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts index 19d4b136..a28b2bb2 100644 --- a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts +++ b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts @@ -1,7 +1,7 @@ import { Component, Inject, OnInit } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; -import { ProjectService } from '@services/project.service'; -import { ToasterService } from '@services/toaster.service'; +import { ProjectService } from '../../../services/project.service'; +import { ToasterService } from '../../../services/toaster.service'; import { Observable, of } from 'rxjs'; import { catchError } from 'rxjs/operators'; diff --git a/src/app/components/projects/projects.component.ts b/src/app/components/projects/projects.component.ts index f88065d8..09a84403 100644 --- a/src/app/components/projects/projects.component.ts +++ b/src/app/components/projects/projects.component.ts @@ -4,7 +4,7 @@ import { MatBottomSheet } from '@angular/material/bottom-sheet'; import { MatDialog } from '@angular/material/dialog'; import { MatSort, MatSortable } from '@angular/material/sort'; import { ActivatedRoute, Router } from '@angular/router'; -import { ExportPortableProjectComponent } from '@components/export-portable-project/export-portable-project.component'; +import { ExportPortableProjectComponent } from '../../components/export-portable-project/export-portable-project.component'; import { ElectronService } from 'ngx-electron'; import { BehaviorSubject, merge, Observable } from 'rxjs'; import { map } from 'rxjs//operators'; From a6661a24c6f81ee9afaaec7fe7743051abd6f008 Mon Sep 17 00:00:00 2001 From: Rajnikant Lodhi Date: Thu, 21 Jul 2022 14:16:55 +0530 Subject: [PATCH 5/9] Resolve all commented issue --- .../choose-name-dialog/choose-name-dialog.component.html | 4 ++-- .../confirmation-delete-all-projects.component.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.html b/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.html index 42d261a1..22505eb6 100644 --- a/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.html +++ b/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.html @@ -1,4 +1,4 @@ -

Please choose name for exporting project

+

Save project as