From 8c444059adfcd30c59174f1f7122a23c04f27b3b Mon Sep 17 00:00:00 2001 From: Rajnikant Lodhi Date: Tue, 19 Jul 2022 17:36:19 +0530 Subject: [PATCH] I have improved on the projects page like this 1.Allow to delete multiple projects at once (similar to what is done in the image manager). 2. Add an export project action in the actions column. The export icon could be improved. 3.Replace "Duplicate" action by "Save project as" (with same icon as on project settings menu). 4.Delete 'Go to system status' button and add 'System status' entry to top right menu. 5.Delete 'Go to preferences' button and add 'Template preferences' entry to top right menu. 6.Add "Image manager" entry to the top right menu --- src/app/app.module.ts | 2 + .../project-map/project-map.component.ts | 1 + ...rmation-delete-all-projects.component.html | 34 +++++++++ ...rmation-delete-all-projects.component.scss | 0 ...tion-delete-all-projects.component.spec.ts | 25 ++++++ ...firmation-delete-all-projects.component.ts | 48 ++++++++++++ .../projects/projects.component.html | 46 +++++++++-- .../components/projects/projects.component.ts | 76 ++++++++++++++++++- .../default-layout.component.html | 13 ++++ .../default-layout.component.ts | 20 ++++- 10 files changed, 253 insertions(+), 12 deletions(-) create mode 100644 src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.html create mode 100644 src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.scss create mode 100644 src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.spec.ts create mode 100644 src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2aa88f01..45dae901 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -280,6 +280,7 @@ import { DeleteAllImageFilesDialogComponent } from './components/image-manager/d import { UploadingProcessbarComponent } from './common/uploading-processbar/uploading-processbar.component'; import { ExportPortableProjectComponent } from './components/export-portable-project/export-portable-project.component'; import { NodesMenuConfirmationDialogComponent } from './components/project-map/nodes-menu/nodes-menu-confirmation-dialog/nodes-menu-confirmation-dialog.component'; +import { ConfirmationDeleteAllProjectsComponent } from './components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component'; @NgModule({ declarations: [ @@ -476,6 +477,7 @@ import { NodesMenuConfirmationDialogComponent } from './components/project-map/n UploadingProcessbarComponent, ExportPortableProjectComponent, NodesMenuConfirmationDialogComponent, + ConfirmationDeleteAllProjectsComponent, ], imports: [ BrowserModule, diff --git a/src/app/components/project-map/project-map.component.ts b/src/app/components/project-map/project-map.component.ts index 25d624d9..13e607d9 100644 --- a/src/app/components/project-map/project-map.component.ts +++ b/src/app/components/project-map/project-map.component.ts @@ -999,6 +999,7 @@ export class ProjectMapComponent implements OnInit, OnDestroy { this.exportPortableProjectDialog(); } } + exportPortableProjectDialog() { const dialogRef = this.dialog.open(ExportPortableProjectComponent, { width: '700px', diff --git a/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.html b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.html new file mode 100644 index 00000000..37d22562 --- /dev/null +++ b/src/app/components/projects/confirmation-delete-all-projects/confirmation-delete-all-projects.component.html @@ -0,0 +1,34 @@ +
+

Do you want delete all files ?.

+
+

Your selected files

+

{{i+1}}. {{file?.filename}}

+
+
+ + +
+
+
+

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 @@ + + +