DM-364 & DM-363 use IS_DOCUMINE & change dossier permissions

This commit is contained in:
Dan Percic 2023-08-03 17:53:28 +03:00
parent a7d1eb115a
commit 086ccb6f95
20 changed files with 109 additions and 128 deletions

View File

@ -1,4 +1,4 @@
<iqser-help-mode *deny="roles.getRss"></iqser-help-mode>
<iqser-help-mode *ngIf="!config.IS_DOCUMINE"></iqser-help-mode>
<div class="top-bar">
<ng-template #menuPlaceholder>
@ -25,7 +25,7 @@
[placeholder]="'search.placeholder' | translate"
></redaction-spotlight-search>
<iqser-help-button *deny="roles.getRss" [attr.help-mode-key]="'help_mode'" id="help-mode-button"></iqser-help-button>
<iqser-help-button *ngIf="!config.IS_DOCUMINE" [attr.help-mode-key]="'help_mode'" id="help-mode-button"></iqser-help-button>
<redaction-notifications
*ngIf="currentUser.isUser || currentUser.isManager"

View File

@ -6,7 +6,7 @@ import { Title } from '@angular/platform-browser';
import { TranslateService } from '@ngx-translate/core';
import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-search-action';
import { filter, map, startWith } from 'rxjs/operators';
import { IqserPermissionsService } from '@iqser/common-ui';
import { getConfig, IqserPermissionsService } from '@iqser/common-ui';
import { BreadcrumbsService } from '@services/breadcrumbs.service';
import { FeaturesService } from '@services/features.service';
import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@red/domain';
@ -24,6 +24,12 @@ const isSearchScreen: (url: string) => boolean = url => url.includes('/search');
styleUrls: ['./base-screen.component.scss'],
})
export class BaseScreenComponent {
readonly #navigationStart$ = this._router.events.pipe(
filter(isNavigationStart),
map(event => event.url),
startWith(this._router.url),
shareDistinctLast(),
);
readonly roles = Roles;
readonly documentViewer = inject(REDDocumentViewer);
readonly currentUser = this.userService.currentUser;
@ -46,23 +52,8 @@ export class BaseScreenComponent {
action: (query): void => this.#search(query, []),
},
];
readonly #navigationStart$ = this._router.events.pipe(
filter(isNavigationStart),
map(event => event.url),
startWith(this._router.url),
shareDistinctLast(),
);
readonly isSearchScreen$ = this.#navigationStart$.pipe(map(isSearchScreen));
get #hideSearchThisDossier() {
const routerLink = this.breadcrumbsService.breadcrumbs[1]?.options?.routerLink;
if (!routerLink) {
return true;
}
const isDossierOverview = (routerLink.includes(DOSSIERS_ROUTE) || routerLink.includes(ARCHIVE_ROUTE)) && routerLink.length === 3;
return !isDossierOverview;
}
readonly config = getConfig();
constructor(
private readonly _router: Router,
@ -80,6 +71,16 @@ export class BaseScreenComponent {
activatedRoute.queryParamMap.pipe(takeUntilDestroyed()).subscribe(queryParams => this.#navigate(queryParams));
}
get #hideSearchThisDossier() {
const routerLink = this.breadcrumbsService.breadcrumbs[1]?.options?.routerLink;
if (!routerLink) {
return true;
}
const isDossierOverview = (routerLink.includes(DOSSIERS_ROUTE) || routerLink.includes(ARCHIVE_ROUTE)) && routerLink.length === 3;
return !isDossierOverview;
}
#navigate(queryParams: ParamMap) {
if (queryParams.has('username')) {
return this._router.navigate([], {

View File

@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { UntypedFormBuilder } from '@angular/forms';
import { NotificationPreferencesService } from '../../../services/notification-preferences.service';
import { BaseFormComponent, IqserPermissionsService, LoadingService, Toaster } from '@iqser/common-ui';
import { BaseFormComponent, getConfig, LoadingService, Toaster } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import {
NotificationCategoriesValues,
@ -13,7 +13,6 @@ import {
import { firstValueFrom } from 'rxjs';
import { notificationsSettingsTranslations } from '@translations/notifications-settings-translations';
import { getCurrentUser } from '@iqser/common-ui/lib/users';
import { Roles } from '@users/roles';
const RSS_EXCLUDED_SETTINGS = ['USER_PROMOTED_TO_APPROVER', 'USER_DEGRADED_TO_REVIEWER', 'ASSIGN_REVIEWER'];
@ -23,19 +22,17 @@ const RSS_EXCLUDED_SETTINGS = ['USER_PROMOTED_TO_APPROVER', 'USER_DEGRADED_TO_RE
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NotificationsScreenComponent extends BaseFormComponent implements OnInit {
readonly notificationCategories = NotificationCategoriesValues;
readonly notificationGroupsKeys = NotificationGroupsKeys;
readonly notificationGroupsValues = NotificationGroupsValues;
readonly translations = notificationsSettingsTranslations;
readonly currentUser = getCurrentUser<User>();
readonly #toaster = inject(Toaster);
readonly #formBuilder = inject(UntypedFormBuilder);
readonly #loadingService = inject(LoadingService);
readonly #notificationPreferencesService = inject(NotificationPreferencesService);
readonly #cdRef = inject(ChangeDetectorRef);
readonly #iqserPermissionsService = inject(IqserPermissionsService);
readonly #isRss = this.#iqserPermissionsService.has(Roles.getRss);
readonly #config = getConfig();
readonly notificationCategories = NotificationCategoriesValues;
readonly notificationGroupsKeys = NotificationGroupsKeys;
readonly notificationGroupsValues = NotificationGroupsValues;
readonly translations = notificationsSettingsTranslations;
readonly currentUser = getCurrentUser<User>();
constructor() {
super();
@ -46,7 +43,10 @@ export class NotificationsScreenComponent extends BaseFormComponent implements O
}
getRssFilteredSettings(settings: string[]) {
return settings.filter(s => (this.#isRss ? !RSS_EXCLUDED_SETTINGS.includes(s) : true));
if (this.#config.IS_DOCUMINE) {
return settings.filter(s => !RSS_EXCLUDED_SETTINGS.includes(s));
}
return settings;
}
isCategoryActive(category: string) {
@ -86,7 +86,7 @@ export class NotificationsScreenComponent extends BaseFormComponent implements O
this.#loadingService.stop();
}
#getForm(): UntypedFormGroup {
#getForm() {
return this.#formBuilder.group({
inAppNotificationsEnabled: [undefined],
emailNotificationsEnabled: [undefined],

View File

@ -79,7 +79,7 @@
</div>
</div>
<ng-container *deny="roles.getRss">
<ng-container *ngIf="!isDocumine">
<p class="heading download-includes">{{ 'download-includes' | translate }}</p>
<div class="flex">
<redaction-select
@ -130,8 +130,9 @@
[label]="'add-edit-clone-dossier-template.save' | translate"
[type]="iconButtonTypes.primary"
></iqser-icon-button>
<iqser-help-button
*deny="roles.getRss; if: !!dossierTemplate"
*ngIf="!isDocumine && !!dossierTemplate"
[helpButtonKey]="'edit_clone_delete_dossier_templates'"
></iqser-help-button>
</div>

View File

@ -9,7 +9,6 @@ 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';
interface EditCloneTemplateData {
dossierTemplateId: string;
@ -26,16 +25,15 @@ 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;
private _previousValidFrom: Dayjs;
private _previousValidTo: Dayjs;
private _lastValidFrom: Dayjs;
private _lastValidTo: Dayjs;
readonly isDocumine = getConfig().IS_DOCUMINE;
hasValidFrom: boolean;
hasValidTo: boolean;
readonly downloadTypes = downloadTypes;
readonly dossierTemplate: DossierTemplate;
private _previousValidFrom: Dayjs;
private _previousValidTo: Dayjs;
private _lastValidFrom: Dayjs;
private _lastValidTo: Dayjs;
constructor(
private readonly _dossierTemplatesService: DossierTemplatesService,

View File

@ -20,7 +20,8 @@
[submit]="true"
[type]="iconButtonTypes.primary"
></iqser-icon-button>
<iqser-help-button *deny="roles.getRss" [helpButtonKey]="'create_new_entity'"></iqser-help-button>
<iqser-help-button *ngIf="!config.IS_DOCUMINE" [helpButtonKey]="'create_new_entity'"></iqser-help-button>
</div>
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>

View File

@ -1,8 +1,7 @@
import { ChangeDetectionStrategy, Component, inject, ViewChild } from '@angular/core';
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 { BaseDialogComponent, getConfig, IconButtonTypes } from '@iqser/common-ui';
interface DialogData {
readonly dossierTemplateId: string;
@ -14,10 +13,10 @@ interface DialogData {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddEntityDialogComponent extends BaseDialogComponent {
readonly iconButtonTypes = IconButtonTypes;
readonly roles = Roles;
readonly data = inject<DialogData>(MAT_DIALOG_DATA);
@ViewChild(AddEditEntityComponent, { static: true }) private readonly _addEditEntityComponent: AddEditEntityComponent;
readonly iconButtonTypes = IconButtonTypes;
readonly data = inject<DialogData>(MAT_DIALOG_DATA);
readonly config = getConfig();
constructor(protected readonly _dialogRef: MatDialogRef<AddEntityDialogComponent>) {
super(_dialogRef, false);

View File

@ -27,7 +27,7 @@
<div (click)="revert()" [translate]="'entity.info.actions.revert'" class="all-caps-label cancel"></div>
<iqser-help-button *deny="roles.getRss" [helpButtonKey]="'edit_delete_entities'"></iqser-help-button>
<iqser-help-button *ngIf="!config.IS_DOCUMINE" [helpButtonKey]="'edit_delete_entities'"></iqser-help-button>
</div>
</div>
</div>

View File

@ -5,9 +5,8 @@ import { ActivatedRoute } from '@angular/router';
import { getCurrentUser } from '@users/user.service';
import { PermissionsService } from '@services/permissions.service';
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
import { IconButtonTypes } from '@iqser/common-ui';
import { getConfig, IconButtonTypes } from '@iqser/common-ui';
import { Observable } from 'rxjs';
import { Roles } from '@users/roles';
import { IqserEventTarget } from '@iqser/common-ui/lib/utils';
@Component({
@ -21,7 +20,7 @@ export class EntityInfoComponent {
readonly currentUser = getCurrentUser();
readonly entity$: Observable<Dictionary>;
readonly dossierTemplateId: string;
readonly roles = Roles;
readonly config = getConfig();
readonly iconButtonTypes = IconButtonTypes;
constructor(route: ActivatedRoute, dictionariesMapService: DictionariesMapService, readonly permissionsService: PermissionsService) {

View File

@ -86,7 +86,7 @@
[type]="iconButtonTypes.primary"
></iqser-icon-button>
<iqser-help-button *deny="roles.getRss" [helpButtonKey]="'edit_delete_file_attribute'"></iqser-help-button>
<iqser-help-button *ngIf="!config.IS_DOCUMINE" [helpButtonKey]="'edit_delete_file_attribute'"></iqser-help-button>
</div>
</form>

View File

@ -3,14 +3,13 @@ import { ReactiveFormsModule, Validators } from '@angular/forms';
import { FileAttributeConfigTypes, IFileAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { fileAttributeTypesTranslations } from '@translations/file-attribute-types-translations';
import { BaseDialogComponent, CircleButtonComponent, IconButtonComponent, IqserDenyDirective, IqserHelpModeModule } from '@iqser/common-ui';
import { BaseDialogComponent, CircleButtonComponent, getConfig, IconButtonComponent, IqserHelpModeModule } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { NgForOf } from '@angular/common';
import { NgForOf, NgIf } from '@angular/common';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatTooltipModule } from '@angular/material/tooltip';
import { Roles } from '@users/roles';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
export interface AddEditFileAttributeDialogData {
@ -35,12 +34,12 @@ export interface AddEditFileAttributeDialogData {
MatTooltipModule,
IconButtonComponent,
CircleButtonComponent,
IqserDenyDirective,
IqserHelpModeModule,
NgIf,
],
})
export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
readonly roles = Roles;
readonly config = getConfig();
readonly DISPLAYED_FILTERABLE_LIMIT = 3;
readonly translations = fileAttributeTypesTranslations;
readonly fileAttribute = this.data.fileAttribute;

View File

@ -1,20 +0,0 @@
import { Injectable } from '@angular/core';
import { TableColumnConfig } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { PermissionsMapping } from '@red/domain';
import { PermissionsConfigurationMapService } from '@services/entity-permissions/permissions-configuration-map.service';
import { permissionsTranslations } from '@translations/permissions-translations';
@Injectable()
export class ConfigService {
constructor(private readonly _permissionsConfigurationMapService: PermissionsConfigurationMapService) {}
tableConfig(targetObject: string): TableColumnConfig<PermissionsMapping>[] {
const columns = this._permissionsConfigurationMapService.getMappedPermissions(targetObject).map(p => ({
label: permissionsTranslations.mapped[p],
class: 'flex-center',
}));
return [{ label: _('permissions-screen.table-col-names.permission') }, ...columns];
}
}

View File

@ -1,27 +1,34 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { IqserPermissionsService, ListingComponent, listingProvidersFactory, LoadingService, TableColumnConfig } from '@iqser/common-ui';
import { Component, OnInit } from '@angular/core';
import {
getConfig,
IqserPermissionsService,
ListingComponent,
listingProvidersFactory,
LoadingService,
TableColumnConfig,
} from '@iqser/common-ui';
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';
import { ActivatedRoute } from '@angular/router';
import { PermissionsMapService } from '@services/entity-permissions/permissions-map.service';
import { PermissionsConfigurationMapService } from '@services/entity-permissions/permissions-configuration-map.service';
import { interval, map, Subscription } from 'rxjs';
import { interval, map } 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 { getCurrentUser } from '@iqser/common-ui/lib/users';
import { SortingOrders } from '@iqser/common-ui/lib/sorting';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
templateUrl: './permissions-screen.component.html',
styleUrls: ['./permissions-screen.component.scss'],
providers: listingProvidersFactory(PermissionsScreenComponent),
})
export class PermissionsScreenComponent extends ListingComponent<PermissionsMapping> implements OnInit, OnDestroy {
readonly #subscription: Subscription = new Subscription();
export class PermissionsScreenComponent extends ListingComponent<PermissionsMapping> implements OnInit {
readonly #config = getConfig();
readonly roles = Roles;
readonly currentUser = getCurrentUser<User>();
readonly translations = permissionsTranslations;
@ -32,37 +39,37 @@ export class PermissionsScreenComponent extends ListingComponent<PermissionsMapp
constructor(
route: ActivatedRoute,
configService: ConfigService,
private readonly _loadingService: LoadingService,
readonly routerHistoryService: RouterHistoryService,
readonly permissionsService: IqserPermissionsService,
private readonly _permissionsMapService: PermissionsMapService,
private readonly _entityPermissionsService: EntityPermissionsService,
permissionsConfigurationMapService: PermissionsConfigurationMapService,
private readonly _permissionsConfigurationMapService: PermissionsConfigurationMapService,
) {
super();
this.targetObject = route.snapshot.data.permissionsObject;
this.tableColumnConfigs = configService.tableConfig(this.targetObject);
this.mappedPermissions = permissionsConfigurationMapService.getMappedPermissions(this.targetObject);
this.mappedPermissions = this.getMappedPermissions(this.targetObject);
this.tableColumnConfigs = this.getTableConfig(this.mappedPermissions);
this.sortingService.setSortingOption({
column: 'sort',
order: SortingOrders.asc,
});
this.#subscription.add(
this._permissionsMapService
.get$(this.targetObject)
.pipe(
// force update internal mappings set in constructor
map(permissions => permissions.map(p => new PermissionsMapping(p))),
tap(permissions => this.entitiesService.setEntities(permissions)),
)
.subscribe(),
);
this.#subscription.add(
interval(5000)
.pipe(switchMap(() => this._entityPermissionsService.loadFor(this.targetObject)))
.subscribe(),
);
this._permissionsMapService
.get$(this.targetObject)
.pipe(
// force update internal mappings set in constructor
map(permissions => permissions.map(p => new PermissionsMapping(p))),
tap(permissions => this.entitiesService.setEntities(permissions)),
takeUntilDestroyed(),
)
.subscribe();
interval(5000)
.pipe(
switchMap(() => this._entityPermissionsService.loadFor(this.targetObject)),
takeUntilDestroyed(),
)
.subscribe();
}
ngOnInit() {
@ -75,7 +82,20 @@ export class PermissionsScreenComponent extends ListingComponent<PermissionsMapp
this._loadingService.stop();
}
ngOnDestroy(): void {
this.#subscription.unsubscribe();
getMappedPermissions(targetObject: string) {
const mappedPermissions = this._permissionsConfigurationMapService.getMappedPermissions(targetObject);
if (this.#config.IS_DOCUMINE) {
return mappedPermissions.filter(p => p !== 'REVIEW');
}
return mappedPermissions;
}
getTableConfig(mappedPermissions: string[]) {
const columns = mappedPermissions.map(p => ({
label: permissionsTranslations.mapped[p],
class: 'flex-center',
}));
return [{ label: _('permissions-screen.table-col-names.permission') }, ...columns];
}
}

View File

@ -2,7 +2,6 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { PermissionsScreenComponent } from './permissions-screen/permissions-screen.component';
import { ConfigService } from './config.service';
import { TranslateModule } from '@ngx-translate/core';
import { IqserHelpModeModule, IqserListingModule } from '@iqser/common-ui';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
@ -12,6 +11,5 @@ const routes = [{ path: '', component: PermissionsScreenComponent }];
@NgModule({
declarations: [PermissionsScreenComponent],
imports: [RouterModule.forChild(routes), CommonModule, TranslateModule, IqserListingModule, IqserHelpModeModule, MatSlideToggleModule],
providers: [ConfigService],
})
export class PermissionsModule {}

View File

@ -85,7 +85,7 @@
</div>
<div *ngIf="form.get('hasDictionary')?.value" class="dictionary-extras">
<ng-container *deny="roles.getRss">
<ng-container *ngIf="!isDocumine">
<span
(click)="toggleDossierOnlyEntity()"
*ngIf="form.get('dossierDictionaryOnly') as field"

View File

@ -5,10 +5,8 @@ import { map, startWith } from 'rxjs/operators';
import { firstValueFrom, Observable } from 'rxjs';
import { toSnakeCase } from '@utils/functions';
import { DictionariesMapService } from '@services/entity-services/dictionaries-map.service';
import { PermissionsService } from '@services/permissions.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { DictionaryService } from '@services/entity-services/dictionary.service';
import { Roles } from '@users/roles';
import { BaseFormComponent, getConfig, LoadingService, Toaster } from '@iqser/common-ui';
const REDACTION_FIELDS = ['defaultReason'];
@ -36,13 +34,10 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
technicalName$: Observable<string>;
colors: Color[];
readonly roles = Roles;
readonly isDocumine = getConfig().IS_DOCUMINE;
constructor(
private readonly _dictionariesMapService: DictionariesMapService,
private readonly _permissionsService: PermissionsService,
private readonly _dictionaryService: DictionaryService,
private readonly _toaster: Toaster,
private readonly _loadingService: LoadingService,

View File

@ -18,13 +18,13 @@
></redaction-select>
<redaction-select
*deny="roles.getRss"
*ngIf="!isDocumine"
[label]="'download-type.label' | translate : { length: downloadFileTypesLength }"
[options]="downloadTypes"
formControlName="downloadFileTypes"
></redaction-select>
<div *deny="roles.getRss" class="iqser-input-group required">
<div *ngIf="!isDocumine" class="iqser-input-group required">
<label translate="download-dialog.form.redaction-preview-color"></label>
<input
[placeholder]="'download-dialog.form.redaction-preview-color-placeholder' | translate"

View File

@ -4,15 +4,7 @@ import { downloadTypesForDownloadTranslations } from '@translations/download-typ
import { ReportTemplateService } from '@services/report-template.service';
import { AbstractControl, FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
import {
CircleButtonComponent,
getConfig,
IconButtonComponent,
IconButtonTypes,
IqserDenyDirective,
IqserDialogComponent,
} from '@iqser/common-ui';
import { Roles } from '@users/roles';
import { CircleButtonComponent, getConfig, IconButtonComponent, IconButtonTypes, IqserDialogComponent } from '@iqser/common-ui';
import { List } from '@iqser/common-ui/lib/utils';
import { NGXLogger } from 'ngx-logger';
import { AsyncPipe, NgIf } from '@angular/common';
@ -41,7 +33,6 @@ export interface DownloadDialogResult {
ReactiveFormsModule,
SelectComponent,
TranslateModule,
IqserDenyDirective,
ColorPickerModule,
MatIconModule,
IconButtonComponent,
@ -50,15 +41,14 @@ export interface DownloadDialogResult {
],
})
export class DownloadDialogComponent extends IqserDialogComponent<DownloadDialogComponent, DownloadDialogData, DownloadDialogResult> {
readonly #logger = inject(NGXLogger);
readonly iconButtonTypes = IconButtonTypes;
readonly hasApprovedFiles: boolean;
readonly downloadTypes: { key: DownloadFileType; label: string }[];
readonly availableReportTypes = this.#availableReportTypes;
readonly form = this.#getForm();
readonly isDocumine = getConfig().IS_DOCUMINE;
readonly roles = Roles;
initialFormValue = this.form.getRawValue();
readonly #logger = inject(NGXLogger);
constructor(
private readonly _defaultColorsService: DefaultColorsService,

View File

@ -1931,10 +1931,10 @@
},
"label": "{targetObject, select, Dossier{Dossier} other{}} Permissions",
"mapped": {
"approve": "Approvers",
"approve": "Dossier members",
"everyone-else": "Everyone else",
"owner": "Owner",
"review": "Reviewers"
"review": ""
},
"table-col-names": {
"permission": "Permission"

View File

@ -1,4 +1,4 @@
FROM node:20.4-buster as builder
FROM node:20.5-buster as builder
WORKDIR /ng-app