RED-8872: More readonly tabs in edit dossier, rework to signals

This commit is contained in:
Adina Țeudan 2024-05-22 14:16:35 +03:00
parent 29cc0d9a11
commit 7319cc7cc9
3 changed files with 77 additions and 87 deletions

View File

@ -1,18 +1,18 @@
<section *ngIf="dossier$ | async as dossier" class="dialog">
<section class="dialog">
<div
[innerHTML]="'edit-dossier-dialog.header' | translate: { dossierName: dossier.dossierName }"
[innerHTML]="'edit-dossier-dialog.header' | translate: { dossierName: dossier().dossierName }"
class="dialog-header heading-l"
id="editDossierHeader"
></div>
<div class="dialog-content">
<iqser-side-nav [title]="'edit-dossier-dialog.side-nav-title' | translate">
<div *ngFor="let item of navItems">
<div *ngFor="let item of navItems()">
<div
*ngIf="!item.hide"
(click)="changeTab(item.key)"
[class.active]="item.key === activeNav"
*ngIf="!item.hide"
[attr.help-mode-key]="item.helpModeKey"
[class.active]="item.key === activeNav()"
class="item"
>
{{ item.sideNavTitle || item.title | translate }}
@ -22,46 +22,46 @@
</iqser-side-nav>
<div>
<div [class.no-actions]="!showActionButtons" [class.no-padding]="noPaddingTab" class="content">
<div *ngIf="showHeading" class="heading">
{{ activeNavItem.title | translate }}
<div [class.no-actions]="!showActionButtons()" [class.no-padding]="noPaddingTab()" class="content">
<div *ngIf="showHeading()" class="heading">
{{ activeNavItem().title | translate }}
</div>
<div *ngIf="activeNavItem.readonly" class="read-only-indicator all-caps-label primary">
<div *ngIf="activeNavItem().readonly" class="read-only-indicator all-caps-label primary">
<mat-icon class="mr-8" svgIcon="red:read-only"></mat-icon>
{{ 'readonly' | translate }}
</div>
<redaction-edit-dossier-general-info
*ngIf="activeNav === 'dossierInfo'"
[dossier]="dossier"
*ngIf="activeNav() === 'dossierInfo'"
[dossier]="dossier()"
></redaction-edit-dossier-general-info>
<redaction-edit-dossier-download-package
*ngIf="activeNav === 'downloadPackage'"
[dossier]="dossier"
*ngIf="activeNav() === 'downloadPackage'"
[dossier]="dossier()"
></redaction-edit-dossier-download-package>
<redaction-edit-dossier-dictionary
*ngIf="activeNav === 'dossierDictionary'"
[dossier]="dossier"
*ngIf="activeNav() === 'dossierDictionary'"
[dossier]="dossier()"
></redaction-edit-dossier-dictionary>
<redaction-edit-dossier-team *ngIf="activeNav === 'members'" [dossier]="dossier"></redaction-edit-dossier-team>
<redaction-edit-dossier-team *ngIf="activeNav() === 'members'" [dossier]="dossier()"></redaction-edit-dossier-team>
<redaction-edit-dossier-attributes
*ngIf="activeNav === 'dossierAttributes'"
[dossier]="dossier"
*ngIf="activeNav() === 'dossierAttributes'"
[dossier]="dossier()"
></redaction-edit-dossier-attributes>
</div>
<div *ngIf="showActionButtons" class="dialog-actions">
<iqser-icon-button
(action)="save()"
[buttonId]="'saveButton'"
[disabled]="disabled || !valid || !changed"
[label]="'edit-dossier-dialog.actions.save' | translate"
[type]="iconButtonTypes.primary"
[buttonId]="'saveButton'"
></iqser-icon-button>
<iqser-icon-button

View File

