RED-3827: Fixes

This commit is contained in:
Adina Țeudan 2022-04-13 12:29:39 +03:00
parent 6aa0ae33b0
commit 09d5d33deb
12 changed files with 77 additions and 76 deletions

View File

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

View File

@ -5,7 +5,7 @@
<div class="flex-1 actions">
<iqser-circle-button
(action)="openDeleteDictionariesDialog()"
*ngIf="currentUser.isAdmin"
*ngIf="this.canDeleteEntity$ | async"
[tooltip]="'entities-listing.action.delete' | translate"
icon="iqser:trash"
></iqser-circle-button>

View File

@ -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<string[]>;
readonly canDeleteEntity$: Observable<boolean>;
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() {

View File

@ -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<AddEntityDialogComponent>,
@Inject(MAT_DIALOG_DATA) private readonly _data: DialogData,

View File

@ -41,7 +41,7 @@
<ng-template #bulkActions>
<iqser-circle-button
(action)="openDeleteEntitiesDialog($event)"
*ngIf="permissionsService.canEditEntities() && (listingService.areSomeSelected$ | async)"
*ngIf="permissionsService.canDeleteEntities(listingService.selected)"
[tooltip]="'entities-listing.bulk.delete' | translate"
[type]="circleButtonTypes.dark"
icon="iqser:trash"
@ -94,15 +94,15 @@
<div class="action-buttons">
<iqser-circle-button
(action)="openDeleteEntitiesDialog($event, [dict])"
*ngIf="permissionsService.canDeleteEntities(dict)"
[tooltip]="'entities-listing.action.delete' | translate"
*ngIf="permissionsService.canDeleteEntity(dict)"
[type]="circleButtonTypes.dark"
icon="iqser:trash"
></iqser-circle-button>
<iqser-circle-button
[routerLink]="dict.routerLink"
*ngIf="permissionsService.canEditEntities()"
[routerLink]="dict.routerLink"
[tooltip]="'entities-listing.action.edit' | translate"
[type]="circleButtonTypes.dark"
icon="iqser:edit"

View File

@ -1,14 +1,12 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, HostListener, ViewChild } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { ChangeDetectionStrategy, Component, HostListener, ViewChild } from '@angular/core';
import { Dictionary } from '@red/domain';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { DOSSIER_TEMPLATE_ID, ENTITY_TYPE } from '@utils/constants';
import { ActivatedRoute } from '@angular/router';
import { UserService } from '@services/user.service';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { PermissionsService } from '@services/permissions.service';
import { AddEditEntityComponent } from '../../../../shared/components/add-edit-entity/add-edit-entity.component';
import { IqserEventTarget } from '../../../../../../../../../../libs/common-ui/src';
import { IqserEventTarget } from '@iqser/common-ui';
@Component({
selector: 'redaction-info',
@ -23,12 +21,9 @@ export class InfoComponent {
@ViewChild(AddEditEntityComponent) private readonly _addEditEntityComponent: AddEditEntityComponent;
constructor(
private readonly _formBuilder: FormBuilder,
private readonly _dictionariesMapService: DictionariesMapService,
private readonly _route: ActivatedRoute,
private readonly _userService: UserService,
private readonly _dictionaryService: DictionaryService,
private readonly _changeRef: ChangeDetectorRef,
readonly permissionsService: PermissionsService,
) {
this.dossierTemplateId = this._route.parent.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID);
@ -36,6 +31,14 @@ export class InfoComponent {
this.entity = this._dictionariesMapService.getDictionary(entityType, this.dossierTemplateId);
}
get disabled(): boolean {
return !this._addEditEntityComponent || this._addEditEntityComponent.form?.invalid || !this._addEditEntityComponent.changed;
}
get changed(): boolean {
return this._addEditEntityComponent.changed;
}
async save(): Promise<void> {
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<void> {
event?.stopImmediatePropagation();

View File

@ -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<void> {
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<void> {
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,

View File

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

View File

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

View File

@ -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) {

View File

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

View File

@ -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;
}