From 09d5d33deb9ec1d8fa9d3745c6d3a1ddb8ed708c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Wed, 13 Apr 2022 12:29:39 +0300 Subject: [PATCH] RED-3827: Fixes --- .../src/app/guards/permissions-guard.ts | 2 +- .../base-entity-screen.component.html | 2 +- .../base-entity-screen.component.ts | 11 ++- .../add-entity-dialog.component.ts | 6 -- .../entities-listing-screen.component.html | 6 +- .../entities/screens/info/info.component.ts | 25 +++---- .../add-edit-entity.component.ts | 72 +++++++++---------- .../services/file-data.service.ts | 2 +- .../services/file-preview-state.service.ts | 4 +- .../services/manual-redaction.service.ts | 10 +-- .../services/page-rotation.service.ts | 2 +- .../src/app/services/permissions.service.ts | 11 ++- 12 files changed, 77 insertions(+), 76 deletions(-) diff --git a/apps/red-ui/src/app/guards/permissions-guard.ts b/apps/red-ui/src/app/guards/permissions-guard.ts index 58094478f..a53249937 100644 --- a/apps/red-ui/src/app/guards/permissions-guard.ts +++ b/apps/red-ui/src/app/guards/permissions-guard.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate } from '@angular/router'; import { firstValueFrom } from 'rxjs'; -import { EntityPermissionsService } from '../services/entity-permissions/entity-permissions.service'; +import { EntityPermissionsService } from '@services/entity-permissions/entity-permissions.service'; @Injectable({ providedIn: 'root' }) export class PermissionsGuard implements CanActivate { diff --git a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.html b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.html index 0e22c8303..119abe9e6 100644 --- a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.html @@ -5,7 +5,7 @@
diff --git a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts index 7f1796ce7..3551ba542 100644 --- a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts @@ -9,6 +9,7 @@ import { LoadingService } from '@iqser/common-ui'; import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service'; import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; import { map } from 'rxjs/operators'; +import { PermissionsService } from '@services/permissions.service'; @Component({ templateUrl: './base-entity-screen.component.html', @@ -17,6 +18,7 @@ import { map } from 'rxjs/operators'; export class BaseEntityScreenComponent { readonly currentUser = this._userService.currentUser; readonly disabledItems$: Observable; + readonly canDeleteEntity$: Observable; readonly #dossierTemplateId: string; readonly #entityType: string; @@ -28,13 +30,16 @@ export class BaseEntityScreenComponent { private readonly _dictionaryService: DictionaryService, private readonly _dictionaryMapService: DictionariesMapService, private readonly _dossierTemplatesService: DossierTemplatesService, + private readonly _permissionsService: PermissionsService, private readonly _router: Router, ) { this.#dossierTemplateId = this._route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); this.#entityType = this._route.snapshot.paramMap.get(ENTITY_TYPE); - this.disabledItems$ = this._dictionaryMapService - .watch$(this.#dossierTemplateId, this.#entityType) - .pipe(map(entity => (entity.hasDictionary ? [] : ['dictionary', 'false-positive', 'false-recommendations']))); + const entity$ = this._dictionaryMapService.watch$(this.#dossierTemplateId, this.#entityType); + this.canDeleteEntity$ = entity$.pipe(map(entity => this._permissionsService.canDeleteEntities(entity))); + this.disabledItems$ = entity$.pipe( + map(entity => (entity.hasDictionary ? [] : ['dictionary', 'false-positive', 'false-recommendations'])), + ); } openDeleteDictionariesDialog() { diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts index d3c61b548..8308e519b 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-entity-dialog/add-entity-dialog.component.ts @@ -1,10 +1,7 @@ import { ChangeDetectionStrategy, Component, Inject, Injector, ViewChild } from '@angular/core'; -import { FormBuilder } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; -import { DictionaryService } from '@services/entity-services/dictionary.service'; import { UserService } from '@services/user.service'; -import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; import { AddEditEntityComponent } from '../../shared/components/add-edit-entity/add-edit-entity.component'; import { BaseDialogComponent } from '@iqser/common-ui'; @@ -25,10 +22,7 @@ export class AddEntityDialogComponent extends BaseDialogComponent { constructor( readonly userService: UserService, - private readonly _formBuilder: FormBuilder, - private readonly _dictionariesMapService: DictionariesMapService, private readonly _translateService: TranslateService, - private readonly _dictionaryService: DictionaryService, protected readonly _injector: Injector, protected readonly _dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) private readonly _data: DialogData, diff --git a/apps/red-ui/src/app/modules/admin/screens/entities-listing/entities-listing-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/entities-listing/entities-listing-screen.component.html index 6685b2597..e72abf4cf 100644 --- a/apps/red-ui/src/app/modules/admin/screens/entities-listing/entities-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/entities-listing/entities-listing-screen.component.html @@ -41,7 +41,7 @@ { try { await this._addEditEntityComponent.save(); @@ -44,18 +47,10 @@ export class InfoComponent { } } - get disabled(): boolean { - return !this._addEditEntityComponent || this._addEditEntityComponent.form?.invalid || !this._addEditEntityComponent.changed; - } - revert(): void { this._addEditEntityComponent.revert(); } - get changed(): boolean { - return this._addEditEntityComponent.changed; - } - @HostListener('window:keydown.Enter', ['$event']) async onEnter(event: KeyboardEvent): Promise { event?.stopImmediatePropagation(); diff --git a/apps/red-ui/src/app/modules/admin/shared/components/add-edit-entity/add-edit-entity.component.ts b/apps/red-ui/src/app/modules/admin/shared/components/add-edit-entity/add-edit-entity.component.ts index 698595da2..340298c87 100644 --- a/apps/red-ui/src/app/modules/admin/shared/components/add-edit-entity/add-edit-entity.component.ts +++ b/apps/red-ui/src/app/modules/admin/shared/components/add-edit-entity/add-edit-entity.component.ts @@ -38,22 +38,49 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit super(); } - revert(): void { - this.form.patchValue(this.initialFormValue); - } - get #caseSensitiveControl() { return { value: this.entity ? !this.entity.caseInsensitive : false, disabled: this.#isSystemManaged }; } - #addToDictionaryActionControl() { - return { value: this.entity?.addToDictionaryAction, disabled: this.#isSystemManaged }; - } - get #isSystemManaged(): boolean { return !!this.entity?.systemManaged; } + revert(): void { + this.form.patchValue(this.initialFormValue); + } + + ngOnInit() { + this._initializeForm(); + } + + async save(): Promise { + this._loadingService.start(); + const dictionary = this._formToObject(); + + try { + if (this.entity) { + // edit mode + await firstValueFrom(this._dictionaryService.updateDictionary(dictionary, this.dossierTemplateId, dictionary.type)); + this._toaster.success(_('add-edit-entity.success.edit')); + } else { + // create mode + await firstValueFrom(this._dictionaryService.addDictionary({ ...dictionary, dossierTemplateId: this.dossierTemplateId })); + this._toaster.success(_('add-edit-entity.success.create')); + } + this.initialFormValue = this.form.getRawValue(); + this._changeRef.markForCheck(); + this._loadingService.stop(); + } catch (e) { + this._loadingService.stop(); + throw e; + } + } + + #addToDictionaryActionControl() { + return { value: this.entity?.addToDictionaryAction, disabled: this.#isSystemManaged }; + } + private _initializeForm(): void { const controlsConfig = { type: [this.entity?.type], @@ -104,33 +131,6 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit this.form = form; } - ngOnInit() { - this._initializeForm(); - } - - async save(): Promise { - this._loadingService.start(); - const dictionary = this._formToObject(); - - try { - if (this.entity) { - // edit mode - await firstValueFrom(this._dictionaryService.updateDictionary(dictionary, this.dossierTemplateId, dictionary.type)); - this._toaster.success(_('add-edit-entity.success.edit')); - } else { - // create mode - await firstValueFrom(this._dictionaryService.addDictionary({ ...dictionary, dossierTemplateId: this.dossierTemplateId })); - this._toaster.success(_('add-edit-entity.success.create')); - } - this.initialFormValue = this.form.getRawValue(); - this._changeRef.markForCheck(); - this._loadingService.stop(); - } catch (e) { - this._loadingService.stop(); - throw e; - } - } - private _toTechnicalName(value: string) { const existingTechnicalNames = this._dictionariesMapService.get(this.dossierTemplateId).map(dict => dict.type); const baseTechnicalName = toSnakeCase(value.trim()); @@ -153,7 +153,7 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit // Fields that aren't set for hints, need additional check const caseInsensitive = this.form.get('caseSensitive') ? !this.form.get('caseSensitive').value : null; const addToDictionaryAction = !!this.form.get('addToDictionaryAction')?.value; - const hasDictionary = !!this.form.get('addToDictionaryAction')?.value; + const hasDictionary = !!this.form.get('hasDictionary')?.value; return { type: this.form.get('type').value, diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts index a67feff0f..db76c6547 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-data.service.ts @@ -28,7 +28,7 @@ import { Core } from '@pdftron/webviewer'; import dayjs from 'dayjs'; import { NGXLogger } from 'ngx-logger'; import { MultiSelectService } from './multi-select.service'; -import { FilesService } from '../../../services/entity-services/files.service'; +import { FilesService } from '@services/entity-services/files.service'; import Annotation = Core.Annotations.Annotation; const DELTA_VIEW_TIME = 10 * 60 * 1000; // 10 minutes; diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts index 3decbf431..079d30bdb 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts @@ -10,8 +10,8 @@ import { FileManagementService } from '@services/entity-services/file-management import { DOSSIER_ID, FILE_ID } from '@utils/constants'; import { dossiersServiceResolver } from '@services/entity-services/dossiers.service.provider'; import { wipeFilesCache } from '@red/cache'; -import { DossiersService } from '../../../services/dossiers/dossiers.service'; -import { FilesService } from '../../../services/entity-services/files.service'; +import { DossiersService } from '@services/dossiers/dossiers.service'; +import { FilesService } from '@services/entity-services/files.service'; @Injectable() export class FilePreviewStateService { diff --git a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts index 2de92e139..23d07b31b 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/manual-redaction.service.ts @@ -10,16 +10,16 @@ import type { IResizeRequest, ManualRedactionActions, } from '@red/domain'; -import { type AnnotationWrapper } from '../../../models/file/annotation.wrapper'; +import { type AnnotationWrapper } from '@models/file/annotation.wrapper'; import { GenericService, List, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { map, tap } from 'rxjs/operators'; -import { PermissionsService } from '../../../services/permissions.service'; +import { PermissionsService } from '@services/permissions.service'; import { dictionaryActionsTranslations, manualRedactionActionsTranslations } from '../../../translations/annotation-actions-translations'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; -import { ActiveDossiersService } from '../../../services/dossiers/active-dossiers.service'; -import { DictionariesMapService } from '../../../services/entity-services/dictionaries-map.service'; -import { type ManualRedactionEntryType } from '../../../models/file/manual-redaction-entry.wrapper'; +import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; +import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service'; +import { type ManualRedactionEntryType } from '@models/file/manual-redaction-entry.wrapper'; import { NGXLogger } from 'ngx-logger'; function getResponseType(error: boolean, isConflict: boolean) { diff --git a/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts b/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts index 47e9a9d40..cf5d751db 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/page-rotation.service.ts @@ -16,7 +16,7 @@ import { import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { MatDialog } from '@angular/material/dialog'; import { ViewerHeaderConfigService } from './viewer-header-config.service'; -import { FilesService } from '../../../services/entity-services/files.service'; +import { FilesService } from '@services/entity-services/files.service'; const ACTION_BUTTONS = [HeaderElements.APPLY_ROTATION, HeaderElements.DISCARD_ROTATION]; const ONE_ROTATION_DEGREE = 90; diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index e7c10cce8..e7c0fca74 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -17,8 +17,11 @@ export class PermissionsService { return user.isAdmin; } - canDeleteEntity(entity: Dictionary, user = this._userService.currentUser): boolean { - return this.canEditEntities(user) && !entity.systemManaged; + canDeleteEntities(entity: Dictionary | Dictionary[], user = this._userService.currentUser): boolean { + const entities = entity instanceof Dictionary ? [entity] : entity; + return ( + entities.length && this.canEditEntities(user) && entities.reduce((acc, _entity) => this._canDeleteEntity(_entity) && acc, true) + ); } canPerformDossierStatesActions(user = this._userService.currentUser): boolean { @@ -235,6 +238,10 @@ export class PermissionsService { return dossier.isActive && this.isFileAssignee(file) && !file.isApproved; } + private _canDeleteEntity(entity: Dictionary): boolean { + return !entity.systemManaged; + } + private _canOcrFile(file: File, dossier: Dossier): boolean { return dossier.isActive && file.canBeOCRed; }