@ -1,22 +1,20 @@
import { AfterViewInit, Component, Inject, ViewChild } from '@angular/core';
import { AfterViewInit, Component, computed, Inject, Signal, signal, untracked, ViewChild, WritableSignal } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Dossier, User } from '@red/domain';
import { Dossier } 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, IconButtonTypes, SaveOptions } from '@iqser/common-ui';
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.component';
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 { getCurrentUser } from '@iqser/common-ui/lib/users';
import { ConfigService } from '@services/config.service';
import { toSignal } from '@angular/core/rxjs-interop';
type Section = 'dossierInfo' | 'downloadPackage' | 'dossierDictionary' | 'members' | 'dossierAttributes';
@ -36,20 +34,24 @@ interface NavItem {
})
export class EditDossierDialogComponent extends BaseDialogComponent implements AfterViewInit {
readonly roles = Roles;
navItems: NavItem[] = [];
readonly iconButtonTypes = IconButtonTypes;
activeNav: Section;
readonly dossier$: Observable<Dossier>;
readonly activeNav: WritableSignal<Section>;
readonly dossier: Signal<Dossier>;
readonly navItems: Signal<NavItem[]>;
readonly activeNavItem: Signal<NavItem>;
readonly activeComponent: Signal<EditDossierSectionInterface>;
readonly noPaddingTab: Signal<boolean>;
readonly showHeading: Signal<boolean>;
readonly showActionButtons: Signal<boolean>;
@ViewChild(EditDossierGeneralInfoComponent) generalInfoComponent: EditDossierGeneralInfoComponent;
@ViewChild(EditDossierDownloadPackageComponent) downloadPackageComponent: EditDossierDownloadPackageComponent;
@ViewChild(EditDossierDictionaryComponent) dictionaryComponent: EditDossierDictionaryComponent;
@ViewChild(EditDossierTeamComponent) membersComponent: EditDossierTeamComponent;
@ViewChild(EditDossierAttributesComponent) attributesComponent: EditDossierAttributesComponent;
readonly #currentUser = getCurrentUser<User>();
#dossier: Dossier;
constructor(
readonly iqserPermissionsService: IqserPermissionsService,
private readonly _dossiersService: DossiersService,
private readonly _permissionsService: PermissionsService,
protected readonly _dialogRef: MatDialogRef<EditDossierDialogComponent>,
@ -61,72 +63,43 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
readonly configService: ConfigService,
) {
super(_dialogRef, true);
this.dossier$ = this._dossiersService.getEntityChanged$(this._data.dossierId).pipe(
tap(dossier => {
this.#dossier = dossier;
this._initializeNavItems();
}),
);
this.activeNav = this._data.section || 'dossierInfo';
}
get activeNavItem(): NavItem {
return this.navItems.find(item => item.key === this.activeNav);
}
get activeComponent(): EditDossierSectionInterface {
return {
dossierInfo: this.generalInfoComponent,
downloadPackage: this.downloadPackageComponent,
dossierDictionary: this.dictionaryComponent,
members: this.membersComponent,
dossierAttributes: this.attributesComponent,
}[this.activeNav];
}
get noPaddingTab(): boolean {
return ['dossierAttributes', 'dossierDictionary'].includes(this.activeNav);
}
get showHeading(): boolean {
return !['dossierAttributes', 'dossierDictionary'].includes(this.activeNav);
}
get showActionButtons(): boolean {
return (
(['dossierDictionary'].includes(this.activeNav) && this._permissionsService.canEditDossierDictionary(this.#dossier)) ||
(['members'].includes(this.activeNav) &&
this.#currentUser.isManager &&
this.iqserPermissionsService.has(Roles.dossiers.edit)) ||
this._permissionsService.canEditDossier(this.#dossier)
);
this.dossier = toSignal(this._dossiersService.getEntityChanged$(this._data.dossierId));
this.navItems = computed(() => this._getNavItems(this.dossier()));
this.activeNav = signal(this._data.section || 'dossierInfo');
this.activeNavItem = computed(() => this.navItems().find(item => item.key === this.activeNav()));
this.activeComponent = computed(() => this._getActiveComponent(this.activeNav()));
this.noPaddingTab = computed(() => ['dossierAttributes', 'dossierDictionary'].includes(this.activeNav()));
this.showHeading = computed(() => !['dossierAttributes', 'dossierDictionary'].includes(this.activeNav()));
this.showActionButtons = computed(() => !this.activeNavItem().readonly);
}
get changed(): boolean {
return this.activeComponent?.changed;
return this.activeComponent()?.changed;
}
get valid(): boolean {
return this.activeComponent?.valid;
return this.activeComponent()?.valid;
}
get disabled(): boolean {
return this.activeComponent?.disabled;
return this.activeComponent()?.disabled;
}
ngAfterViewInit() {
if (!this.#dossier.ownerId) {
if (!untracked(this.dossier).ownerId) {
this._toaster.error(_('edit-dossier-dialog.missing-owner'));
}
}
async save(options?: SaveOptions) {
this._loadingService.start();
const result = await this.activeComponent.save();
const result = await untracked(this.activeComponent).save();
this._loadingService.stop();
if (result.success) {
this._toaster.success(_('edit-dossier-dialog.change-successful'), { params: { dossierName: this.#dossier.dossierName } });
this._toaster.success(_('edit-dossier-dialog.change-successful'), {
params: { dossierName: untracked(this.dossier).dossierName },
});
}
if (result.success && options?.closeAfterSave) {
@ -135,7 +108,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
}
revert() {
this.activeComponent.revert();
untracked(this.activeComponent).revert();
}
changeTab(key: Section) {
@ -146,34 +119,44 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
} else {
this.revert();
}
this.activeNav = key;
this.activeNav.set(key);
});
} else {
this.activeNav = key;
this.activeNav.set(key);
}
}
private _initializeNavItems(): void {
this.navItems = [
private _getActiveComponent(section: Section): EditDossierSectionInterface {
return {
dossierInfo: this.generalInfoComponent,
downloadPackage: this.downloadPackageComponent,
dossierDictionary: this.dictionaryComponent,
members: this.membersComponent,
dossierAttributes: this.attributesComponent,
}[section];
}
private _getNavItems(dossier: Dossier): NavItem[] {
return [
{
key: 'dossierInfo',
title: _('edit-dossier-dialog.nav-items.general-info'),
sideNavTitle: _('edit-dossier-dialog.nav-items.dossier-info'),
readonly: !this.#dossier.isActive || !this._permissionsService.canEditDossier(this.#dossier),
readonly: !this._permissionsService.canEditDossier(dossier),
helpModeKey: 'edit_dossier_dossier_info_DIALOG',
},
{
key: 'downloadPackage',
title: _('edit-dossier-dialog.nav-items.choose-download'),
sideNavTitle: _('edit-dossier-dialog.nav-items.download-package'),
readonly: !this._permissionsService.canEditDossier(this.#dossier),
readonly: !this._permissionsService.canEditDossier(dossier),
helpModeKey: 'edit_dossier_download_package_DIALOG',
},
{
key: 'dossierDictionary',
sideNavTitle: _('edit-dossier-dialog.nav-items.dictionary'),
title: _('edit-dossier-dialog.nav-items.dossier-dictionary'),
readonly: !this._permissionsService.canEditDossierDictionary(this.#dossier),
readonly: !this._permissionsService.canEditDossierDictionary(dossier),
helpModeKey: 'edit_dossier_dossier_dictionary_DIALOG',
hide: this.configService.values.IS_DOCUMINE,
},
@ -181,13 +164,13 @@ export class EditDossierDialogComponent extends BaseDialogComponent implements A
key: 'members',
title: _('edit-dossier-dialog.nav-items.team-members'),
sideNavTitle: _('edit-dossier-dialog.nav-items.members'),
readonly: !this._permissionsService.canEditTeamMembers(this.#dossier),
readonly: !this._permissionsService.canEditTeamMembers(dossier),
helpModeKey: 'edit_dossier_members_DIALOG',
},
{
key: 'dossierAttributes',
title: _('edit-dossier-dialog.nav-items.dossier-attributes'),
readonly: !this._permissionsService.canEditDossierAttributes(this.#dossier),
readonly: !this._permissionsService.canEditDossierAttributes(dossier),
helpModeKey: 'edit_dossier_dossier_attributes_DIALOG',
},
];

View File

@ -302,7 +302,14 @@ export class PermissionsService {
}
canEditDossier(dossier: Dossier): boolean {
return this._iqserPermissionsService.has(Roles.dossiers.edit) && this.isManager() && !!dossier?.ownerId;
const dossierTemplate = this._dossierTemplatesService.find(dossier.dossierTemplateId);
return (
this._iqserPermissionsService.has(Roles.dossiers.edit) &&
this.isManager() &&
!!dossier?.ownerId &&
dossier.isActive &&
dossierTemplate.isActive
);
}
canEditDossierDictionary(dossier: Dossier): boolean {