RED-5482: wip permissions
This commit is contained in:
parent
0d2b816263
commit
0b4de15f07
@ -27,6 +27,15 @@ import { ROLES } from '@users/roles';
|
||||
const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
{
|
||||
path: `${DOSSIERS_ROUTE}`,
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||
data: {
|
||||
routeGuards: [DossiersGuard],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
allow: [ROLES.files.readStatus],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: `:${DOSSIER_ID}`,
|
||||
@ -65,15 +74,6 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
},
|
||||
},
|
||||
],
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||
data: {
|
||||
routeGuards: [DossiersGuard],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
allow: [ROLES.files.readStatus],
|
||||
redirectTo: '/auth-error',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
path: `${ARCHIVE_ROUTE}`,
|
||||
|
||||
@ -112,14 +112,14 @@ export const appModuleFactory = (config: AppConfig) => {
|
||||
features: {
|
||||
ANNOTATIONS: {
|
||||
color: 'aqua',
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
level: NgxLoggerLevel.DEBUG,
|
||||
},
|
||||
FILTERS: {
|
||||
enabled: false,
|
||||
},
|
||||
PDF: {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
},
|
||||
FILE: {
|
||||
enabled: false,
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<div class="menu-placeholder"></div>
|
||||
</ng-template>
|
||||
|
||||
<div *allow="roles.templates.read; else menuPlaceholder" class="flex-2 visible-lg breadcrumbs-container">
|
||||
<div *allow="roles.templates.read; if: currentUser.isUser; else: menuPlaceholder" class="flex-2 visible-lg breadcrumbs-container">
|
||||
<redaction-breadcrumbs></redaction-breadcrumbs>
|
||||
</div>
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<div class="actions flex-2">
|
||||
<div class="buttons">
|
||||
<redaction-spotlight-search
|
||||
*allow="roles.search; if: (isSearchScreen$ | async) === false"
|
||||
*allow="roles.search; if: (isSearchScreen$ | async) === false && (currentUser.isUser || currentUser.isManager)"
|
||||
[actions]="searchActions"
|
||||
[iqserHelpMode]="'search_in_entire_application'"
|
||||
[placeholder]="'search.placeholder' | translate"
|
||||
|
||||
@ -43,19 +43,19 @@ export class BaseScreenComponent {
|
||||
id: 'admin',
|
||||
name: _('top-bar.navigation-items.my-account.children.admin'),
|
||||
routerLink: '/main/admin',
|
||||
show: 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._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._permissionsService.has([ROLES.dossiers.read, ROLES.files.readStatus]),
|
||||
show: this.currentUser.isUser && this._permissionsService.has([ROLES.dossiers.read, ROLES.files.readStatus]),
|
||||
},
|
||||
];
|
||||
readonly searchActions: readonly SpotlightSearchAction[] = [
|
||||
|
||||
@ -54,7 +54,7 @@ export class AnnotationWrapper implements IListable, Record<string, unknown> {
|
||||
imported?: boolean;
|
||||
image?: boolean;
|
||||
manual?: boolean;
|
||||
pending?: boolean;
|
||||
pending = false;
|
||||
hintDictionary?: boolean;
|
||||
textAfter?: string;
|
||||
textBefore?: string;
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||
import { BaseFormComponent } from '@iqser/common-ui';
|
||||
import { BaseFormComponent, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { ROLES } from '@users/roles';
|
||||
|
||||
interface PreferencesForm {
|
||||
autoExpandFiltersOnActions: boolean;
|
||||
@ -22,12 +23,21 @@ export class PreferencesComponent extends BaseFormComponent {
|
||||
readonly form: FormGroup<AsControl<PreferencesForm>>;
|
||||
initialFormValue: PreferencesForm;
|
||||
|
||||
constructor(readonly userPreferenceService: UserPreferenceService, private readonly _formBuilder: FormBuilder) {
|
||||
constructor(
|
||||
readonly userPreferenceService: UserPreferenceService,
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
private readonly _permissionsService: IqserPermissionsService,
|
||||
) {
|
||||
super();
|
||||
this.form = this._formBuilder.group({
|
||||
autoExpandFiltersOnActions: [this.userPreferenceService.getAutoExpandFiltersOnActions()],
|
||||
showSuggestionsInPreview: [this.userPreferenceService.getShowSuggestionsInPreview()],
|
||||
});
|
||||
|
||||
if (!this._permissionsService.has(ROLES.managePreferences)) {
|
||||
this.form.disable();
|
||||
}
|
||||
|
||||
this.initialFormValue = this.form.getRawValue();
|
||||
}
|
||||
|
||||
|
||||
@ -2,14 +2,14 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BaseFormComponent, LanguageService, LoadingService } from '@iqser/common-ui';
|
||||
import { BaseFormComponent, IqserPermissionsService, LanguageService, LoadingService } from '@iqser/common-ui';
|
||||
import { IProfile } from '@red/domain';
|
||||
import { languagesTranslations } from '@translations/languages-translations';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-user-profile-screen',
|
||||
@ -28,12 +28,12 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
domSanitizer: DomSanitizer,
|
||||
configService: ConfigService,
|
||||
private readonly _userService: UserService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
readonly userPreferences: UserPreferenceService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _formBuilder: UntypedFormBuilder,
|
||||
private readonly _languageService: LanguageService,
|
||||
protected readonly _translateService: TranslateService,
|
||||
private readonly _permissionsService: IqserPermissionsService,
|
||||
protected readonly _userPreferenceService: UserPreferenceService,
|
||||
) {
|
||||
super();
|
||||
@ -112,6 +112,9 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
|
||||
private _initializeForm(): void {
|
||||
try {
|
||||
this.form = this._getForm();
|
||||
if (!this._permissionsService.has(ROLES.updateMyProfile)) {
|
||||
this.form.disable();
|
||||
}
|
||||
this.#profileModel = {
|
||||
email: this._userService.currentUser.email ?? '',
|
||||
firstName: this._userService.currentUser.firstName ?? '',
|
||||
|
||||
@ -162,10 +162,13 @@ const routes: IqserRoutes = [
|
||||
component: UserListingScreenComponent,
|
||||
},
|
||||
],
|
||||
canActivate: [CompositeRouteGuard],
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||
requiredRoles: ['RED_USER_ADMIN'],
|
||||
permissions: {
|
||||
allow: [ROLES.users.read],
|
||||
redirectTo: '/',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@ -4,9 +4,9 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { adminSideNavTranslations } from '@translations/admin-side-nav-translations';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminSideNavType, AdminSideNavTypes, ENTITY_TYPE } from '@red/domain';
|
||||
import { AdminSideNavType, AdminSideNavTypes, ENTITY_TYPE, User } from '@red/domain';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { getCurrentUser, IqserPermissionsService } from '@iqser/common-ui';
|
||||
|
||||
interface NavItem {
|
||||
readonly label: string;
|
||||
@ -24,6 +24,7 @@ export class AdminSideNavComponent implements OnInit {
|
||||
@Input() type: AdminSideNavType;
|
||||
@Input() disabledItems: string[] = [];
|
||||
readonly translations = adminSideNavTranslations;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = ROLES;
|
||||
prefix: string;
|
||||
|
||||
@ -32,7 +33,7 @@ export class AdminSideNavComponent implements OnInit {
|
||||
{
|
||||
screen: 'dossier-templates',
|
||||
label: _('admin-side-nav.dossier-templates'),
|
||||
hideIf: !this._permissionsService.has(ROLES.templates.read),
|
||||
hideIf: !this.currentUser.isManager && !this.currentUser.isAdmin && !this._permissionsService.has(ROLES.templates.read),
|
||||
helpModeKey: 'dossier_templates',
|
||||
},
|
||||
{
|
||||
@ -56,7 +57,7 @@ export class AdminSideNavComponent implements OnInit {
|
||||
{
|
||||
screen: 'users',
|
||||
label: _('admin-side-nav.user-management'),
|
||||
hideIf: !this._userService.currentUser.isUserAdmin,
|
||||
hideIf: !this._permissionsService.has(ROLES.users.read) && !this._userService.currentUser.isUserAdmin,
|
||||
helpModeKey: 'user_management',
|
||||
},
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<iqser-page-header
|
||||
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
|
||||
[pageLabel]="'audit' | translate"
|
||||
[showCloseButton]="permissionsService.has$(roles.dossiers.read) | async"
|
||||
[showCloseButton]="currentUser.isUser && permissionsService.has$(roles.dossiers.read) | async"
|
||||
></iqser-page-header>
|
||||
|
||||
<iqser-table
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
import { Component, inject, OnDestroy, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { applyIntervalConstraints } from '@utils/date-inputs-utils';
|
||||
import { IqserPermissionsService, ListingComponent, listingProvidersFactory, LoadingService, TableColumnConfig } from '@iqser/common-ui';
|
||||
import {
|
||||
getCurrentUser,
|
||||
IqserPermissionsService,
|
||||
ListingComponent,
|
||||
listingProvidersFactory,
|
||||
LoadingService,
|
||||
TableColumnConfig,
|
||||
} from '@iqser/common-ui';
|
||||
import { auditCategoriesTranslations } from '@translations/audit-categories-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { Audit, IAudit, IAuditResponse, IAuditSearchRequest } from '@red/domain';
|
||||
import { Audit, IAudit, IAuditResponse, IAuditSearchRequest, User } from '@red/domain';
|
||||
import { AuditService } from '../../services/audit.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { Dayjs } from 'dayjs';
|
||||
@ -26,6 +33,7 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
|
||||
readonly routerHistoryService = inject(RouterHistoryService);
|
||||
readonly permissionsService = inject(IqserPermissionsService);
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
categories: string[] = [];
|
||||
userIds: Set<string>;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<iqser-page-header
|
||||
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
|
||||
[pageLabel]="'digital-signature' | translate"
|
||||
[showCloseButton]="permissionsService.has$(roles.dossiers.read) | async"
|
||||
[showCloseButton]="currentUser.isUser && permissionsService.has$(roles.dossiers.read) | async"
|
||||
></iqser-page-header>
|
||||
|
||||
<div class="content-container">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { IconButtonTypes, IqserPermissionsService, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { getCurrentUser, IconButtonTypes, IqserPermissionsService, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { RouterHistoryService } from '@services/router-history.service';
|
||||
import { DigitalSignatureService } from '../../services/digital-signature.service';
|
||||
@ -7,7 +7,7 @@ import { firstValueFrom } from 'rxjs';
|
||||
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 } from '@red/domain';
|
||||
import { DigitalSignatureOptions, IKmsDigitalSignatureRequest, IPkcsDigitalSignatureRequest, User } from '@red/domain';
|
||||
import { ROLES } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
@ -22,6 +22,7 @@ export class DigitalSignatureScreenComponent implements OnInit {
|
||||
readonly certificateType = DigitalSignatureOptions;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
digitalSignature: IPkcsDigitalSignatureRequest | IKmsDigitalSignatureRequest;
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddEditStateDialog($event)"
|
||||
*allow="roles.states.write"
|
||||
*ngIf="permissionsService.canPerformDossierStatesActions()"
|
||||
[iqserHelpMode]="'create_new_dossier_state'"
|
||||
[label]="'dossier-states-listing.add-new' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
@ -80,7 +80,7 @@
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<div *allow="roles.states.write" class="action-buttons">
|
||||
<div *ngIf="permissionsService.canPerformDossierStatesActions()" class="action-buttons">
|
||||
<div [iqserHelpMode]="'edit_delete_dossier_state'">
|
||||
<iqser-circle-button
|
||||
(action)="openAddEditStateDialog($event, state)"
|
||||
|
||||
@ -15,7 +15,7 @@ import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { DossierStatesMapService } from '@services/entity-services/dossier-states-map.service';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { DossierStatesService } from '@services/entity-services/dossier-states.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './dossier-states-listing-screen.component.html',
|
||||
@ -26,7 +26,6 @@ import { ROLES } from '@users/roles';
|
||||
export class DossierStatesListingScreenComponent extends ListingComponent<DossierState> implements OnInit, OnDestroy {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly tableHeaderLabel = _('dossier-states-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<DossierState>[] = [
|
||||
{ label: _('dossier-states-listing.table-col-names.name'), sortByKey: 'name', width: '3fr' },
|
||||
@ -40,6 +39,7 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
|
||||
private readonly _dialogService: AdminDialogService,
|
||||
private readonly _dossierStatesMapService: DossierStatesMapService,
|
||||
private readonly _dossierStatesService: DossierStatesService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
) {
|
||||
super();
|
||||
this.chartConfig$ = this._dossierStatesMapService.get$(this.#dossierTemplateId).pipe(
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
|
||||
[hideResetButton]="true"
|
||||
[pageLabel]="'dossier-templates.label' | translate"
|
||||
[showCloseButton]="permissionsService.has$(roles.dossiers.read) | async"
|
||||
[showCloseButton]="currentUser.isUser && (permissionsService.has$(roles.dossiers.read) | async)"
|
||||
></iqser-page-header>
|
||||
|
||||
<iqser-table
|
||||
@ -19,7 +19,7 @@
|
||||
<ng-template #bulkActions>
|
||||
<iqser-circle-button
|
||||
(action)="openBulkDeleteTemplatesDialog($event)"
|
||||
*allow="roles.templates.write; if: listingService.areSomeSelected$ | async"
|
||||
*allow="roles.templates.write; if: currentUser.isAdmin && (listingService.areSomeSelected$ | async)"
|
||||
[icon]="'iqser:trash'"
|
||||
[tooltip]="'dossier-templates-listing.bulk.delete' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="openAddDossierTemplateDialog()"
|
||||
*allow="roles.templates.write; if: userPreferenceService.areDevFeaturesEnabled"
|
||||
*allow="roles.templates.write; if: currentUser.isAdmin && userPreferenceService.areDevFeaturesEnabled"
|
||||
[icon]="'iqser:plus'"
|
||||
[label]="'dossier-templates-listing.add-new' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||
import { DossierTemplate } from '@red/domain';
|
||||
import { DossierTemplate, User } from '@red/domain';
|
||||
import {
|
||||
CircleButtonTypes,
|
||||
getCurrentUser,
|
||||
IconButtonTypes,
|
||||
IqserPermissionsService,
|
||||
ListingComponent,
|
||||
@ -30,6 +31,7 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly tableHeaderLabel = _('dossier-templates-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<DossierTemplate>[] = [
|
||||
{ label: _('dossier-templates-listing.table-col-names.name'), sortByKey: 'searchKey', width: '3fr' },
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
<div class="actions">
|
||||
<iqser-icon-button
|
||||
(action)="openAddEntityDialog()"
|
||||
*allow="roles.dictionaryTypes.write"
|
||||
*ngIf="permissionsService.canEditEntities()"
|
||||
[iqserHelpMode]="'create_new_entity'"
|
||||
[label]="'entities-listing.add-new' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
@ -109,7 +109,7 @@
|
||||
></iqser-circle-button>
|
||||
|
||||
<iqser-circle-button
|
||||
*allow="roles.dictionaryTypes.write"
|
||||
*ngIf="permissionsService.canEditEntities()"
|
||||
[routerLink]="dict.routerLink"
|
||||
[tooltip]="'entities-listing.action.edit' | translate"
|
||||
[type]="circleButtonTypes.dark"
|
||||
|
||||
@ -17,7 +17,6 @@ import { DossierTemplateStatsService } from '@services/entity-services/dossier-t
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
templateUrl: './entities-listing-screen.component.html',
|
||||
@ -27,7 +26,6 @@ import { ROLES } from '@users/roles';
|
||||
export class EntitiesListingScreenComponent extends ListingComponent<Dictionary> {
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly tableHeaderLabel = _('entities-listing.table-header.title');
|
||||
readonly tableColumnConfigs: TableColumnConfig<Dictionary>[] = [
|
||||
{ label: _('entities-listing.table-col-names.type'), sortByKey: 'searchKey', width: '2fr' },
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
></redaction-add-edit-entity>
|
||||
</div>
|
||||
|
||||
<div *allow="roles.dictionaryTypes.write" class="dialog-actions">
|
||||
<div *ngIf="permissionsService.canEditEntities()" class="dialog-actions">
|
||||
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button>
|
||||
{{ 'entity.info.actions.save' | translate }}
|
||||
</button>
|
||||
|
||||
@ -7,7 +7,6 @@ import { PermissionsService } from '@services/permissions.service';
|
||||
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
|
||||
import { IqserEventTarget } from '@iqser/common-ui';
|
||||
import { Observable } from 'rxjs';
|
||||
import { ROLES } from '@users/roles';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-entity-info',
|
||||
@ -17,7 +16,6 @@ import { ROLES } from '@users/roles';
|
||||
})
|
||||
export class EntityInfoComponent {
|
||||
readonly currentUser = getCurrentUser();
|
||||
readonly roles = ROLES;
|
||||
readonly entity$: Observable<Dictionary>;
|
||||
readonly dossierTemplateId: string;
|
||||
@ViewChild(AddEditEntityComponent) private readonly _addEditEntityComponent: AddEditEntityComponent;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="heading-l" translate="general-config-screen.general.title"></div>
|
||||
<div translate="general-config-screen.general.subtitle"></div>
|
||||
</div>
|
||||
<form (submit)="save()" [formGroup]="form" *ngIf="form">
|
||||
<form (submit)="save()" *ngIf="form" [formGroup]="form">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-content-left">
|
||||
<div class="iqser-input-group">
|
||||
@ -22,13 +22,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="form?.invalid || !changed"
|
||||
[iqserHelpMode]="'general_configurations'"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
[iqserHelpMode]="'general_configurations'"
|
||||
>
|
||||
{{ 'general-config-screen.actions.save' | translate }}
|
||||
</button>
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { BaseFormComponent, LoadingService } from '@iqser/common-ui';
|
||||
import { BaseFormComponent, IqserPermissionsService, LoadingService } from '@iqser/common-ui';
|
||||
import { GeneralSettingsService } from '@services/general-settings.service';
|
||||
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';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-general-config-form',
|
||||
@ -18,9 +19,13 @@ export class GeneralConfigFormComponent extends BaseFormComponent implements OnI
|
||||
private readonly _generalSettingsService: GeneralSettingsService,
|
||||
private readonly _configService: ConfigService,
|
||||
private readonly _formBuilder: UntypedFormBuilder,
|
||||
private readonly _permissionsService: IqserPermissionsService,
|
||||
) {
|
||||
super();
|
||||
this.form = this._getForm();
|
||||
if (!_permissionsService.has(ROLES.generalConfiguration.write)) {
|
||||
this.form.disable();
|
||||
}
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { ISmtpConfiguration } from '@red/domain';
|
||||
import { BaseFormComponent, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { BaseFormComponent, IconButtonTypes, IqserPermissionsService, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
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';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-smtp-form',
|
||||
@ -21,9 +22,13 @@ export class SmtpFormComponent extends BaseFormComponent implements OnInit {
|
||||
private readonly _smtpConfigService: SmtpConfigService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _permissionsService: IqserPermissionsService,
|
||||
) {
|
||||
super();
|
||||
this.form = this._getForm();
|
||||
if (!_permissionsService.has(ROLES.smtp.write)) {
|
||||
this.form.disable();
|
||||
}
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { SystemPreferences } from '@red/domain';
|
||||
import { BaseFormComponent, KeysOf, LoadingService } from '@iqser/common-ui';
|
||||
import { BaseFormComponent, IqserPermissionsService, KeysOf, LoadingService } from '@iqser/common-ui';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { SystemPreferencesService } from '@services/system-preferences.service';
|
||||
import { systemPreferencesTranslations } from '@translations/system-preferences-translations';
|
||||
import { ROLES } from '@users/roles';
|
||||
|
||||
export type ValueType = 'number' | 'string' | 'boolean';
|
||||
|
||||
@ -25,10 +26,14 @@ export class SystemPreferencesFormComponent extends BaseFormComponent {
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _systemPreferencesService: SystemPreferencesService,
|
||||
private readonly _formBuilder: UntypedFormBuilder,
|
||||
private readonly _permissionsService: IqserPermissionsService,
|
||||
) {
|
||||
super();
|
||||
this.form = this._getForm();
|
||||
this._loadData();
|
||||
if (!_permissionsService.has(ROLES.appConfiguration.write)) {
|
||||
this.form.disable();
|
||||
}
|
||||
}
|
||||
|
||||
async save(): Promise<void> {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
|
||||
[buttonConfigs]="buttonConfigs"
|
||||
[pageLabel]="'license-information' | translate"
|
||||
[showCloseButton]="permissionsService.has$(roles.dossiers.read) | async"
|
||||
[showCloseButton]="currentUser.isUser && permissionsService.has$(roles.dossiers.read) | async"
|
||||
></iqser-page-header>
|
||||
|
||||
<div class="content-inner">
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { ButtonConfig, IconButtonTypes, IqserPermissionsService, LoadingService } from '@iqser/common-ui';
|
||||
import { ButtonConfig, getCurrentUser, IconButtonTypes, IqserPermissionsService, LoadingService } from '@iqser/common-ui';
|
||||
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 { User } from '@red/domain';
|
||||
|
||||
@Component({
|
||||
templateUrl: './license-screen.component.html',
|
||||
@ -14,6 +15,7 @@ import { ROLES } from '@users/roles';
|
||||
})
|
||||
export class LicenseScreenComponent implements OnInit {
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly currentYear = new Date().getFullYear();
|
||||
readonly buttonConfigs: readonly ButtonConfig[] = [
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<iqser-page-header
|
||||
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
|
||||
[pageLabel]="'permissions-screen.label' | translate: { targetObject: this.targetObject }"
|
||||
[showCloseButton]="permissionsService.has$(roles.dossiers.read) | async"
|
||||
[showCloseButton]="currentUser.isUser && permissionsService.has$(roles.dossiers.read) | async"
|
||||
></iqser-page-header>
|
||||
|
||||
<iqser-table [itemSize]="80" [tableColumnConfigs]="tableColumnConfigs"></iqser-table>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import {
|
||||
getCurrentUser,
|
||||
IqserPermissionsService,
|
||||
ListingComponent,
|
||||
listingProvidersFactory,
|
||||
@ -7,7 +8,7 @@ import {
|
||||
SortingOrders,
|
||||
TableColumnConfig,
|
||||
} from '@iqser/common-ui';
|
||||
import { PermissionsMapping } from '@red/domain';
|
||||
import { PermissionsMapping, User } from '@red/domain';
|
||||
import { ConfigService } from '../config.service';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { EntityPermissionsService } from '@services/entity-permissions/entity-permissions.service';
|
||||
@ -30,6 +31,7 @@ import { ROLES } from '@users/roles';
|
||||
})
|
||||
export class PermissionsScreenComponent extends ListingComponent<PermissionsMapping> {
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly translations = permissionsTranslations;
|
||||
readonly tableColumnConfigs: TableColumnConfig<PermissionsMapping>[];
|
||||
readonly tableHeaderLabel = _('permissions-screen.table-header.title');
|
||||
|
||||
@ -59,14 +59,14 @@
|
||||
></mat-slide-toggle>
|
||||
</div>
|
||||
|
||||
<div class="cell" [ngClass]="!user.hasAnyRole && 'no-role-alignment'">
|
||||
<div [ngClass]="!user.hasAnyRole && 'no-role-alignment'" class="cell">
|
||||
<mat-icon *ngIf="!user.hasAnyRole" [svgIcon]="'red:alert-circle'" class="icon"></mat-icon>
|
||||
<span class="small-label opacity-1">{{ getDisplayRoles(user) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<div class="action-buttons">
|
||||
<div [iqserHelpMode]="'edit_delete_user'">
|
||||
<div *allow="roles.users.write" [iqserHelpMode]="'edit_delete_user'">
|
||||
<iqser-circle-button
|
||||
(action)="openAddEditUserDialog($event, user)"
|
||||
[tooltip]="'user-listing.action.edit' | translate"
|
||||
|
||||
@ -21,6 +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';
|
||||
|
||||
function configToFilter({ key, label }: DonutChartConfig) {
|
||||
return new NestedFilter({
|
||||
@ -43,6 +44,7 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
|
||||
readonly translations = rolesTranslations;
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
readonly canDeleteSelected$ = this.#canDeleteSelected$;
|
||||
readonly tableHeaderLabel = _('user-listing.table-header.title');
|
||||
@ -101,11 +103,9 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
|
||||
}
|
||||
|
||||
getDisplayRoles(user: User) {
|
||||
const separator = ', ';
|
||||
return (
|
||||
user.roles.map(role => this._translateService.instant(this.translations[role])).join(separator) ||
|
||||
this._translateService.instant(this.translations['NO_ROLE'])
|
||||
);
|
||||
const oldRedRoles = user.roles.filter(role => role.startsWith('RED_'));
|
||||
const translatedRoles = oldRedRoles.map(role => this._translateService.instant(this.translations[role]));
|
||||
return translatedRoles.join(', ') || this._translateService.instant(this.translations['NO_ROLE']);
|
||||
}
|
||||
|
||||
async toggleActive(user: User) {
|
||||
|
||||
@ -16,12 +16,12 @@
|
||||
<div class="action-buttons">
|
||||
<iqser-circle-button
|
||||
(action)="openEditDossierDialog($event, dossier.id)"
|
||||
*allow="roles.dossiers.read"
|
||||
[icon]="(permissionsService.has$(roles.dossiers.edit) | async) ? 'iqser:edit' : 'red:info'"
|
||||
*allow="roles.dossiers.read; if: currentUser.isUser"
|
||||
[icon]="(permissionsService.has$(roles.dossiers.edit) | async) && currentUser.isManager ? 'iqser:edit' : 'red:info'"
|
||||
[iqserHelpMode]="'edit_dossier_dossier_info'"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
[tooltip]="
|
||||
((permissionsService.has$(roles.dossiers.edit) | async)
|
||||
((permissionsService.has$(roles.dossiers.edit) | async) && currentUser.isManager
|
||||
? 'dossier-listing.edit.action'
|
||||
: 'dossier-listing.dossier-info.action'
|
||||
) | translate
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
|
||||
import { Dossier, DossierStats } from '@red/domain';
|
||||
import { Dossier, DossierStats, User } from '@red/domain';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { DossierStatsService } from '@services/dossiers/dossier-stats.service';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { CircleButtonTypes, IqserPermissionsService, ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
|
||||
import { CircleButtonTypes, getCurrentUser, IqserPermissionsService, ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
|
||||
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
|
||||
@ -15,6 +15,7 @@ import { ROLES } from '@users/roles';
|
||||
export class TableItemComponent implements OnChanges {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
@Input() dossier!: Dossier;
|
||||
readonly stats$: Observable<DossierStats>;
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
|
||||
<iqser-icon-button
|
||||
(action)="newDossier()"
|
||||
*allow="roles.dossiers.write; if: dossierTemplate.isEmpty"
|
||||
*ngIf="permissionsService.canCreateDossier(dossierTemplate)"
|
||||
[iqserHelpMode]="'new_dossier_button'"
|
||||
[label]="'dashboard.empty-template.new-dossier' | translate"
|
||||
[type]="iconButtonTypes.primary"
|
||||
|
||||
@ -4,6 +4,7 @@ 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 { PermissionsService } from '@services/permissions.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-template-stats [stats]',
|
||||
@ -17,7 +18,11 @@ export class TemplateStatsComponent {
|
||||
|
||||
@Input() stats: DashboardStats;
|
||||
|
||||
constructor(private readonly _dialogService: SharedDialogService, readonly translateChartService: TranslateChartService) {}
|
||||
constructor(
|
||||
private readonly _dialogService: SharedDialogService,
|
||||
readonly translateChartService: TranslateChartService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
) {}
|
||||
|
||||
newDossier(): void {
|
||||
this._dialogService.openDialog('addDossier', null, { dossierTemplateId: this.stats.dossierTemplateId });
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="editingOwner = true"
|
||||
*allow="roles.dossiers.edit"
|
||||
*allow="roles.dossiers.edit; if: currentUser.isManager"
|
||||
[icon]="'iqser:edit'"
|
||||
[iqserHelpMode]="'dashboard_in_dossier'"
|
||||
[tooltipPosition]="'below'"
|
||||
|
||||
@ -13,7 +13,16 @@ import {
|
||||
} from '@red/domain';
|
||||
import { TranslateChartService } from '@services/translate-chart.service';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { ContextComponent, FilterService, getParam, INestedFilter, ProgressBarConfigModel, shareLast, Toaster } from '@iqser/common-ui';
|
||||
import {
|
||||
ContextComponent,
|
||||
FilterService,
|
||||
getCurrentUser,
|
||||
getParam,
|
||||
INestedFilter,
|
||||
ProgressBarConfigModel,
|
||||
shareLast,
|
||||
Toaster,
|
||||
} from '@iqser/common-ui';
|
||||
import { workflowFileStatusTranslations } from '@translations/file-status-translations';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { combineLatestWith, firstValueFrom, Observable } from 'rxjs';
|
||||
@ -44,6 +53,7 @@ export class DossierDetailsComponent extends ContextComponent<DossierDetailsCont
|
||||
|
||||
editingOwner = false;
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly collapseTooltip = _('dossier-details.collapse');
|
||||
readonly expandTooltip = _('dossier-details.expand');
|
||||
readonly needsWorkFilters$ = this.filterService.getFilterModels$('needsWorkFilters');
|
||||
@ -78,7 +88,7 @@ export class DossierDetailsComponent extends ContextComponent<DossierDetailsCont
|
||||
}
|
||||
|
||||
get managers() {
|
||||
return this._userService.all.filter(u => u.has(ROLES.dossiers.write) || u.isManager).map(u => u.id);
|
||||
return this._userService.all.filter(u => u.isManager).map(u => u.id);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Injectable, TemplateRef } from '@angular/core';
|
||||
import {
|
||||
ActionConfig,
|
||||
getCurrentUser,
|
||||
getParam,
|
||||
IFilterGroup,
|
||||
INestedFilter,
|
||||
@ -22,6 +23,7 @@ import {
|
||||
IFileAttributeConfig,
|
||||
ProcessingType,
|
||||
StatusSorter,
|
||||
User,
|
||||
WorkflowFileStatus,
|
||||
WorkflowFileStatuses,
|
||||
} from '@red/domain';
|
||||
@ -48,6 +50,7 @@ import { ROLES } from '@users/roles';
|
||||
export class ConfigService {
|
||||
readonly listingMode$: Observable<ListingMode>;
|
||||
readonly dossierId = getParam(DOSSIER_ID);
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
private readonly _listingMode$ = new BehaviorSubject<ListingMode>(ListingModes.table);
|
||||
|
||||
constructor(
|
||||
@ -155,7 +158,7 @@ export class ConfigService {
|
||||
label: this._translateService.instant('dossier-overview.header-actions.edit'),
|
||||
action: $event => this._openEditDossierDialog($event, dossierId),
|
||||
icon: 'iqser:edit',
|
||||
hide: !this._iqserPermissionsService.has(ROLES.dossiers.edit),
|
||||
hide: !this.currentUser.isManager && !this._iqserPermissionsService.has(ROLES.dossiers.edit),
|
||||
helpModeKey: 'edit_dossier_in_dossier',
|
||||
disabled$,
|
||||
},
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<div (longPress)="forceReanalysisAction($event)" class="action-buttons" redactionLongPress>
|
||||
<iqser-circle-button
|
||||
(action)="openEditDossierDialog($event, dossier.id)"
|
||||
*allow="roles.dossiers.read"
|
||||
[icon]="(iqserPermissionsService.has$(roles.dossiers.edit) | async) ? 'iqser:edit' : 'red:info'"
|
||||
*allow="roles.dossiers.read; if: currentUser.isUser"
|
||||
[icon]="(iqserPermissionsService.has$(roles.dossiers.edit) | async) && currentUser.isManager ? 'iqser:edit' : 'red:info'"
|
||||
[iqserHelpMode]="'edit_dossier_dossier_info'"
|
||||
[scrollableParentView]="scrollableParentView"
|
||||
[tooltip]="
|
||||
((iqserPermissionsService.has$(roles.dossiers.edit) | async)
|
||||
((iqserPermissionsService.has$(roles.dossiers.edit) | async) && currentUser.isManager
|
||||
? 'dossier-listing.edit.action'
|
||||
: 'dossier-listing.dossier-info.action'
|
||||
) | translate
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { CircleButtonTypes, IqserPermissionsService, ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
|
||||
import { Dossier, DossierStats, File } from '@red/domain';
|
||||
import { CircleButtonTypes, getCurrentUser, IqserPermissionsService, ScrollableParentView, ScrollableParentViews } from '@iqser/common-ui';
|
||||
import { Dossier, DossierStats, File, User } from '@red/domain';
|
||||
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
|
||||
import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
@ -18,6 +18,7 @@ import { ROLES } from '@users/roles';
|
||||
export class DossiersListingActionsComponent implements OnChanges {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
analysisForced: boolean;
|
||||
files: File[];
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
IqserScrollbarModule,
|
||||
IqserSharedModule,
|
||||
IqserUsersModule,
|
||||
LogPipe,
|
||||
} from '@iqser/common-ui';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { DossiersListingScreenComponent } from './screen/dossiers-listing-screen.component';
|
||||
@ -58,6 +59,7 @@ const routes: Routes = [
|
||||
IqserScrollbarModule,
|
||||
IqserSharedModule,
|
||||
IqserPermissionsModule,
|
||||
LogPipe,
|
||||
],
|
||||
})
|
||||
export class DossiersListingModule {}
|
||||
|
||||
@ -82,7 +82,7 @@
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="annotationActionsService.undoDirectAction($event, annotations)"
|
||||
*ngIf="annotationPermissions.canUndo"
|
||||
*allow="roles.redactions.deleteManual; if: annotationPermissions.canUndo"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="'annotation-actions.undo' | translate"
|
||||
[type]="buttonType"
|
||||
|
||||
@ -9,6 +9,7 @@ import { FilePreviewStateService } from '../../services/file-preview-state.servi
|
||||
import { HelpModeService } 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';
|
||||
|
||||
export const AnnotationButtonTypes = {
|
||||
dark: 'dark',
|
||||
@ -29,6 +30,7 @@ export class AnnotationActionsComponent implements OnChanges {
|
||||
@Input() canPerformAnnotationActions: boolean;
|
||||
@Input() alwaysVisible: boolean;
|
||||
annotationPermissions: AnnotationPermissions;
|
||||
readonly roles = ROLES;
|
||||
|
||||
constructor(
|
||||
readonly viewModeService: ViewModeService,
|
||||
|
||||
@ -11,7 +11,7 @@ import type {
|
||||
ManualRedactionActions,
|
||||
} from '@red/domain';
|
||||
import { type AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { GenericService, List, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { GenericService, IqserPermissionsService, List, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { map, tap } from 'rxjs/operators';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { dictionaryActionsTranslations, manualRedactionActionsTranslations } from '@translations/annotation-actions-translations';
|
||||
@ -20,6 +20,8 @@ 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 { of } from 'rxjs';
|
||||
|
||||
function getResponseType(error: boolean, isConflict: boolean) {
|
||||
const isConflictError = isConflict ? 'conflictError' : 'error';
|
||||
@ -45,6 +47,7 @@ export class ManualRedactionService extends GenericService<IManualAddResponse> {
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _logger: NGXLogger,
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
private readonly _iqaerPermissionsService: IqserPermissionsService,
|
||||
private readonly _activeDossiersService: ActiveDossiersService,
|
||||
) {
|
||||
super();
|
||||
@ -93,11 +96,17 @@ 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');
|
||||
if (this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||
const canAddRedaction = this._iqaerPermissionsService.has(ROLES.redactions.write);
|
||||
if (canAddRedaction && this._permissionsService.isApprover(this.#dossier(dossierId))) {
|
||||
return this.add(requests, dossierId, fileId).pipe(toast);
|
||||
}
|
||||
|
||||
return this.requestAdd(requests, dossierId, fileId).pipe(toast);
|
||||
const canRequestRedaction = this._iqaerPermissionsService.has(ROLES.redactions.request);
|
||||
if (canRequestRedaction) {
|
||||
return this.requestAdd(requests, dossierId, fileId).pipe(toast);
|
||||
}
|
||||
|
||||
return of(undefined);
|
||||
}
|
||||
|
||||
bulkForce(requests: List<ILegalBasisChangeRequest>, dossierId: string, fileId: string) {
|
||||
|
||||
@ -5,9 +5,10 @@ import { PermissionsService } from '../../../services/permissions.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { AnnotationActionsService } from './annotation-actions.service';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui';
|
||||
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';
|
||||
|
||||
@Injectable()
|
||||
export class PdfAnnotationActionsService {
|
||||
@ -17,6 +18,7 @@ export class PdfAnnotationActionsService {
|
||||
readonly #ngZone = inject(NgZone);
|
||||
readonly #convertPath = inject(BASE_HREF_FN);
|
||||
readonly #annotationActionsService = inject(AnnotationActionsService);
|
||||
readonly #iqserPermissionsService = inject(IqserPermissionsService);
|
||||
|
||||
get(annotations: AnnotationWrapper[]): IHeaderElement[] {
|
||||
const availableActions: IHeaderElement[] = [];
|
||||
@ -152,7 +154,9 @@ export class PdfAnnotationActionsService {
|
||||
),
|
||||
canAcceptRecommendation: permissions.reduce((acc, next) => acc && next.canAcceptRecommendation, true),
|
||||
canAcceptSuggestion: permissions.reduce((acc, next) => acc && next.canAcceptSuggestion, true),
|
||||
canUndo: permissions.reduce((acc, next) => acc && next.canUndo, true),
|
||||
canUndo:
|
||||
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),
|
||||
canForceHint: permissions.reduce((acc, next) => acc && next.canForceHint, true),
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
} from '@models/file/manual-redaction-entry.wrapper';
|
||||
import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service';
|
||||
import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { BASE_HREF_FN, BaseHrefFn, shareDistinctLast } from '@iqser/common-ui';
|
||||
import { BASE_HREF_FN, BaseHrefFn, IqserPermissionsService, shareDistinctLast } from '@iqser/common-ui';
|
||||
import { toPosition } from '../utils/pdf-calculation.utils';
|
||||
import { MultiSelectService } from './multi-select.service';
|
||||
import { FilePreviewStateService } from './file-preview-state.service';
|
||||
@ -28,6 +28,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 Annotation = Core.Annotations.Annotation;
|
||||
import Quad = Core.Math.Quad;
|
||||
|
||||
@ -70,6 +71,7 @@ export class PdfProxyService {
|
||||
private readonly _listingService: AnnotationsListingService,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _dictionariesMapService: DictionariesMapService,
|
||||
private readonly _iqserPermissionsService: IqserPermissionsService,
|
||||
) {
|
||||
this.canPerformAnnotationActions$ = this.#canPerformAnnotationActions$;
|
||||
}
|
||||
@ -240,20 +242,23 @@ export class PdfProxyService {
|
||||
});
|
||||
}
|
||||
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_REDACTION,
|
||||
img: this.#addRedactionIcon,
|
||||
title: this.#getTitle(ManualRedactionEntryTypes.REDACTION),
|
||||
onClick: () => this._addManualRedactionOfType(ManualRedactionEntryTypes.REDACTION),
|
||||
});
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_DICTIONARY,
|
||||
img: this.#addDictIcon,
|
||||
title: this.#getTitle(ManualRedactionEntryTypes.DICTIONARY),
|
||||
onClick: () => this._addManualRedactionOfType(ManualRedactionEntryTypes.DICTIONARY),
|
||||
});
|
||||
if (this._iqserPermissionsService.has(ROLES.redactions.write) || this._iqserPermissionsService.has(ROLES.redactions.request)) {
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_REDACTION,
|
||||
img: this.#addRedactionIcon,
|
||||
title: this.#getTitle(ManualRedactionEntryTypes.REDACTION),
|
||||
onClick: () => this._addManualRedactionOfType(ManualRedactionEntryTypes.REDACTION),
|
||||
});
|
||||
|
||||
popups.push({
|
||||
type: 'actionButton',
|
||||
dataElement: TextPopups.ADD_DICTIONARY,
|
||||
img: this.#addDictIcon,
|
||||
title: this.#getTitle(ManualRedactionEntryTypes.DICTIONARY),
|
||||
onClick: () => this._addManualRedactionOfType(ManualRedactionEntryTypes.DICTIONARY),
|
||||
});
|
||||
}
|
||||
|
||||
this._pdf.configureTextPopups(popups);
|
||||
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
import { AfterViewInit, Component, Inject, ViewChild } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Dossier } from '@red/domain';
|
||||
import { Dossier, User } from '@red/domain';
|
||||
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
|
||||
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
|
||||
import { EditDossierSectionInterface } from './edit-dossier-section.interface';
|
||||
import { BaseDialogComponent, ConfirmOptions, IconButtonTypes, IqserPermissionsService, SaveOptions } from '@iqser/common-ui';
|
||||
import {
|
||||
BaseDialogComponent,
|
||||
ConfirmOptions,
|
||||
getCurrentUser,
|
||||
IconButtonTypes,
|
||||
IqserPermissionsService,
|
||||
SaveOptions,
|
||||
} from '@iqser/common-ui';
|
||||
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
|
||||
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
|
||||
|
||||
@ -42,6 +49,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
|
||||
@ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent;
|
||||
@ViewChild(EditDossierTeamComponent) membersComponent: EditDossierTeamComponent;
|
||||
@ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent;
|
||||
readonly #currentUser = getCurrentUser<User>();
|
||||
private _dossier: Dossier;
|
||||
|
||||
constructor(
|
||||
@ -89,7 +97,9 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
|
||||
|
||||
get showActionButtons(): boolean {
|
||||
return (
|
||||
(['members'].includes(this.activeNav) && this._iqserPermissionsService.has(ROLES.dossiers.edit)) ||
|
||||
(['members'].includes(this.activeNav) &&
|
||||
this.#currentUser.isManager &&
|
||||
this._iqserPermissionsService.has(ROLES.dossiers.edit)) ||
|
||||
this._permissionsService.canEditDossier(this._dossier)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { Dossier, IDossierRequest } from '@red/domain';
|
||||
import { Dossier, IDossierRequest, User } from '@red/domain';
|
||||
import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-dossier-section.interface';
|
||||
import { BehaviorSubject, firstValueFrom } from 'rxjs';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { compareLists } from '@utils/functions';
|
||||
import { FilesService } from '@services/files/files.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { getCurrentUser } from '@iqser/common-ui';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-edit-dossier-team',
|
||||
@ -23,9 +23,9 @@ export class EditDossierTeamComponent implements EditDossierSectionInterface, On
|
||||
@Input() dossier: Dossier;
|
||||
|
||||
membersSelectOptions: string[] = [];
|
||||
|
||||
readonly ownersSelectOptions = this.userService.all.filter(u => u.has(ROLES.dossiers.write) || u.isManager).map(m => m.id);
|
||||
readonly ownersSelectOptions = this.userService.all.filter(u => u.isManager).map(m => m.id);
|
||||
readonly selectedReviewers$ = new BehaviorSubject<string[]>([]);
|
||||
readonly #currentUser = getCurrentUser<User>();
|
||||
|
||||
constructor(
|
||||
readonly userService: UserService,
|
||||
@ -138,7 +138,7 @@ export class EditDossierTeamComponent implements EditDossierSectionInterface, On
|
||||
}
|
||||
|
||||
setMembersSelectOptions(value = this.searchQuery): void {
|
||||
const possibleMembers = this.userService.all.filter(user => user.has(ROLES.dossiers.read) || user.isUser || user.isManager);
|
||||
const possibleMembers = this.userService.all.filter(user => user.isUser || user.isManager);
|
||||
this.membersSelectOptions = possibleMembers
|
||||
.filter(user => this.userService.getName(user.id).toLowerCase().includes(value.toLowerCase()))
|
||||
.filter(user => this.selectedOwnerId !== user.id)
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openEditDossierDialog()"
|
||||
*allow="roles.dossiers.edit; if: canAdd"
|
||||
*allow="roles.dossiers.edit; if: currentUser.isManager && canAdd"
|
||||
[class.large-spacing]="largeSpacing"
|
||||
[icon]="'iqser:plus'"
|
||||
[iqserHelpMode]="'edit_dossier_members'"
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { CircleButtonTypes, List } from '@iqser/common-ui';
|
||||
import { CircleButtonTypes, getCurrentUser, List } from '@iqser/common-ui';
|
||||
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
|
||||
import { ROLES } from '@users/roles';
|
||||
import { User } from '@red/domain';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-team-members',
|
||||
@ -11,6 +12,7 @@ import { ROLES } from '@users/roles';
|
||||
export class TeamMembersComponent {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly roles = ROLES;
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
|
||||
@Input() memberIds: List;
|
||||
@Input() perLine: number;
|
||||
|
||||
@ -23,14 +23,19 @@ export class PermissionsService {
|
||||
return this.isAdmin() || this.isManager();
|
||||
}
|
||||
|
||||
canPerformDossierStatesActions() {
|
||||
return this.isAdmin() && this._iqserPermissionsService.has(ROLES.states.write);
|
||||
}
|
||||
|
||||
canEditEntities(): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dictionaryTypes.write);
|
||||
return this._iqserPermissionsService.has(ROLES.dictionaryTypes.write) && this.isAdmin();
|
||||
}
|
||||
|
||||
canDeleteEntities(entity: Dictionary | Dictionary[]): boolean {
|
||||
const entities = entity instanceof Dictionary ? [entity] : entity;
|
||||
return (
|
||||
entities.length &&
|
||||
this.isAdmin() &&
|
||||
this._iqserPermissionsService.has(ROLES.dictionaryTypes.delete) &&
|
||||
entities.reduce((acc, _entity) => this._canDeleteEntity(_entity) && acc, true)
|
||||
);
|
||||
@ -239,7 +244,10 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canSoftDeleteDossier(dossier: IDossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.delete) && (this.isOwner(dossier) || this.isDossierMember(dossier));
|
||||
return (
|
||||
this._iqserPermissionsService.has(ROLES.dossiers.delete) &&
|
||||
(this.isOwner(dossier) || (this.isManager() && this.isDossierMember(dossier)))
|
||||
);
|
||||
}
|
||||
|
||||
canHardDeleteDossier(dossier: IDossier): boolean {
|
||||
@ -251,7 +259,7 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canCreateDossier(dossierTemplate: DossierTemplate | DashboardStats): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.write) && dossierTemplate.isActive;
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.write) && this.isManager() && dossierTemplate.isActive;
|
||||
}
|
||||
|
||||
canArchiveDossier(dossier: Dossier): boolean {
|
||||
@ -264,7 +272,7 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canEditDossier(dossier: Dossier): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.edit) && !!dossier?.ownerId;
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.edit) && this.isManager() && !!dossier?.ownerId;
|
||||
}
|
||||
|
||||
canEditDossierDictionary(dossier: Dossier): boolean {
|
||||
@ -276,7 +284,7 @@ export class PermissionsService {
|
||||
}
|
||||
|
||||
canEditTeamMembers(): boolean {
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.edit);
|
||||
return this._iqserPermissionsService.has(ROLES.dossiers.edit) && this.isManager();
|
||||
}
|
||||
|
||||
isAdmin(): boolean {
|
||||
|
||||
@ -2,15 +2,15 @@ export const ROLES = {
|
||||
RED_CREATE_TENANT: 'red-create-tenant',
|
||||
RED_DEPLOYMENT_INFO: 'red-deployment-info',
|
||||
RED_GET_TENANTS: 'red-get-tenants',
|
||||
RED_MANAGE_USER_PREFERENCES: 'red-manage-user-preferences',
|
||||
RED_PROCESS_DOWNLOAD: 'red-process-download',
|
||||
RED_PROCESS_MANUAL_REDACTION_REQUEST: 'red-process-manual-redaction-request',
|
||||
RED_READ_RULES: 'red-read-rules',
|
||||
RED_READ_VERSIONS: 'red-read-versions',
|
||||
RED_REINDEX: 'red-reindex',
|
||||
RED_ROTATE_PAGE: 'red-rotate-page',
|
||||
RED_UPDATE_MY_PROFILE: 'red-update-my-profile',
|
||||
RED_WRITE_RULES: 'red-write-rules',
|
||||
managePreferences: 'red-manage-user-preferences',
|
||||
updateMyProfile: 'red-update-my-profile',
|
||||
getRss: 'red-get-rss',
|
||||
excludeIncludeFile: 'red-exclude-include-file',
|
||||
excludeIncludePages: 'red-exclude-include-pages',
|
||||
|
||||
@ -17,7 +17,7 @@ export class UserService extends IqserUserService<IIqserUser, User> {
|
||||
this._permissionsService.add({
|
||||
[ROLES.any]: (permission, all) => {
|
||||
console.log('all roles: ', Object.keys(all));
|
||||
return Object.keys(all).some(key => key.startsWith('red-'));
|
||||
return Object.keys(all).some(key => key.startsWith('red-') || key.startsWith('RED_'));
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user