RED-6829: update file data service
This commit is contained in:
parent
e083fa5eb4
commit
bf0685339a
@ -25,7 +25,7 @@ import { TrashGuard } from '@guards/trash.guard';
|
||||
import { ARCHIVE_ROUTE, BreadcrumbTypes, DOSSIER_ID, DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE, FILE_ID } from '@red/domain';
|
||||
import { DossierFilesGuard } from '@guards/dossier-files-guard';
|
||||
import { WebViewerLoadedGuard } from './modules/pdf-viewer/services/webviewer-loaded.guard';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { mainResolver } from '@utils/main.resolver';
|
||||
|
||||
const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
@ -36,7 +36,7 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
routeGuards: [DossiersGuard],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
allow: [ROLES.files.readStatus],
|
||||
allow: [Roles.files.readStatus],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -49,7 +49,7 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
breadcrumbs: [BreadcrumbTypes.dossierTemplate, BreadcrumbTypes.dossier],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
allow: [ROLES.dossierAttributes.read, ROLES.dossierAttributes.readConfig],
|
||||
allow: [Roles.dossierAttributes.read, Roles.dossierAttributes.readConfig],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
skeleton: 'dossier',
|
||||
@ -64,7 +64,7 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
breadcrumbs: [BreadcrumbTypes.dossierTemplate, BreadcrumbTypes.dossier, BreadcrumbTypes.file],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
allow: [ROLES.readRedactionLog, ROLES.files.downloadOriginal, ROLES.highlights.read],
|
||||
allow: [Roles.readRedactionLog, Roles.files.downloadOriginal, Roles.highlights.read],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -120,19 +120,19 @@ const mainRoutes: IqserRoutes = [
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, IqserPermissionsGuard, DossierTemplatesGuard, DashboardGuard],
|
||||
permissions: {
|
||||
allow: [
|
||||
ROLES.any,
|
||||
ROLES.templates.read,
|
||||
ROLES.fileAttributes.readConfig,
|
||||
ROLES.watermarks.read,
|
||||
ROLES.dictionaryTypes.read,
|
||||
ROLES.colors.read,
|
||||
ROLES.states.read,
|
||||
ROLES.notifications.read,
|
||||
Roles.any,
|
||||
Roles.templates.read,
|
||||
Roles.fileAttributes.readConfig,
|
||||
Roles.watermarks.read,
|
||||
Roles.dictionaryTypes.read,
|
||||
Roles.colors.read,
|
||||
Roles.states.read,
|
||||
Roles.notifications.read,
|
||||
'RED_USER',
|
||||
],
|
||||
redirectTo: {
|
||||
RED_USER: '/main/admin',
|
||||
[ROLES.templates.read]: '/main/admin',
|
||||
[Roles.templates.read]: '/main/admin',
|
||||
[DEFAULT_REDIRECT_KEY]: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -147,7 +147,7 @@ const mainRoutes: IqserRoutes = [
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||
permissions: {
|
||||
allow: ROLES.readDownloadStatus,
|
||||
allow: Roles.readDownloadStatus,
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -159,7 +159,7 @@ const mainRoutes: IqserRoutes = [
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, DossiersGuard],
|
||||
permissions: {
|
||||
allow: [ROLES.search],
|
||||
allow: [Roles.search],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -172,7 +172,7 @@ const mainRoutes: IqserRoutes = [
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, DossiersGuard, TrashGuard],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
allow: [ROLES.dossiers.read, ROLES.files.readStatus],
|
||||
allow: [Roles.dossiers.read, Roles.files.readStatus],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -185,19 +185,19 @@ const mainRoutes: IqserRoutes = [
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, DossierTemplatesGuard, DashboardGuard],
|
||||
permissions: {
|
||||
allow: [
|
||||
ROLES.any,
|
||||
ROLES.templates.read,
|
||||
ROLES.fileAttributes.readConfig,
|
||||
ROLES.watermarks.read,
|
||||
ROLES.dictionaryTypes.read,
|
||||
ROLES.colors.read,
|
||||
ROLES.states.read,
|
||||
ROLES.notifications.read,
|
||||
ROLES.dossiers.read,
|
||||
Roles.any,
|
||||
Roles.templates.read,
|
||||
Roles.fileAttributes.readConfig,
|
||||
Roles.watermarks.read,
|
||||
Roles.dictionaryTypes.read,
|
||||
Roles.colors.read,
|
||||
Roles.states.read,
|
||||
Roles.notifications.read,
|
||||
Roles.dossiers.read,
|
||||
'RED_USER',
|
||||
],
|
||||
redirectTo: {
|
||||
[ROLES.any]: '/auth-error',
|
||||
[Roles.any]: '/auth-error',
|
||||
RED_USER: '/main/admin',
|
||||
[DEFAULT_REDIRECT_KEY]: '/',
|
||||
},
|
||||
|
||||
@ -10,7 +10,7 @@ import { IqserPermissionsService, List, shareDistinctLast, TenantsService } from
|
||||
import { BreadcrumbsService } from '@services/breadcrumbs.service';
|
||||
import { FeaturesService } from '@services/features.service';
|
||||
import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@red/domain';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { REDDocumentViewer } from '../../modules/pdf-viewer/services/document-viewer.service';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@ -22,7 +22,7 @@ const isSearchScreen: (url: string) => boolean = url => url.includes('/search');
|
||||
styleUrls: ['./base-screen.component.scss'],
|
||||
})
|
||||
export class BaseScreenComponent {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly documentViewer = inject(REDDocumentViewer);
|
||||
readonly currentUser = this.userService.currentUser;
|
||||
readonly searchActions: List<SpotlightSearchAction> = [
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { getCurrentUser, IqserPermissionsService, List, TenantsService } from '@iqser/common-ui';
|
||||
import { User } from '@red/domain';
|
||||
import { UserService } from '@users/user.service';
|
||||
|
||||
interface MenuItem {
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
@ -34,19 +35,19 @@ export class UserMenuComponent {
|
||||
id: 'admin',
|
||||
name: _('top-bar.navigation-items.my-account.children.admin'),
|
||||
routerLink: '/main/admin',
|
||||
show: (this.currentUser.isManager || this.currentUser.isUserAdmin) && this.#permissionsService.has([ROLES.templates.read]),
|
||||
show: (this.currentUser.isManager || this.currentUser.isUserAdmin) && this.#permissionsService.has([Roles.templates.read]),
|
||||
},
|
||||
{
|
||||
id: 'downloads',
|
||||
name: _('top-bar.navigation-items.my-account.children.downloads'),
|
||||
routerLink: '/main/downloads',
|
||||
show: this.currentUser.isUser && this.#permissionsService.has(ROLES.readDownloadStatus),
|
||||
show: this.currentUser.isUser && this.#permissionsService.has(Roles.readDownloadStatus),
|
||||
},
|
||||
{
|
||||
id: 'trash',
|
||||
name: _('top-bar.navigation-items.my-account.children.trash'),
|
||||
routerLink: '/main/trash',
|
||||
show: this.currentUser.isUser && this.#permissionsService.has([ROLES.dossiers.read, ROLES.files.readStatus]),
|
||||
show: this.currentUser.isUser && this.#permissionsService.has([Roles.dossiers.read, Roles.files.readStatus]),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { AnnotationWrapper } from './annotation.wrapper';
|
||||
import { Dictionary } from '@red/domain';
|
||||
import { isArray } from 'lodash-es';
|
||||
import { IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
export class AnnotationPermissions {
|
||||
canUndo = true;
|
||||
@ -29,9 +29,9 @@ export class AnnotationPermissions {
|
||||
}
|
||||
|
||||
const summedPermissions: AnnotationPermissions = new AnnotationPermissions();
|
||||
const canAddRedaction = permissionsService.has(ROLES.redactions.write);
|
||||
const canRequestRedaction = permissionsService.has(ROLES.redactions.request);
|
||||
const canProcessManualRedaction = permissionsService.has(ROLES.redactions.processManualRequest);
|
||||
const canAddRedaction = permissionsService.has(Roles.redactions.write);
|
||||
const canRequestRedaction = permissionsService.has(Roles.redactions.request);
|
||||
const canProcessManualRedaction = permissionsService.has(Roles.redactions.processManualRequest);
|
||||
const canAddOrRequestRedaction = canAddRedaction || canRequestRedaction;
|
||||
|
||||
for (const annotation of annotations) {
|
||||
|
||||
@ -4,7 +4,7 @@ import { CompositeRouteGuard, IqserAuthGuard, IqserPermissionsGuard, IqserRoutes
|
||||
import { RedRoleGuard } from '@users/red-role.guard';
|
||||
import { BaseAccountScreenComponent } from './base-account-screen/base-account-screen-component';
|
||||
import { PreferencesComponent } from './screens/preferences/preferences.component';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
const routes: IqserRoutes = [
|
||||
{ path: '', redirectTo: 'user-profile', pathMatch: 'full' },
|
||||
@ -24,7 +24,7 @@ const routes: IqserRoutes = [
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||
permissions: {
|
||||
allow: [ROLES.notifications.write, 'RED_USER'],
|
||||
allow: [Roles.notifications.write, 'RED_USER'],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { getCurrentUser, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { User } from '@red/domain';
|
||||
|
||||
interface NavItem {
|
||||
@ -26,7 +26,7 @@ export class AccountSideNavComponent {
|
||||
},
|
||||
{
|
||||
screen: 'notifications',
|
||||
show: this.currentUser.isUser && this._permissionsService.has(ROLES.notifications.write),
|
||||
show: this.currentUser.isUser && this._permissionsService.has(Roles.notifications.write),
|
||||
label: _('notifications.label'),
|
||||
},
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@ import { PreferencesKeys, UserPreferenceService } from '@users/user-preference.s
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AsControl, BaseFormComponent, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
interface PreferencesForm {
|
||||
// preferences
|
||||
@ -52,7 +52,7 @@ export class PreferencesComponent extends BaseFormComponent {
|
||||
loadAllAnnotationsWarning: [this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)],
|
||||
});
|
||||
|
||||
if (!this._permissionsService.has(ROLES.managePreferences)) {
|
||||
if (!this._permissionsService.has(Roles.managePreferences)) {
|
||||
this.form.disable();
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ import { languagesTranslations } from '@translations/languages-translations';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { UserProfileDialogService } from '../services/user-profile-dialog.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@ -136,7 +136,7 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
private _initializeForm(): void {
|
||||
try {
|
||||
this.form = this._getForm();
|
||||
if (!this._permissionsService.has(ROLES.updateMyProfile)) {
|
||||
if (!this._permissionsService.has(Roles.updateMyProfile)) {
|
||||
this.form.disable();
|
||||
}
|
||||
this.#profileModel = {
|
||||
|
||||
@ -17,7 +17,7 @@ import { templateExistsWhenEnteringAdmin } from '@guards/dossier-template-exists
|
||||
import { entityExistsGuard } from '@guards/entity-exists-guard.service';
|
||||
import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-screen.component';
|
||||
import { PermissionsGuard } from '@guards/permissions-guard';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
{
|
||||
@ -54,7 +54,7 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||
permissions: {
|
||||
allow: [ROLES.rules.read],
|
||||
allow: [Roles.rules.read],
|
||||
redirectTo: 'info',
|
||||
},
|
||||
},
|
||||
@ -82,7 +82,7 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
canActivate: [IqserAuthGuard, IqserPermissionsGuard],
|
||||
data: {
|
||||
permissions: {
|
||||
allow: [ROLES.reportTemplates.read],
|
||||
allow: [Roles.reportTemplates.read],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -122,7 +122,7 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
canActivate: [IqserPermissionsGuard],
|
||||
data: {
|
||||
permissions: {
|
||||
allow: [ROLES.legalBasis.read],
|
||||
allow: [Roles.legalBasis.read],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
@ -155,7 +155,7 @@ const routes: IqserRoutes = [
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, DossierTemplatesGuard],
|
||||
requiredRoles: ['RED_MANAGER', 'RED_ADMIN'],
|
||||
permissions: {
|
||||
allow: [ROLES.templates.read],
|
||||
allow: [Roles.templates.read],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
@ -173,7 +173,7 @@ const routes: IqserRoutes = [
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||
permissions: {
|
||||
allow: [ROLES.users.read, 'RED_USER_ADMIN'],
|
||||
allow: [Roles.users.read, 'RED_USER_ADMIN'],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
@ -186,7 +186,7 @@ const routes: IqserRoutes = [
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, PermissionsGuard],
|
||||
permissionsObject: 'Dossier',
|
||||
permissions: {
|
||||
allow: [ROLES.manageAclPermissions, 'RED_ADMIN'],
|
||||
allow: [Roles.manageAclPermissions, 'RED_ADMIN'],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
@ -198,7 +198,7 @@ const routes: IqserRoutes = [
|
||||
canActivate: [IqserAuthGuard, IqserPermissionsGuard, RedRoleGuard],
|
||||
data: {
|
||||
permissions: {
|
||||
allow: [ROLES.license.readReport, 'RED_ADMIN'],
|
||||
allow: [Roles.license.readReport, 'RED_ADMIN'],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
@ -216,7 +216,7 @@ const routes: IqserRoutes = [
|
||||
canActivate: [IqserAuthGuard, IqserPermissionsGuard, RedRoleGuard],
|
||||
data: {
|
||||
permissions: {
|
||||
allow: [ROLES.digitalSignature.read, 'RED_ADMIN'],
|
||||
allow: [Roles.digitalSignature.read, 'RED_ADMIN'],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
@ -233,7 +233,7 @@ const routes: IqserRoutes = [
|
||||
canActivate: [IqserAuthGuard, IqserPermissionsGuard, RedRoleGuard],
|
||||
data: {
|
||||
permissions: {
|
||||
allow: [ROLES.searchAudit, 'RED_ADMIN'],
|
||||
allow: [Roles.searchAudit, 'RED_ADMIN'],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
@ -252,7 +252,7 @@ const routes: IqserRoutes = [
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||
permissions: {
|
||||
allow: [ROLES.generalConfiguration.read, ROLES.smtp.read, 'RED_ADMIN'],
|
||||
allow: [Roles.generalConfiguration.read, Roles.smtp.read, 'RED_ADMIN'],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
|
||||
@ -9,7 +9,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { DossierTemplate, IDossierTemplate } from '@red/domain';
|
||||
import { HttpStatusCode } from '@angular/common/http';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
interface EditCloneTemplateData {
|
||||
dossierTemplateId: string;
|
||||
@ -26,7 +26,7 @@ const downloadTypes = ['ORIGINAL', 'PREVIEW', 'DELTA_PREVIEW', 'REDACTED'].map(t
|
||||
styleUrls: ['./add-edit-clone-dossier-template-dialog.component.scss'],
|
||||
})
|
||||
export class AddEditCloneDossierTemplateDialogComponent extends BaseDialogComponent {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
hasValidFrom: boolean;
|
||||
hasValidTo: boolean;
|
||||
readonly downloadTypes = downloadTypes;
|
||||
|
||||
@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, inject, ViewChild } from '@angular/
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
|
||||
import { BaseDialogComponent, IconButtonTypes } from '@iqser/common-ui';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
interface DialogData {
|
||||
readonly dossierTemplateId: string;
|
||||
@ -15,7 +15,7 @@ interface DialogData {
|
||||
})
|
||||
export class AddEntityDialogComponent extends BaseDialogComponent {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly data = inject<DialogData>(MAT_DIALOG_DATA);
|
||||
@ViewChild(AddEditEntityComponent, { static: true }) private readonly _addEditEntityComponent: AddEditEntityComponent;
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ import { AuditService } from '../../services/audit.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { Dayjs } from 'dayjs';
|
||||
import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
const PAGE_SIZE = 50;
|
||||
@ -35,7 +35,7 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
|
||||
readonly form: UntypedFormGroup = this._getForm();
|
||||
readonly routerHistoryService = inject(RouterHistoryService);
|
||||
readonly permissionsService = inject(IqserPermissionsService);
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
categories: string[] = [];
|
||||
|
||||
@ -15,7 +15,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { combineLatest } from 'rxjs';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
interface ListItem extends IListable {
|
||||
readonly key: string;
|
||||
@ -31,7 +31,7 @@ interface ListItem extends IListable {
|
||||
export class DefaultColorsScreenComponent extends ListingComponent<ListItem> {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly translations = defaultColorsTranslations;
|
||||
readonly tableHeaderLabel = _('default-colors-screen.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<ListItem>[] = [
|
||||
|
||||
@ -8,7 +8,7 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { PkcsSignatureConfigurationComponent } from '../../dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component';
|
||||
import { KmsSignatureConfigurationComponent } from '../../dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component';
|
||||
import { DigitalSignatureOptions, IKmsDigitalSignatureRequest, IPkcsDigitalSignatureRequest, User } from '@red/domain';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-digital-signature-screen',
|
||||
@ -21,7 +21,7 @@ export class DigitalSignatureScreenComponent implements OnInit {
|
||||
|
||||
readonly certificateType = DigitalSignatureOptions;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
digitalSignature: IPkcsDigitalSignatureRequest | IKmsDigitalSignatureRequest;
|
||||
|
||||
@ -16,7 +16,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-templates-listing-screen.component.html',
|
||||
@ -30,7 +30,7 @@ import { ROLES } from '@users/roles';
|
||||
export class DossierTemplatesListingScreenComponent extends ListingComponent<DossierTemplate> {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly tableHeaderLabel = _('dossier-templates-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<DossierTemplate>[] = [
|
||||
|
||||
@ -6,7 +6,7 @@ import { getCurrentUser, getParam, IqserPermissionsService, List, LoadingService
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { DICTIONARY_TO_ENTRY_TYPE_MAP, DICTIONARY_TYPE_KEY_MAP, DictionaryType, DOSSIER_TEMPLATE_ID, ENTITY_TYPE, User } from '@red/domain';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
|
||||
@Component({
|
||||
@ -16,7 +16,7 @@ import { NGXLogger } from 'ngx-logger';
|
||||
})
|
||||
export class DictionaryScreenComponent implements OnInit {
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly initialEntries$ = new BehaviorSubject<string[]>([]);
|
||||
isLeavingPage = false;
|
||||
readonly type: DictionaryType;
|
||||
|
||||
@ -7,7 +7,7 @@ import { PermissionsService } from '@services/permissions.service';
|
||||
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
|
||||
import { IconButtonTypes, IqserEventTarget } from '@iqser/common-ui';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-entity-info',
|
||||
@ -19,7 +19,7 @@ export class EntityInfoComponent {
|
||||
readonly currentUser = getCurrentUser();
|
||||
readonly entity$: Observable<Dictionary>;
|
||||
readonly dossierTemplateId: string;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
@ViewChild(AddEditEntityComponent) private readonly _addEditEntityComponent: AddEditEntityComponent;
|
||||
|
||||
@ -10,7 +10,7 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { NgForOf } from '@angular/common';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
|
||||
export interface AddEditFileAttributeDialogData {
|
||||
@ -40,7 +40,7 @@ export interface AddEditFileAttributeDialogData {
|
||||
],
|
||||
})
|
||||
export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly DISPLAYED_FILTERABLE_LIMIT = 3;
|
||||
readonly translations = fileAttributeTypesTranslations;
|
||||
readonly fileAttribute = this.data.fileAttribute;
|
||||
|
||||
@ -21,7 +21,7 @@ import { HttpStatusCode } from '@angular/common/http';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import {
|
||||
AddEditFileAttributeDialogComponent,
|
||||
@ -58,7 +58,7 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
|
||||
rightIconTooltip: _('file-attributes-listing.table-col-names.primary-info-tooltip'),
|
||||
},
|
||||
];
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
@ViewChild('impactedTemplates') private readonly _impactedTemplatesRef: TemplateRef<unknown>;
|
||||
#existingConfiguration: IFileAttributesConfig;
|
||||
@ViewChild('fileInput') private _fileInput: ElementRef;
|
||||
|
||||
@ -5,7 +5,7 @@ import { IGeneralConfiguration } from '@red/domain';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-general-config-form',
|
||||
@ -23,7 +23,7 @@ export class GeneralConfigFormComponent extends BaseFormComponent implements OnI
|
||||
) {
|
||||
super();
|
||||
this.form = this._getForm();
|
||||
if (!_permissionsService.has(ROLES.generalConfiguration.write)) {
|
||||
if (!_permissionsService.has(Roles.generalConfiguration.write)) {
|
||||
this.form.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
import { SmtpConfigService } from '../../../services/smtp-config.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-smtp-form',
|
||||
@ -26,7 +26,7 @@ export class SmtpFormComponent extends BaseFormComponent implements OnInit {
|
||||
) {
|
||||
super();
|
||||
this.form = this._getForm();
|
||||
if (!_permissionsService.has(ROLES.smtp.write)) {
|
||||
if (!_permissionsService.has(Roles.smtp.write)) {
|
||||
this.form.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { SystemPreferences } from '@red/domain';
|
||||
import { BaseFormComponent, IqserPermissionsService, KeysOf, LoadingService } from '@iqser/common-ui';
|
||||
import { SystemPreferencesService } from '@services/system-preferences.service';
|
||||
import { systemPreferencesTranslations } from '@translations/system-preferences-translations';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
export type ValueType = 'number' | 'string' | 'boolean';
|
||||
|
||||
@ -30,7 +30,7 @@ export class SystemPreferencesFormComponent extends BaseFormComponent {
|
||||
super();
|
||||
this.form = this._getForm();
|
||||
this._loadData();
|
||||
if (!_permissionsService.has(ROLES.appConfiguration.write)) {
|
||||
if (!_permissionsService.has(Roles.appConfiguration.write)) {
|
||||
this.form.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { LicenseService } from '@services/license.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import type { User } from '@red/domain';
|
||||
|
||||
@Component({
|
||||
@ -14,7 +14,7 @@ import type { User } from '@red/domain';
|
||||
styleUrls: ['./license-screen.component.scss'],
|
||||
})
|
||||
export class LicenseScreenComponent {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly currentYear = new Date().getFullYear();
|
||||
readonly buttonConfigs: readonly ButtonConfig[] = [
|
||||
@ -23,7 +23,7 @@ export class LicenseScreenComponent {
|
||||
action: (): void => this.sendMail(),
|
||||
type: IconButtonTypes.primary,
|
||||
helpModeKey: 'license_information',
|
||||
hide: !this.permissionsService.has(ROLES.license.readReport),
|
||||
hide: !this.permissionsService.has(Roles.license.readReport),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ import { interval, map, Subscription } from 'rxjs';
|
||||
import { switchMap, tap } from 'rxjs/operators';
|
||||
import { permissionsTranslations } from '@translations/permissions-translations';
|
||||
import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
templateUrl: './permissions-screen.component.html',
|
||||
@ -27,7 +27,7 @@ import { ROLES } from '@users/roles';
|
||||
providers: listingProvidersFactory(PermissionsScreenComponent),
|
||||
})
|
||||
export class PermissionsScreenComponent extends ListingComponent<PermissionsMapping> implements OnDestroy {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly translations = permissionsTranslations;
|
||||
readonly tableColumnConfigs: TableColumnConfig<PermissionsMapping>[];
|
||||
|
||||
@ -12,7 +12,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
import { ReportTemplateService } from '@services/report-template.service';
|
||||
import { BehaviorSubject, firstValueFrom } from 'rxjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
interface Placeholder {
|
||||
placeholder: string;
|
||||
@ -33,7 +33,7 @@ export class ReportsScreenComponent implements OnInit {
|
||||
readonly placeholders$ = new BehaviorSubject<Placeholder[]>([]);
|
||||
readonly availableTemplates$ = new BehaviorSubject<IReportTemplate[]>([]);
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
@ViewChild('fileInput') private readonly _fileInput: ElementRef;
|
||||
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ import {
|
||||
listingProvidersFactory,
|
||||
LoadingService,
|
||||
NestedFilter,
|
||||
OverlappingElements,
|
||||
SearchPositions,
|
||||
TableColumnConfig,
|
||||
} from '@iqser/common-ui';
|
||||
@ -22,7 +21,7 @@ import { rolesTranslations } from '@translations/roles-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { userTypeChecker, userTypeFilters } from '../../../../utils';
|
||||
import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
function configToFilter({ key, label }: DonutChartConfig) {
|
||||
return new NestedFilter({
|
||||
@ -45,7 +44,7 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
|
||||
readonly translations = rolesTranslations;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
readonly canDeleteSelected$ = this.#canDeleteSelected$;
|
||||
readonly tableHeaderLabel = _('user-listing.table-header.title');
|
||||
|
||||
@ -36,7 +36,7 @@ import { LicenseService } from '@services/license.service';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { environment } from '@environments/environment';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { watermarkTranslations } from '@translations/watermark-translations';
|
||||
@ -143,7 +143,7 @@ export class WatermarkScreenComponent implements OnInit {
|
||||
verticalTextAlignment: [null],
|
||||
});
|
||||
|
||||
if (!this.currentUser.isAdmin || !this.permissionsService.has(ROLES.watermarks.write)) {
|
||||
if (!this.currentUser.isAdmin || !this.permissionsService.has(Roles.watermarks.write)) {
|
||||
form.disable();
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
||||
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
templateUrl: './watermarks-listing-screen.component.html',
|
||||
@ -28,7 +28,7 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly tableColumnConfigs: TableColumnConfig<Watermark>[] = [
|
||||
{ label: _('watermarks-listing.table-col-names.name'), sortByKey: 'searchKey', width: '2fr' },
|
||||
{ label: _('watermarks-listing.table-col-names.status'), sortByKey: 'enabled', class: 'flex-center' },
|
||||
|
||||
@ -4,7 +4,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { adminSideNavTranslations } from '@translations/admin-side-nav-translations';
|
||||
import { ActivatedRoute, RouterLink, RouterLinkActive } from '@angular/router';
|
||||
import { AdminSideNavType, AdminSideNavTypes, DOSSIER_TEMPLATE_ID, ENTITY_TYPE, User, WATERMARK_ID } from '@red/domain';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { getCurrentUser, IqserHelpModeModule, IqserPermissionsService, SideNavComponent, TenantPipe } from '@iqser/common-ui';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NgForOf, NgIf } from '@angular/common';
|
||||
@ -28,7 +28,7 @@ export class AdminSideNavComponent implements OnInit {
|
||||
@Input() disabledItems: string[] = [];
|
||||
readonly translations = adminSideNavTranslations;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
prefix: string;
|
||||
|
||||
readonly items: { readonly [key in AdminSideNavType]: NavItem[] } = {
|
||||
@ -36,43 +36,43 @@ export class AdminSideNavComponent implements OnInit {
|
||||
{
|
||||
screen: 'dossier-templates',
|
||||
label: _('admin-side-nav.dossier-templates'),
|
||||
show: (this.currentUser.isManager || this.currentUser.isAdmin) && this._permissionsService.has(ROLES.templates.read),
|
||||
show: (this.currentUser.isManager || this.currentUser.isAdmin) && this._permissionsService.has(Roles.templates.read),
|
||||
helpModeKey: 'dossier_templates',
|
||||
},
|
||||
{
|
||||
screen: 'digital-signature',
|
||||
label: _('admin-side-nav.digital-signature'),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(ROLES.digitalSignature.read),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(Roles.digitalSignature.read),
|
||||
helpModeKey: 'digital_signature',
|
||||
},
|
||||
{
|
||||
screen: 'license-info',
|
||||
label: _('admin-side-nav.license-information'),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(ROLES.license.readReport),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(Roles.license.readReport),
|
||||
helpModeKey: 'license_information',
|
||||
},
|
||||
{
|
||||
screen: 'audit',
|
||||
label: _('admin-side-nav.audit'),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(ROLES.searchAudit),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(Roles.searchAudit),
|
||||
helpModeKey: 'audit',
|
||||
},
|
||||
{
|
||||
screen: 'users',
|
||||
label: _('admin-side-nav.user-management'),
|
||||
show: this.currentUser.isUserAdmin && this._permissionsService.has(ROLES.users.read),
|
||||
show: this.currentUser.isUserAdmin && this._permissionsService.has(Roles.users.read),
|
||||
helpModeKey: 'user_management',
|
||||
},
|
||||
{
|
||||
screen: 'dossier-permissions',
|
||||
label: _('dossier-permissions'),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(ROLES.manageAclPermissions),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has(Roles.manageAclPermissions),
|
||||
helpModeKey: 'dossier_permissions',
|
||||
},
|
||||
{
|
||||
screen: 'general-config',
|
||||
label: _('admin-side-nav.configurations'),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has([ROLES.generalConfiguration.read, ROLES.smtp.read]),
|
||||
show: this.currentUser.isAdmin && this._permissionsService.has([Roles.generalConfiguration.read, Roles.smtp.read]),
|
||||
helpModeKey: 'configurations',
|
||||
},
|
||||
],
|
||||
@ -92,7 +92,7 @@ export class AdminSideNavComponent implements OnInit {
|
||||
{
|
||||
screen: 'rules',
|
||||
label: _('admin-side-nav.rule-editor'),
|
||||
show: this.userPreferenceService.areDevFeaturesEnabled && this._permissionsService.has(ROLES.rules.read),
|
||||
show: this.userPreferenceService.areDevFeaturesEnabled && this._permissionsService.has(Roles.rules.read),
|
||||
},
|
||||
{
|
||||
screen: 'default-colors',
|
||||
@ -127,13 +127,13 @@ export class AdminSideNavComponent implements OnInit {
|
||||
{
|
||||
screen: 'reports',
|
||||
label: _('admin-side-nav.reports'),
|
||||
show: this._permissionsService.has([ROLES.reportTemplates.read]),
|
||||
show: this._permissionsService.has([Roles.reportTemplates.read]),
|
||||
helpModeKey: 'reports',
|
||||
},
|
||||
{
|
||||
screen: 'justifications',
|
||||
label: _('admin-side-nav.justifications'),
|
||||
show: this._permissionsService.has([ROLES.legalBasis.read]),
|
||||
show: this._permissionsService.has([Roles.legalBasis.read]),
|
||||
helpModeKey: 'justifications',
|
||||
},
|
||||
],
|
||||
|
||||
@ -3,7 +3,7 @@ import { DashboardStats } from '@red/domain';
|
||||
import { IconButtonTypes } from '@iqser/common-ui';
|
||||
import { TranslateChartService } from '@services/translate-chart.service';
|
||||
import { SharedDialogService } from '@shared/services/dialog.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
|
||||
@Component({
|
||||
@ -13,7 +13,7 @@ import { PermissionsService } from '@services/permissions.service';
|
||||
})
|
||||
export class TemplateStatsComponent {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
|
||||
@Input() stats: DashboardStats;
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ import { DossierStatsService } from '@services/dossiers/dossier-stats.service';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { FilesMapService } from '@services/files/files-map.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
interface DossierDetailsContext {
|
||||
needsWorkFilters: INestedFilter[] | undefined;
|
||||
@ -49,7 +49,7 @@ export class DossierDetailsComponent extends ContextComponent<DossierDetailsCont
|
||||
@Output() readonly toggleCollapse = new EventEmitter();
|
||||
|
||||
editingOwner = false;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly collapseTooltip = _('dossier-details.collapse');
|
||||
readonly expandTooltip = _('dossier-details.expand');
|
||||
|
||||
@ -21,7 +21,7 @@ import { UserService } from '@users/user.service';
|
||||
import { ConfigService } from '../../config.service';
|
||||
import { PrimaryFileAttributeService } from '@services/primary-file-attribute.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-overview-screen-header [dossier] [upload]',
|
||||
@ -31,7 +31,7 @@ export class DossierOverviewScreenHeaderComponent implements OnInit {
|
||||
@Input() dossier: Dossier;
|
||||
@Output() readonly upload = new EventEmitter<void>();
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
actionConfigs: List<ActionConfig>;
|
||||
readonly downloadBtnDisabled$: Observable<boolean>;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Component, HostListener, Input, OnDestroy } from '@angular/core';
|
||||
import { Dossier, File, FileAttributeConfigTypes, IFileAttributeConfig } from '@red/domain';
|
||||
import { BaseFormComponent, HelpModeService, ListingService, Toaster } from '@iqser/common-ui';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
@ -76,7 +76,7 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr
|
||||
await firstValueFrom(
|
||||
this.fileAttributesService.setFileAttributes({ attributeIdToValue }, this.file.dossierId, this.file.fileId),
|
||||
);
|
||||
await firstValueFrom(this._filesService.reload(this.file.dossierId, this.file));
|
||||
await this._filesService.reload(this.file.dossierId, this.file);
|
||||
this.initialFormValue = rawFormValue;
|
||||
this._toaster.success(_('file-attribute.update.success'));
|
||||
} catch (e) {
|
||||
|
||||
@ -12,7 +12,6 @@ import {
|
||||
ListingMode,
|
||||
ListingModes,
|
||||
NestedFilter,
|
||||
OverlappingElements,
|
||||
TableColumnConfig,
|
||||
WorkflowColumn,
|
||||
WorkflowConfig,
|
||||
@ -46,7 +45,7 @@ import { map } from 'rxjs/operators';
|
||||
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Injectable()
|
||||
export class ConfigService {
|
||||
@ -160,7 +159,7 @@ export class ConfigService {
|
||||
label: this._translateService.instant('dossier-overview.header-actions.edit'),
|
||||
action: () => this._openEditDossierDialog(dossierId),
|
||||
icon: 'iqser:edit',
|
||||
hide: !this.#currentUser.isManager && !this._iqserPermissionsService.has(ROLES.dossiers.edit),
|
||||
hide: !this.#currentUser.isManager && !this._iqserPermissionsService.has(Roles.dossiers.edit),
|
||||
helpModeKey: 'edit_dossier_in_dossier',
|
||||
disabled$,
|
||||
},
|
||||
|
||||
@ -9,7 +9,7 @@ import { FilePreviewStateService } from '../../services/file-preview-state.servi
|
||||
import { HelpModeService, IqserPermissionsService, shareLast } from '@iqser/common-ui';
|
||||
import { ViewModeService } from '../../services/view-mode.service';
|
||||
import { REDAnnotationManager } from '../../../pdf-viewer/services/annotation-manager.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { map } from 'rxjs';
|
||||
|
||||
export const AnnotationButtonTypes = {
|
||||
@ -30,7 +30,7 @@ export class AnnotationActionsComponent implements OnChanges {
|
||||
@Input() canPerformAnnotationActions: boolean;
|
||||
@Input() alwaysVisible: boolean;
|
||||
annotationPermissions: AnnotationPermissions;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
|
||||
isImage = true;
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { Component, Input } from '@angular/core';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { annotationTypesTranslations } from '@translations/annotation-types-translations';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotation-card',
|
||||
@ -10,7 +10,7 @@ import { ROLES } from '@users/roles';
|
||||
styleUrls: ['./annotation-card.component.scss'],
|
||||
})
|
||||
export class AnnotationCardComponent {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly annotationTypesTranslations = annotationTypesTranslations;
|
||||
@Input() annotation: AnnotationWrapper;
|
||||
@Input() isSelected = false;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div *ngIf="annotationReferencesService.references$ | async as references" class="content-container">
|
||||
<div *ngIf="annotationReferencesService.references() as references" class="content-container">
|
||||
<div class="dialog references-dialog">
|
||||
<div class="references-header flex">
|
||||
<div class="small-label uppercase">
|
||||
@ -7,7 +7,7 @@
|
||||
<iqser-circle-button (action)="annotationReferencesService.hide()" icon="iqser:close"></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<div *ngIf="annotationReferencesService.annotation$ | async as annotation" class="annotations-container flex">
|
||||
<div *ngIf="annotationReferencesService.annotation() as annotation" class="annotations-container flex">
|
||||
<div [class.active]="isSelected$ | async" class="annotation-container">
|
||||
<div class="annotation-card-container flex">
|
||||
<redaction-annotation-card [annotation]="annotation"></redaction-annotation-card>
|
||||
|
||||
@ -4,6 +4,7 @@ import { AnnotationReferencesService } from '../../services/annotation-reference
|
||||
import { Observable, switchMap } from 'rxjs';
|
||||
import { AnnotationsListingService } from '../../services/annotations-listing.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { toObservable } from '@angular/core/rxjs-interop';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-annotation-references-list',
|
||||
@ -13,12 +14,13 @@ import { filter } from 'rxjs/operators';
|
||||
export class AnnotationReferencesListComponent {
|
||||
@Output() readonly referenceClicked = new EventEmitter<AnnotationWrapper>();
|
||||
readonly isSelected$: Observable<boolean>;
|
||||
readonly annotation$ = toObservable(this.annotationReferencesService.annotation);
|
||||
|
||||
constructor(
|
||||
private readonly _listingService: AnnotationsListingService,
|
||||
readonly annotationReferencesService: AnnotationReferencesService,
|
||||
) {
|
||||
this.isSelected$ = this.annotationReferencesService.annotation$.pipe(
|
||||
this.isSelected$ = this.annotation$.pipe(
|
||||
filter(annotation => !!annotation),
|
||||
switchMap(annotation => this._listingService.isSelected$(annotation)),
|
||||
);
|
||||
|
||||
@ -11,5 +11,5 @@
|
||||
|
||||
<redaction-annotation-references-list
|
||||
(referenceClicked)="referenceClicked($event)"
|
||||
*ngIf="annotationReferencesService.annotation$ | async"
|
||||
*ngIf="annotationReferencesService.annotation()"
|
||||
></redaction-annotation-references-list>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<div class="comment-actions">
|
||||
<iqser-circle-button
|
||||
(action)="deleteComment(comment)"
|
||||
*ngIf="permissionsService.canDeleteComment(comment, ctx.file, ctx.dossier)"
|
||||
*ngIf="permissionsService.canDeleteComment(comment, _state.file(), ctx.dossier)"
|
||||
[iconSize]="10"
|
||||
[size]="20"
|
||||
class="pointer"
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
<iqser-input-with-action
|
||||
(action)="addComment($event)"
|
||||
*ngIf="permissionsService.canAddComment(ctx.file, ctx.dossier)"
|
||||
*ngIf="permissionsService.canAddComment(_state.file(), ctx.dossier)"
|
||||
[placeholder]="'comments.add-comment' | translate"
|
||||
autocomplete="off"
|
||||
icon="iqser:collapse"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ChangeDetectorRef, Component, HostBinding, Input, OnInit, ViewChild } from '@angular/core';
|
||||
import type { Dossier, File, IComment, User } from '@red/domain';
|
||||
import type { Dossier, IComment, User } from '@red/domain';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { ContextComponent, getCurrentUser, InputWithActionComponent, LoadingService, trackByFactory } from '@iqser/common-ui';
|
||||
@ -11,7 +11,6 @@ import { ManualRedactionService } from '../../services/manual-redaction.service'
|
||||
|
||||
interface CommentsContext {
|
||||
dossier: Dossier;
|
||||
file: File;
|
||||
hiddenComments: boolean;
|
||||
}
|
||||
|
||||
@ -34,7 +33,7 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
private readonly _commentingService: CommentingService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _changeRef: ChangeDetectorRef,
|
||||
private readonly _stateService: FilePreviewStateService,
|
||||
protected readonly _state: FilePreviewStateService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
@ -47,8 +46,7 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
);
|
||||
|
||||
super._initContext({
|
||||
file: this._stateService.file$,
|
||||
dossier: this._stateService.dossier$,
|
||||
dossier: this._state.dossier$,
|
||||
hiddenComments: this.hiddenComments$,
|
||||
});
|
||||
}
|
||||
@ -58,7 +56,7 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
return;
|
||||
}
|
||||
this._loadingService.start();
|
||||
const { dossierId, fileId } = this._stateService;
|
||||
const { dossierId, fileId } = this._state;
|
||||
const commentId = await this._manualRedactionService.addComment(value, this.annotation.id, dossierId, fileId);
|
||||
this.annotation.comments.push({
|
||||
text: value,
|
||||
@ -77,7 +75,7 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
|
||||
|
||||
async deleteComment(comment: IComment): Promise<void> {
|
||||
this._loadingService.start();
|
||||
const { dossierId, fileId } = this._stateService;
|
||||
const { dossierId, fileId } = this._state;
|
||||
await this._manualRedactionService.deleteComment(comment.id, this.annotation.id, dossierId, fileId);
|
||||
this.annotation.comments.splice(this.annotation.comments.indexOf(comment), 1);
|
||||
this._changeRef.markForCheck();
|
||||
|
||||
@ -2,18 +2,18 @@
|
||||
<div class="right-title heading" translate="file-preview.tabs.document-info.label">
|
||||
<div>
|
||||
<iqser-circle-button
|
||||
buttonId="edit-document-info-btn"
|
||||
(action)="edit(ctx.file)"
|
||||
*ngIf="permissionsService.canEditFileAttributes(ctx.file, ctx.dossier)"
|
||||
(action)="edit()"
|
||||
*ngIf="permissionsService.canEditFileAttributes(_state.file(), ctx.dossier)"
|
||||
[tooltip]="'file-preview.tabs.document-info.edit' | translate"
|
||||
buttonId="edit-document-info-btn"
|
||||
icon="iqser:edit"
|
||||
tooltipPosition="before"
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
buttonId="close-document-info-btn"
|
||||
(action)="documentInfoService.hide()"
|
||||
[tooltip]="'file-preview.tabs.document-info.close' | translate"
|
||||
buttonId="close-document-info-btn"
|
||||
icon="iqser:close"
|
||||
tooltipPosition="before"
|
||||
></iqser-circle-button>
|
||||
@ -38,10 +38,10 @@
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="iqser:document"></mat-icon>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.pages' | translate : { pages: ctx.file.numberOfPages } }}</span>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.pages' | translate : { pages: _state.file().numberOfPages } }}</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="ctx.file.added | date : 'mediumDate' as added">
|
||||
<div *ngIf="_state.file().added | date : 'mediumDate' as added">
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
<span [innerHTML]="'file-preview.tabs.document-info.details.created-on' | translate : { date: added }"></span>
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { DocumentInfoService } from '../../services/document-info.service';
|
||||
import { combineLatest, switchMap } from 'rxjs';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { type Dossier, type File, type FileAttributeConfigType, FileAttributeConfigTypes } from '@red/domain';
|
||||
import { type Dossier, type FileAttributeConfigType, FileAttributeConfigTypes } from '@red/domain';
|
||||
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
import { ContextComponent } from '@iqser/common-ui';
|
||||
@ -17,7 +17,6 @@ interface FileAttribute {
|
||||
}
|
||||
|
||||
interface Context {
|
||||
readonly file: File;
|
||||
readonly dossier: Dossier;
|
||||
readonly dossierTemplateName: string;
|
||||
readonly fileAttributes: FileAttribute[];
|
||||
@ -29,8 +28,9 @@ interface Context {
|
||||
styleUrls: ['./document-info.component.scss'],
|
||||
})
|
||||
export class DocumentInfoComponent extends ContextComponent<Context> {
|
||||
protected readonly _state = inject(FilePreviewStateService);
|
||||
|
||||
constructor(
|
||||
state: FilePreviewStateService,
|
||||
fileAttributesService: FileAttributesService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
readonly documentInfoService: DocumentInfoService,
|
||||
@ -38,25 +38,24 @@ export class DocumentInfoComponent extends ContextComponent<Context> {
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
) {
|
||||
super();
|
||||
const fileAttributes$ = combineLatest([state.file$, state.dossier$, fileAttributesService.fileAttributesConfig$]).pipe(
|
||||
const fileAttributes$ = combineLatest([this._state.file$, this._state.dossier$, fileAttributesService.fileAttributesConfig$]).pipe(
|
||||
switchMap(([file, dossier]) => this.documentInfoService.fileAttributes$(file.id, dossier.id, dossier.dossierTemplateId)),
|
||||
);
|
||||
|
||||
const dossierTemplateName$ = state.dossier$.pipe(
|
||||
const dossierTemplateName$ = this._state.dossier$.pipe(
|
||||
switchMap(dossier => this._dossierTemplatesService.getEntityChanged$(dossier.dossierTemplateId)),
|
||||
map(dossierTemplate => dossierTemplate.name),
|
||||
);
|
||||
|
||||
super._initContext({
|
||||
file: state.file$,
|
||||
dossier: state.dossier$,
|
||||
dossier: this._state.dossier$,
|
||||
dossierTemplateName: dossierTemplateName$,
|
||||
fileAttributes: fileAttributes$,
|
||||
});
|
||||
}
|
||||
|
||||
edit(file: File) {
|
||||
this._dialogService.openDialog('documentInfo', file);
|
||||
edit() {
|
||||
this._dialogService.openDialog('documentInfo', this._state.file());
|
||||
}
|
||||
|
||||
isDate(attribute: FileAttribute) {
|
||||
|
||||
@ -275,7 +275,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnDestroy
|
||||
}
|
||||
|
||||
scrollQuickNavLast() {
|
||||
this.pdf.navigateTo(this.state.file.numberOfPages);
|
||||
this.pdf.navigateTo(this.state.file().numberOfPages);
|
||||
}
|
||||
|
||||
preventKeyDefault($event: KeyboardEvent): void {
|
||||
|
||||
@ -6,7 +6,7 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
|
||||
import { FileDataService } from '../../services/file-data.service';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-highlights-separator [highlightGroup] [annotation]',
|
||||
@ -20,7 +20,7 @@ export class HighlightsSeparatorComponent {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly isWritable$ = this._state.isWritable$;
|
||||
readonly multiSelectInactive$ = this._multiSelectService.inactive$;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
|
||||
constructor(
|
||||
private readonly _dialogService: FilePreviewDialogService,
|
||||
|
||||
@ -5,7 +5,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { IPageRange } from '@red/domain';
|
||||
import { ReanalysisService } from '@services/reanalysis.service';
|
||||
import { ExcludedPagesService } from '../../services/excluded-pages.service';
|
||||
import { combineLatest, firstValueFrom, Observable } from 'rxjs';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { extractPageRanges } from '@utils/page-ranges-mapper';
|
||||
@ -53,11 +53,10 @@ export class PageExclusionComponent {
|
||||
|
||||
async excludePagesRange(inputValue: string): Promise<void> {
|
||||
this._loadingService.start();
|
||||
const file = this._state.file;
|
||||
const file = this._state.file();
|
||||
try {
|
||||
const pageRanges = extractPageRanges(inputValue, file);
|
||||
const excludePages$ = this._reanalysisService.excludePages({ pageRanges }, file.dossierId, file);
|
||||
await firstValueFrom(excludePages$);
|
||||
await this._reanalysisService.excludePages({ pageRanges }, file);
|
||||
this._inputComponent.reset();
|
||||
} catch (e) {
|
||||
this._toaster.error(_('file-preview.tabs.exclude-pages.error'));
|
||||
@ -67,15 +66,7 @@ export class PageExclusionComponent {
|
||||
|
||||
async includePagesRange(range: IPageRange): Promise<void> {
|
||||
this._loadingService.start();
|
||||
const file = this._state.file;
|
||||
const includePages$ = this._reanalysisService.includePages(
|
||||
{
|
||||
pageRanges: [range],
|
||||
},
|
||||
file.dossierId,
|
||||
file,
|
||||
);
|
||||
await firstValueFrom(includePages$);
|
||||
await this._reanalysisService.includePages({ pageRanges: [range] }, this._state.file());
|
||||
this._inputComponent.reset();
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ export class PageIndicatorComponent extends ContextComponent<PageIndicatorContex
|
||||
}
|
||||
|
||||
async toggleReadState() {
|
||||
if (this._permissionService.canMarkPagesAsViewed(this._state.file)) {
|
||||
if (this._permissionService.canMarkPagesAsViewed(this._state.file())) {
|
||||
if (this.read) {
|
||||
await this.#markPageUnread();
|
||||
} else {
|
||||
@ -72,7 +72,7 @@ export class PageIndicatorComponent extends ContextComponent<PageIndicatorContex
|
||||
}
|
||||
|
||||
handlePageRead(): void {
|
||||
if (!this._permissionService.canMarkPagesAsViewed(this._state.file)) {
|
||||
if (!this._permissionService.canMarkPagesAsViewed(this._state.file())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ export class PagesComponent {
|
||||
|
||||
hasOnlyManualRedactionsAndIsExcluded(pageNumber: number): boolean {
|
||||
const hasOnlyManualRedactions = this.displayedAnnotations.get(pageNumber)?.every(annotation => annotation.manual);
|
||||
return hasOnlyManualRedactions && this.#state.file.excludedPages.includes(pageNumber);
|
||||
return hasOnlyManualRedactions && this.#state.file().excludedPages.includes(pageNumber);
|
||||
}
|
||||
|
||||
getViewedPage(viewedPages: ViewedPage[], pageNumber: number) {
|
||||
|
||||
@ -1,51 +1,49 @@
|
||||
<ng-container *ngIf="viewModeService.viewMode$ | async as viewMode">
|
||||
<button
|
||||
(click)="switchView(viewModes.STANDARD)"
|
||||
[attr.help-mode-key]="'views'"
|
||||
[class.active]="viewModeService.isStandard()"
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="'file-preview.standard-tooltip' | translate"
|
||||
class="red-tab"
|
||||
>
|
||||
{{ 'file-preview.standard' | translate }}
|
||||
</button>
|
||||
|
||||
<div [matTooltipPosition]="'above'" [matTooltip]="'file-preview.delta-tooltip' | translate">
|
||||
<button
|
||||
(click)="switchView(viewModes.STANDARD)"
|
||||
[class.active]="viewMode === viewModes.STANDARD"
|
||||
(click)="switchView(viewModes.DELTA)"
|
||||
*deny="roles.getRss"
|
||||
[attr.help-mode-key]="'views'"
|
||||
[matTooltip]="'file-preview.standard-tooltip' | translate"
|
||||
[matTooltipPosition]="'above'"
|
||||
[class.active]="viewModeService.isDelta()"
|
||||
[disabled]="!canSwitchToDeltaView()"
|
||||
class="red-tab"
|
||||
>
|
||||
{{ 'file-preview.standard' | translate }}
|
||||
{{ 'file-preview.delta' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div [matTooltip]="'file-preview.delta-tooltip' | translate" [matTooltipPosition]="'above'">
|
||||
<button
|
||||
(click)="switchView(viewModes.DELTA)"
|
||||
*deny="roles.getRss"
|
||||
[class.active]="viewMode === viewModes.DELTA"
|
||||
[disabled]="(canSwitchToDeltaView$ | async) === false"
|
||||
[attr.help-mode-key]="'views'"
|
||||
class="red-tab"
|
||||
>
|
||||
{{ 'file-preview.delta' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div [matTooltipPosition]="'above'" [matTooltip]="'file-preview.redacted-tooltip' | translate">
|
||||
<button
|
||||
(click)="switchView(viewModes.REDACTED)"
|
||||
*deny="roles.getRss"
|
||||
[attr.help-mode-key]="'views'"
|
||||
[class.active]="viewModeService.isRedacted()"
|
||||
[disabled]="!canSwitchToRedactedView()"
|
||||
class="red-tab"
|
||||
>
|
||||
{{ 'file-preview.redacted' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div [matTooltip]="'file-preview.redacted-tooltip' | translate" [matTooltipPosition]="'above'">
|
||||
<button
|
||||
(click)="switchView(viewModes.REDACTED)"
|
||||
*deny="roles.getRss"
|
||||
[class.active]="viewMode === viewModes.REDACTED"
|
||||
[disabled]="(canSwitchToRedactedView$ | async) === false"
|
||||
[attr.help-mode-key]="'views'"
|
||||
class="red-tab"
|
||||
>
|
||||
{{ 'file-preview.redacted' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div [matTooltip]="'file-preview.text-highlights-tooltip' | translate" [matTooltipPosition]="'above'">
|
||||
<button
|
||||
(click)="switchView(viewModes.TEXT_HIGHLIGHTS)"
|
||||
*deny="roles.getRss"
|
||||
[class.active]="viewMode === viewModes.TEXT_HIGHLIGHTS"
|
||||
[disabled]="(canSwitchToEarmarksView$ | async) === false"
|
||||
[attr.help-mode-key]="'views'"
|
||||
class="red-tab"
|
||||
>
|
||||
{{ 'file-preview.text-highlights' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</ng-container>
|
||||
<div [matTooltipPosition]="'above'" [matTooltip]="'file-preview.text-highlights-tooltip' | translate">
|
||||
<button
|
||||
(click)="switchView(viewModes.TEXT_HIGHLIGHTS)"
|
||||
*deny="roles.getRss"
|
||||
[attr.help-mode-key]="'views'"
|
||||
[class.active]="viewModeService.isEarmarks()"
|
||||
[disabled]="!canSwitchToEarmarksView()"
|
||||
class="red-tab"
|
||||
>
|
||||
{{ 'file-preview.text-highlights' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { Component, computed, Inject } from '@angular/core';
|
||||
import { ViewMode, ViewModes } from '@red/domain';
|
||||
import { ViewModeService } from '../../services/view-mode.service';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { FileDataService } from '../../services/file-data.service';
|
||||
import { BASE_HREF, ConfirmOptions, IConfirmationDialogData, Toaster } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { FilePreviewDialogService } from '../../services/file-preview-dialog.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-view-switch',
|
||||
@ -17,32 +15,32 @@ import { ROLES } from '@users/roles';
|
||||
styleUrls: ['./view-switch.component.scss'],
|
||||
})
|
||||
export class ViewSwitchComponent {
|
||||
readonly roles = Roles;
|
||||
readonly viewModes = ViewModes;
|
||||
readonly canSwitchToDeltaView$: Observable<boolean>;
|
||||
readonly canSwitchToRedactedView$: Observable<boolean>;
|
||||
readonly canSwitchToEarmarksView$: Observable<boolean>;
|
||||
readonly roles = ROLES;
|
||||
readonly canSwitchToDeltaView = computed(() => {
|
||||
const annotations = this._fileDataService.annotations();
|
||||
const file = this._state.file();
|
||||
const hasChangeLog = annotations.some(a => a.isChangeLogEntry);
|
||||
return hasChangeLog && !file.isApproved;
|
||||
});
|
||||
readonly canSwitchToRedactedView = computed(() => {
|
||||
const file = this._state.file();
|
||||
return !file.analysisRequired && !file.excluded;
|
||||
});
|
||||
readonly canSwitchToEarmarksView = computed(() => {
|
||||
const file = this._state.file();
|
||||
return file.hasHighlights && !file.analysisRequired && !file.excluded;
|
||||
});
|
||||
|
||||
constructor(
|
||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||
readonly viewModeService: ViewModeService,
|
||||
private readonly _stateService: FilePreviewStateService,
|
||||
private readonly _state: FilePreviewStateService,
|
||||
private readonly _fileDataService: FileDataService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _dialogService: FilePreviewDialogService,
|
||||
private readonly _toaster: Toaster,
|
||||
) {
|
||||
const hasChangeLog$ = this._fileDataService.annotations$.pipe(map(annotations => annotations.some(a => a.isChangeLogEntry)));
|
||||
this.canSwitchToDeltaView$ = combineLatest([hasChangeLog$, _stateService.file$]).pipe(
|
||||
map(([hasChangeLog, file]) => hasChangeLog && !file.isApproved),
|
||||
);
|
||||
|
||||
this.canSwitchToRedactedView$ = _stateService.file$.pipe(map(file => !file.analysisRequired && !file.excluded));
|
||||
|
||||
this.canSwitchToEarmarksView$ = _stateService.file$.pipe(
|
||||
map(file => file.hasHighlights && !file.analysisRequired && !file.excluded),
|
||||
);
|
||||
}
|
||||
) {}
|
||||
|
||||
switchView(viewMode: ViewMode) {
|
||||
if (viewMode === ViewModes.REDACTED) {
|
||||
@ -57,7 +55,7 @@ export class ViewSwitchComponent {
|
||||
return this.viewModeService.switchToRedacted();
|
||||
}
|
||||
|
||||
const suggestions = (await this._fileDataService.annotations).filter(a => a.isSuggestion);
|
||||
const suggestions = this._fileDataService.annotations().filter(a => a.isSuggestion);
|
||||
if (!suggestions.length) {
|
||||
return this.viewModeService.switchToRedacted();
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ export class DocumentInfoDialogComponent extends BaseDialogComponent implements
|
||||
...this._mapFormValues(this.form.getRawValue()),
|
||||
};
|
||||
await firstValueFrom(this._fileAttributesService.setFileAttributes({ attributeIdToValue }, this.file.dossierId, this.file.fileId));
|
||||
await firstValueFrom(this._filesService.reload(this.file.dossierId, this.file));
|
||||
await this._filesService.reload(this.file.dossierId, this.file);
|
||||
this._dialogRef.close(true);
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { EarmarksService } from '@services/files/earmarks.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { highlightsTranslations } from '@translations/highlights-translations';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
export interface HighlightActionData {
|
||||
readonly operation: EarmarkOperation;
|
||||
@ -24,7 +24,7 @@ export interface HighlightActionData {
|
||||
})
|
||||
export class HighlightActionDialogComponent extends BaseDialogComponent {
|
||||
readonly translations = highlightsTranslations;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly #operation = this.data.operation;
|
||||
readonly options: DetailsRadioOption<EarmarkOperationPages>[] = [
|
||||
{
|
||||
|
||||
@ -10,7 +10,7 @@ import { BaseDialogComponent, CircleButtonTypes, IqserPermissionsService } from
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { ManualRedactionService } from '../../services/manual-redaction.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
export interface LegalBasisOption {
|
||||
label?: string;
|
||||
@ -23,7 +23,7 @@ export interface LegalBasisOption {
|
||||
styleUrls: ['./manual-annotation-dialog.component.scss'],
|
||||
})
|
||||
export class ManualAnnotationDialogComponent extends BaseDialogComponent implements OnInit {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
isDictionaryRequest: boolean;
|
||||
isFalsePositiveRequest: boolean;
|
||||
@ -172,7 +172,7 @@ export class ManualAnnotationDialogComponent extends BaseDialogComponent impleme
|
||||
addRedactionRequest.legalBasis = legalOption.legalBasis;
|
||||
}
|
||||
|
||||
if (this.iqserPermissionsService.has(ROLES.getRss)) {
|
||||
if (this.iqserPermissionsService.has(Roles.getRss)) {
|
||||
const selectedType = this.possibleDictionaries.find(d => d.type === addRedactionRequest.type);
|
||||
addRedactionRequest.addToDictionary = selectedType.hasDictionary;
|
||||
} else {
|
||||
|
||||
@ -41,12 +41,12 @@ import { AnnotationDrawService } from '../pdf-viewer/services/annotation-draw.se
|
||||
import { AnnotationProcessingService } from './services/annotation-processing.service';
|
||||
import { Dictionary, File, ViewModes } from '@red/domain';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { combineLatest, firstValueFrom, Observable, of, pairwise } from 'rxjs';
|
||||
import { combineLatest, firstValueFrom, of, pairwise } from 'rxjs';
|
||||
import { PreferencesKeys, UserPreferenceService } from '@users/user-preference.service';
|
||||
import { byId, byPage, download, handleFilterDelta, hasChanges } from '../../utils';
|
||||
import { FilesService } from '@services/files/files.service';
|
||||
import { FileManagementService } from '@services/files/file-management.service';
|
||||
import { catchError, filter, map, startWith, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { catchError, filter, map, startWith, switchMap, tap } from 'rxjs/operators';
|
||||
import { FilesMapService } from '@services/files/files-map.service';
|
||||
import { ViewModeService } from './services/view-mode.service';
|
||||
import { ReanalysisService } from '@services/reanalysis.service';
|
||||
@ -72,7 +72,7 @@ import { AnnotationsListingService } from './services/annotations-listing.servic
|
||||
import { PdfProxyService } from './services/pdf-proxy.service';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { ReadableRedactionsService } from '../pdf-viewer/services/readable-redactions.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { SuggestionsService } from './services/suggestions.service';
|
||||
|
||||
const textActions = [TextPopups.ADD_DICTIONARY, TextPopups.ADD_FALSE_POSITIVE];
|
||||
@ -87,7 +87,7 @@ export class FilePreviewScreenComponent
|
||||
implements AfterViewInit, OnInit, OnDestroy, OnAttach, OnDetach, ComponentCanDeactivate
|
||||
{
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
fullScreen = false;
|
||||
readonly fileId = this.state.fileId;
|
||||
readonly dossierId = this.state.dossierId;
|
||||
@ -176,7 +176,6 @@ export class FilePreviewScreenComponent
|
||||
const earmarks$ = isEarmarksViewMode$.pipe(
|
||||
tap(() => this._loadingService.start()),
|
||||
switchMap(() => this._fileDataService.loadEarmarks()),
|
||||
switchMap(() => this._fileDataService.earmarks$),
|
||||
tap(() => this.updateViewMode().then(() => this._loadingService.stop())),
|
||||
);
|
||||
|
||||
@ -202,8 +201,8 @@ export class FilePreviewScreenComponent
|
||||
);
|
||||
|
||||
return isChangingFromEarmarksViewMode$.pipe(
|
||||
withLatestFrom(this._fileDataService.earmarks$),
|
||||
map(([, earmarks]) => this.deleteAnnotations(earmarks.get(this.pdf.currentPage) ?? [], [])),
|
||||
map(() => this._fileDataService.earmarks().get(this.pdf.currentPage) ?? []),
|
||||
map(earmarks => this.deleteAnnotations(earmarks, [])),
|
||||
);
|
||||
}
|
||||
|
||||
@ -220,7 +219,7 @@ export class FilePreviewScreenComponent
|
||||
|
||||
switch (this._viewModeService.viewMode()) {
|
||||
case ViewModes.STANDARD: {
|
||||
const wrappers = await this._fileDataService.annotations;
|
||||
const wrappers = this._fileDataService.annotations();
|
||||
const ocrAnnotationIds = wrappers.filter(a => a.isOCR).map(a => a.id);
|
||||
const standardEntries = annotations
|
||||
.filter(a => !bool(a.getCustomData('changeLogRemoved')) && !this._annotationManager.isHidden(a.Id))
|
||||
@ -288,7 +287,7 @@ export class FilePreviewScreenComponent
|
||||
}
|
||||
|
||||
async ngOnAttach(previousRoute: ActivatedRouteSnapshot) {
|
||||
if (!this.state.file.canBeOpened) {
|
||||
if (!this.state.file().canBeOpened) {
|
||||
return this._navigateToDossier();
|
||||
}
|
||||
|
||||
@ -302,7 +301,7 @@ export class FilePreviewScreenComponent
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
const file = this.state.file;
|
||||
const file = this.state.file();
|
||||
|
||||
if (!file) {
|
||||
return this._handleDeletedFile();
|
||||
@ -329,7 +328,7 @@ export class FilePreviewScreenComponent
|
||||
|
||||
openManualAnnotationDialog(manualRedactionEntryWrapper: ManualRedactionEntryWrapper) {
|
||||
return this._ngZone.run(() => {
|
||||
const file = this.state.file;
|
||||
const file = this.state.file();
|
||||
|
||||
this._dialogService.openDialog(
|
||||
'manualAnnotation',
|
||||
@ -403,7 +402,7 @@ export class FilePreviewScreenComponent
|
||||
|
||||
async viewerReady(pageNumber: string = this._activatedRoute.snapshot.queryParams.page) {
|
||||
if (pageNumber) {
|
||||
const file = this.state.file;
|
||||
const file = this.state.file();
|
||||
let page = parseInt(pageNumber, 10);
|
||||
|
||||
if (page < 1 || Number.isNaN(page)) {
|
||||
@ -463,18 +462,22 @@ export class FilePreviewScreenComponent
|
||||
);
|
||||
|
||||
const currentPageAnnotations$ = combineLatest([currentPageIfNotHighlightsView$, annotations$]).pipe(
|
||||
tap(() => console.time('annotation-filter')),
|
||||
map(
|
||||
([page, [oldAnnotations, newAnnotations]]) =>
|
||||
[oldAnnotations.filter(byPage(page)), newAnnotations.filter(byPage(page))] as const,
|
||||
),
|
||||
tap(() => console.timeEnd('annotation-filter')),
|
||||
);
|
||||
|
||||
return combineLatest([currentPageAnnotations$, documentLoaded$]).pipe(
|
||||
filter(([, loaded]) => loaded),
|
||||
tap(() => console.time('loadAnnotations')),
|
||||
map(([annotations]) => annotations),
|
||||
switchMap(annotations => this.drawChangedAnnotations(...annotations)),
|
||||
tap(([, newAnnotations]) => this.#highlightSelectedAnnotations(newAnnotations)),
|
||||
tap(() => this.updateViewMode()),
|
||||
tap(() => console.timeEnd('loadAnnotations')),
|
||||
);
|
||||
}
|
||||
|
||||
@ -622,7 +625,7 @@ export class FilePreviewScreenComponent
|
||||
this.addActiveScreenSubscription = this.state.blob$
|
||||
.pipe(
|
||||
tap(() => this._errorService.clear()),
|
||||
switchMap(blob => this.pdf.loadDocument(blob, this.state.file, () => this.state.reloadBlob())),
|
||||
switchMap(blob => this.pdf.loadDocument(blob, this.state.file(), () => this.state.reloadBlob())),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
@ -641,9 +644,9 @@ export class FilePreviewScreenComponent
|
||||
this.addActiveScreenSubscription = this._viewerHeaderService.events$
|
||||
.pipe(
|
||||
filter(event => event.type === ViewerEvents.LOAD_ALL_ANNOTATIONS),
|
||||
switchMap(() => this._fileDataService.annotations),
|
||||
switchMap<AnnotationWrapper[], Observable<readonly [boolean, AnnotationWrapper[]]>>(annotations => {
|
||||
switchMap(() => {
|
||||
// TODO: this switchMap is ugly, to be refactored
|
||||
const annotations = this._fileDataService.annotations();
|
||||
const showWarning = !this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning);
|
||||
const annotationsExceedThreshold = annotations.length >= this.configService.values.ANNOTATIONS_THRESHOLD;
|
||||
|
||||
@ -749,7 +752,7 @@ export class FilePreviewScreenComponent
|
||||
const secondaryFilters = this._filterService.getGroup('secondaryFilters').filters;
|
||||
const hasAnyFilterSet = [...primaryFilters, ...secondaryFilters].some(f => f.checked || f.indeterminate);
|
||||
const autoExpandFilters = this.userPreferenceService.getAutoExpandFiltersOnActions();
|
||||
const isReviewer = this.permissionsService.isFileAssignee(this.state.file);
|
||||
const isReviewer = this.permissionsService.isFileAssignee(this.state.file());
|
||||
const shouldExpandFilters = hasAnyFilterSet && autoExpandFilters && isReviewer;
|
||||
|
||||
if (!shouldExpandFilters) {
|
||||
|
||||
@ -1,34 +1,28 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Observable, switchMap } from 'rxjs';
|
||||
import { filterEach, shareDistinctLast } from '@iqser/common-ui';
|
||||
import { computed, Injectable, Signal, signal } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { FileDataService } from './file-data.service';
|
||||
|
||||
@Injectable()
|
||||
export class AnnotationReferencesService {
|
||||
readonly annotation$: Observable<AnnotationWrapper>;
|
||||
readonly references$: Observable<AnnotationWrapper[]>;
|
||||
readonly references: Signal<AnnotationWrapper[]>;
|
||||
readonly annotation: Signal<AnnotationWrapper | undefined>;
|
||||
private readonly _annotation$ = new BehaviorSubject<AnnotationWrapper | undefined>(undefined);
|
||||
readonly #annotation = signal<AnnotationWrapper | undefined>(undefined);
|
||||
|
||||
constructor(private readonly _fileDataService: FileDataService) {
|
||||
this.annotation$ = this._annotation$.asObservable().pipe(shareDistinctLast());
|
||||
this.references$ = this.#references$;
|
||||
}
|
||||
|
||||
get #references$(): Observable<AnnotationWrapper[]> {
|
||||
const annotations$ = this._fileDataService.annotations$.pipe(map(dict => Object.values(dict)));
|
||||
return this.annotation$.pipe(
|
||||
filter(annotation => !!annotation),
|
||||
switchMap(({ reference }) => annotations$.pipe(filterEach(a => reference.includes(a.id)))),
|
||||
);
|
||||
this.annotation = this.#annotation.asReadonly();
|
||||
this.references = computed(() => {
|
||||
const annotation = this.annotation();
|
||||
return annotation ? this._fileDataService.annotations().filter(a => annotation.reference.includes(a.id)) : [];
|
||||
});
|
||||
}
|
||||
|
||||
show(annotation: AnnotationWrapper) {
|
||||
this._annotation$.next(annotation);
|
||||
this.#annotation.set(annotation);
|
||||
}
|
||||
|
||||
hide() {
|
||||
this._annotation$.next(undefined);
|
||||
this.#annotation.set(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,15 +10,14 @@ import {
|
||||
ViewModes,
|
||||
} from '@red/domain';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { firstValueFrom, Observable, Subject } from 'rxjs';
|
||||
import { Injectable, signal } from '@angular/core';
|
||||
import { firstValueFrom, Observable } from 'rxjs';
|
||||
import { effect, Injectable, Signal, signal } from '@angular/core';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { ViewedPagesService } from '@services/files/viewed-pages.service';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { map, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { EntitiesService, shareLast, Toaster } from '@iqser/common-ui';
|
||||
import { EntitiesService, Toaster } from '@iqser/common-ui';
|
||||
import { RedactionLogService } from '@services/files/redaction-log.service';
|
||||
import { EarmarksService } from '@services/files/earmarks.service';
|
||||
import { ViewModeService } from './view-mode.service';
|
||||
@ -30,7 +29,7 @@ import { DefaultColorsService } from '@services/entity-services/default-colors.s
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
import { SuggestionsService } from './suggestions.service';
|
||||
import { ViewedPagesMapService } from '@services/files/viewed-pages-map.service';
|
||||
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
||||
import { toObservable } from '@angular/core/rxjs-interop';
|
||||
|
||||
const DELTA_VIEW_TIME = 10 * 60 * 1000; // 10 minutes;
|
||||
|
||||
@ -45,10 +44,11 @@ export function chronologicallyBy<T>(property: (x: T) => string) {
|
||||
@Injectable()
|
||||
export class FileDataService extends EntitiesService<AnnotationWrapper, AnnotationWrapper> {
|
||||
missingTypes = new Set<string>();
|
||||
readonly earmarks: Signal<Map<number, AnnotationWrapper[]>>;
|
||||
readonly annotations: Signal<AnnotationWrapper[]>;
|
||||
readonly annotations$: Observable<AnnotationWrapper[]>;
|
||||
readonly earmarks$: Observable<Map<number, AnnotationWrapper[]>>;
|
||||
protected readonly _entityClass = AnnotationWrapper;
|
||||
readonly #redactionLog$ = new Subject<IRedactionLog>();
|
||||
readonly #annotations = signal<AnnotationWrapper[]>([]);
|
||||
readonly #earmarks = signal<Map<number, AnnotationWrapper[]>>(new Map());
|
||||
#originalViewedPages: ViewedPage[] = [];
|
||||
|
||||
@ -70,38 +70,15 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
private readonly _defaultColorsService: DefaultColorsService,
|
||||
) {
|
||||
super();
|
||||
this.annotations$ = this.#annotations$;
|
||||
this.earmarks$ = toObservable(this.#earmarks);
|
||||
this._viewModeService.viewMode$
|
||||
.pipe(
|
||||
switchMap(viewMode =>
|
||||
viewMode === ViewModes.TEXT_HIGHLIGHTS
|
||||
? this.earmarks$.pipe(map(textHighlights => ([] as AnnotationWrapper[]).concat(...textHighlights.values())))
|
||||
: this.annotations$.pipe(map(annotations => this.#getVisibleAnnotations(annotations, viewMode))),
|
||||
),
|
||||
tap(annotations => this.setEntities(annotations)),
|
||||
takeUntilDestroyed(),
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
get annotations() {
|
||||
return firstValueFrom(this.annotations$);
|
||||
}
|
||||
|
||||
get #annotations$() {
|
||||
return this.#redactionLog$.pipe(
|
||||
tap(() => console.time('buildAnnotations')),
|
||||
withLatestFrom(this._state.file$),
|
||||
tap(([redactionLog, file]) => this.#buildRemovedRedactions(redactionLog, file)),
|
||||
switchMap(([redactionLog, file]) => this.#convertData(redactionLog, file)),
|
||||
tap(() => this.#checkMissingTypes()),
|
||||
map(annotations =>
|
||||
this._userPreferenceService.areDevFeaturesEnabled ? annotations : annotations.filter(a => !a.isFalsePositive),
|
||||
),
|
||||
tap(() => console.timeEnd('buildAnnotations')),
|
||||
shareLast(),
|
||||
);
|
||||
this.annotations$ = toObservable(this.#annotations);
|
||||
this.annotations = this.#annotations.asReadonly();
|
||||
this.earmarks = this.#earmarks.asReadonly();
|
||||
effect(() => {
|
||||
const viewMode = this._viewModeService.viewMode();
|
||||
const earmarks = ([] as AnnotationWrapper[]).concat(...this.#earmarks().values());
|
||||
const annotations = this.#getVisibleAnnotations(this.#annotations(), viewMode);
|
||||
this.setEntities(viewMode === ViewModes.TEXT_HIGHLIGHTS ? earmarks : annotations);
|
||||
});
|
||||
}
|
||||
|
||||
setEntities(entities: AnnotationWrapper[]): void {
|
||||
@ -137,14 +114,14 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
|
||||
async annotationsChanged() {
|
||||
this._multiSelectService.deactivate();
|
||||
const file = this._state.file;
|
||||
const fileReloaded = await firstValueFrom(this._filesService.reload(file.dossierId, file));
|
||||
const file = this._state.file();
|
||||
const fileReloaded = await this._filesService.reload(file.dossierId, file);
|
||||
if (!fileReloaded) {
|
||||
await this.loadAnnotations(file);
|
||||
}
|
||||
}
|
||||
|
||||
async loadEarmarks() {
|
||||
async loadEarmarks(): Promise<Map<number, AnnotationWrapper[]>> {
|
||||
const rawHighlights = await this._earmarksService.getEarmarks(this._state.dossierId, this._state.fileId);
|
||||
const earmarks = rawHighlights.groupBy(h => h.pageNumber);
|
||||
this.#earmarks.set(earmarks);
|
||||
@ -153,14 +130,14 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
}
|
||||
|
||||
async loadRedactionLog() {
|
||||
this._logger.info('[REDACTION-LOG] Loading redaction log...');
|
||||
console.time('redaction-log');
|
||||
const redactionLog$ = this._redactionLogService.getRedactionLog(this._state.dossierId, this._state.fileId);
|
||||
const redactionLog = await firstValueFrom(redactionLog$);
|
||||
this.#redactionLog$.next(redactionLog);
|
||||
console.timeEnd('redaction-log');
|
||||
this._logger.info('[REDACTION-LOG] Redaction log loaded', redactionLog);
|
||||
return redactionLog;
|
||||
this._logger.info('[REDACTION_LOG] Loading redaction log...');
|
||||
const redactionLog = await this._redactionLogService.getRedactionLog(this._state.dossierId, this._state.fileId);
|
||||
|
||||
this._logger.info('[REDACTION_LOG] Redaction log loaded', redactionLog);
|
||||
let [annotations] = await Promise.all([this.#convertData(redactionLog), this.#buildRemovedRedactions(redactionLog)]);
|
||||
this.#checkMissingTypes();
|
||||
annotations = this._userPreferenceService.areDevFeaturesEnabled ? annotations : annotations.filter(a => !a.isFalsePositive);
|
||||
this.#annotations.set(annotations);
|
||||
}
|
||||
|
||||
#checkMissingTypes() {
|
||||
@ -199,7 +176,7 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
});
|
||||
}
|
||||
|
||||
async #buildRemovedRedactions(redactionLog: IRedactionLog, file: File): Promise<void> {
|
||||
async #buildRemovedRedactions(redactionLog: IRedactionLog): Promise<void> {
|
||||
const redactionLogCopy: IRedactionLog = JSON.parse(JSON.stringify(redactionLog));
|
||||
const redactionLogEntries: IRedactionLogEntry[] = [];
|
||||
|
||||
@ -217,15 +194,16 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
}
|
||||
|
||||
redactionLogCopy.redactionLogEntry = redactionLogEntries;
|
||||
const annotations = await this.#convertData(redactionLogCopy, file);
|
||||
const annotations = await this.#convertData(redactionLogCopy);
|
||||
this._suggestionsService.removedRedactions = annotations.filter(a => !a.isSkipped);
|
||||
}
|
||||
|
||||
async #convertData(redactionLog: IRedactionLog, file: File) {
|
||||
async #convertData(redactionLog: IRedactionLog) {
|
||||
if (!redactionLog.redactionLogEntry) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const file = this._state.file();
|
||||
const annotations: AnnotationWrapper[] = [];
|
||||
const sourceIds: { [key: string]: AnnotationWrapper[] } = {};
|
||||
const dictionaries = this._state.dictionaries;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { Injectable, Injector, Signal } from '@angular/core';
|
||||
import { combineLatest, firstValueFrom, from, merge, Observable, of, pairwise, Subject, switchMap } from 'rxjs';
|
||||
import { Dictionary, Dossier, DOSSIER_ID, DOSSIER_TEMPLATE_ID, File, FILE_ID } from '@red/domain';
|
||||
import { Router } from '@angular/router';
|
||||
@ -14,6 +14,7 @@ import { HttpEvent, HttpEventType, HttpProgressEvent, HttpResponse } from '@angu
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
||||
import { DossierDictionariesMapService } from '@services/entity-services/dossier-dictionaries-map.service';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
|
||||
const ONE_MEGABYTE = 1024 * 1024;
|
||||
|
||||
@ -41,7 +42,7 @@ export class FilePreviewStateService {
|
||||
readonly dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
readonly fileId = getParam(FILE_ID);
|
||||
dossier: Dossier;
|
||||
file: File;
|
||||
readonly file: Signal<File>;
|
||||
readonly dossierDictionary$: Observable<Dictionary>;
|
||||
#dossierDictionary: Dictionary;
|
||||
readonly #reloadBlob$ = new Subject();
|
||||
@ -66,7 +67,8 @@ export class FilePreviewStateService {
|
||||
) {
|
||||
const dossiersService = dossiersServiceResolver(_injector, router);
|
||||
this.dossier$ = dossiersService.getEntityChanged$(this.dossierId).pipe(tap(dossier => (this.dossier = dossier)));
|
||||
this.file$ = _filesMapService.watch$(this.dossierId, this.fileId).pipe(tap(file => (this.file = file)));
|
||||
this.file$ = _filesMapService.watch$(this.dossierId, this.fileId);
|
||||
this.file = toSignal(this.file$);
|
||||
// this.file$ = combineLatest([this.isAttached, file$]).pipe(
|
||||
// filter(([isAttached]) => isAttached),
|
||||
// map(([, file]) => file),
|
||||
@ -157,7 +159,7 @@ export class FilePreviewStateService {
|
||||
const progress = Math.round((event.loaded / event.total) * 100);
|
||||
const loading: string = this._translateService.instant('loading');
|
||||
this._loadingService.update({
|
||||
title: loading + ' ' + this.file.filename,
|
||||
title: loading + ' ' + this.file().filename,
|
||||
type: 'progress-bar',
|
||||
value: progress,
|
||||
remainingTime: this.#getRemainingTimeVerbose(event, startTime),
|
||||
|
||||
@ -20,7 +20,7 @@ import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
import { type ManualRedactionEntryType } from '@models/file/manual-redaction-entry.wrapper';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { firstValueFrom, of } from 'rxjs';
|
||||
|
||||
function getResponseType(error: boolean, isConflict: boolean) {
|
||||
@ -95,12 +95,12 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
|
||||
addAnnotation(requests: List<IAddRedactionRequest>, dossierId: string, fileId: string, dictionaryLabel?: string) {
|
||||
const toast = requests[0].addToDictionary ? this.#showAddToDictionaryToast(requests, dictionaryLabel) : this.#showToast('add');
|
||||
const canAddRedaction = this._iqaerPermissionsService.has(ROLES.redactions.write);
|
||||
const canAddRedaction = this._iqaerPermissionsService.has(Roles.redactions.write);
|
||||
if (canAddRedaction && this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||
return this.add(requests, dossierId, fileId).pipe(toast);
|
||||
}
|
||||
|
||||
const canRequestRedaction = this._iqaerPermissionsService.has(ROLES.redactions.request);
|
||||
const canRequestRedaction = this._iqaerPermissionsService.has(Roles.redactions.request);
|
||||
if (canRequestRedaction) {
|
||||
return this.requestAdd(requests, dossierId, fileId).pipe(toast);
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import { AnnotationActionsService } from './annotation-actions.service';
|
||||
import { BASE_HREF_FN, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { IHeaderElement } from '@red/domain';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
|
||||
|
||||
@Injectable()
|
||||
@ -159,7 +159,7 @@ export class PdfAnnotationActionsService {
|
||||
canAcceptRecommendation: permissions.reduce((acc, next) => acc && next.canAcceptRecommendation, true),
|
||||
canAcceptSuggestion: permissions.reduce((acc, next) => acc && next.canAcceptSuggestion, true),
|
||||
canUndo:
|
||||
this.#iqserPermissionsService.has(ROLES.redactions.deleteManual) &&
|
||||
this.#iqserPermissionsService.has(Roles.redactions.deleteManual) &&
|
||||
permissions.reduce((acc, next) => acc && next.canUndo, true),
|
||||
canMarkAsFalsePositive: permissions.reduce((acc, next) => acc && next.canMarkAsFalsePositive, true),
|
||||
canForceRedaction: permissions.reduce((acc, next) => acc && next.canForceRedaction, true),
|
||||
|
||||
@ -33,7 +33,7 @@ import { PermissionsService } from '@services/permissions.service';
|
||||
import { AnnotationsListingService } from './annotations-listing.service';
|
||||
import { PdfAnnotationActionsService } from './pdf-annotation-actions.service';
|
||||
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { AnnotationActionsService } from './annotation-actions.service';
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
import Quad = Core.Math.Quad;
|
||||
@ -53,7 +53,7 @@ export class PdfProxyService {
|
||||
readonly #visibilityOffIcon = this._convertPath('/assets/icons/general/visibility-off.svg');
|
||||
readonly #visibilityIcon = this._convertPath('/assets/icons/general/visibility.svg');
|
||||
readonly #falsePositiveIcon = this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg');
|
||||
readonly #addRedactionIcon = this._iqserPermissionsService.has(ROLES.getRss)
|
||||
readonly #addRedactionIcon = this._iqserPermissionsService.has(Roles.getRss)
|
||||
? this._convertPath('/assets/icons/general/pdftron-action-add-component.svg')
|
||||
: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg');
|
||||
readonly #addDictIcon = this._convertPath('/assets/icons/general/pdftron-action-add-dict.svg');
|
||||
@ -148,7 +148,7 @@ export class PdfProxyService {
|
||||
private _configureTextPopup() {
|
||||
const popups: IHeaderElement[] = [];
|
||||
|
||||
if (!this._state.file.isApproved) {
|
||||
if (!this._state.file().isApproved) {
|
||||
// Adding directly to the false-positive dict is only available in dev-mode
|
||||
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
||||
popups.push({
|
||||
@ -160,7 +160,7 @@ export class PdfProxyService {
|
||||
});
|
||||
}
|
||||
|
||||
if (this._iqserPermissionsService.has(ROLES.redactions.write) || this._iqserPermissionsService.has(ROLES.redactions.request)) {
|
||||
if (this._iqserPermissionsService.has(Roles.redactions.write) || this._iqserPermissionsService.has(Roles.redactions.request)) {
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_REDACTION,
|
||||
@ -169,7 +169,7 @@ export class PdfProxyService {
|
||||
onClick: () => this._addManualRedactionOfType(ManualRedactionEntryTypes.REDACTION),
|
||||
});
|
||||
|
||||
if (!this._iqserPermissionsService.has(ROLES.getRss)) {
|
||||
if (!this._iqserPermissionsService.has(Roles.getRss)) {
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_DICTIONARY,
|
||||
@ -194,7 +194,7 @@ export class PdfProxyService {
|
||||
}
|
||||
|
||||
private _handleCustomActions() {
|
||||
const isCurrentPageExcluded = this._state.file.isPageExcluded(this._pdf.currentPage);
|
||||
const isCurrentPageExcluded = this._state.file().isPageExcluded(this._pdf.currentPage);
|
||||
|
||||
if (this._viewModeService.isRedacted()) {
|
||||
this._viewerHeaderService.enable([HeaderElements.TOGGLE_READABLE_REDACTIONS]);
|
||||
|
||||
@ -29,7 +29,7 @@ export class StampService {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = this._state.file;
|
||||
const file = this._state.file();
|
||||
const allPages = [...Array(file.numberOfPages).keys()].map(page => page + 1);
|
||||
|
||||
try {
|
||||
|
||||
@ -2,7 +2,7 @@ import { Injectable, Injector } from '@angular/core';
|
||||
import { BehaviorSubject, firstValueFrom, Observable, of } from 'rxjs';
|
||||
import { RotationType } from '@red/domain';
|
||||
import { FileManagementService } from '@services/files/file-management.service';
|
||||
import { distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
|
||||
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
|
||||
import {
|
||||
ConfirmationDialogComponent,
|
||||
ConfirmOption,
|
||||
@ -21,8 +21,8 @@ import { REDDocumentViewer } from './document-viewer.service';
|
||||
|
||||
@Injectable()
|
||||
export class PageRotationService {
|
||||
readonly #rotations$ = new BehaviorSubject<Record<number, number>>({});
|
||||
readonly rotations$: Observable<Record<number, number>>;
|
||||
readonly #rotations$ = new BehaviorSubject<Record<number, number>>({});
|
||||
|
||||
constructor(
|
||||
private readonly _pdf: PdfViewer,
|
||||
@ -48,6 +48,10 @@ export class PageRotationService {
|
||||
return Math.abs(rotationsSum < 360 ? rotationsSum : 360 - rotationsSum);
|
||||
}
|
||||
|
||||
get #rotations() {
|
||||
return this.#rotations$.value;
|
||||
}
|
||||
|
||||
isRotated$(page: number) {
|
||||
return this.#rotations$.pipe(
|
||||
map(rotations => !!rotations[page]),
|
||||
@ -55,7 +59,7 @@ export class PageRotationService {
|
||||
);
|
||||
}
|
||||
|
||||
applyRotation() {
|
||||
async applyRotation() {
|
||||
this._loadingService.start();
|
||||
const pages = this.#rotations$.value;
|
||||
const { dossierId, fileId } = this._pdf;
|
||||
@ -73,9 +77,10 @@ export class PageRotationService {
|
||||
|
||||
const request$ = this._fileManagementService.rotatePage({ pages }, dossierId, fileId);
|
||||
this.clearRotations();
|
||||
const reloaded$ = request$.pipe(switchMap(() => this._filesService.reload(dossierId, file)));
|
||||
await firstValueFrom(request$);
|
||||
await this._filesService.reload(dossierId, file);
|
||||
|
||||
return firstValueFrom(reloaded$.pipe(tap(() => this._loadingService.stop())));
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
discardRotation() {
|
||||
@ -101,10 +106,6 @@ export class PageRotationService {
|
||||
return this.hasRotations ? this.#showConfirmationDialog() : of(false);
|
||||
}
|
||||
|
||||
get #rotations() {
|
||||
return this.#rotations$.value;
|
||||
}
|
||||
|
||||
#showConfirmationDialog() {
|
||||
const ref = this._injector.get(MatDialog).open(ConfirmationDialogComponent, {
|
||||
...defaultDialogConfig,
|
||||
|
||||
@ -7,7 +7,7 @@ import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { FilesMapService } from '@services/files/files-map.service';
|
||||
import { ReanalysisService } from '@services/reanalysis.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossiers-listing-actions [dossier]',
|
||||
@ -15,7 +15,7 @@ import { ROLES } from '@users/roles';
|
||||
})
|
||||
export class DossiersListingActionsComponent implements OnChanges {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly scrollableParentViews = ScrollableParentViews;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ import { PageRotationService } from '../../../pdf-viewer/services/page-rotation.
|
||||
import { FileAssignService } from '../../services/file-assign.service';
|
||||
import { ViewerHeaderService } from '../../../pdf-viewer/services/viewer-header.service';
|
||||
import { ROTATION_ACTION_BUTTONS } from '../../../pdf-viewer/utils/constants';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
|
||||
@Component({
|
||||
@ -145,7 +145,7 @@ export class FileActionsComponent implements OnChanges {
|
||||
action: () => this.#openImportRedactionsDialog(),
|
||||
tooltip: _('dossier-overview.import-redactions'),
|
||||
icon: 'red:import_redactions',
|
||||
show: this.showImportRedactions && !this._iqserPermissionsService.has(ROLES.getRss),
|
||||
show: this.showImportRedactions && !this._iqserPermissionsService.has(Roles.getRss),
|
||||
},
|
||||
{
|
||||
id: 'download-file-btn',
|
||||
@ -176,7 +176,7 @@ export class FileActionsComponent implements OnChanges {
|
||||
show:
|
||||
!!this._excludedPagesService &&
|
||||
this._permissionsService.canExcludePages(this.file, this.dossier) &&
|
||||
!this._iqserPermissionsService.has(ROLES.getRss),
|
||||
!this._iqserPermissionsService.has(Roles.getRss),
|
||||
},
|
||||
{
|
||||
id: 'set-file-to-new-btn',
|
||||
|
||||
@ -22,7 +22,7 @@ import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
type Section = 'dossierInfo' | 'downloadPackage' | 'dossierDictionary' | 'members' | 'dossierAttributes';
|
||||
|
||||
@ -40,7 +40,7 @@ interface NavItem {
|
||||
providers: [dossiersServiceProvider],
|
||||
})
|
||||
export class EditDossierDialogComponent extends BaseDialogComponent implements AfterViewInit {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
navItems: NavItem[] = [];
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
activeNav: Section;
|
||||
@ -100,7 +100,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
|
||||
return (
|
||||
(['members'].includes(this.activeNav) &&
|
||||
this.#currentUser.isManager &&
|
||||
this.iqserPermissionsService.has(ROLES.dossiers.edit)) ||
|
||||
this.iqserPermissionsService.has(Roles.dossiers.edit)) ||
|
||||
this._permissionsService.canEditDossier(this._dossier)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Component, ElementRef, EventEmitter, inject, Input, OnChanges, Output, ViewChild } from '@angular/core';
|
||||
import { CircleButtonTypes, getCurrentUser, List } from '@iqser/common-ui';
|
||||
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { User } from '@red/domain';
|
||||
import { UserService } from '@users/user.service';
|
||||
|
||||
@ -12,7 +12,7 @@ import { UserService } from '@users/user.service';
|
||||
})
|
||||
export class TeamMembersComponent implements OnChanges {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly userService = inject(UserService);
|
||||
|
||||
@ -31,11 +31,6 @@ export class TeamMembersComponent implements OnChanges {
|
||||
|
||||
constructor(private readonly _dialogService: DossiersDialogService) {}
|
||||
|
||||
ngOnChanges() {
|
||||
this.memberIds ??= [];
|
||||
this.memberIds = [...this.memberIds].sort((a, b) => this.userService.getName(a).localeCompare(this.userService.getName(b)));
|
||||
}
|
||||
|
||||
get maxTeamMembersBeforeExpand(): number {
|
||||
return this.perLine - (this.canAdd ? 1 : 0);
|
||||
}
|
||||
@ -48,6 +43,11 @@ export class TeamMembersComponent implements OnChanges {
|
||||
return this.memberIds.length > this.maxTeamMembersBeforeExpand ? this.memberIds.length - (this.maxTeamMembersBeforeExpand - 1) : 0;
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
this.memberIds ??= [];
|
||||
this.memberIds = [...this.memberIds].sort((a, b) => this.userService.getName(a).localeCompare(this.userService.getName(b)));
|
||||
}
|
||||
|
||||
toggleExpandedTeam() {
|
||||
this.expandedTeam = !this.expandedTeam;
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import { firstValueFrom } from 'rxjs';
|
||||
import dayjs from 'dayjs';
|
||||
import { Router } from '@angular/router';
|
||||
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
|
||||
interface DialogData {
|
||||
readonly dossierTemplateId?: string;
|
||||
@ -22,7 +22,7 @@ interface DialogData {
|
||||
styleUrls: ['./add-dossier-dialog.component.scss'],
|
||||
})
|
||||
export class AddDossierDialogComponent extends BaseDialogComponent implements OnInit {
|
||||
readonly roles = ROLES;
|
||||
readonly roles = Roles;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
|
||||
hasDueDate = false;
|
||||
@ -33,8 +33,8 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
|
||||
}))
|
||||
.filter(
|
||||
element =>
|
||||
!this.permissionsService.has(ROLES.getRss) ||
|
||||
(this.permissionsService.has(ROLES.getRss) && !['DELTA_PREVIEW', 'REDACTED'].includes(element.key)),
|
||||
!this.permissionsService.has(Roles.getRss) ||
|
||||
(this.permissionsService.has(Roles.getRss) && !['DELTA_PREVIEW', 'REDACTED'].includes(element.key)),
|
||||
);
|
||||
dossierTemplates: IDossierTemplate[];
|
||||
availableReportTypes: IReportTemplate[] = [];
|
||||
|
||||
@ -18,7 +18,7 @@ export class EarmarksService extends GenericService<EarmarkResponse> {
|
||||
map(response => response.highlights),
|
||||
map(highlights => highlights.map(highlight => AnnotationWrapper.fromEarmark(highlight))),
|
||||
map(highlights => highlights.sort((h1, h2) => h1.color.localeCompare(h2.color))),
|
||||
catchError(() => of([])),
|
||||
catchError(() => of([] as AnnotationWrapper[])),
|
||||
);
|
||||
|
||||
return firstValueFrom(request);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { EntitiesService, isArray, List, mapEach, QueryParam } from '@iqser/common-ui';
|
||||
import { File, IFile } from '@red/domain';
|
||||
import { firstValueFrom, Observable } from 'rxjs';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { FilesMapService } from './files-map.service';
|
||||
import { map, switchMap, tap } from 'rxjs/operators';
|
||||
@ -36,13 +36,12 @@ export class FilesService extends EntitiesService<IFile, File> {
|
||||
return loadStats$.pipe(tap(files => this._filesMapService.set(dossierId, files)));
|
||||
}
|
||||
|
||||
reload(dossierId: string, file: File): Observable<boolean> {
|
||||
return super._getOne([dossierId, file.id]).pipe(
|
||||
map(_file => new File(_file, this._userService.getName(_file.assignee))),
|
||||
switchMap(_file => this._dossierStatsService.getFor([dossierId]).pipe(map(() => _file))),
|
||||
map(_file => this._filesMapService.replace(dossierId, [_file])),
|
||||
tap(() => this._logger.info('[FILE] Reloaded')),
|
||||
);
|
||||
async reload(dossierId: string, file: File) {
|
||||
const _file = await firstValueFrom(super._getOne([dossierId, file.id]));
|
||||
const reloadedFile = new File(_file, this._userService.getName(_file.assignee));
|
||||
await firstValueFrom(this._dossierStatsService.getFor([dossierId]));
|
||||
this._logger.info('[FILE] Reloaded');
|
||||
return this._filesMapService.replace(dossierId, [reloadedFile]);
|
||||
}
|
||||
|
||||
async setAssignee(files: File | List<File>, assigneeId: string) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { GenericService, QueryParam } from '@iqser/common-ui';
|
||||
import { IRedactionLog, ISectionGrid } from '@red/domain';
|
||||
import { catchError, tap } from 'rxjs/operators';
|
||||
import { of } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { firstValueFrom, of } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -10,17 +10,16 @@ import { of } from 'rxjs';
|
||||
export class RedactionLogService extends GenericService<unknown> {
|
||||
protected readonly _defaultModelPath = '';
|
||||
|
||||
getRedactionLog(dossierId: string, fileId: string, withManualRedactions?: boolean) {
|
||||
async getRedactionLog(dossierId: string, fileId: string, withManualRedactions?: boolean) {
|
||||
const queryParams: QueryParam[] = [];
|
||||
if (withManualRedactions) {
|
||||
queryParams.push({ key: 'withManualRedactions', value: withManualRedactions });
|
||||
}
|
||||
|
||||
const redactionLog$ = this._getOne<IRedactionLog>([dossierId, fileId], 'redactionLog', queryParams);
|
||||
return redactionLog$.pipe(
|
||||
tap(redactionLog => redactionLog.redactionLogEntry.sort((a, b) => a.positions[0].page - b.positions[0].page)),
|
||||
catchError(() => of({} as IRedactionLog)),
|
||||
);
|
||||
const redactionLog = await firstValueFrom(redactionLog$.pipe(catchError(() => of({} as IRedactionLog))));
|
||||
redactionLog.redactionLogEntry.sort((a, b) => a.positions[0].page - b.positions[0].page);
|
||||
return redactionLog;
|
||||
}
|
||||
|
||||
getSectionGrid(dossierId: string, fileId: string) {
|
||||
|
||||
@ -4,7 +4,7 @@ import { DashboardStats, Dictionary, Dossier, DOSSIERS_ARCHIVE, DossierTemplate,
|
||||
import { FilesMapService } from '@services/files/files-map.service';
|
||||
import { FeaturesService } from '@services/features.service';
|
||||
import { IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { DossierDictionariesMapService } from '@services/entity-services/dossier-dictionaries-map.service';
|
||||
|
||||
@ -25,16 +25,16 @@ export class PermissionsService {
|
||||
|
||||
canAddEditJustifications() {
|
||||
return (
|
||||
this._userPreferenceService.areDevFeaturesEnabled && this.isAdmin() && this._iqserPermissionsService.has(ROLES.legalBasis.write)
|
||||
this._userPreferenceService.areDevFeaturesEnabled && this.isAdmin() && this._iqserPermissionsService.has(Roles.legalBasis.write)
|
||||
);
|
||||
}
|
||||
|
||||
canEditGlobalFileAttributes() {
|
||||
return this._iqserPermissionsService.has(ROLES.fileAttributes.write) && this.isAdmin();
|
||||
return this._iqserPermissionsService.has(Roles.fileAttributes.write) && this.isAdmin();
|
||||
}
|
||||
|
||||
canEditGlobalDossierAttributes() {
|
||||
return this._iqserPermissionsService.has(ROLES.dossierAttributes.writeConfig) && this.isAdmin();
|
||||
return this._iqserPermissionsService.has(Roles.dossierAttributes.writeConfig) && this.isAdmin();
|
||||
}
|
||||
|
||||
canDownloadEntityDictionary(): boolean {
|
||||
@ -42,11 +42,11 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canPerformDossierStatesActions() {
|
||||
return this.isAdmin() && this._iqserPermissionsService.has(ROLES.states.write);
|
||||
return this.isAdmin() && this._iqserPermissionsService.has(Roles.states.write);
|
||||
}
|
||||
|
||||
canEditEntities(): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dictionaryTypes.write) && this.isAdmin();
|
||||
return this._iqserPermissionsService.has(Roles.dictionaryTypes.write) && this.isAdmin();
|
||||
}
|
||||
|
||||
canDeleteEntities(entity: Dictionary | Dictionary[]): boolean {
|
||||
@ -54,7 +54,7 @@ export class PermissionsService {
|
||||
return (
|
||||
entities.length &&
|
||||
this.isAdmin() &&
|
||||
this._iqserPermissionsService.has(ROLES.dictionaryTypes.delete) &&
|
||||
this._iqserPermissionsService.has(Roles.dictionaryTypes.delete) &&
|
||||
entities.reduce((acc, _entity) => this._canDeleteEntity(_entity) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -66,14 +66,14 @@ export class PermissionsService {
|
||||
displayReanalyseBtn(dossier: Dossier): boolean {
|
||||
return (
|
||||
dossier.isActive &&
|
||||
this._iqserPermissionsService.has(ROLES.dossiers.reanalyze) &&
|
||||
this._iqserPermissionsService.has(Roles.dossiers.reanalyze) &&
|
||||
this.isApprover(dossier) &&
|
||||
!!this._filesMapService.get(dossier.id).find(f => f.analysisRequired)
|
||||
);
|
||||
}
|
||||
|
||||
canUploadFiles(dossier: Dossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.files.upload) && dossier.isActive;
|
||||
return this._iqserPermissionsService.has(Roles.files.upload) && dossier.isActive;
|
||||
}
|
||||
|
||||
canDownloadCsvReport(dossier: Dossier): boolean {
|
||||
@ -88,7 +88,7 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canToggleAnalysis(file: File | File[], dossier: Dossier): boolean {
|
||||
if (!this._iqserPermissionsService.has(ROLES.files.reanalyze)) {
|
||||
if (!this._iqserPermissionsService.has(Roles.files.reanalyze)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -98,27 +98,27 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
showToggleAnalysis(dossier: Dossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.excludeIncludeFile) && dossier.isActive;
|
||||
return this._iqserPermissionsService.has(Roles.excludeIncludeFile) && dossier.isActive;
|
||||
}
|
||||
|
||||
canReanalyseFile(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.reanalyze) &&
|
||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||
files.reduce((acc, _file) => this._canReanalyseFile(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
|
||||
canEnableAutoAnalysis(files: File[], dossier: Dossier): boolean {
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.reanalyze) &&
|
||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||
files.reduce((acc, _file) => this._canEnableAutoAnalysis(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
|
||||
canDisableAutoAnalysis(files: File[], dossier: Dossier): boolean {
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.reanalyze) &&
|
||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||
files.reduce((acc, _file) => this._canDisableAutoAnalysis(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -130,7 +130,7 @@ export class PermissionsService {
|
||||
canSoftDeleteFile(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.delete) &&
|
||||
this._iqserPermissionsService.has(Roles.files.delete) &&
|
||||
files.reduce((acc, _file) => this._canSoftDeleteFile(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -138,7 +138,7 @@ export class PermissionsService {
|
||||
canRestoreFile(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.delete) &&
|
||||
this._iqserPermissionsService.has(Roles.files.delete) &&
|
||||
files.reduce((acc, _file) => this._canRestoreFile(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -146,7 +146,7 @@ export class PermissionsService {
|
||||
canHardDeleteFile(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.delete) &&
|
||||
this._iqserPermissionsService.has(Roles.files.delete) &&
|
||||
files.reduce((acc, _file) => this._canHardDeleteFile(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -154,7 +154,7 @@ export class PermissionsService {
|
||||
canOcrFile(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.reanalyze) &&
|
||||
this._iqserPermissionsService.has(Roles.files.reanalyze) &&
|
||||
files.reduce((acc, _file) => this._canOcrFile(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -162,7 +162,7 @@ export class PermissionsService {
|
||||
canAssignToSelf(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.setReviewer) &&
|
||||
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
||||
files.reduce((acc, _file) => this._canAssignToSelf(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -170,7 +170,7 @@ export class PermissionsService {
|
||||
canAssignUser(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.setReviewer) &&
|
||||
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
||||
files.reduce((acc, _file) => this._canAssignUser(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -178,7 +178,7 @@ export class PermissionsService {
|
||||
canUnassignUser(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.setReviewer) &&
|
||||
this._iqserPermissionsService.has(Roles.setReviewer) &&
|
||||
files.reduce((acc, _file) => this._canUnassignUser(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -196,7 +196,7 @@ export class PermissionsService {
|
||||
canBeApproved(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.setApproved) &&
|
||||
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
||||
files.reduce((acc, _file) => this._canBeApproved(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -204,7 +204,7 @@ export class PermissionsService {
|
||||
isReadyForApproval(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.setApproved) &&
|
||||
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
||||
files.reduce((acc, _file) => this._isReadyForApproval(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -212,7 +212,7 @@ export class PermissionsService {
|
||||
canSetUnderApproval(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.setUnderApproval) &&
|
||||
this._iqserPermissionsService.has(Roles.files.setUnderApproval) &&
|
||||
files.reduce((acc, _file) => this._canSetUnderApproval(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
@ -246,14 +246,14 @@ export class PermissionsService {
|
||||
canUndoApproval(file: File | File[], dossier: Dossier): boolean {
|
||||
const files = file instanceof File ? [file] : file;
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.files.setApproved) &&
|
||||
this._iqserPermissionsService.has(Roles.files.setApproved) &&
|
||||
files.reduce((acc, _file) => this._canUndoApproval(_file, dossier) && acc, true)
|
||||
);
|
||||
}
|
||||
|
||||
canMarkPagesAsViewed(file: File): boolean {
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.manageViewedPages) &&
|
||||
this._iqserPermissionsService.has(Roles.manageViewedPages) &&
|
||||
(file.isUnderReview || file.isUnderApproval) &&
|
||||
this.isFileAssignee(file)
|
||||
);
|
||||
@ -267,20 +267,20 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canDeleteDossier(dossier: IDossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.delete) && this.isOwner(dossier);
|
||||
return this._iqserPermissionsService.has(Roles.dossiers.delete) && this.isOwner(dossier);
|
||||
}
|
||||
|
||||
canRestoreDossier(dossier: IDossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.delete) && this.isOwner(dossier);
|
||||
return this._iqserPermissionsService.has(Roles.dossiers.delete) && this.isOwner(dossier);
|
||||
}
|
||||
|
||||
canCreateDossier(dossierTemplate: DossierTemplate | DashboardStats): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.write) && this.isManager() && dossierTemplate.isActive;
|
||||
return this._iqserPermissionsService.has(Roles.dossiers.write) && this.isManager() && dossierTemplate.isActive;
|
||||
}
|
||||
|
||||
canArchiveDossier(dossier: Dossier): boolean {
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.dossiers.archived) &&
|
||||
this._iqserPermissionsService.has(Roles.dossiers.archived) &&
|
||||
this._featuresService.isEnabled(DOSSIERS_ARCHIVE) &&
|
||||
dossier.isActive &&
|
||||
this.isOwner(dossier)
|
||||
@ -288,7 +288,7 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canEditDossier(dossier: Dossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.edit) && this.isManager() && !!dossier?.ownerId;
|
||||
return this._iqserPermissionsService.has(Roles.dossiers.edit) && this.isManager() && !!dossier?.ownerId;
|
||||
}
|
||||
|
||||
canEditDossierDictionary(dossier: Dossier): boolean {
|
||||
@ -296,16 +296,16 @@ export class PermissionsService {
|
||||
dossier.isActive &&
|
||||
this._dossierDictionariesMapService.get(dossier.id).length > 0 &&
|
||||
this.isOwner(dossier) &&
|
||||
this._iqserPermissionsService.has(ROLES.dossiers.dictionaryEntries.write)
|
||||
this._iqserPermissionsService.has(Roles.dossiers.dictionaryEntries.write)
|
||||
);
|
||||
}
|
||||
|
||||
canEditDossierAttributes(dossier: Dossier): boolean {
|
||||
return dossier.isActive && this.isOwner(dossier) && this._iqserPermissionsService.has(ROLES.dossierAttributes.write);
|
||||
return dossier.isActive && this.isOwner(dossier) && this._iqserPermissionsService.has(Roles.dossierAttributes.write);
|
||||
}
|
||||
|
||||
canEditTeamMembers(): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.edit) && this.isManager();
|
||||
return this._iqserPermissionsService.has(Roles.dossiers.edit) && this.isManager();
|
||||
}
|
||||
|
||||
isAdmin(): boolean {
|
||||
@ -317,16 +317,16 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canAddComment(file: File, dossier: Dossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.comments.write) && this.isAssigneeOrApprover(file, dossier) && !file.isApproved;
|
||||
return this._iqserPermissionsService.has(Roles.comments.write) && this.isAssigneeOrApprover(file, dossier) && !file.isApproved;
|
||||
}
|
||||
|
||||
canExcludePages(file: File, dossier: Dossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.excludeIncludePages) && this.canPerformAnnotationActions(file, dossier);
|
||||
return this._iqserPermissionsService.has(Roles.excludeIncludePages) && this.canPerformAnnotationActions(file, dossier);
|
||||
}
|
||||
|
||||
canDeleteComment(comment: IComment, file: File, dossier: Dossier) {
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.comments.delete) &&
|
||||
this._iqserPermissionsService.has(Roles.comments.delete) &&
|
||||
(comment.user === this.#userId || this.isApprover(dossier)) &&
|
||||
!file.isApproved
|
||||
);
|
||||
@ -334,7 +334,7 @@ export class PermissionsService {
|
||||
|
||||
canImportRedactions(file: File, dossier: Dossier) {
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.redactions.write) &&
|
||||
this._iqserPermissionsService.has(Roles.redactions.write) &&
|
||||
dossier.isActive &&
|
||||
this.isFileAssignee(file) &&
|
||||
!file.isApproved &&
|
||||
@ -343,15 +343,15 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canRotatePage(file: File) {
|
||||
return this.isFileAssignee(file) && this._iqserPermissionsService.has(ROLES.files.rotatePage);
|
||||
return this.isFileAssignee(file) && this._iqserPermissionsService.has(Roles.files.rotatePage);
|
||||
}
|
||||
|
||||
canDownloadRedactedFile() {
|
||||
return this._iqserPermissionsService.has(ROLES.files.processDownload);
|
||||
return this._iqserPermissionsService.has(Roles.files.processDownload);
|
||||
}
|
||||
|
||||
canEditRules() {
|
||||
return this._iqserPermissionsService.has(ROLES.rules.write) && this.isAdmin();
|
||||
return this._iqserPermissionsService.has(Roles.rules.write) && this.isAdmin();
|
||||
}
|
||||
|
||||
private _canDeleteEntity(entity: Dictionary): boolean {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { GenericService, List, QueryParam, Toaster } from '@iqser/common-ui';
|
||||
import { Dossier, File, IPageExclusionRequest } from '@red/domain';
|
||||
import { catchError, switchMap, tap } from 'rxjs/operators';
|
||||
import { catchError, tap } from 'rxjs/operators';
|
||||
import { FilesService } from './files/files.service';
|
||||
import { FilesMapService } from './files/files-map.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
@ -26,12 +26,16 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
super();
|
||||
}
|
||||
|
||||
excludePages(body: IPageExclusionRequest, dossierId: string, file: File) {
|
||||
return this._post(body, `exclude-pages/${dossierId}/${file.id}`).pipe(switchMap(() => this._filesService.reload(dossierId, file)));
|
||||
async excludePages(body: IPageExclusionRequest, file: File) {
|
||||
const dossierId = file.dossierId;
|
||||
await firstValueFrom(this._post(body, `exclude-pages/${dossierId}/${file.id}`));
|
||||
return await this._filesService.reload(dossierId, file);
|
||||
}
|
||||
|
||||
includePages(body: IPageExclusionRequest, dossierId: string, file: File) {
|
||||
return this._post(body, `include-pages/${dossierId}/${file.id}`).pipe(switchMap(() => this._filesService.reload(dossierId, file)));
|
||||
async includePages(body: IPageExclusionRequest, file: File) {
|
||||
const dossierId = file.dossierId;
|
||||
await firstValueFrom(this._post(body, `include-pages/${dossierId}/${file.id}`));
|
||||
return await this._filesService.reload(dossierId, file);
|
||||
}
|
||||
|
||||
async reanalyzeFilesForDossier(files: List<File>, dossierId: string, params?: ReanalyzeQueryParams) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export const ROLES = {
|
||||
export const Roles = {
|
||||
RED_CREATE_TENANT: 'red-create-tenant',
|
||||
RED_DEPLOYMENT_INFO: 'red-deployment-info',
|
||||
RED_GET_TENANTS: 'red-get-tenants',
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { User } from '@red/domain';
|
||||
import { IIqserUser, IqserUserService, List, QueryParam } from '@iqser/common-ui';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
@ -15,19 +15,19 @@ export class UserService extends IqserUserService<IIqserUser, User> {
|
||||
const currentUser = await super.loadCurrentUser();
|
||||
|
||||
this._permissionsService.add({
|
||||
[ROLES.any]: (permission, all) => Object.keys(all).some(key => this._permissionsFilter(key)),
|
||||
[Roles.any]: (permission, all) => Object.keys(all).some(key => this._permissionsFilter(key)),
|
||||
});
|
||||
|
||||
return currentUser;
|
||||
}
|
||||
|
||||
loadAll() {
|
||||
const canReadUsers = this._permissionsService.has(ROLES.users.read);
|
||||
const canReadUsers = this._permissionsService.has(Roles.users.read);
|
||||
return canReadUsers ? super.loadAll() : of([]);
|
||||
}
|
||||
|
||||
getAll() {
|
||||
const canReadAllUsers = this._permissionsService.has(ROLES.users.readAll);
|
||||
const canReadAllUsers = this._permissionsService.has(Roles.users.readAll);
|
||||
const url = canReadAllUsers ? this._defaultModelPath : `${this._defaultModelPath}/red`;
|
||||
return super.getAll(url);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import { FeaturesService } from '@services/features.service';
|
||||
import { GeneralSettingsService } from '@services/general-settings.service';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { Roles } from '@users/roles';
|
||||
import { DossiersChangesService } from '@services/dossiers/dossier-changes.service';
|
||||
import { ResolveFn } from '@angular/router';
|
||||
|
||||
@ -26,7 +26,7 @@ export const mainResolver: ResolveFn<void> = async () => {
|
||||
logger.info('[ROUTES] Main resolver started...');
|
||||
|
||||
inject(FeaturesService).loadConfig();
|
||||
if (inject(IqserPermissionsService).has(ROLES.dossiers.read)) {
|
||||
if (inject(IqserPermissionsService).has(Roles.dossiers.read)) {
|
||||
inject(DossiersChangesService).initialize();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user