From 558acc023e1056fd85aca8e8539214edd71e6a6b Mon Sep 17 00:00:00 2001 From: Timo Bejan Date: Wed, 4 Aug 2021 10:41:41 +0300 Subject: [PATCH] Fixed various issues for 2.2.0 --- angular.json | 3 +- .../screens/trash/trash-screen.component.html | 2 +- .../screens/trash/trash-screen.component.ts | 32 ++++++-- .../user-listing-screen.component.ts | 3 +- .../dossier-details.component.html | 2 +- ...edit-dossier-download-package.component.ts | 22 ++--- .../edit-dossier-general-info.component.html | 2 +- .../edit-dossier-general-info.component.ts | 11 ++- .../remove-annotations-dialog.component.html | 80 ++++++++++--------- .../remove-annotations-dialog.component.ts | 14 +++- .../dossier-overview-screen.component.ts | 2 +- .../search-screen/search-screen.component.ts | 2 +- .../services/annotation-actions.service.ts | 4 +- .../services/dossiers-dialog.service.ts | 49 +----------- .../services/manual-annotation.service.ts | 6 +- .../popup-filter/popup-filter.component.html | 18 +++-- .../popup-filter/popup-filter.component.scss | 5 ++ apps/red-ui/src/app/services/user.service.ts | 34 ++++---- apps/red-ui/src/app/state/app-state.guard.ts | 4 +- apps/red-ui/src/assets/config/config.json | 4 +- apps/red-ui/src/assets/i18n/en.json | 5 +- package.json | 2 +- proxy.config.json | 8 -- 23 files changed, 155 insertions(+), 159 deletions(-) delete mode 100644 proxy.config.json diff --git a/angular.json b/angular.json index aa7773254..261a4327f 100644 --- a/angular.json +++ b/angular.json @@ -102,8 +102,7 @@ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { - "browserTarget": "red-ui:build", - "proxyConfig": "proxy.config.json" + "browserTarget": "red-ui:build" }, "configurations": { "production": { diff --git a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html index 8e07e620f..4d1ada6e4 100644 --- a/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/trash/trash-screen.component.html @@ -114,7 +114,7 @@ > implemen protected readonly _injector: Injector, private readonly _dossiersService: DossiersService, private readonly _loadingService: LoadingService, + private readonly _adminDialogService: AdminDialogService, private readonly _appConfigService: AppConfigService ) { super(_injector); @@ -66,8 +70,8 @@ export class TrashScreenComponent extends BaseListingComponent implemen return moment(softDeletedTime).add(this._deleteRetentionHours, 'hours').toISOString(); } - bulkDelete(dossierIds = this.screenStateService.selectedEntities.map(d => d.dossierId)) { - this._loadingService.loadWhile(this._hardDelete(dossierIds)); + bulkDelete(dossiers = this.screenStateService.selectedEntities) { + this._loadingService.loadWhile(this._hardDelete(dossiers)); } bulkRestore(dossierIds = this.screenStateService.selectedEntities.map(d => d.dossierId)) { @@ -75,13 +79,31 @@ export class TrashScreenComponent extends BaseListingComponent implemen } private async _restore(dossierIds: string[]): Promise { + this._loadingService.start(); await this._dossiersService.restore(dossierIds); this._removeFromList(dossierIds); + this._loadingService.stop(); } - private async _hardDelete(dossierIds: string[]): Promise { - await this._dossiersService.hardDelete(dossierIds); - this._removeFromList(dossierIds); + private async _hardDelete(dossiers: Dossier[]): Promise { + const period = this._appConfigService.getConfig('DELETE_RETENTION_HOURS'); + const data = new ConfirmationDialogInput({ + title: dossiers.length > 1 ? _('confirmation-dialog.delete-dossier.title-alt') : _('confirmation-dialog.delete-dossier.title'), + titleColor: TitleColors.PRIMARY, + question: _('confirmation-dialog.delete-dossier.question'), + // details: _('confirmation-dialog.delete-dossier.details'), + confirmationText: _('confirmation-dialog.delete-dossier.confirmation-text'), + requireInput: true, + denyText: _('confirmation-dialog.delete-dossier.deny-text'), + translateParams: { dossierName: dossiers[0].dossierName, period: period } + }); + this._adminDialogService.openDialog('confirm', null, data, async () => { + this._loadingService.start(); + const dossierIds = dossiers.map(d => d.dossierId); + await this._dossiersService.hardDelete(dossierIds); + this._removeFromList(dossierIds); + this._loadingService.stop(); + }); } private _removeFromList(ids: string[]): void { diff --git a/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts index b07578d2b..df2ef3e5a 100644 --- a/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/user-listing/user-listing-screen.component.ts @@ -54,6 +54,7 @@ export class UserListingScreenComponent extends BaseListingComponent imple async ngOnInit() { await this._loadData(); + this.searchService.setSearchKey('searchKey'); } openAddEditUserDialog($event: MouseEvent, user?: User) { @@ -89,7 +90,7 @@ export class UserListingScreenComponent extends BaseListingComponent imple } private async _loadData() { - this.screenStateService.setEntities(await this._userControllerService.getAllUsers().toPromise()); + this.screenStateService.setEntities(await this.userService.loadAllUsers()); await this.userService.loadAllUsers(); this._computeStats(); this._loadingService.stop(); diff --git a/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.html b/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.html index d808d7b0a..4fa628321 100644 --- a/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.html +++ b/apps/red-ui/src/app/modules/dossier/components/dossier-details/dossier-details.component.html @@ -15,7 +15,7 @@
- + { - this._editDossierDialogRef.componentInstance.afterSave(); - this._editDossierDialogRef.close(); - this._router.navigate(['main', 'dossiers']).then(() => this._notifyDossierDeleted()); - }); + async deleteDossier($event: MouseEvent) { + await this._appStateService.deleteDossier(this.dossierWrapper); + this._editDossierDialogRef.componentInstance.afterSave(); + this._editDossierDialogRef.close(); + this._router.navigate(['main', 'dossiers']).then(() => this._notifyDossierDeleted()); } private _notifyDossierDeleted() { diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.html b/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.html index a83b023dd..551cdefb5 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.html +++ b/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.html @@ -7,47 +7,53 @@ ) | translate }}
+
+
+ {{ + (data.removeFromDictionary + ? 'remove-annotations-dialog.remove-from-dictionary.question' + : 'remove-annotations-dialog.remove-only-here.question' + ) | translate + }} -
- {{ - (data.removeFromDictionary - ? 'remove-annotations-dialog.remove-from-dictionary.question' - : 'remove-annotations-dialog.remove-only-here.question' - ) | translate - }} +
+ + + + + + + + + + + + + +
{{ 'remove-annotations-dialog.dictionary' | translate }}{{ 'remove-annotations-dialog.value' | translate }}
{{ annotation.dictionary }}{{ annotation.value }}
+
-
- - - - - - - - - - - - - -
{{ 'remove-annotations-dialog.dictionary' | translate }}{{ 'remove-annotations-dialog.value' | translate }}
{{ annotation.dictionary }}{{ annotation.value }}
+
    +
  • + {{ printable(annotation) }} +
  • +
+ +
+ + +
-
    -
  • - {{ printable(annotation) }} -
  • -
-
- -
- - -
+
+ + +
+ diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts index f4cdc488b..4564ea62b 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/remove-annotations-dialog/remove-annotations-dialog.component.ts @@ -3,6 +3,8 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { TranslateService } from '@ngx-translate/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { humanize } from '../../../../utils/functions'; +import { PermissionsService } from '../../../../services/permissions.service'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; export interface RemoveAnnotationsDialogInput { annotationsToRemove: AnnotationWrapper[]; @@ -15,18 +17,26 @@ export interface RemoveAnnotationsDialogInput { styleUrls: ['./remove-annotations-dialog.component.scss'] }) export class RemoveAnnotationsDialogComponent { + redactionForm: FormGroup; + constructor( private readonly _translateService: TranslateService, + private readonly _formBuilder: FormBuilder, + public readonly permissionsService: PermissionsService, public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: RemoveAnnotationsDialogInput - ) {} + ) { + this.redactionForm = this._formBuilder.group({ + comment: this.permissionsService.isApprover() ? [null] : [null, Validators.required] + }); + } deny() { this.dialogRef.close(); } confirm() { - this.dialogRef.close(true); + this.dialogRef.close(this.redactionForm.getRawValue().comment); } printable(annotation: AnnotationWrapper) { diff --git a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts index 1ef8098ec..4b79949d1 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/dossier-overview-screen/dossier-overview-screen.component.ts @@ -105,7 +105,6 @@ export class DossierOverviewScreenComponent async ngOnInit(): Promise { this._loadingService.start(); - try { this._fileDropOverlayService.initFileDropHandling(); @@ -129,6 +128,7 @@ export class DossierOverviewScreenComponent }); this.dossierAttributes = await this._dossierAttributesService.getValues(this.activeDossier); + this.searchService.setSearchKey('searchField'); } catch (e) { } finally { this._loadingService.stop(); diff --git a/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts index 7aa2fa7d4..ca841e50a 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/search-screen/search-screen.component.ts @@ -120,7 +120,7 @@ export class SearchScreenComponent extends BaseListingComponent implem dossierId: this._dossierId, queryString: query ?? '', from: 0, - returnSections: true, + returnSections: false, size: 100 }); } diff --git a/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts b/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts index b00cf0589..87cea40fe 100644 --- a/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/annotation-actions.service.ts @@ -73,10 +73,10 @@ export class AnnotationActionsService { removeFromDictionary: boolean, annotationsChanged: EventEmitter ) { - this._dialogService.openRemoveFromDictionaryDialog($event, annotations, removeFromDictionary, () => { + this._dialogService.openRemoveFromDictionaryDialog($event, annotations, removeFromDictionary, comment => { annotations.forEach(annotation => { this._processObsAndEmit( - this._manualAnnotationService.removeOrSuggestRemoveAnnotation(annotation, removeFromDictionary), + this._manualAnnotationService.removeOrSuggestRemoveAnnotation(annotation, removeFromDictionary, comment), annotation, annotationsChanged ); diff --git a/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts b/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts index 08b34e1bd..d159bf7a4 100644 --- a/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/dossiers-dialog.service.ts @@ -190,33 +190,7 @@ export class DossiersDialogService extends DialogService { }); ref.afterClosed().subscribe(async result => { if (result) { - if (cb) cb(); - } - }); - return ref; - } - - openDeleteDossierDialog($event: MouseEvent, dossier: DossierWrapper, cb?: Function): MatDialogRef { - $event.stopPropagation(); - const period = this._appConfigService.getConfig('DELETE_RETENTION_HOURS'); - const ref = this._dialog.open(ConfirmationDialogComponent, { - ...dialogConfig, - data: new ConfirmationDialogInput({ - title: _('confirmation-dialog.delete-dossier.title'), - titleColor: TitleColors.PRIMARY, - question: _('confirmation-dialog.delete-dossier.question'), - // details: _('confirmation-dialog.delete-dossier.details'), - confirmationText: _('confirmation-dialog.delete-dossier.confirmation-text'), - requireInput: true, - denyText: _('confirmation-dialog.delete-dossier.deny-text'), - translateParams: { dossierName: dossier.dossierName, period: period } - }) - }); - - ref.afterClosed().subscribe(async result => { - if (result) { - await this._appStateService.deleteDossier(dossier); - if (cb) cb(); + if (cb) cb(result); } }); return ref; @@ -287,25 +261,4 @@ export class DossiersDialogService extends DialogService { return ref; } - - openRemoveAnnotationModal($event: MouseEvent, annotation: AnnotationWrapper, callback: () => void) { - $event?.stopPropagation(); - - const ref = this._dialog.open(ConfirmationDialogComponent, { - width: '400px', - maxWidth: '90vw' - }); - - ref.afterClosed().subscribe(result => { - if (result) { - this._manualAnnotationService.removeOrSuggestRemoveAnnotation(annotation).subscribe(() => { - if (callback) { - callback(); - } - }); - } - }); - - return ref; - } } diff --git a/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts b/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts index fcc562013..550db6f80 100644 --- a/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts +++ b/apps/red-ui/src/app/modules/dossier/services/manual-annotation.service.ts @@ -161,7 +161,7 @@ export class ManualAnnotationService { // this wraps // /manualRedaction/redaction/remove/ // /manualRedaction/request/remove/ - removeOrSuggestRemoveAnnotation(annotationWrapper: AnnotationWrapper, removeFromDictionary: boolean = false) { + removeOrSuggestRemoveAnnotation(annotationWrapper: AnnotationWrapper, removeFromDictionary: boolean = false, comment: string) { let mode: AnnotationActionMode, body: any, removeDict = false; @@ -176,7 +176,7 @@ export class ManualAnnotationService { body = { annotationId: annotationWrapper.id, removeFromDictionary, - comment: '-' + comment: comment }; removeDict = removeFromDictionary; } @@ -185,7 +185,7 @@ export class ManualAnnotationService { body = { annotationId: annotationWrapper.id, removeFromDictionary, - comment: '-' + comment: comment }; removeDict = removeFromDictionary; } diff --git a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html index 55747bc04..9e6b04e70 100644 --- a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html +++ b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.html @@ -31,14 +31,16 @@
-
- +
+
+ +
diff --git a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.scss b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.scss index 30410b491..f5bd6e27e 100644 --- a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.scss +++ b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/popup-filter.component.scss @@ -16,6 +16,11 @@ } } +.filter-content { + max-height: 570px; + overflow: auto; +} + .filter-menu-options { margin-top: 8px; padding: 16px 16px 3px; diff --git a/apps/red-ui/src/app/services/user.service.ts b/apps/red-ui/src/app/services/user.service.ts index 306dcac07..95cc5886d 100644 --- a/apps/red-ui/src/app/services/user.service.ts +++ b/apps/red-ui/src/app/services/user.service.ts @@ -7,6 +7,7 @@ import { wipeCaches } from '@redaction/red-cache'; import { BASE_HREF } from '../tokens'; export interface ProfileModel { + username?: string; email: string; firstName: string; lastName: string; @@ -16,7 +17,7 @@ export interface ProfileModel { export class UserWrapper { name: string; - constructor(private readonly _currentUser: KeycloakProfile, public roles: string[], public id: string) { + constructor(private readonly _currentUser: KeycloakProfile | User, public roles: string[], public id: string) { this.name = this.firstName && this.lastName ? `${this.firstName} ${this.lastName}` : this.username; } @@ -40,6 +41,10 @@ export class UserWrapper { return this._currentUser.lastName; } + get searchKey() { + return this.name + this.username + this.email; + } + get isManager() { return this.roles.indexOf('RED_MANAGER') >= 0; } @@ -67,7 +72,7 @@ export class UserWrapper { export class UserService { usersReloaded$: EventEmitter = new EventEmitter(); private _currentUser: UserWrapper; - private _allUsers: User[]; + private _allUsers: UserWrapper[]; constructor( @Inject(BASE_HREF) private readonly _baseHref: string, @@ -75,9 +80,9 @@ export class UserService { private readonly _userControllerService: UserControllerService ) {} - private _allRedUsers: User[]; + private _allRedUsers: UserWrapper[]; - get allRedUsers(): User[] { + get allRedUsers(): UserWrapper[] { return this._allRedUsers; } @@ -85,11 +90,11 @@ export class UserService { return this._currentUser.id; } - get managerUsers(): User[] { + get managerUsers(): UserWrapper[] { return this._allRedUsers.filter(u => u.roles.indexOf('RED_MANAGER') >= 0); } - get eligibleUsers(): User[] { + get eligibleUsers(): UserWrapper[] { return this._allRedUsers.filter(u => u.roles.indexOf('RED_USER') >= 0 || u.roles.indexOf('RED_MANAGER') >= 0); } @@ -97,7 +102,7 @@ export class UserService { return this._currentUser; } - private static _hasAnyRedRole(user: User) { + private static _hasAnyRedRole(user: UserWrapper) { return ( user.roles.indexOf('RED_USER') >= 0 || user.roles.indexOf('RED_MANAGER') >= 0 || @@ -111,20 +116,19 @@ export class UserService { this._keycloakService.logout(window.location.origin + this._baseHref).then(); } - async loadRedUsersIfNecessary() { + async loadUsersIfNecessary() { if (!this._allRedUsers) { - await this.loadRedUsers(); + await this.loadAllUsers(); } } - async loadRedUsers() { - const allRedUsers = await this._userControllerService.getUsers().toPromise(); - this._allRedUsers = allRedUsers.filter(u => UserService._hasAnyRedRole(u)); - } - async loadAllUsers() { - this._allUsers = await this._userControllerService.getAllUsers().toPromise(); + this._allUsers = (await this._userControllerService.getAllUsers().toPromise()).map( + user => new UserWrapper(user, user.roles, user.userId) + ); + this._allRedUsers = this._allUsers.filter(u => UserService._hasAnyRedRole(u)); this.usersReloaded$.next(); + return this._allUsers; } async loadCurrentUser() { diff --git a/apps/red-ui/src/app/state/app-state.guard.ts b/apps/red-ui/src/app/state/app-state.guard.ts index 4370d8944..aed5ee2ef 100644 --- a/apps/red-ui/src/app/state/app-state.guard.ts +++ b/apps/red-ui/src/app/state/app-state.guard.ts @@ -15,11 +15,11 @@ export class AppStateGuard implements CanActivate { async canActivate(route: ActivatedRouteSnapshot): Promise { if (this._userService.user.isUserAdmin) { - await this._userService.loadRedUsersIfNecessary(); + await this._userService.loadUsersIfNecessary(); } if (this._userService.user.isUser || this._userService.user.isAdmin) { - await this._userService.loadRedUsersIfNecessary(); + await this._userService.loadUsersIfNecessary(); await this._appStateService.loadDossierTemplatesIfNecessary(); await this._appStateService.loadDictionaryDataIfNecessary(); } diff --git a/apps/red-ui/src/assets/config/config.json b/apps/red-ui/src/assets/config/config.json index 4b001a0b1..6cfc820ed 100644 --- a/apps/red-ui/src/assets/config/config.json +++ b/apps/red-ui/src/assets/config/config.json @@ -1,6 +1,6 @@ { - "OAUTH_URL": "https://red-staging.iqser.cloud/auth/realms/redaction", - "API_URL": "https://red-staging.iqser.cloud/redaction-gateway-v1", + "OAUTH_URL": "https://dev-06.iqser.cloud/auth/realms/redaction", + "API_URL": "https://dev-06.iqser.cloud/redaction-gateway-v1", "OAUTH_CLIENT_ID": "redaction", "BACKEND_APP_VERSION": "4.4.40", "FRONTEND_APP_VERSION": "1.1", diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 2af385c72..dc5a8a529 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -365,7 +365,8 @@ "deny-text": "Keep Dossier", "input-label": "To proceed please type below", "question": "Are you sure you want to delete this dossier?", - "title": "Delete {dossierName}" + "title": "Delete {dossierName}", + "title-alt": "Delete selected Dossiers" }, "delete-file": { "question": "Do you wish to proceed?", @@ -712,7 +713,7 @@ }, "download-includes": "Choose what is included at download:", "download-status": { - "queued": "Your download has been queued, you can see all your requested downloads here: My Downloads." + "queued": "Your download has been queued, you can see all your requested downloads here: My Downloads." }, "download-type": { "annotated": "Annotated PDF", diff --git a/package.json b/package.json index 89f6fbe95..985d5e503 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "lint": "nx workspace-lint && nx lint", "lint-fix": "nx workspace-lint --fix && nx lint --fix", "nx": "nx", - "start": "nx serve", + "start": "nx serve --base-href /ui/", "test": "nx test", "update": "nx migrate latest", "workspace-generator": "nx workspace-generator" diff --git a/proxy.config.json b/proxy.config.json deleted file mode 100644 index bd0788da7..000000000 --- a/proxy.config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "/auth/*": { - "target": "http://localhost:8080/", - "secure": false, - "logLevel": "debug", - "changeOrigin": true - } -}