RED-3800: use stopPropagation

This commit is contained in:
Dan Percic 2023-03-18 02:17:25 +02:00
parent 9a53d68efd
commit df0b528b8d
82 changed files with 346 additions and 393 deletions

View File

@ -25,6 +25,7 @@ import {
SERVER_ERROR_SKIP_PATHS, SERVER_ERROR_SKIP_PATHS,
ServerErrorInterceptor, ServerErrorInterceptor,
SkeletonComponent, SkeletonComponent,
StopPropagationDirective,
ToastComponent, ToastComponent,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { ToastrModule } from 'ngx-toastr'; import { ToastrModule } from 'ngx-toastr';
@ -161,6 +162,7 @@ export const appModuleFactory = (config: AppConfig) => {
SkeletonComponent, SkeletonComponent,
LogoComponent, LogoComponent,
HiddenActionDirective, HiddenActionDirective,
StopPropagationDirective,
], ],
providers: [ providers: [
{ {

View File

@ -1,7 +1,7 @@
<iqser-circle-button <iqser-circle-button
buttonId="notification-button"
[matMenuTriggerFor]="menu" [matMenuTriggerFor]="menu"
[showDot]="hasUnreadNotifications$ | async" [showDot]="hasUnreadNotifications$ | async"
buttonId="notification-button"
icon="red:notification" icon="red:notification"
></iqser-circle-button> ></iqser-circle-button>
@ -19,22 +19,24 @@
<div class="all-caps-label flex-align-items-center"> <div class="all-caps-label flex-align-items-center">
<div>{{ group.date }}</div> <div>{{ group.date }}</div>
<div <div
(click)="markRead($event)" (click)="markRead()"
*ngIf="(hasUnreadNotifications$ | async) && first" *ngIf="(hasUnreadNotifications$ | async) && first"
id="notifications-mark-all-as-read-btn"
class="view-all" class="view-all"
id="notifications-mark-all-as-read-btn"
stopPropagation
> >
{{ 'notifications.mark-all-as-read' | translate }} {{ 'notifications.mark-all-as-read' | translate }}
</div> </div>
</div> </div>
<div <div
(click)="markRead($event, [notification], true)" (click)="markRead([notification], true)"
*ngFor="let notification of group.notifications; trackBy: trackBy" *ngFor="let notification of group.notifications; trackBy: trackBy"
[id]="'notifications-mark-as-read-' + notification.id + '-btn'"
[class.unread]="!notification.readDate" [class.unread]="!notification.readDate"
[id]="'notifications-mark-as-read-' + notification.id + '-btn'"
class="notification" class="notification"
mat-menu-item mat-menu-item
stopPropagation
> >
<iqser-initials-avatar [user]="notification.userId"></iqser-initials-avatar> <iqser-initials-avatar [user]="notification.userId"></iqser-initials-avatar>
@ -42,12 +44,14 @@
<div [innerHTML]="notification.message"></div> <div [innerHTML]="notification.message"></div>
<div class="small-label mt-2">{{ notification.creationDate | date : 'exactDate' }}</div> <div class="small-label mt-2">{{ notification.creationDate | date : 'exactDate' }}</div>
</div> </div>
<div <div
(click)="markRead($event, [notification], !notification.readDate)" (click)="markRead([notification], !notification.readDate)"
[id]="'notifications-mark-' + notification.id"
class="dot" class="dot"
matTooltip="{{ 'notifications.mark-as' | translate : { type: notification.readDate ? 'unread' : 'read' } }}" matTooltip="{{ 'notifications.mark-as' | translate : { type: notification.readDate ? 'unread' : 'read' } }}"
matTooltipPosition="before" matTooltipPosition="before"
[id]="'notifications-mark-' + notification.id" stopPropagation
></div> ></div>
</div> </div>
</div> </div>

View File

@ -48,9 +48,7 @@ export class NotificationsComponent {
); );
} }
async markRead($event, notifications: Notification[] = this._notificationsService.all, isRead = true): Promise<void> { async markRead(notifications: Notification[] = this._notificationsService.all, isRead = true): Promise<void> {
$event.stopPropagation();
if (!notifications.find(notification => !!notification.readDate !== isRead)) { if (!notifications.find(notification => !!notification.readDate !== isRead)) {
// If no notification changes status after the request, abort // If no notification changes status after the request, abort
return; return;

View File

@ -86,7 +86,7 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
const value = this.form.getRawValue() as IProfile; const value = this.form.getRawValue() as IProfile;
if (this.emailChanged) { if (this.emailChanged) {
const dialogRef = this._dialogService.openDialog('confirmPassword', null, null); const dialogRef = this._dialogService.openDialog('confirmPassword');
const password = await firstValueFrom(dialogRef.afterClosed()); const password = await firstValueFrom(dialogRef.afterClosed());
if (!password) { if (!password) {
return; return;

View File

@ -17,8 +17,8 @@ import { PermissionsService } from '@services/permissions.service';
export class BaseEntityScreenComponent { export class BaseEntityScreenComponent {
readonly disabledItems$: Observable<string[]>; readonly disabledItems$: Observable<string[]>;
readonly canDeleteEntity$: Observable<boolean>; readonly canDeleteEntity$: Observable<boolean>;
readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID); readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly #entityType: string = getParam(ENTITY_TYPE); readonly #entityType = getParam(ENTITY_TYPE);
constructor( constructor(
private readonly _router: Router, private readonly _router: Router,
@ -37,7 +37,7 @@ export class BaseEntityScreenComponent {
} }
openDeleteDictionariesDialog() { openDeleteDictionariesDialog() {
this._dialogService.openDialog('confirm', null, null, async () => { this._dialogService.openDialog('confirm', null, async () => {
this._loadingService.start(); this._loadingService.start();
const dossierTemplate = this._dossierTemplatesService.find(this.#dossierTemplateId); const dossierTemplate = this._dossierTemplatesService.find(this.#dossierTemplateId);
await firstValueFrom(this._dictionaryService.deleteDictionaries([this.#entityType], this.#dossierTemplateId)); await firstValueFrom(this._dictionaryService.deleteDictionaries([this.#entityType], this.#dossierTemplateId));

View File

@ -103,7 +103,7 @@ export class UserDetailsComponent extends BaseFormComponent implements OnChanges
} }
delete() { delete() {
this._dialogService.deleteUsers([this.user.id], null, () => this.closeDialog.emit(true)); this._dialogService.deleteUsers([this.user.id], () => this.closeDialog.emit(true));
} }
setRolesRequirements(checked: boolean, role: string): void { setRolesRequirements(checked: boolean, role: string): void {

View File

@ -99,7 +99,7 @@
<div class="cell"> <div class="cell">
<div class="action-buttons"> <div class="action-buttons">
<iqser-circle-button <iqser-circle-button
(action)="openAuditDetails($event, log)" (action)="openAuditDetails(log)"
*ngIf="log.hasDetails" *ngIf="log.hasDetails"
[tooltip]="'audit-screen.action.info' | translate" [tooltip]="'audit-screen.action.info' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"

View File

@ -83,6 +83,10 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
} }
} }
openAuditDetails(log: Audit) {
this._dialogService.openDialog('auditInfo', { auditEntry: log });
}
private _getForm(): UntypedFormGroup { private _getForm(): UntypedFormGroup {
return this._formBuilder.group({ return this._formBuilder.group({
category: [this.ALL_CATEGORIES], category: [this.ALL_CATEGORIES],
@ -136,8 +140,4 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
} }
this._loadingService.stop(); this._loadingService.stop();
} }
openAuditDetails($event: MouseEvent, log: Audit) {
this._dialogService.openDialog('auditInfo', $event, { auditEntry: log });
}
} }

View File

@ -38,7 +38,7 @@
<div class="cell"> <div class="cell">
<div class="action-buttons"> <div class="action-buttons">
<iqser-circle-button <iqser-circle-button
(action)="openEditColorDialog($event, entity)" (action)="openEditColorDialog(entity)"
*allow="roles.colors.write; if: currentUser.isAdmin" *allow="roles.colors.write; if: currentUser.isAdmin"
[iqserHelpMode]="'default_colors'" [iqserHelpMode]="'default_colors'"
[overlappingElements]="['USER_MENU']" [overlappingElements]="['USER_MENU']"

View File

@ -53,7 +53,7 @@ export class DefaultColorsScreenComponent extends ListingComponent<ListItem> {
); );
} }
openEditColorDialog($event: MouseEvent, color: ListItem) { openEditColorDialog(color: ListItem) {
this._dialogService.openDialog('editColor', $event, { colorKey: color.key, dossierTemplateId: this.#dossierTemplateId }); this._dialogService.openDialog('editColor', { colorKey: color.key, dossierTemplateId: this.#dossierTemplateId });
} }
} }

View File

@ -81,7 +81,7 @@ export class DigitalSignatureScreenComponent implements OnInit {
} }
openConfigureCertificate(): void { openConfigureCertificate(): void {
const dialogRef = this._dialogService.openDialog('configureCertificate', null, null); const dialogRef = this._dialogService.openDialog('configureCertificate');
firstValueFrom(dialogRef.afterClosed()).then(async res => { firstValueFrom(dialogRef.afterClosed()).then(async res => {
if (res) { if (res) {
await this.loadDigitalSignature(); await this.loadDigitalSignature();

View File

@ -21,7 +21,7 @@
<div class="content-container"> <div class="content-container">
<iqser-table <iqser-table
(noDataAction)="openAddEditAttributeDialog(null)" (noDataAction)="openAddEditAttributeDialog()"
[bulkActions]="bulkActions" [bulkActions]="bulkActions"
[headerTemplate]="headerTemplate" [headerTemplate]="headerTemplate"
[itemSize]="50" [itemSize]="50"
@ -56,11 +56,11 @@
></iqser-input-with-action> ></iqser-input-with-action>
<iqser-icon-button <iqser-icon-button
(action)="openAddEditAttributeDialog($event)" (action)="openAddEditAttributeDialog()"
*ngIf="canEditDossierAttributes" *ngIf="canEditDossierAttributes"
[iqserHelpMode]="'create_new_dossier_attribute'" [iqserHelpMode]="'create_new_dossier_attribute'"
[overlappingElements]="['USER_MENU']"
[label]="'dossier-attributes-listing.add-new' | translate" [label]="'dossier-attributes-listing.add-new' | translate"
[overlappingElements]="['USER_MENU']"
[type]="iconButtonTypes.primary" [type]="iconButtonTypes.primary"
icon="iqser:plus" icon="iqser:plus"
></iqser-icon-button> ></iqser-icon-button>
@ -91,7 +91,7 @@
<div *ngIf="canEditDossierAttributes" class="action-buttons"> <div *ngIf="canEditDossierAttributes" class="action-buttons">
<div [iqserHelpMode]="'edit_delete_dossier_attributes'" [overlappingElements]="['USER_MENU']"> <div [iqserHelpMode]="'edit_delete_dossier_attributes'" [overlappingElements]="['USER_MENU']">
<iqser-circle-button <iqser-circle-button
(action)="openAddEditAttributeDialog($event, attribute)" (action)="openAddEditAttributeDialog(attribute)"
[tooltip]="'dossier-attributes-listing.action.edit' | translate" [tooltip]="'dossier-attributes-listing.action.edit' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:edit" icon="iqser:edit"

View File

@ -54,27 +54,18 @@ export class DossierAttributesListingScreenComponent extends ListingComponent<Do
} }
async openConfirmDeleteAttributeDialog($event: MouseEvent, attributes: DossierAttributeConfig[] = this.listingService.selected) { async openConfirmDeleteAttributeDialog($event: MouseEvent, attributes: DossierAttributeConfig[] = this.listingService.selected) {
await this._dialogService.deleteAttributes( await this._dialogService.deleteAttributes(attributes, this.#dossierTemplateId, this.impactedTemplatesRef, 'dossier', async () => {
attributes, this._loadingService.start();
this.#dossierTemplateId, const ids = attributes.map(a => a.id);
this.impactedTemplatesRef, await firstValueFrom(this._dossierAttributesService.delete(ids, this.#dossierTemplateId));
'dossier', await this._loadData();
$event, });
async () => {
this._loadingService.start();
const ids = attributes.map(a => a.id);
await firstValueFrom(this._dossierAttributesService.delete(ids, this.#dossierTemplateId));
await this._loadData();
},
);
} }
openAddEditAttributeDialog($event: MouseEvent, dossierAttribute?: IDossierAttributeConfig) { openAddEditAttributeDialog(dossierAttribute?: IDossierAttributeConfig) {
const dossierTemplateId = this.#dossierTemplateId; const dossierTemplateId = this.#dossierTemplateId;
this._dialogService.openDialog('addEditDossierAttribute', $event, { dossierAttribute, dossierTemplateId }, async () => this._dialogService.openDialog('addEditDossierAttribute', { dossierAttribute, dossierTemplateId }, async () => this._loadData());
this._loadData(),
);
} }
private async _loadData() { private async _loadData() {

View File

@ -52,7 +52,7 @@
></iqser-input-with-action> ></iqser-input-with-action>
<iqser-icon-button <iqser-icon-button
(action)="openAddStateDialog($event)" (action)="openAddStateDialog()"
*ngIf="permissionsService.canPerformDossierStatesActions()" *ngIf="permissionsService.canPerformDossierStatesActions()"
[iqserHelpMode]="'create_new_dossier_state'" [iqserHelpMode]="'create_new_dossier_state'"
[label]="'dossier-states-listing.add-new' | translate" [label]="'dossier-states-listing.add-new' | translate"

View File

@ -58,9 +58,7 @@ export class DossierStatesListingScreenComponent extends ListingComponent<Dossie
await firstValueFrom(this._dossierStatesService.loadAllForTemplate(this.#dossierTemplateId)); await firstValueFrom(this._dossierStatesService.loadAllForTemplate(this.#dossierTemplateId));
} }
openAddStateDialog($event: MouseEvent) { openAddStateDialog() {
$event.stopPropagation();
this._dialog.open<AddEditDossierStateDialogComponent, AddEditDossierStateDialogData>(AddEditDossierStateDialogComponent, { this._dialog.open<AddEditDossierStateDialogComponent, AddEditDossierStateDialogData>(AddEditDossierStateDialogComponent, {
...defaultDialogConfig, ...defaultDialogConfig,
data: { data: {

View File

@ -17,14 +17,14 @@
<div *ngIf="permissionsService.canPerformDossierStatesActions()" class="action-buttons"> <div *ngIf="permissionsService.canPerformDossierStatesActions()" class="action-buttons">
<div [iqserHelpMode]="'edit_delete_dossier_state'"> <div [iqserHelpMode]="'edit_delete_dossier_state'">
<iqser-circle-button <iqser-circle-button
(action)="openEditStateDialog($event, state)" (action)="openEditStateDialog(state)"
[tooltip]="'dossier-states-listing.action.edit' | translate" [tooltip]="'dossier-states-listing.action.edit' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:edit" icon="iqser:edit"
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="openConfirmDeleteStateDialog($event, state)" (action)="openConfirmDeleteStateDialog(state)"
[tooltip]="'dossier-states-listing.action.delete' | translate" [tooltip]="'dossier-states-listing.action.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:trash" icon="iqser:trash"

View File

@ -25,9 +25,7 @@ export class DossierStatesTableItemComponent {
readonly #dialog = inject(MatDialog); readonly #dialog = inject(MatDialog);
readonly #entitiesService = inject(EntitiesService); readonly #entitiesService = inject(EntitiesService);
openConfirmDeleteStateDialog($event: MouseEvent, dossierState: DossierState) { openConfirmDeleteStateDialog(dossierState: DossierState) {
$event.stopPropagation();
const data: ConfirmDeleteDossierStateDialogData = { const data: ConfirmDeleteDossierStateDialogData = {
toBeDeletedState: dossierState, toBeDeletedState: dossierState,
otherStates: this.#entitiesService.all.filter(s => s.id !== dossierState.id), otherStates: this.#entitiesService.all.filter(s => s.id !== dossierState.id),
@ -43,9 +41,7 @@ export class DossierStatesTableItemComponent {
); );
} }
openEditStateDialog($event: MouseEvent, dossierState: IDossierState) { openEditStateDialog(dossierState: IDossierState) {
$event.stopPropagation();
this.#dialog.open<AddEditDossierStateDialogComponent, AddEditDossierStateDialogData>(AddEditDossierStateDialogComponent, { this.#dialog.open<AddEditDossierStateDialogComponent, AddEditDossierStateDialogData>(AddEditDossierStateDialogComponent, {
...defaultDialogConfig, ...defaultDialogConfig,
data: { data: {

View File

@ -18,21 +18,21 @@
<ng-template #bulkActions> <ng-template #bulkActions>
<iqser-circle-button <iqser-circle-button
buttonId="dossier-template-listing-bulk-delete-btn" (action)="openBulkDeleteTemplatesDialog()"
(action)="openBulkDeleteTemplatesDialog($event)"
*allow="roles.templates.write; if: currentUser.isAdmin && (listingService.areSomeSelected$ | async)" *allow="roles.templates.write; if: currentUser.isAdmin && (listingService.areSomeSelected$ | async)"
[icon]="'iqser:trash'" [icon]="'iqser:trash'"
[tooltip]="'dossier-templates-listing.bulk.delete' | translate" [tooltip]="'dossier-templates-listing.bulk.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
buttonId="dossier-template-listing-bulk-delete-btn"
></iqser-circle-button> ></iqser-circle-button>
</ng-template> </ng-template>
<ng-template #headerTemplate> <ng-template #headerTemplate>
<div class="table-header-actions"> <div class="table-header-actions">
<iqser-input-with-action <iqser-input-with-action
inputId="dossier-template-listing-search-input"
[(value)]="searchService.searchValue" [(value)]="searchService.searchValue"
[placeholder]="'dossier-templates-listing.search' | translate" [placeholder]="'dossier-templates-listing.search' | translate"
inputId="dossier-template-listing-search-input"
></iqser-input-with-action> ></iqser-input-with-action>
<iqser-icon-button <iqser-icon-button

View File

@ -54,14 +54,14 @@ export class DossierTemplatesListingScreenComponent extends ListingComponent<Dos
super(); super();
} }
openBulkDeleteTemplatesDialog($event?: MouseEvent) { openBulkDeleteTemplatesDialog() {
return this._dialogService.openDialog('confirm', $event, null, () => { return this._dialogService.openDialog('confirm', null, () => {
this._loadingService.loadWhile(this._deleteTemplates()); this._loadingService.loadWhile(this._deleteTemplates());
}); });
} }
openAddDossierTemplateDialog() { openAddDossierTemplateDialog() {
this._dialogService.openDialog('addEditCloneDossierTemplate', null, null); this._dialogService.openDialog('addEditCloneDossierTemplate');
} }
private async _deleteTemplates(templateIds = this.listingService.selected.map(d => d.dossierTemplateId)) { private async _deleteTemplates(templateIds = this.listingService.selected.map(d => d.dossierTemplateId)) {

View File

@ -39,7 +39,7 @@
<ng-template #bulkActions> <ng-template #bulkActions>
<iqser-circle-button <iqser-circle-button
(action)="openDeleteEntitiesDialog($event)" (action)="openDeleteEntitiesDialog()"
*ngIf="permissionsService.canDeleteEntities(listingService.selected)" *ngIf="permissionsService.canDeleteEntities(listingService.selected)"
[tooltip]="'entities-listing.bulk.delete' | translate" [tooltip]="'entities-listing.bulk.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
@ -58,8 +58,8 @@
(action)="openAddEntityDialog()" (action)="openAddEntityDialog()"
*ngIf="permissionsService.canEditEntities()" *ngIf="permissionsService.canEditEntities()"
[iqserHelpMode]="'create_new_entity'" [iqserHelpMode]="'create_new_entity'"
[overlappingElements]="['USER_MENU']"
[label]="'entities-listing.add-new' | translate" [label]="'entities-listing.add-new' | translate"
[overlappingElements]="['USER_MENU']"
[type]="iconButtonTypes.primary" [type]="iconButtonTypes.primary"
icon="iqser:plus" icon="iqser:plus"
></iqser-icon-button> ></iqser-icon-button>
@ -101,7 +101,7 @@
<div class="action-buttons"> <div class="action-buttons">
<div [iqserHelpMode]="'edit_delete_entities'" [overlappingElements]="['USER_MENU']"> <div [iqserHelpMode]="'edit_delete_entities'" [overlappingElements]="['USER_MENU']">
<iqser-circle-button <iqser-circle-button
(action)="openDeleteEntitiesDialog($event, [dict])" (action)="openDeleteEntitiesDialog([dict])"
*ngIf="permissionsService.canDeleteEntities(dict)" *ngIf="permissionsService.canDeleteEntities(dict)"
[tooltip]="'entities-listing.action.delete' | translate" [tooltip]="'entities-listing.action.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"

View File

@ -48,8 +48,8 @@ export class EntitiesListingScreenComponent extends ListingComponent<Dictionary>
this.templateStats$ = this._dossierTemplateStatsService.watch$(this.#dossierTemplateId).pipe(tap(() => this._loadDictionaryData())); this.templateStats$ = this._dossierTemplateStatsService.watch$(this.#dossierTemplateId).pipe(tap(() => this._loadDictionaryData()));
} }
openDeleteEntitiesDialog($event?: MouseEvent, types = this.listingService.selected) { openDeleteEntitiesDialog(types = this.listingService.selected) {
this._dialogService.openDialog('confirm', $event, null, async () => { this._dialogService.openDialog('confirm', null, async () => {
this._loadingService.start(); this._loadingService.start();
await firstValueFrom( await firstValueFrom(
this._dictionaryService.deleteDictionaries( this._dictionaryService.deleteDictionaries(
@ -62,8 +62,8 @@ export class EntitiesListingScreenComponent extends ListingComponent<Dictionary>
}); });
} }
openAddEntityDialog($event?: MouseEvent) { openAddEntityDialog() {
this._dialogService.openDialog('addEntity', $event, { dossierTemplateId: this.#dossierTemplateId }); this._dialogService.openDialog('addEntity', { dossierTemplateId: this.#dossierTemplateId });
} }
private _loadDictionaryData(): void { private _loadDictionaryData(): void {

View File

@ -45,7 +45,7 @@
<ng-template #bulkActions> <ng-template #bulkActions>
<iqser-circle-button <iqser-circle-button
(action)="openConfirmDeleteAttributeDialog($event)" (action)="openConfirmDeleteAttributeDialog()"
*ngIf="permissionsService.canEditGlobalFileAttributes() && (listingService.areSomeSelected$ | async)" *ngIf="permissionsService.canEditGlobalFileAttributes() && (listingService.areSomeSelected$ | async)"
[tooltip]="'file-attributes-listing.bulk-actions.delete' | translate" [tooltip]="'file-attributes-listing.bulk-actions.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
@ -73,7 +73,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="openConfigurationsDialog($event)" (action)="openConfigurationsDialog()"
*allow="roles.fileAttributes.writeConfig; if: currentUser.isAdmin" *allow="roles.fileAttributes.writeConfig; if: currentUser.isAdmin"
[iqserHelpMode]="'upload_file_attribute'" [iqserHelpMode]="'upload_file_attribute'"
[overlappingElements]="['USER_MENU']" [overlappingElements]="['USER_MENU']"
@ -84,7 +84,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-icon-button <iqser-icon-button
(action)="openAddEditAttributeDialog($event)" (action)="openAddEditAttributeDialog()"
*ngIf="permissionsService.canEditGlobalFileAttributes()" *ngIf="permissionsService.canEditGlobalFileAttributes()"
[iqserHelpMode]="'create_new_file_attribute'" [iqserHelpMode]="'create_new_file_attribute'"
[label]="'file-attributes-listing.add-new' | translate" [label]="'file-attributes-listing.add-new' | translate"
@ -134,13 +134,14 @@
<div *ngIf="permissionsService.canEditGlobalFileAttributes()" class="action-buttons"> <div *ngIf="permissionsService.canEditGlobalFileAttributes()" class="action-buttons">
<div [iqserHelpMode]="'edit_delete_file_attribute'" [overlappingElements]="['USER_MENU']"> <div [iqserHelpMode]="'edit_delete_file_attribute'" [overlappingElements]="['USER_MENU']">
<iqser-circle-button <iqser-circle-button
(action)="openAddEditAttributeDialog($event, attribute)" (action)="openAddEditAttributeDialog(attribute)"
[tooltip]="'file-attributes-listing.action.edit' | translate" [tooltip]="'file-attributes-listing.action.edit' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:edit" icon="iqser:edit"
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="openConfirmDeleteAttributeDialog($event, [attribute])" (action)="openConfirmDeleteAttributeDialog([attribute])"
[tooltip]="'file-attributes-listing.action.delete' | translate" [tooltip]="'file-attributes-listing.action.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:trash" icon="iqser:trash"

View File

@ -76,36 +76,26 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
await this.#loadData(); await this.#loadData();
} }
openAddEditAttributeDialog($event: MouseEvent, fileAttribute?: IFileAttributeConfig) { openAddEditAttributeDialog(fileAttribute?: IFileAttributeConfig) {
const data = { const data = {
fileAttribute, fileAttribute,
dossierTemplateId: this.#dossierTemplateId, dossierTemplateId: this.#dossierTemplateId,
numberOfDisplayedAttrs: this._numberOfDisplayedAttrs, numberOfDisplayedAttrs: this._numberOfDisplayedAttrs,
numberOfFilterableAttrs: this._numberOfFilterableAttrs, numberOfFilterableAttrs: this._numberOfFilterableAttrs,
}; };
this._dialogService.openDialog('addEditFileAttribute', $event, data, (newValue: IFileAttributeConfig) => { this._dialogService.openDialog('addEditFileAttribute', data, (newValue: IFileAttributeConfig) => {
this._loadingService.loadWhile(this.#createNewFileAttributeAndRefreshView(newValue)); this._loadingService.loadWhile(this.#createNewFileAttributeAndRefreshView(newValue));
}); });
} }
async openConfirmDeleteAttributeDialog( async openConfirmDeleteAttributeDialog(attributes: FileAttributeConfig[] = this.listingService.selected): Promise<void> {
$event: MouseEvent, await this._dialogService.deleteAttributes(attributes, this.#dossierTemplateId, this._impactedTemplatesRef, 'file', async () => {
attributes: FileAttributeConfig[] = this.listingService.selected, this._loadingService.start();
): Promise<void> { const ids = attributes.map(a => a.id);
await this._dialogService.deleteAttributes( await firstValueFrom(this._fileAttributesService.deleteFileAttributes(ids, this.#dossierTemplateId));
attributes, await firstValueFrom(this._dossierTemplatesService.refreshDossierTemplate(this.#dossierTemplateId));
this.#dossierTemplateId, await this.#loadData();
this._impactedTemplatesRef, });
'file',
$event,
async () => {
this._loadingService.start();
const ids = attributes.map(a => a.id);
await firstValueFrom(this._fileAttributesService.deleteFileAttributes(ids, this.#dossierTemplateId));
await firstValueFrom(this._dossierTemplatesService.refreshDossierTemplate(this.#dossierTemplateId));
await this.#loadData();
},
);
} }
importCSV(files: FileList | File[]) { importCSV(files: FileList | File[]) {
@ -114,7 +104,6 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
this._dialogService.openDialog( this._dialogService.openDialog(
'importFileAttributes', 'importFileAttributes',
null,
{ {
csv, csv,
dossierTemplateId: this.#dossierTemplateId, dossierTemplateId: this.#dossierTemplateId,
@ -124,8 +113,8 @@ export class FileAttributesListingScreenComponent extends ListingComponent<FileA
); );
} }
openConfigurationsDialog($event: MouseEvent) { openConfigurationsDialog() {
const ref = this._dialogService.openDialog('fileAttributesConfigurations', $event, { const ref = this._dialogService.openDialog('fileAttributesConfigurations', {
config: this.#existingConfiguration, config: this.#existingConfiguration,
dossierTemplateId: this.#dossierTemplateId, dossierTemplateId: this.#dossierTemplateId,
}); });

View File

@ -42,7 +42,7 @@ export class SmtpFormComponent extends BaseFormComponent implements OnInit {
} }
openAuthConfigDialog(skipDisableOnCancel?: boolean) { openAuthConfigDialog(skipDisableOnCancel?: boolean) {
this._dialogService.openDialog('smtpAuthConfig', null, this.form.getRawValue(), null, authConfig => { this._dialogService.openDialog('smtpAuthConfig', this.form.getRawValue(), null, authConfig => {
if (authConfig) { if (authConfig) {
this.form.patchValue(authConfig); this.form.patchValue(authConfig);
} else if (!skipDisableOnCancel) { } else if (!skipDisableOnCancel) {

View File

@ -48,7 +48,8 @@ export class JustificationsDialogService extends DialogService<DialogType> {
justificationName: justifications[0].name, justificationName: justifications[0].name,
}, },
}); });
this.openDialog('confirm', null, data, async () => {
this.openDialog('confirm', data, async () => {
this._loadingService.start(); this._loadingService.start();
const justificationIds = justifications.map(j => j.id); const justificationIds = justifications.map(j => j.id);
await firstValueFrom(this._justificationService.delete(justificationIds, dossierTemplateId)); await firstValueFrom(this._justificationService.delete(justificationIds, dossierTemplateId));

View File

@ -60,7 +60,7 @@ export class JustificationsScreenComponent extends ListingComponent<Justificatio
} }
openAddJustificationDialog(): void { openAddJustificationDialog(): void {
this._dialogService.openDialog('addEditJustification', null, { justification: null, dossierTemplateId: this.#dossierTemplateId }); this._dialogService.openDialog('addEditJustification', { justification: null, dossierTemplateId: this.#dossierTemplateId });
} }
openConfirmDeleteDialog() { openConfirmDeleteDialog() {

View File

@ -18,7 +18,7 @@ export class TableItemComponent {
constructor(private readonly _dialogService: JustificationsDialogService) {} constructor(private readonly _dialogService: JustificationsDialogService) {}
openEditJustificationDialog() { openEditJustificationDialog() {
this._dialogService.openDialog('addEditJustification', null, { this._dialogService.openDialog('addEditJustification', {
justification: this.justification, justification: this.justification,
dossierTemplateId: this.#dossierTemplateId, dossierTemplateId: this.#dossierTemplateId,
}); });

View File

@ -67,7 +67,7 @@ export class ReportsScreenComponent implements OnInit {
} }
deleteTemplate(template: IReportTemplate) { deleteTemplate(template: IReportTemplate) {
this._dialogService.openDialog('confirm', null, null, () => { this._dialogService.openDialog('confirm', null, () => {
this._loadingService.loadWhile(this._deleteTemplate(template)); this._loadingService.loadWhile(this._deleteTemplate(template));
}); });
} }
@ -90,7 +90,7 @@ export class ReportsScreenComponent implements OnInit {
fileName: file.name, fileName: file.name,
}, },
}); });
this._dialogService.openDialog('confirm', null, data, null, async result => { this._dialogService.openDialog('confirm', data, null, async result => {
if (result) { if (result) {
const multiFileReport = result > 1; const multiFileReport = result > 1;
if ( if (
@ -129,7 +129,7 @@ export class ReportsScreenComponent implements OnInit {
}, },
}); });
this._dialogService.openDialog('confirm', null, data, null, async result => { this._dialogService.openDialog('confirm', data, null, async result => {
if (result) { if (result) {
await this._uploadTemplateForm(file, multiFileReport); await this._uploadTemplateForm(file, multiFileReport);
} }

View File

@ -1,5 +1,4 @@
<iqser-page-header <iqser-page-header
searchInputId="user-management-search-input"
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()" (closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
[buttonConfigs]="buttonConfigs" [buttonConfigs]="buttonConfigs"
[hideResetButton]="true" [hideResetButton]="true"
@ -7,6 +6,7 @@
[searchPlaceholder]="'user-listing.search' | translate" [searchPlaceholder]="'user-listing.search' | translate"
[searchPosition]="searchPositions.withActions" [searchPosition]="searchPositions.withActions"
[showCloseButton]="true" [showCloseButton]="true"
searchInputId="user-management-search-input"
></iqser-page-header> ></iqser-page-header>
<div class="content-inner"> <div class="content-inner">
@ -28,7 +28,6 @@
<ng-template #bulkActions> <ng-template #bulkActions>
<iqser-circle-button <iqser-circle-button
buttonId="bulk-delete-users-btn"
(action)="bulkDelete()" (action)="bulkDelete()"
*ngIf="listingService.areSomeSelected$ | async" *ngIf="listingService.areSomeSelected$ | async"
[disabled]="(canDeleteSelected$ | async) === false" [disabled]="(canDeleteSelected$ | async) === false"
@ -36,6 +35,7 @@
(canDeleteSelected$ | async) ? ('user-listing.bulk.delete' | translate) : ('user-listing.bulk.delete-disabled' | translate) (canDeleteSelected$ | async) ? ('user-listing.bulk.delete' | translate) : ('user-listing.bulk.delete-disabled' | translate)
" "
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
buttonId="bulk-delete-users-btn"
icon="iqser:trash" icon="iqser:trash"
tooltipPosition="after" tooltipPosition="after"
></iqser-circle-button> ></iqser-circle-button>
@ -53,10 +53,10 @@
<div class="center cell"> <div class="center cell">
<mat-slide-toggle <mat-slide-toggle
[id]="'toggle-active-' + user.id"
(toggleChange)="toggleActive(user)" (toggleChange)="toggleActive(user)"
[checked]="user.active" [checked]="user.active"
[disabled]="!canDeactivate(user)" [disabled]="!canDeactivate(user)"
[id]="'toggle-active-' + user.id"
[iqserHelpMode]="'activate_deactivate_user'" [iqserHelpMode]="'activate_deactivate_user'"
color="primary" color="primary"
></mat-slide-toggle> ></mat-slide-toggle>
@ -71,14 +71,14 @@
<div class="action-buttons"> <div class="action-buttons">
<div *allow="roles.users.write" [iqserHelpMode]="'edit_delete_user'"> <div *allow="roles.users.write" [iqserHelpMode]="'edit_delete_user'">
<iqser-circle-button <iqser-circle-button
(action)="openAddEditUserDialog($event, user)" (action)="openAddEditUserDialog(user)"
[tooltip]="'user-listing.action.edit' | translate" [tooltip]="'user-listing.action.edit' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:edit" icon="iqser:edit"
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="openDeleteUsersDialog([user.id], $event)" (action)="openDeleteUsersDialog([user.id])"
[disabled]="deleteDisabled(user)" [disabled]="deleteDisabled(user)"
[tooltip]="'user-listing.action.delete' | translate" [tooltip]="'user-listing.action.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"

View File

@ -92,14 +92,14 @@ export class UserListingScreenComponent extends ListingComponent<User> implement
await this.#loadData(); await this.#loadData();
} }
openAddEditUserDialog(event?: MouseEvent, user?: User) { openAddEditUserDialog(user?: User) {
this._dialogService.openDialog('addEditUser', event, user, async () => { this._dialogService.openDialog('addEditUser', user, async () => {
await this.#loadData(); await this.#loadData();
}); });
} }
openDeleteUsersDialog(userIds: string[], $event?: MouseEvent) { openDeleteUsersDialog(userIds: string[]) {
this._dialogService.deleteUsers(userIds, $event, async () => { this._dialogService.deleteUsers(userIds, async () => {
await this.#loadData(); await this.#loadData();
}); });
} }

View File

@ -14,8 +14,8 @@
<iqser-icon-button <iqser-icon-button
*allow="roles.watermarks.write; if: currentUser.isAdmin" *allow="roles.watermarks.write; if: currentUser.isAdmin"
[iqserHelpMode]="'create_new_watermark'" [iqserHelpMode]="'create_new_watermark'"
[overlappingElements]="['USER_MENU']"
[label]="'watermarks-listing.add-new' | translate" [label]="'watermarks-listing.add-new' | translate"
[overlappingElements]="['USER_MENU']"
[routerLink]="getRouterLink()" [routerLink]="getRouterLink()"
[type]="iconButtonTypes.primary" [type]="iconButtonTypes.primary"
icon="iqser:plus" icon="iqser:plus"
@ -66,7 +66,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="openConfirmDeleteWatermarkDialog($event, entity)" (action)="openConfirmDeleteWatermarkDialog(entity)"
*allow="roles.watermarks.write; if: currentUser.isAdmin" *allow="roles.watermarks.write; if: currentUser.isAdmin"
[tooltip]="'watermarks-listing.action.delete' | translate" [tooltip]="'watermarks-listing.action.delete' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"

View File

@ -51,13 +51,13 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
this.entitiesService.setEntities(this._watermarksMapService.get(this.#dossierTemplateId)); this.entitiesService.setEntities(this._watermarksMapService.get(this.#dossierTemplateId));
} }
async openConfirmDeleteWatermarkDialog($event: MouseEvent, watermark: Watermark) { async openConfirmDeleteWatermarkDialog(watermark: Watermark) {
const isUsed = await this._watermarkService.isWatermarkUsed(watermark.id); const isUsed = await this._watermarkService.isWatermarkUsed(watermark.id);
const data = new ConfirmationDialogInput({ const data = new ConfirmationDialogInput({
question: isUsed ? _('watermarks-listing.watermark-is-used') : null, question: isUsed ? _('watermarks-listing.watermark-is-used') : null,
}); });
this._dialogService.openDialog('confirm', $event, data, async () => { this._dialogService.openDialog('confirm', data, async () => {
await this._deleteWatermark(watermark); await this._deleteWatermark(watermark);
}); });
} }

View File

@ -108,7 +108,7 @@ export class AdminDialogService extends DialogService<DialogType> {
super(_dialog); super(_dialog);
} }
deleteUsers(userIds: string[], $event?: MouseEvent, cb?: () => Promise<void> | void): void { deleteUsers(userIds: string[], cb?: () => Promise<void> | void): void {
const data = new ConfirmationDialogInput({ const data = new ConfirmationDialogInput({
title: _('confirm-delete-users.title'), title: _('confirm-delete-users.title'),
question: _('confirm-delete-users.warning'), question: _('confirm-delete-users.warning'),
@ -123,7 +123,7 @@ export class AdminDialogService extends DialogService<DialogType> {
toastMessage: _('confirm-delete-users.toast-error'), toastMessage: _('confirm-delete-users.toast-error'),
}); });
this.openDialog('confirm', $event, data, async result => { this.openDialog('confirm', data, async result => {
if (result === ConfirmOptions.CONFIRM) { if (result === ConfirmOptions.CONFIRM) {
this._loadingService.start(); this._loadingService.start();
await firstValueFrom(this._userService.delete(userIds)); await firstValueFrom(this._userService.delete(userIds));
@ -138,7 +138,6 @@ export class AdminDialogService extends DialogService<DialogType> {
dossierTemplateId: string, dossierTemplateId: string,
impactedTemplatesRef: TemplateRef<unknown>, impactedTemplatesRef: TemplateRef<unknown>,
type: 'dossier' | 'file', type: 'dossier' | 'file',
$event: MouseEvent,
cb: () => Promise<void> | void, cb: () => Promise<void> | void,
): Promise<void> { ): Promise<void> {
this._loadingService.start(); this._loadingService.start();
@ -175,6 +174,7 @@ export class AdminDialogService extends DialogService<DialogType> {
toastMessage: _('confirm-delete-attribute.toast-error'), toastMessage: _('confirm-delete-attribute.toast-error'),
translateParams: { reportsCount: uniqueTemplates.length, count: attributes.length, name: attributes[0].label }, translateParams: { reportsCount: uniqueTemplates.length, count: attributes.length, name: attributes[0].label },
}); });
if (templates.length) { if (templates.length) {
data.checkboxes.push({ data.checkboxes.push({
value: false, value: false,
@ -183,7 +183,8 @@ export class AdminDialogService extends DialogService<DialogType> {
extraContentData: { templates: uniqueTemplates }, extraContentData: { templates: uniqueTemplates },
}); });
} }
this.openDialog('confirm', $event, data, async () => {
this.openDialog('confirm', data, async () => {
await cb(); await cb();
}); });
} }

View File

@ -1,27 +1,27 @@
<div class="action-buttons" *ngIf="currentUser.isAdmin"> <div *ngIf="currentUser.isAdmin" class="action-buttons">
<div [iqserHelpMode]="'edit_clone_delete_dossier_templates'" [overlappingElements]="['USER_MENU']"> <div [iqserHelpMode]="'edit_clone_delete_dossier_templates'" [overlappingElements]="['USER_MENU']">
<iqser-circle-button <iqser-circle-button
(action)="openDeleteDossierTemplateDialog()"
[buttonId]="'delete-dossier-template-btn-' + dossierTemplateId" [buttonId]="'delete-dossier-template-btn-' + dossierTemplateId"
(action)="openDeleteDossierTemplateDialog($event)"
[tooltip]="'dossier-templates-listing.action.delete' | translate" [tooltip]="'dossier-templates-listing.action.delete' | translate"
[type]="circleButtonTypes.dark"
icon="iqser:trash" icon="iqser:trash"
[type]="circleButtonTypes.dark"
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="openEditCloneDossierTemplateDialog(true)"
[buttonId]="'copy-dossier-template-btn-' + dossierTemplateId" [buttonId]="'copy-dossier-template-btn-' + dossierTemplateId"
(action)="openEditCloneDossierTemplateDialog($event, true)"
[tooltip]="'dossier-templates-listing.action.clone' | translate" [tooltip]="'dossier-templates-listing.action.clone' | translate"
icon="iqser:copy"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:copy"
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="openEditCloneDossierTemplateDialog()"
[buttonId]="'edit-dossier-template-btn-' + dossierTemplateId" [buttonId]="'edit-dossier-template-btn-' + dossierTemplateId"
(action)="openEditCloneDossierTemplateDialog($event)"
[tooltip]="'dossier-templates-listing.action.edit' | translate" [tooltip]="'dossier-templates-listing.action.edit' | translate"
icon="iqser:edit"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
icon="iqser:edit"
></iqser-circle-button> ></iqser-circle-button>
</div> </div>
</div> </div>

View File

@ -33,12 +33,12 @@ export class DossierTemplateActionsComponent implements OnInit {
this.dossierTemplateId ??= this._route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID); this.dossierTemplateId ??= this._route.snapshot.paramMap.get(DOSSIER_TEMPLATE_ID);
} }
openEditCloneDossierTemplateDialog($event: MouseEvent, clone: boolean = false) { openEditCloneDossierTemplateDialog(clone: boolean = false) {
this._dialogService.openDialog('addEditCloneDossierTemplate', $event, { dossierTemplateId: this.dossierTemplateId, clone }); this._dialogService.openDialog('addEditCloneDossierTemplate', { dossierTemplateId: this.dossierTemplateId, clone });
} }
openDeleteDossierTemplateDialog($event?: MouseEvent) { openDeleteDossierTemplateDialog() {
this._dialogService.openDialog('confirm', $event, null, async () => { this._dialogService.openDialog('confirm', null, async () => {
this._loadingService.start(); this._loadingService.start();
const success = await firstValueFrom(this._dossierTemplatesService.delete([this.dossierTemplateId])); const success = await firstValueFrom(this._dossierTemplatesService.delete([this.dossierTemplateId]));

View File

@ -24,6 +24,6 @@ export class TemplateStatsComponent {
) {} ) {}
newDossier(): void { newDossier(): void {
this._dialogService.openDialog('addDossier', null, { dossierTemplateId: this.stats.dossierTemplateId }); this._dialogService.openDialog('addDossier', { dossierTemplateId: this.stats.dossierTemplateId });
} }
} }

View File

@ -33,7 +33,7 @@ export class DossierDetailsStatsComponent implements OnInit {
openEditDossierDialog(section: string): void { openEditDossierDialog(section: string): void {
const data = { dossierId: this.dossier.id, section }; const data = { dossierId: this.dossier.id, section };
this._dialogService.openDialog('editDossier', null, data, async () => { this._dialogService.openDialog('editDossier', data, async () => {
await firstValueFrom(this._filesService.loadAll(this.dossier.id)); await firstValueFrom(this._filesService.loadAll(this.dossier.id));
}); });
} }

View File

@ -7,7 +7,7 @@
<ng-container *ngIf="(isEditingFileAttribute$ | async) === false || isInEditMode"> <ng-container *ngIf="(isEditingFileAttribute$ | async) === false || isInEditMode">
<div *ngIf="!isInEditMode; else input" class="edit-button"> <div *ngIf="!isInEditMode; else input" class="edit-button">
<iqser-circle-button <iqser-circle-button
(action)="editFileAttribute($event)" (action)="editFileAttribute()"
*ngIf="permissionsService.canEditFileAttributes(file, dossier)" *ngIf="permissionsService.canEditFileAttributes(file, dossier)"
[disabled]="!fileAttribute.editable" [disabled]="!fileAttribute.editable"
[icon]="'iqser:edit'" [icon]="'iqser:edit'"
@ -15,8 +15,9 @@
id="edit-attribute-button" id="edit-attribute-button"
></iqser-circle-button> ></iqser-circle-button>
</div> </div>
<ng-template #input> <ng-template #input>
<div (click)="$event?.stopPropagation()" class="edit-input"> <div class="edit-input" stopPropagation>
<form (submit)="save()" [formGroup]="form"> <form (submit)="save()" [formGroup]="form">
<iqser-dynamic-input <iqser-dynamic-input
(closedDatepicker)="closedDatepicker = $event" (closedDatepicker)="closedDatepicker = $event"
@ -24,17 +25,11 @@
[formControlName]="fileAttribute.id" [formControlName]="fileAttribute.id"
[id]="fileAttribute.id" [id]="fileAttribute.id"
[type]="fileAttribute.type" [type]="fileAttribute.type"
> ></iqser-dynamic-input>
</iqser-dynamic-input>
<iqser-circle-button <iqser-circle-button (action)="save()" [disabled]="disabled" [icon]="'iqser:check'" class="save"></iqser-circle-button>
(action)="save($event)"
[disabled]="disabled"
[icon]="'iqser:check'"
class="save"
></iqser-circle-button>
<iqser-circle-button (action)="close($event)" [icon]="'iqser:close'"></iqser-circle-button> <iqser-circle-button (action)="close()" [icon]="'iqser:close'"></iqser-circle-button>
</form> </form>
</div> </div>
</ng-template> </ng-template>

View File

@ -50,15 +50,6 @@ export class FileAttributeComponent extends BaseFormComponent implements OnInit
); );
} }
ngOnInit(): void {
if (this.#noFileAttributes) {
this.#initFileAttributes();
}
this.form = this.#getForm();
this.initialFormValue = this.form.getRawValue();
}
get isDate(): boolean { get isDate(): boolean {
return this.fileAttribute.type === FileAttributeConfigTypes.DATE; return this.fileAttribute.type === FileAttributeConfigTypes.DATE;
} }
@ -71,28 +62,20 @@ export class FileAttributeComponent extends BaseFormComponent implements OnInit
return JSON.stringify(this.file.fileAttributes.attributeIdToValue) === '{}'; return JSON.stringify(this.file.fileAttributes.attributeIdToValue) === '{}';
} }
#initFileAttributes() { ngOnInit(): void {
const configs = this._fileAttributesService.getFileAttributeConfig(this.file.dossierTemplateId).fileAttributeConfigs; if (this.#noFileAttributes) {
configs.forEach(config => (this.file.fileAttributes.attributeIdToValue[config.id] = null)); this.#initFileAttributes();
}
this.form = this.#getForm();
this.initialFormValue = this.form.getRawValue();
} }
async editFileAttribute($event: MouseEvent): Promise<void> { async editFileAttribute(): Promise<void> {
$event?.stopPropagation();
this.#toggleEdit(); this.#toggleEdit();
} }
#getForm(): UntypedFormGroup { async save() {
const config = {};
const fileAttributes = this.file.fileAttributes.attributeIdToValue;
Object.keys(fileAttributes).forEach(key => {
const attrValue = fileAttributes[key];
config[key] = [dayjs(attrValue, 'YYYY-MM-DD', true).isValid() ? dayjs(attrValue).toDate() : attrValue];
});
return this._formBuilder.group(config);
}
async save($event?: MouseEvent): Promise<void> {
$event?.stopPropagation();
const rawFormValue = this.form.getRawValue(); const rawFormValue = this.form.getRawValue();
const fileAttrValue = rawFormValue[this.fileAttribute.id]; const fileAttrValue = rawFormValue[this.fileAttribute.id];
const attributeIdToValue = { const attributeIdToValue = {
@ -113,14 +96,35 @@ export class FileAttributeComponent extends BaseFormComponent implements OnInit
this.#toggleEdit(); this.#toggleEdit();
} }
close($event?: MouseEvent): void { close(): void {
$event?.stopPropagation();
if (this.isInEditMode) { if (this.isInEditMode) {
this.form = this.#getForm(); this.form = this.#getForm();
this.#toggleEdit(); this.#toggleEdit();
} }
} }
@HostListener('document:click')
clickOutside() {
if (this.isInEditMode && this.closedDatepicker) {
this.close();
}
}
#initFileAttributes() {
const configs = this._fileAttributesService.getFileAttributeConfig(this.file.dossierTemplateId).fileAttributeConfigs;
configs.forEach(config => (this.file.fileAttributes.attributeIdToValue[config.id] = null));
}
#getForm(): UntypedFormGroup {
const config = {};
const fileAttributes = this.file.fileAttributes.attributeIdToValue;
Object.keys(fileAttributes).forEach(key => {
const attrValue = fileAttributes[key];
config[key] = [dayjs(attrValue, 'YYYY-MM-DD', true).isValid() ? dayjs(attrValue).toDate() : attrValue];
});
return this._formBuilder.group(config);
}
#formatAttributeValue(attrValue) { #formatAttributeValue(attrValue) {
return this.isDate ? attrValue && dayjs(attrValue).format('YYYY-MM-DD') : attrValue; return this.isDate ? attrValue && dayjs(attrValue).format('YYYY-MM-DD') : attrValue;
} }
@ -140,11 +144,4 @@ export class FileAttributeComponent extends BaseFormComponent implements OnInit
input.focus(); input.focus();
}, 100); }, 100);
} }
@HostListener('document:click')
clickOutside() {
if (this.isInEditMode && this.closedDatepicker) {
this.close();
}
}
} }

View File

@ -157,7 +157,7 @@ export class ConfigService {
{ {
id: 'editDossier', id: 'editDossier',
label: this._translateService.instant('dossier-overview.header-actions.edit'), label: this._translateService.instant('dossier-overview.header-actions.edit'),
action: $event => this._openEditDossierDialog($event, dossierId), action: () => this._openEditDossierDialog(dossierId),
icon: 'iqser:edit', icon: 'iqser:edit',
hide: !this.currentUser.isManager && !this._iqserPermissionsService.has(ROLES.dossiers.edit), hide: !this.currentUser.isManager && !this._iqserPermissionsService.has(ROLES.dossiers.edit),
helpModeKey: 'edit_dossier_in_dossier', helpModeKey: 'edit_dossier_in_dossier',
@ -449,8 +449,8 @@ export class ConfigService {
].map(filter => new NestedFilter(filter)); ].map(filter => new NestedFilter(filter));
} }
private _openEditDossierDialog($event: MouseEvent, dossierId: string) { private _openEditDossierDialog(dossierId: string) {
this._dialogService.openDialog('editDossier', $event, { dossierId }); this._dialogService.openDialog('editDossier', { dossierId });
} }
private _sortByName(ids: string[]) { private _sortByName(ids: string[]) {

View File

@ -11,6 +11,7 @@ import {
IqserScrollbarModule, IqserScrollbarModule,
IqserUsersModule, IqserUsersModule,
StatusBarComponent, StatusBarComponent,
StopPropagationDirective,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { DossierOverviewScreenComponent } from './screen/dossier-overview-screen.component'; import { DossierOverviewScreenComponent } from './screen/dossier-overview-screen.component';
@ -65,6 +66,7 @@ const routes: Routes = [
SharedModule, SharedModule,
CircleButtonComponent, CircleButtonComponent,
StatusBarComponent, StatusBarComponent,
StopPropagationDirective,
], ],
}) })
export class DossierOverviewModule {} export class DossierOverviewModule {}

View File

@ -47,7 +47,6 @@ export class BulkActionsService {
delete(files: File[]) { delete(files: File[]) {
this._dialogService.openDialog( this._dialogService.openDialog(
'confirm', 'confirm',
null,
new ConfirmationDialogInput({ new ConfirmationDialogInput({
title: _('confirmation-dialog.delete-file.title'), title: _('confirmation-dialog.delete-file.title'),
question: _('confirmation-dialog.delete-file.question'), question: _('confirmation-dialog.delete-file.question'),
@ -98,7 +97,6 @@ export class BulkActionsService {
if (foundAnalysisRequiredFile || foundUpdatedFile) { if (foundAnalysisRequiredFile || foundUpdatedFile) {
this._dialogService.openDialog( this._dialogService.openDialog(
'confirm', 'confirm',
null,
new ConfirmationDialogInput({ new ConfirmationDialogInput({
title: foundAnalysisRequiredFile title: foundAnalysisRequiredFile
? _('confirmation-dialog.approve-multiple-files-without-analysis.title') ? _('confirmation-dialog.approve-multiple-files-without-analysis.title')
@ -133,6 +131,6 @@ export class BulkActionsService {
} }
private _assignFiles(files: File[], targetStatus: WorkflowFileStatus, ignoreChanged = false, withUnassignedOption = false): void { private _assignFiles(files: File[], targetStatus: WorkflowFileStatus, ignoreChanged = false, withUnassignedOption = false): void {
this._dialogService.openDialog('assignFile', null, { targetStatus, files, ignoreChanged, withUnassignedOption }); this._dialogService.openDialog('assignFile', { targetStatus, files, ignoreChanged, withUnassignedOption });
} }
} }

View File

@ -217,7 +217,7 @@ export class ConfigService {
} }
private _openAddDossierDialog(dossierTemplateId: string): void { private _openAddDossierDialog(dossierTemplateId: string): void {
this._dialogService.openDialog('addDossier', null, { dossierTemplateId }); this._dialogService.openDialog('addDossier', { dossierTemplateId });
} }
private _quickFilters(entities: Dossier[]): NestedFilter[] { private _quickFilters(entities: Dossier[]): NestedFilter[] {

View File

@ -47,7 +47,7 @@ export class DossiersListingScreenComponent extends ListingComponent<Dossier> im
} }
openAddDossierDialog(): void { openAddDossierDialog(): void {
this._dialogService.openDialog('addDossier', null, { dossierTemplateId: this.dossierTemplate.id }); this._dialogService.openDialog('addDossier', { dossierTemplateId: this.dossierTemplate.id });
} }
async ngOnInit(): Promise<void> { async ngOnInit(): Promise<void> {

View File

@ -6,7 +6,7 @@
<!-- Resize Mode for annotation -> only resize accept and deny actions are available--> <!-- Resize Mode for annotation -> only resize accept and deny actions are available-->
<ng-container *ngIf="resizing && annotationPermissions.canResizeAnnotation"> <ng-container *ngIf="resizing && annotationPermissions.canResizeAnnotation">
<iqser-circle-button <iqser-circle-button
(action)="acceptResize($event)" (action)="acceptResize()"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.resize-accept.label' | translate" [tooltip]="'annotation-actions.resize-accept.label' | translate"
[type]="buttonType" [type]="buttonType"
@ -14,7 +14,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="cancelResize($event)" (action)="cancelResize()"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.resize-cancel.label' | translate" [tooltip]="'annotation-actions.resize-cancel.label' | translate"
[type]="buttonType" [type]="buttonType"
@ -25,7 +25,7 @@
<!-- Not resizing - standard actions --> <!-- Not resizing - standard actions -->
<ng-container *ngIf="!resizing"> <ng-container *ngIf="!resizing">
<iqser-circle-button <iqser-circle-button
(action)="resize($event)" (action)="resize()"
*ngIf="annotationPermissions.canResizeAnnotation && annotations.length === 1" *ngIf="annotationPermissions.canResizeAnnotation && annotations.length === 1"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.resize.label' | translate" [tooltip]="'annotation-actions.resize.label' | translate"
@ -34,7 +34,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="annotationActionsService.changeLegalBasis($event, annotations)" (action)="annotationActionsService.changeLegalBasis(annotations)"
*ngIf="annotationPermissions.canChangeLegalBasis" *ngIf="annotationPermissions.canChangeLegalBasis"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.edit-reason.label' | translate" [tooltip]="'annotation-actions.edit-reason.label' | translate"
@ -43,7 +43,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="acceptRecommendation($event)" (action)="acceptRecommendation()"
*ngIf="annotationPermissions.canAcceptRecommendation" *ngIf="annotationPermissions.canAcceptRecommendation"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.accept-recommendation.label' | translate" [tooltip]="'annotation-actions.accept-recommendation.label' | translate"
@ -52,7 +52,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="annotationActionsService.acceptSuggestion($event, annotations)" (action)="annotationActionsService.acceptSuggestion(annotations)"
*ngIf="annotationPermissions.canAcceptSuggestion" *ngIf="annotationPermissions.canAcceptSuggestion"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.accept-suggestion.label' | translate" [tooltip]="'annotation-actions.accept-suggestion.label' | translate"
@ -79,7 +79,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="annotationActionsService.undoDirectAction($event, annotations)" (action)="annotationActionsService.undoDirectAction(annotations)"
*allow="roles.redactions.deleteManual; if: annotationPermissions.canUndo" *allow="roles.redactions.deleteManual; if: annotationPermissions.canUndo"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.undo' | translate" [tooltip]="'annotation-actions.undo' | translate"
@ -88,7 +88,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="annotationActionsService.rejectSuggestion($event, annotations)" (action)="annotationActionsService.rejectSuggestion(annotations)"
*ngIf="annotationPermissions.canRejectSuggestion" *ngIf="annotationPermissions.canRejectSuggestion"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.reject-suggestion' | translate" [tooltip]="'annotation-actions.reject-suggestion' | translate"
@ -97,7 +97,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="annotationActionsService.recategorizeImages($event, annotations)" (action)="annotationActionsService.recategorizeImages(annotations)"
*ngIf="annotationPermissions.canRecategorizeImage" *ngIf="annotationPermissions.canRecategorizeImage"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.recategorize-image' | translate" [tooltip]="'annotation-actions.recategorize-image' | translate"
@ -106,7 +106,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="$event.stopPropagation(); annotationReferencesService.show(annotations[0])" (action)="annotationReferencesService.show(annotations[0])"
*ngIf="!multiSelectService.isActive && annotations[0].reference.length" *ngIf="!multiSelectService.isActive && annotations[0].reference.length"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.see-references.label' | translate" [tooltip]="'annotation-actions.see-references.label' | translate"
@ -115,7 +115,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="annotationActionsService.forceAnnotation($event, annotations)" (action)="annotationActionsService.forceAnnotation(annotations)"
*ngIf="annotationPermissions.canForceRedaction" *ngIf="annotationPermissions.canForceRedaction"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.force-redaction.label' | translate" [tooltip]="'annotation-actions.force-redaction.label' | translate"
@ -124,7 +124,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="annotationActionsService.forceAnnotation($event, annotations, true)" (action)="annotationActionsService.forceAnnotation(annotations, true)"
*ngIf="annotationPermissions.canForceHint" *ngIf="annotationPermissions.canForceHint"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.force-hint.label' | translate" [tooltip]="'annotation-actions.force-hint.label' | translate"
@ -133,7 +133,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="hideAnnotation($event)" (action)="hideAnnotation()"
*ngIf="isImage && (isVisible$ | async)" *ngIf="isImage && (isVisible$ | async)"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.hide' | translate" [tooltip]="'annotation-actions.hide' | translate"
@ -142,7 +142,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="showAnnotation($event)" (action)="showAnnotation()"
*ngIf="isImage && (isVisible$ | async) === false" *ngIf="isImage && (isVisible$ | async) === false"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.show' | translate" [tooltip]="'annotation-actions.show' | translate"
@ -151,7 +151,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="removeOrSuggestRemoveAnnotation($event, true)" (action)="removeOrSuggestRemoveAnnotation(true)"
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveFromDictionary" *ngIf="annotationPermissions.canRemoveOrSuggestToRemoveFromDictionary"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.remove-annotation.remove-from-dict' | translate" [tooltip]="'annotation-actions.remove-annotation.remove-from-dict' | translate"
@ -160,7 +160,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="markAsFalsePositive($event)" (action)="markAsFalsePositive()"
*ngIf="annotationPermissions.canMarkAsFalsePositive" *ngIf="annotationPermissions.canMarkAsFalsePositive"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.remove-annotation.false-positive' | translate" [tooltip]="'annotation-actions.remove-annotation.false-positive' | translate"
@ -169,7 +169,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="removeOrSuggestRemoveAnnotation($event, false)" (action)="removeOrSuggestRemoveAnnotation(false)"
*ngIf="annotationPermissions.canRemoveOrSuggestToRemoveOnlyHere" *ngIf="annotationPermissions.canRemoveOrSuggestToRemoveOnlyHere"
[tooltipPosition]="tooltipPosition" [tooltipPosition]="tooltipPosition"
[tooltip]="'annotation-actions.remove-annotation.only-here' | translate" [tooltip]="'annotation-actions.remove-annotation.only-here' | translate"

View File

@ -34,11 +34,6 @@ export class AnnotationActionsComponent implements OnChanges {
isImage = true; isImage = true;
readonly isVisible$ = this._annotationManager.hidden$.pipe(
map(hidden => this._annotations.reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true)),
shareLast(),
);
constructor( constructor(
readonly viewModeService: ViewModeService, readonly viewModeService: ViewModeService,
readonly helpModeService: HelpModeService, readonly helpModeService: HelpModeService,
@ -53,6 +48,11 @@ export class AnnotationActionsComponent implements OnChanges {
private _annotations: AnnotationWrapper[]; private _annotations: AnnotationWrapper[];
readonly isVisible$ = this._annotationManager.hidden$.pipe(
map(hidden => this._annotations.reduce((acc, annotation) => !hidden.has(annotation.id) && acc, true)),
shareLast(),
);
get annotations(): AnnotationWrapper[] { get annotations(): AnnotationWrapper[] {
return this._annotations; return this._annotations;
} }
@ -75,43 +75,40 @@ export class AnnotationActionsComponent implements OnChanges {
this._setPermissions(); this._setPermissions();
} }
removeOrSuggestRemoveAnnotation($event: MouseEvent, removeFromDict: boolean) { removeOrSuggestRemoveAnnotation(removeFromDict: boolean) {
$event.stopPropagation(); this.annotationActionsService.removeOrSuggestRemoveAnnotation(this.annotations, removeFromDict);
this.annotationActionsService.removeOrSuggestRemoveAnnotation($event, this.annotations, removeFromDict);
} }
markAsFalsePositive($event: MouseEvent) { markAsFalsePositive() {
this.annotationActionsService.markAsFalsePositive($event, this.annotations); this.annotationActionsService.markAsFalsePositive(this.annotations);
} }
acceptRecommendation($event: MouseEvent) { acceptRecommendation() {
this.annotationActionsService.convertRecommendationToAnnotation($event, this.annotations); this.annotationActionsService.convertRecommendationToAnnotation(this.annotations);
} }
hideAnnotation($event: MouseEvent) { hideAnnotation() {
$event.stopPropagation();
this._annotationManager.hide(this.viewerAnnotations); this._annotationManager.hide(this.viewerAnnotations);
this._annotationManager.deselect(); this._annotationManager.deselect();
this._annotationManager.addToHidden(this.viewerAnnotations[0].Id); this._annotationManager.addToHidden(this.viewerAnnotations[0].Id);
} }
showAnnotation($event: MouseEvent) { showAnnotation() {
$event.stopPropagation();
this._annotationManager.show(this.viewerAnnotations); this._annotationManager.show(this.viewerAnnotations);
this._annotationManager.deselect(); this._annotationManager.deselect();
this._annotationManager.removeFromHidden(this.viewerAnnotations[0].Id); this._annotationManager.removeFromHidden(this.viewerAnnotations[0].Id);
} }
resize($event: MouseEvent) { resize() {
return this.annotationActionsService.resize($event, this.annotations[0]); return this.annotationActionsService.resize(this.annotations[0]);
} }
acceptResize($event: MouseEvent) { acceptResize() {
return this.annotationActionsService.acceptResize($event, this.annotations[0]); return this.annotationActionsService.acceptResize(this.annotations[0]);
} }
cancelResize($event: MouseEvent) { cancelResize() {
return this.annotationActionsService.cancelResize($event, this.annotations[0]); return this.annotationActionsService.cancelResize(this.annotations[0]);
} }
private _setPermissions() { private _setPermissions() {

View File

@ -10,10 +10,11 @@
<div *ngIf="!annotation.isEarmark" class="actions-wrapper"> <div *ngIf="!annotation.isEarmark" class="actions-wrapper">
<div <div
(click)="comments.toggleExpandComments($event)" (click)="comments.toggleExpandComments()"
[matTooltip]="'comments.comments' | translate : { count: annotation.comments?.length }" [matTooltip]="'comments.comments' | translate : { count: annotation.comments?.length }"
class="comments-counter" class="comments-counter"
matTooltipPosition="above" matTooltipPosition="above"
stopPropagation
> >
<mat-icon svgIcon="red:comment"></mat-icon> <mat-icon svgIcon="red:comment"></mat-icon>
{{ annotation.comments.length }} {{ annotation.comments.length }}

View File

@ -8,12 +8,13 @@
<div class="comment-actions"> <div class="comment-actions">
<iqser-circle-button <iqser-circle-button
(action)="deleteComment($event, comment)" (action)="deleteComment(comment)"
*ngIf="permissionsService.canDeleteComment(comment, ctx.file, ctx.dossier)" *ngIf="permissionsService.canDeleteComment(comment, ctx.file, ctx.dossier)"
[iconSize]="10" [iconSize]="10"
[size]="20" [size]="20"
class="pointer" class="pointer"
icon="iqser:trash" icon="iqser:trash"
stopPropagation
></iqser-circle-button> ></iqser-circle-button>
</div> </div>
</div> </div>
@ -30,5 +31,10 @@
width="full" width="full"
></iqser-input-with-action> ></iqser-input-with-action>
<div (click)="toggleExpandComments($event)" class="all-caps-label pointer hide-comments" translate="comments.hide-comments"></div> <div
(click)="toggleExpandComments()"
class="all-caps-label pointer hide-comments"
stopPropagation
translate="comments.hide-comments"
></div>
</ng-container> </ng-container>

View File

@ -71,13 +71,11 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
this._loadingService.stop(); this._loadingService.stop();
} }
toggleExpandComments($event?: MouseEvent): void { toggleExpandComments(): void {
$event?.stopPropagation();
this._commentingService.toggle(this.annotation.id); this._commentingService.toggle(this.annotation.id);
} }
async deleteComment($event: MouseEvent, comment: IComment): Promise<void> { async deleteComment(comment: IComment): Promise<void> {
$event.stopPropagation();
this._loadingService.start(); this._loadingService.start();
const { dossierId, fileId } = this._stateService; const { dossierId, fileId } = this._stateService;
await this._manualRedactionService.deleteComment(comment.id, this.annotation.id, dossierId, fileId); await this._manualRedactionService.deleteComment(comment.id, this.annotation.id, dossierId, fileId);

View File

@ -56,7 +56,7 @@ export class DocumentInfoComponent extends ContextComponent<Context> {
} }
edit(file: File) { edit(file: File) {
this._dialogService.openDialog('documentInfo', null, file); this._dialogService.openDialog('documentInfo', file);
} }
isDate(attribute: FileAttribute) { isDate(attribute: FileAttribute) {

View File

@ -214,9 +214,10 @@
<ng-template #annotationFilterActionTemplate let-filter="filter"> <ng-template #annotationFilterActionTemplate let-filter="filter">
<iqser-circle-button <iqser-circle-button
(action)="skippedService.toggleSkipped($event)" (action)="skippedService.toggleSkipped()"
*ngIf="filter.id === 'skipped'" *ngIf="filter.id === 'skipped'"
[icon]="(skippedService.hideSkipped$ | async) ? 'red:visibility-off' : 'red:visibility'" [icon]="(skippedService.hideSkipped$ | async) ? 'red:visibility-off' : 'red:visibility'"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"
preventDefault
></iqser-circle-button> ></iqser-circle-button>
</ng-template> </ng-template>

View File

@ -31,12 +31,12 @@ export class HighlightsSeparatorComponent {
convertHighlights(highlightGroup: EarmarkGroup): void { convertHighlights(highlightGroup: EarmarkGroup): void {
const data = this._getActionData(highlightGroup, EarmarkOperation.CONVERT); const data = this._getActionData(highlightGroup, EarmarkOperation.CONVERT);
this._dialogService.openDialog('highlightAction', null, data); this._dialogService.openDialog('highlightAction', data);
} }
removeHighlights(highlightGroup: EarmarkGroup): void { removeHighlights(highlightGroup: EarmarkGroup): void {
const data = this._getActionData(highlightGroup, EarmarkOperation.REMOVE); const data = this._getActionData(highlightGroup, EarmarkOperation.REMOVE);
this._dialogService.openDialog('highlightAction', null, data); this._dialogService.openDialog('highlightAction', data);
} }
private _getActionData(highlightGroup: EarmarkGroup, operation: EarmarkOperation) { private _getActionData(highlightGroup: EarmarkGroup, operation: EarmarkOperation) {

View File

@ -80,7 +80,7 @@ export class ViewSwitchComponent {
checkboxesValidation: false, checkboxesValidation: false,
}); });
return this._dialogService.openDialog('confirm', null, data, result => { return this._dialogService.openDialog('confirm', data, result => {
if (!result) { if (!result) {
return; return;
} }

View File

@ -320,7 +320,6 @@ export class FilePreviewScreenComponent
this.state.dialogRef = this._dialogService.openDialog( this.state.dialogRef = this._dialogService.openDialog(
'manualAnnotation', 'manualAnnotation',
null,
{ manualRedactionEntryWrapper, dossierId: this.dossierId, file }, { manualRedactionEntryWrapper, dossierId: this.dossierId, file },
(result: { annotations: ManualRedactionEntryWrapper[]; dictionary?: Dictionary }) => { (result: { annotations: ManualRedactionEntryWrapper[]; dictionary?: Dictionary }) => {
const selectedAnnotations = this._annotationManager.selected; const selectedAnnotations = this._annotationManager.selected;
@ -422,7 +421,7 @@ export class FilePreviewScreenComponent
} }
openRSSView(file: File) { openRSSView(file: File) {
this._dialogService.openDialog('rss', null, { file }); this._dialogService.openDialog('rss', { file });
} }
loadAnnotations() { loadAnnotations() {
@ -663,7 +662,7 @@ export class FilePreviewScreenComponent
}, },
}); });
const ref = this._dialogService.openDialog('confirm', null, data); const ref = this._dialogService.openDialog('confirm', data);
return ref.afterClosed().pipe( return ref.afterClosed().pipe(
switchMap(async (result: ConfirmOptions) => { switchMap(async (result: ConfirmOptions) => {
const doNotShowWarningAgain = result === ConfirmOptions.SECOND_CONFIRM; const doNotShowWarningAgain = result === ConfirmOptions.SECOND_CONFIRM;

View File

@ -12,7 +12,9 @@ import {
IqserScrollbarModule, IqserScrollbarModule,
IqserUploadFileModule, IqserUploadFileModule,
IqserUsersModule, IqserUsersModule,
PreventDefaultDirective,
StatusBarComponent, StatusBarComponent,
StopPropagationDirective,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
@ -124,6 +126,8 @@ const components = [
IconButtonComponent, IconButtonComponent,
EmptyStateComponent, EmptyStateComponent,
StatusBarComponent, StatusBarComponent,
StopPropagationDirective,
PreventDefaultDirective,
], ],
providers: [FilePreviewDialogService, ManualRedactionService, DocumentUnloadedGuard, SuggestionsService], providers: [FilePreviewDialogService, ManualRedactionService, DocumentUnloadedGuard, SuggestionsService],
}) })

View File

@ -6,7 +6,6 @@ import { getFirstRelevantTextPart } from '../../../utils';
import { Core } from '@pdftron/webviewer'; import { Core } from '@pdftron/webviewer';
import { import {
DictionaryEntryTypes, DictionaryEntryTypes,
Dossier,
EarmarkOperation, EarmarkOperation,
IAddRedactionRequest, IAddRedactionRequest,
ILegalBasisChangeRequest, ILegalBasisChangeRequest,
@ -16,7 +15,6 @@ import {
} from '@red/domain'; } from '@red/domain';
import { toPosition } from '../utils/pdf-calculation.utils'; import { toPosition } from '../utils/pdf-calculation.utils';
import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service'; import { AnnotationDrawService } from '../../pdf-viewer/services/annotation-draw.service';
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
import { import {
AcceptRecommendationData, AcceptRecommendationData,
AcceptRecommendationDialogComponent, AcceptRecommendationDialogComponent,
@ -43,18 +41,12 @@ export class AnnotationActionsService {
private readonly _documentViewer: REDDocumentViewer, private readonly _documentViewer: REDDocumentViewer,
private readonly _annotationManager: REDAnnotationManager, private readonly _annotationManager: REDAnnotationManager,
private readonly _annotationDrawService: AnnotationDrawService, private readonly _annotationDrawService: AnnotationDrawService,
private readonly _activeDossiersService: ActiveDossiersService,
private readonly _state: FilePreviewStateService, private readonly _state: FilePreviewStateService,
private readonly _fileDataService: FileDataService, private readonly _fileDataService: FileDataService,
private readonly _skippedService: SkippedService, private readonly _skippedService: SkippedService,
) {} ) {}
private get _dossier(): Dossier { acceptSuggestion(annotations: AnnotationWrapper[]) {
return this._activeDossiersService.find(this._state.dossierId);
}
acceptSuggestion($event: MouseEvent, annotations: AnnotationWrapper[]) {
$event?.stopPropagation();
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
const ids = annotations.map(a => a.id); const ids = annotations.map(a => a.id);
const request = this._manualRedactionService.approve(ids, dossierId, fileId); const request = this._manualRedactionService.approve(ids, dossierId, fileId);
@ -63,16 +55,15 @@ export class AnnotationActionsService {
removeHighlights(highlights: AnnotationWrapper[]): void { removeHighlights(highlights: AnnotationWrapper[]): void {
const data = this.#getHighlightOperationData(EarmarkOperation.REMOVE, highlights); const data = this.#getHighlightOperationData(EarmarkOperation.REMOVE, highlights);
this._dialogService.openDialog('highlightAction', null, data); this._dialogService.openDialog('highlightAction', data);
} }
convertHighlights(highlights: AnnotationWrapper[]): void { convertHighlights(highlights: AnnotationWrapper[]): void {
const data = this.#getHighlightOperationData(EarmarkOperation.CONVERT, highlights); const data = this.#getHighlightOperationData(EarmarkOperation.CONVERT, highlights);
this._dialogService.openDialog('highlightAction', null, data); this._dialogService.openDialog('highlightAction', data);
} }
rejectSuggestion($event: MouseEvent, annotations: AnnotationWrapper[]) { rejectSuggestion(annotations: AnnotationWrapper[]) {
$event?.stopPropagation();
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
this.#processObsAndEmit( this.#processObsAndEmit(
this._manualRedactionService.declineOrRemove( this._manualRedactionService.declineOrRemove(
@ -84,10 +75,10 @@ export class AnnotationActionsService {
); );
} }
forceAnnotation($event: MouseEvent, annotations: AnnotationWrapper[], hint: boolean = false) { forceAnnotation(annotations: AnnotationWrapper[], hint: boolean = false) {
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
const data = { dossier: this._dossier, annotations, hint }; const data = { dossier: this._state.dossier, annotations, hint };
this._dialogService.openDialog('forceAnnotation', $event, data, (request: ILegalBasisChangeRequest) => { this._dialogService.openDialog('forceAnnotation', data, (request: ILegalBasisChangeRequest) => {
this.#processObsAndEmit( this.#processObsAndEmit(
this._manualRedactionService.bulkForce( this._manualRedactionService.bulkForce(
annotations.map(a => ({ ...request, annotationId: a.id })), annotations.map(a => ({ ...request, annotationId: a.id })),
@ -99,12 +90,11 @@ export class AnnotationActionsService {
}); });
} }
changeLegalBasis($event: MouseEvent, annotations: AnnotationWrapper[]) { changeLegalBasis(annotations: AnnotationWrapper[]) {
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
this._dialogService.openDialog( this._dialogService.openDialog(
'changeLegalBasis', 'changeLegalBasis',
$event, { annotations, dossier: this._state.dossier },
{ annotations, dossier: this._dossier },
(data: { comment: string; legalBasis: string; section: string; value: string }) => { (data: { comment: string; legalBasis: string; section: string; value: string }) => {
const body = annotations.map(annotation => ({ const body = annotations.map(annotation => ({
annotationId: annotation.id, annotationId: annotation.id,
@ -119,15 +109,15 @@ export class AnnotationActionsService {
); );
} }
removeOrSuggestRemoveAnnotation($event: MouseEvent, annotations: AnnotationWrapper[], removeFromDictionary: boolean) { removeOrSuggestRemoveAnnotation(annotations: AnnotationWrapper[], removeFromDictionary: boolean) {
const data = { const data = {
annotationsToRemove: annotations, annotationsToRemove: annotations,
removeFromDictionary, removeFromDictionary,
dossier: this._dossier, dossier: this._state.dossier,
hint: annotations[0].hintDictionary, hint: annotations[0].hintDictionary,
}; };
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
this._dialogService.openDialog('removeAnnotations', $event, data, (result: { comment: string }) => { this._dialogService.openDialog('removeAnnotations', data, (result: { comment: string }) => {
const body = annotations.map(annotation => ({ const body = annotations.map(annotation => ({
annotationId: annotation.id, annotationId: annotation.id,
removeFromDictionary, removeFromDictionary,
@ -139,10 +129,10 @@ export class AnnotationActionsService {
}); });
} }
recategorizeImages($event: MouseEvent, annotations: AnnotationWrapper[]) { recategorizeImages(annotations: AnnotationWrapper[]) {
const data = { annotations, dossier: this._dossier }; const data = { annotations, dossier: this._state.dossier };
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
this._dialogService.openDialog('recategorizeImage', $event, data, ({ comment, type }: { type: string; comment: string }) => { this._dialogService.openDialog('recategorizeImage', data, ({ comment, type }: { type: string; comment: string }) => {
const body: List<IRecategorizationRequest> = annotations.map(({ annotationId }) => ({ const body: List<IRecategorizationRequest> = annotations.map(({ annotationId }) => ({
annotationId, annotationId,
type, type,
@ -152,9 +142,7 @@ export class AnnotationActionsService {
}); });
} }
undoDirectAction($event: MouseEvent, annotations: AnnotationWrapper[]) { undoDirectAction(annotations: AnnotationWrapper[]) {
$event?.stopPropagation();
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
const modifyDictionary = annotations[0].isModifyDictionary; const modifyDictionary = annotations[0].isModifyDictionary;
this.#processObsAndEmit( this.#processObsAndEmit(
@ -167,9 +155,7 @@ export class AnnotationActionsService {
); );
} }
convertRecommendationToAnnotation($event: any, recommendations: AnnotationWrapper[]) { convertRecommendationToAnnotation(recommendations: AnnotationWrapper[]) {
$event?.stopPropagation();
const { dossierId, fileId } = this._state; const { dossierId, fileId } = this._state;
const dialogRef = this._dialog.open<AcceptRecommendationDialogComponent, AcceptRecommendationData, AcceptRecommendationReturnType>( const dialogRef = this._dialog.open<AcceptRecommendationDialogComponent, AcceptRecommendationData, AcceptRecommendationReturnType>(
AcceptRecommendationDialogComponent, AcceptRecommendationDialogComponent,
@ -179,19 +165,16 @@ export class AnnotationActionsService {
const dialogClosed = dialogRef.afterClosed().pipe(filter(value => !!value && !!value.annotations)); const dialogClosed = dialogRef.afterClosed().pipe(filter(value => !!value && !!value.annotations));
dialogClosed.subscribe(({ annotations, comment: commentText }) => { dialogClosed.subscribe(({ annotations, comment: commentText }) => {
if (isJustOne(annotations) && this._annotationManager.resizingAnnotationId === annotations[0].id) { if (isJustOne(annotations) && this._annotationManager.resizingAnnotationId === annotations[0].id) {
this.cancelResize(null, annotations[0]).then(); this.cancelResize(annotations[0]).then();
} }
const comment = commentText ? { text: commentText } : undefined; const comment = commentText ? { text: commentText } : undefined;
this.#processObsAndEmit(this._manualRedactionService.addRecommendation(annotations, dossierId, fileId, comment)); this.#processObsAndEmit(this._manualRedactionService.addRecommendation(annotations, dossierId, fileId, comment));
}); });
} }
async resize($event: MouseEvent, annotationWrapper: AnnotationWrapper) { async resize(annotationWrapper: AnnotationWrapper) {
$event?.stopPropagation();
this._annotationManager.resizingAnnotationId = annotationWrapper.id; this._annotationManager.resizingAnnotationId = annotationWrapper.id;
const viewerAnnotation = this._annotationManager.get(annotationWrapper);
if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) { if (annotationWrapper.rectangle || annotationWrapper.imported || annotationWrapper.isImage) {
this._annotationManager.delete(annotationWrapper); this._annotationManager.delete(annotationWrapper);
const rectangleAnnotation = this.#generateRectangle(annotationWrapper); const rectangleAnnotation = this.#generateRectangle(annotationWrapper);
@ -199,6 +182,7 @@ export class AnnotationActionsService {
return; return;
} }
const viewerAnnotation = this._annotationManager.get(annotationWrapper);
viewerAnnotation.ReadOnly = false; viewerAnnotation.ReadOnly = false;
viewerAnnotation.Hidden = false; viewerAnnotation.Hidden = false;
viewerAnnotation.disableRotationControl(); viewerAnnotation.disableRotationControl();
@ -206,7 +190,7 @@ export class AnnotationActionsService {
this._annotationManager.select(viewerAnnotation); this._annotationManager.select(viewerAnnotation);
} }
async acceptResize($event: MouseEvent, annotation: AnnotationWrapper): Promise<void> { async acceptResize(annotation: AnnotationWrapper): Promise<void> {
const textAndPositions = await this.#extractTextAndPositions(annotation.id); const textAndPositions = await this.#extractTextAndPositions(annotation.id);
if (annotation.isRecommendation) { if (annotation.isRecommendation) {
const recommendation = { const recommendation = {
@ -214,14 +198,14 @@ export class AnnotationActionsService {
value: textAndPositions.text, value: textAndPositions.text,
positions: textAndPositions.positions, positions: textAndPositions.positions,
} as AnnotationWrapper; } as AnnotationWrapper;
return this.convertRecommendationToAnnotation($event, [recommendation]); return this.convertRecommendationToAnnotation([recommendation]);
} }
const isImageText = annotation.isImage ? 'Image' : textAndPositions.text; const isImageText = annotation.isImage ? 'Image' : textAndPositions.text;
const text = annotation.rectangle ? annotation.value : isImageText; const text = annotation.rectangle ? annotation.value : isImageText;
const data = { annotation, text }; const data = { annotation, text };
this._dialogService.openDialog('resizeAnnotation', $event, data, (result: { comment: string; updateDictionary: boolean }) => { this._dialogService.openDialog('resizeAnnotation', data, (result: { comment: string; updateDictionary: boolean }) => {
const resizeRequest: IResizeRequest = { const resizeRequest: IResizeRequest = {
annotationId: annotation.id, annotationId: annotation.id,
comment: result.comment, comment: result.comment,
@ -230,7 +214,7 @@ export class AnnotationActionsService {
updateDictionary: result.updateDictionary, updateDictionary: result.updateDictionary,
}; };
this.cancelResize(null, annotation).then(); this.cancelResize(annotation).then();
const { fileId, dossierId } = this._state; const { fileId, dossierId } = this._state;
const request = this._manualRedactionService.resizeOrSuggestResize([resizeRequest], dossierId, fileId); const request = this._manualRedactionService.resizeOrSuggestResize([resizeRequest], dossierId, fileId);
@ -238,20 +222,15 @@ export class AnnotationActionsService {
}); });
} }
async cancelResize($event: MouseEvent, annotationWrapper: AnnotationWrapper) { async cancelResize(annotationWrapper: AnnotationWrapper) {
$event?.stopPropagation();
this._annotationManager.resizingAnnotationId = undefined; this._annotationManager.resizingAnnotationId = undefined;
this._annotationManager.delete(annotationWrapper); this._annotationManager.delete(annotationWrapper);
await this._annotationDrawService.draw([annotationWrapper], this._skippedService.hideSkipped, this._state.dossierTemplateId); await this._annotationDrawService.draw([annotationWrapper], this._skippedService.hideSkipped, this._state.dossierTemplateId);
this._annotationManager.deselect(); this._annotationManager.deselect();
await this._fileDataService.annotationsChanged(); await this._fileDataService.annotationsChanged();
} }
markAsFalsePositive($event: MouseEvent, annotations: AnnotationWrapper[]) { markAsFalsePositive(annotations: AnnotationWrapper[]) {
$event?.stopPropagation();
const requests: List<IAddRedactionRequest> = annotations.map(annotation => ({ const requests: List<IAddRedactionRequest> = annotations.map(annotation => ({
sourceId: annotation.id, sourceId: annotation.id,
value: this._getFalsePositiveText(annotation), value: this._getFalsePositiveText(annotation),
@ -301,6 +280,7 @@ export class AnnotationActionsService {
} }
#processObsAndEmit(obs: Observable<unknown>) { #processObsAndEmit(obs: Observable<unknown>) {
// TODO: remove observables and use promises instead
obs.subscribe({ obs.subscribe({
next: () => this._fileDataService.annotationsChanged(), next: () => this._fileDataService.annotationsChanged(),
error: () => this._fileDataService.annotationsChanged(), error: () => this._fileDataService.annotationsChanged(),

View File

@ -1,7 +1,7 @@
import { inject, Injectable, NgZone } from '@angular/core'; import { inject, Injectable, NgZone } from '@angular/core';
import { AnnotationWrapper } from '../../../models/file/annotation.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { AnnotationPermissions } from '../../../models/file/annotation.permissions'; import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { PermissionsService } from '../../../services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { FilePreviewStateService } from './file-preview-state.service'; import { FilePreviewStateService } from './file-preview-state.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { AnnotationActionsService } from './annotation-actions.service'; import { AnnotationActionsService } from './annotation-actions.service';
@ -32,17 +32,17 @@ export class PdfAnnotationActionsService {
// if we already entered resize-mode previously // if we already entered resize-mode previously
if (firstAnnotation.id === this.#annotationManager.resizingAnnotationId) { if (firstAnnotation.id === this.#annotationManager.resizingAnnotationId) {
const acceptResizeButton = this.#getButton('check', _('annotation-actions.resize-accept.label'), () => const acceptResizeButton = this.#getButton('check', _('annotation-actions.resize-accept.label'), () =>
this.#annotationActionsService.acceptResize(null, firstAnnotation), this.#annotationActionsService.acceptResize(firstAnnotation),
); );
const cancelResizeButton = this.#getButton('close', _('annotation-actions.resize-cancel.label'), () => const cancelResizeButton = this.#getButton('close', _('annotation-actions.resize-cancel.label'), () =>
this.#annotationActionsService.cancelResize(null, firstAnnotation), this.#annotationActionsService.cancelResize(firstAnnotation),
); );
return [acceptResizeButton, cancelResizeButton]; return [acceptResizeButton, cancelResizeButton];
} }
const resizeButton = this.#getButton('resize', _('annotation-actions.resize.label'), () => const resizeButton = this.#getButton('resize', _('annotation-actions.resize.label'), () =>
this.#annotationActionsService.resize(null, firstAnnotation), this.#annotationActionsService.resize(firstAnnotation),
); );
availableActions.push(resizeButton); availableActions.push(resizeButton);
@ -50,14 +50,14 @@ export class PdfAnnotationActionsService {
if (permissions.canChangeLegalBasis) { if (permissions.canChangeLegalBasis) {
const editButton = this.#getButton('edit', _('annotation-actions.edit-reason.label'), () => const editButton = this.#getButton('edit', _('annotation-actions.edit-reason.label'), () =>
this.#annotationActionsService.changeLegalBasis(null, annotations), this.#annotationActionsService.changeLegalBasis(annotations),
); );
availableActions.push(editButton); availableActions.push(editButton);
} }
if (permissions.canRecategorizeImage) { if (permissions.canRecategorizeImage) {
const recategorizeButton = this.#getButton('thumb-down', _('annotation-actions.recategorize-image'), () => const recategorizeButton = this.#getButton('thumb-down', _('annotation-actions.recategorize-image'), () =>
this.#annotationActionsService.recategorizeImages(null, annotations), this.#annotationActionsService.recategorizeImages(annotations),
); );
availableActions.push(recategorizeButton); availableActions.push(recategorizeButton);
} }
@ -66,56 +66,56 @@ export class PdfAnnotationActionsService {
const removeFromDictButton = this.#getButton( const removeFromDictButton = this.#getButton(
'remove-from-dict', 'remove-from-dict',
_('annotation-actions.remove-annotation.remove-from-dict'), _('annotation-actions.remove-annotation.remove-from-dict'),
() => this.#annotationActionsService.removeOrSuggestRemoveAnnotation(null, annotations, true), () => this.#annotationActionsService.removeOrSuggestRemoveAnnotation(annotations, true),
); );
availableActions.push(removeFromDictButton); availableActions.push(removeFromDictButton);
} }
if (permissions.canAcceptRecommendation) { if (permissions.canAcceptRecommendation) {
const acceptRecommendationButton = this.#getButton('check', _('annotation-actions.accept-recommendation.label'), () => const acceptRecommendationButton = this.#getButton('check', _('annotation-actions.accept-recommendation.label'), () =>
this.#annotationActionsService.convertRecommendationToAnnotation(null, annotations), this.#annotationActionsService.convertRecommendationToAnnotation(annotations),
); );
availableActions.push(acceptRecommendationButton); availableActions.push(acceptRecommendationButton);
} }
if (permissions.canAcceptSuggestion) { if (permissions.canAcceptSuggestion) {
const acceptSuggestionButton = this.#getButton('check', _('annotation-actions.accept-suggestion.label'), () => const acceptSuggestionButton = this.#getButton('check', _('annotation-actions.accept-suggestion.label'), () =>
this.#annotationActionsService.acceptSuggestion(null, annotations), this.#annotationActionsService.acceptSuggestion(annotations),
); );
availableActions.push(acceptSuggestionButton); availableActions.push(acceptSuggestionButton);
} }
if (permissions.canUndo) { if (permissions.canUndo) {
const undoButton = this.#getButton('undo', _('annotation-actions.undo'), () => const undoButton = this.#getButton('undo', _('annotation-actions.undo'), () =>
this.#annotationActionsService.undoDirectAction(null, annotations), this.#annotationActionsService.undoDirectAction(annotations),
); );
availableActions.push(undoButton); availableActions.push(undoButton);
} }
if (permissions.canMarkAsFalsePositive) { if (permissions.canMarkAsFalsePositive) {
const markAsFalsePositiveButton = this.#getButton('thumb-down', _('annotation-actions.remove-annotation.false-positive'), () => const markAsFalsePositiveButton = this.#getButton('thumb-down', _('annotation-actions.remove-annotation.false-positive'), () =>
this.#annotationActionsService.markAsFalsePositive(null, annotations), this.#annotationActionsService.markAsFalsePositive(annotations),
); );
availableActions.push(markAsFalsePositiveButton); availableActions.push(markAsFalsePositiveButton);
} }
if (permissions.canForceRedaction) { if (permissions.canForceRedaction) {
const forceRedactionButton = this.#getButton('thumb-up', _('annotation-actions.force-redaction.label'), () => const forceRedactionButton = this.#getButton('thumb-up', _('annotation-actions.force-redaction.label'), () =>
this.#annotationActionsService.forceAnnotation(null, annotations), this.#annotationActionsService.forceAnnotation(annotations),
); );
availableActions.push(forceRedactionButton); availableActions.push(forceRedactionButton);
} }
if (permissions.canForceHint) { if (permissions.canForceHint) {
const forceHintButton = this.#getButton('thumb-up', _('annotation-actions.force-hint.label'), () => const forceHintButton = this.#getButton('thumb-up', _('annotation-actions.force-hint.label'), () =>
this.#annotationActionsService.forceAnnotation(null, annotations, true), this.#annotationActionsService.forceAnnotation(annotations, true),
); );
availableActions.push(forceHintButton); availableActions.push(forceHintButton);
} }
if (permissions.canRejectSuggestion) { if (permissions.canRejectSuggestion) {
const rejectSuggestionButton = this.#getButton('close', _('annotation-actions.reject-suggestion'), () => const rejectSuggestionButton = this.#getButton('close', _('annotation-actions.reject-suggestion'), () =>
this.#annotationActionsService.rejectSuggestion(null, annotations), this.#annotationActionsService.rejectSuggestion(annotations),
); );
availableActions.push(rejectSuggestionButton); availableActions.push(rejectSuggestionButton);
} }
@ -124,7 +124,7 @@ export class PdfAnnotationActionsService {
const removeOrSuggestToRemoveOnlyHereButton = this.#getButton( const removeOrSuggestToRemoveOnlyHereButton = this.#getButton(
'trash', 'trash',
_('annotation-actions.remove-annotation.only-here'), _('annotation-actions.remove-annotation.only-here'),
() => this.#annotationActionsService.removeOrSuggestRemoveAnnotation(null, annotations, false), () => this.#annotationActionsService.removeOrSuggestRemoveAnnotation(annotations, false),
); );
availableActions.push(removeOrSuggestToRemoveOnlyHereButton); availableActions.push(removeOrSuggestToRemoveOnlyHereButton);
} }

View File

@ -191,7 +191,7 @@ export class PdfProxyService {
return; return;
} }
this._annotationsActionsService.cancelResize(null, wrapper).then(); this._annotationsActionsService.cancelResize(wrapper).then();
} }
#configureAnnotationSpecificActions(viewerAnnotations: Annotation[]) { #configureAnnotationSpecificActions(viewerAnnotations: Annotation[]) {

View File

@ -21,9 +21,7 @@ export class SkippedService {
return this.#hideSkipped$.value; return this.#hideSkipped$.value;
} }
toggleSkipped($event): void { toggleSkipped(): void {
$event.stopPropagation();
$event.preventDefault();
this.#hideSkipped$.next(!this.hideSkipped); this.#hideSkipped$.next(!this.hideSkipped);
} }

View File

@ -83,7 +83,6 @@ export class CompareFileInputComponent {
#askForConfirmation(fileName: string, currentDocumentPageCount: number, compareDocumentPageCount: number) { #askForConfirmation(fileName: string, currentDocumentPageCount: number, compareDocumentPageCount: number) {
const ref: MatDialogRef<unknown, ConfirmOptions> = this._dialogService.openDialog( const ref: MatDialogRef<unknown, ConfirmOptions> = this._dialogService.openDialog(
'confirm', 'confirm',
null,
new ConfirmationDialogInput({ new ConfirmationDialogInput({
title: _('confirmation-dialog.compare-file.title'), title: _('confirmation-dialog.compare-file.title'),
question: _('confirmation-dialog.compare-file.question'), question: _('confirmation-dialog.compare-file.question'),

View File

@ -22,7 +22,7 @@
{{ 'search-screen.missing' | translate }}:<span *ngFor="let term of unmatched" {{ 'search-screen.missing' | translate }}:<span *ngFor="let term of unmatched"
>&nbsp;<s>{{ term }}</s></span >&nbsp;<s>{{ term }}</s></span
>.&nbsp;{{ 'search-screen.must-contain' | translate }}: >.&nbsp;{{ 'search-screen.must-contain' | translate }}:
<span (click)="$event.stopPropagation(); mustContain.emit(term)" *ngFor="let term of unmatched" <span (click)="mustContain.emit(term)" *ngFor="let term of unmatched" stopPropagation
>&nbsp;<u>{{ term }}</u></span >&nbsp;<u>{{ term }}</u></span
> >
</span> </span>

View File

@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { SearchScreenComponent } from './search-screen/search-screen.component'; import { SearchScreenComponent } from './search-screen/search-screen.component';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { IqserListingModule, IqserUsersModule, StatusBarComponent } from '@iqser/common-ui'; import { IqserListingModule, IqserUsersModule, StatusBarComponent, StopPropagationDirective } from '@iqser/common-ui';
import { SharedModule } from '@shared/shared.module'; import { SharedModule } from '@shared/shared.module';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { SearchItemTemplateComponent } from './search-item-template/search-item-template.component'; import { SearchItemTemplateComponent } from './search-item-template/search-item-template.component';
@ -19,6 +19,7 @@ const routes = [{ path: '', component: SearchScreenComponent }];
TranslateModule, TranslateModule,
IqserListingModule, IqserListingModule,
StatusBarComponent, StatusBarComponent,
StopPropagationDirective,
], ],
}) })
export class SearchModule {} export class SearchModule {}

View File

@ -1,6 +1,6 @@
<div (longPress)="forceReanalysisAction($event)" class="action-buttons" redactionLongPress> <div (longPress)="forceReanalysisAction($event)" class="action-buttons" redactionLongPress>
<iqser-circle-button <iqser-circle-button
(action)="openEditDossierDialog($event, dossier.id)" (action)="openEditDossierDialog(dossier.id)"
*allow="roles.dossiers.read; if: currentUser.isUser" *allow="roles.dossiers.read; if: currentUser.isUser"
[icon]="(iqserPermissionsService.has$(roles.dossiers.edit) | async) && currentUser.isManager ? 'iqser:edit' : 'red:info'" [icon]="(iqserPermissionsService.has$(roles.dossiers.edit) | async) && currentUser.isManager ? 'iqser:edit' : 'red:info'"
[iqserHelpMode]="'edit_dossier_dossier_info'" [iqserHelpMode]="'edit_dossier_dossier_info'"
@ -15,7 +15,7 @@
></iqser-circle-button> ></iqser-circle-button>
<iqser-circle-button <iqser-circle-button
(action)="reanalyseDossier($event, dossier)" (action)="reanalyseDossier(dossier)"
*ngIf="displayReanalyseBtn" *ngIf="displayReanalyseBtn"
[tooltip]="'dossier-listing.reanalyse.action' | translate" [tooltip]="'dossier-listing.reanalyse.action' | translate"
[type]="circleButtonTypes.dark" [type]="circleButtonTypes.dark"

View File

@ -45,12 +45,11 @@ export class DossiersListingActionsComponent implements OnChanges {
this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled; this.analysisForced = !$event.touchEnd && this._userPreferenceService.areDevFeaturesEnabled;
} }
openEditDossierDialog($event: MouseEvent, dossierId: string): void { openEditDossierDialog(dossierId: string): void {
this._dialogService.openDialog('editDossier', $event, { dossierId }); this._dialogService.openDialog('editDossier', { dossierId });
} }
async reanalyseDossier($event: MouseEvent, dossier: Dossier): Promise<void> { async reanalyseDossier(dossier: Dossier): Promise<void> {
$event.stopPropagation();
await this._reanalysisService.reanalyzeDossier(dossier); await this._reanalysisService.reanalyzeDossier(dossier);
} }
} }

View File

@ -125,7 +125,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'delete-file-btn-' + fileId, id: 'delete-file-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._openDeleteFileDialog($event), action: () => this._openDeleteFileDialog(),
tooltip: _('dossier-overview.delete.action'), tooltip: _('dossier-overview.delete.action'),
icon: 'iqser:trash', icon: 'iqser:trash',
show: this.showDelete, show: this.showDelete,
@ -133,7 +133,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'assign-btn-' + fileId, id: 'assign-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._assign($event), action: () => this._assign(),
tooltip: this.assignTooltip, tooltip: this.assignTooltip,
icon: 'red:assign', icon: 'red:assign',
show: this.showAssign, show: this.showAssign,
@ -141,7 +141,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'assign-to-me-btn-' + fileId, id: 'assign-to-me-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._assignToMe($event), action: () => this._assignToMe(),
tooltip: _('dossier-overview.assign-me'), tooltip: _('dossier-overview.assign-me'),
icon: 'red:assign-me', icon: 'red:assign-me',
show: this.showAssignToSelf, show: this.showAssignToSelf,
@ -149,7 +149,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'open-import-redactions-dialog-btn-' + fileId, id: 'open-import-redactions-dialog-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._openImportRedactionsDialog($event), action: () => this._openImportRedactionsDialog(),
tooltip: _('dossier-overview.import-redactions'), tooltip: _('dossier-overview.import-redactions'),
icon: 'red:import_redactions', icon: 'red:import_redactions',
show: this.showImportRedactions && !this._iqserPermissionsService.has(ROLES.getRss), show: this.showImportRedactions && !this._iqserPermissionsService.has(ROLES.getRss),
@ -188,7 +188,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'set-file-to-new-btn-' + fileId, id: 'set-file-to-new-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this.#setToNew($event), action: () => this.#setToNew(),
tooltip: _('dossier-overview.back-to-new'), tooltip: _('dossier-overview.back-to-new'),
icon: 'red:undo', icon: 'red:undo',
show: this.showSetToNew, show: this.showSetToNew,
@ -196,7 +196,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'set-file-under-approval-btn-' + fileId, id: 'set-file-under-approval-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._setFileUnderApproval($event), action: () => this._setFileUnderApproval(),
tooltip: _('dossier-overview.under-approval'), tooltip: _('dossier-overview.under-approval'),
icon: 'red:ready-for-approval', icon: 'red:ready-for-approval',
show: this.showUnderApproval, show: this.showUnderApproval,
@ -204,7 +204,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'set-file-under-review-btn-' + fileId, id: 'set-file-under-review-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._setFileUnderReview($event), action: () => this._setFileUnderReview(),
tooltip: _('dossier-overview.under-review'), tooltip: _('dossier-overview.under-review'),
icon: 'red:undo', icon: 'red:undo',
show: this.showUnderReview, show: this.showUnderReview,
@ -212,7 +212,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'set-file-approved-btn-' + fileId, id: 'set-file-approved-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this.setFileApproved($event), action: () => this.setFileApproved(),
tooltip: this.file.canBeApproved ? _('dossier-overview.approve') : _('dossier-overview.approve-disabled'), tooltip: this.file.canBeApproved ? _('dossier-overview.approve') : _('dossier-overview.approve-disabled'),
icon: 'red:approved', icon: 'red:approved',
disabled: !this.file.canBeApproved, disabled: !this.file.canBeApproved,
@ -221,7 +221,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'toggle-automatic-analysis-btn-' + fileId, id: 'toggle-automatic-analysis-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._toggleAutomaticAnalysis($event), action: () => this._toggleAutomaticAnalysis(),
tooltip: _('dossier-overview.stop-auto-analysis'), tooltip: _('dossier-overview.stop-auto-analysis'),
icon: 'red:disable-analysis', icon: 'red:disable-analysis',
show: this.canDisableAutoAnalysis, show: this.canDisableAutoAnalysis,
@ -229,7 +229,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'reanalyse-file-preview-btn-' + fileId, id: 'reanalyse-file-preview-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._reanalyseFile($event), action: () => this._reanalyseFile(),
tooltip: _('file-preview.reanalyse-notification'), tooltip: _('file-preview.reanalyse-notification'),
tooltipClass: 'small', tooltipClass: 'small',
icon: 'iqser:refresh', icon: 'iqser:refresh',
@ -239,7 +239,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'toggle-automatic-analysis-btn-' + fileId, id: 'toggle-automatic-analysis-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._toggleAutomaticAnalysis($event), action: () => this._toggleAutomaticAnalysis(),
tooltip: _('dossier-overview.start-auto-analysis'), tooltip: _('dossier-overview.start-auto-analysis'),
buttonType: this.isFilePreview ? CircleButtonTypes.warn : CircleButtonTypes.default, buttonType: this.isFilePreview ? CircleButtonTypes.warn : CircleButtonTypes.default,
icon: 'red:enable-analysis', icon: 'red:enable-analysis',
@ -248,7 +248,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'set-under-approval-btn-' + fileId, id: 'set-under-approval-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._setFileUnderApproval($event), action: () => this._setFileUnderApproval(),
tooltip: _('dossier-overview.under-approval'), tooltip: _('dossier-overview.under-approval'),
icon: 'red:undo', icon: 'red:undo',
show: this.showUndoApproval, show: this.showUndoApproval,
@ -256,7 +256,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'ocr-file-btn-' + fileId, id: 'ocr-file-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._ocrFile($event), action: () => this._ocrFile(),
tooltip: _('dossier-overview.ocr-file'), tooltip: _('dossier-overview.ocr-file'),
icon: 'iqser:ocr', icon: 'iqser:ocr',
show: this.showOCR, show: this.showOCR,
@ -264,7 +264,7 @@ export class FileActionsComponent implements OnChanges {
{ {
id: 'reanalyse-file-btn-' + fileId, id: 'reanalyse-file-btn-' + fileId,
type: ActionTypes.circleBtn, type: ActionTypes.circleBtn,
action: ($event: MouseEvent) => this._reanalyseFile($event), action: () => this._reanalyseFile(),
tooltip: _('dossier-overview.reanalyse.action'), tooltip: _('dossier-overview.reanalyse.action'),
icon: 'iqser:refresh', icon: 'iqser:refresh',
show: this.showReanalyseDossierOverview, show: this.showReanalyseDossierOverview,
@ -292,8 +292,7 @@ export class FileActionsComponent implements OnChanges {
} }
} }
async setFileApproved($event: MouseEvent) { async setFileApproved() {
$event.stopPropagation();
if (!this.file.analysisRequired && !this.file.hasUpdates) { if (!this.file.analysisRequired && !this.file.hasUpdates) {
await this.#setFileApproved(); await this.#setFileApproved();
return; return;
@ -301,7 +300,6 @@ export class FileActionsComponent implements OnChanges {
this._dialogService.openDialog( this._dialogService.openDialog(
'confirm', 'confirm',
$event,
new ConfirmationDialogInput({ new ConfirmationDialogInput({
title: this.file.analysisRequired title: this.file.analysisRequired
? _('confirmation-dialog.approve-file-without-analysis.title') ? _('confirmation-dialog.approve-file-without-analysis.title')
@ -330,18 +328,17 @@ export class FileActionsComponent implements OnChanges {
denyText: _('ocr.confirmation-dialog.cancel'), denyText: _('ocr.confirmation-dialog.cancel'),
}); });
const ref = this._dialogService.openDialog('confirm', null, data); const ref = this._dialogService.openDialog('confirm', data);
return ref.afterClosed(); return ref.afterClosed();
} }
private _openImportRedactionsDialog($event: MouseEvent) { private _openImportRedactionsDialog() {
this._dialogService.openDialog('importRedactions', $event, { dossierId: this.file.dossierId, fileId: this.file.fileId }); this._dialogService.openDialog('importRedactions', { dossierId: this.file.dossierId, fileId: this.file.fileId });
} }
private _openDeleteFileDialog($event: MouseEvent) { private _openDeleteFileDialog() {
this._dialogService.openDialog( this._dialogService.openDialog(
'confirm', 'confirm',
$event,
new ConfirmationDialogInput({ new ConfirmationDialogInput({
title: _('confirmation-dialog.delete-file.title'), title: _('confirmation-dialog.delete-file.title'),
question: _('confirmation-dialog.delete-file.question'), question: _('confirmation-dialog.delete-file.question'),
@ -360,21 +357,19 @@ export class FileActionsComponent implements OnChanges {
); );
} }
private _assign($event: MouseEvent) { private _assign() {
const files = [this.file]; const files = [this.file];
const targetStatus = this.file.workflowStatus; const targetStatus = this.file.workflowStatus;
const withCurrentUserAsDefault = true; const withCurrentUserAsDefault = true;
const withUnassignedOption = true; const withUnassignedOption = true;
this._dialogService.openDialog('assignFile', $event, { targetStatus, files, withCurrentUserAsDefault, withUnassignedOption }); this._dialogService.openDialog('assignFile', { targetStatus, files, withCurrentUserAsDefault, withUnassignedOption });
} }
private async _assignToMe($event: MouseEvent) { private async _assignToMe() {
$event.stopPropagation();
await this._fileAssignService.assignToMe([this.file]); await this._fileAssignService.assignToMe([this.file]);
} }
private async _reanalyseFile($event?: MouseEvent) { private async _reanalyseFile() {
$event?.stopPropagation();
const params: ReanalyzeQueryParams = { const params: ReanalyzeQueryParams = {
force: true, force: true,
triggeredByUser: true, triggeredByUser: true,
@ -382,20 +377,17 @@ export class FileActionsComponent implements OnChanges {
await firstValueFrom(this._reanalysisService.reanalyzeFilesForDossier([this.file], this.file.dossierId, params)); await firstValueFrom(this._reanalysisService.reanalyzeFilesForDossier([this.file], this.file.dossierId, params));
} }
private async _toggleAutomaticAnalysis($event: MouseEvent) { private async _toggleAutomaticAnalysis() {
$event.stopPropagation();
this._loadingService.start(); this._loadingService.start();
await firstValueFrom(this._reanalysisService.toggleAutomaticAnalysis(this.file.dossierId, [this.file])); await firstValueFrom(this._reanalysisService.toggleAutomaticAnalysis(this.file.dossierId, [this.file]));
this._loadingService.stop(); this._loadingService.stop();
} }
private async _setFileUnderApproval($event: MouseEvent) { private async _setFileUnderApproval() {
$event.stopPropagation(); await this._fileAssignService.assignApprover(this.file, true);
await this._fileAssignService.assignApprover($event, this.file, true);
} }
private async _ocrFile($event: MouseEvent) { private async _ocrFile() {
$event.stopPropagation();
if (this.file.lastManualChangeDate) { if (this.file.lastManualChangeDate) {
const confirm = await firstValueFrom(this.#showOCRConfirmationDialog()); const confirm = await firstValueFrom(this.#showOCRConfirmationDialog());
if (!confirm) { if (!confirm) {
@ -413,8 +405,8 @@ export class FileActionsComponent implements OnChanges {
this._loadingService.stop(); this._loadingService.stop();
} }
private async _setFileUnderReview($event: MouseEvent) { private async _setFileUnderReview() {
await this._fileAssignService.assignReviewer($event, this.file, true); await this._fileAssignService.assignReviewer(this.file, true);
} }
private async _toggleAnalysis() { private async _toggleAnalysis() {
@ -475,8 +467,7 @@ export class FileActionsComponent implements OnChanges {
this._loadingService.stop(); this._loadingService.stop();
} }
async #setToNew($event: MouseEvent) { async #setToNew() {
$event.stopPropagation();
this._loadingService.start(); this._loadingService.start();
await this._filesService.setToNew(this.file); await this._filesService.setToNew(this.file);
this._loadingService.stop(); this._loadingService.stop();

View File

@ -74,7 +74,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
openEditDetailsDialog(): void { openEditDetailsDialog(): void {
const data = { dictionary: this.dossierDictionary, dossierId: this.dossier.id, readOnly: !this.canEdit }; const data = { dictionary: this.dossierDictionary, dossierId: this.dossier.id, readOnly: !this.canEdit };
this._dialogService.openDialog('editDictionaryDetails', null, data, async () => { this._dialogService.openDialog('editDictionaryDetails', data, async () => {
await this._updateDossierDictionary(); await this._updateDossierDictionary();
}); });
} }

View File

@ -62,9 +62,10 @@
<div class="actions"> <div class="actions">
<div <div
(click)="!disabled && toggleApprover(userId, $event)" (click)="!disabled && toggleApprover(userId)"
*ngIf="!disabled || isApprover(userId)" *ngIf="!disabled || isApprover(userId)"
class="make-approver" class="make-approver"
stopPropagation
> >
<iqser-round-checkbox <iqser-round-checkbox
[active]="isApprover(userId)" [active]="isApprover(userId)"

View File

@ -101,9 +101,7 @@ export class EditDossierTeamComponent implements EditDossierSectionInterface, On
return this.selectedApproversList.indexOf(userId) !== -1; return this.selectedApproversList.indexOf(userId) !== -1;
} }
toggleApprover(userId: string, $event?: MouseEvent) { toggleApprover(userId: string) {
$event?.stopPropagation();
if (this.isApprover(userId)) { if (this.isApprover(userId)) {
this.selectedApproversList.splice(this.selectedApproversList.indexOf(userId), 1); this.selectedApproversList.splice(this.selectedApproversList.indexOf(userId), 1);
} else { } else {

View File

@ -139,7 +139,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
dossiersCount: 1, dossiersCount: 1,
}, },
}); });
this._dialogService.openDialog('confirm', null, data, async () => { this._dialogService.openDialog('confirm', data, async () => {
this._loadingService.start(); this._loadingService.start();
await firstValueFrom(this._trashService.deleteDossier(this.dossier)); await firstValueFrom(this._trashService.deleteDossier(this.dossier));
this._editDossierDialogRef.close(); this._editDossierDialogRef.close();
@ -165,7 +165,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
checkboxes: [{ value: false, label: _('confirm-archive-dossier.checkbox.documents') }], checkboxes: [{ value: false, label: _('confirm-archive-dossier.checkbox.documents') }],
toastMessage: _('confirm-archive-dossier.toast-error'), toastMessage: _('confirm-archive-dossier.toast-error'),
}); });
this._dialogService.openDialog('confirm', null, data, async result => { this._dialogService.openDialog('confirm', data, async result => {
if (result === ConfirmOptions.CONFIRM) { if (result === ConfirmOptions.CONFIRM) {
this._loadingService.start(); this._loadingService.start();
await firstValueFrom(this._archivedDossiersService.archive([this.dossier])); await firstValueFrom(this._archivedDossiersService.archive([this.dossier]));

View File

@ -40,24 +40,22 @@ export class FileAssignService {
? _('confirmation-dialog.assign-file-to-me.question.single') ? _('confirmation-dialog.assign-file-to-me.question.single')
: _('confirmation-dialog.assign-file-to-me.question.multiple'), : _('confirmation-dialog.assign-file-to-me.question.multiple'),
}); });
const ref = this._dialogService.openDialog('confirm', null, dialogInput, assignReq); const ref = this._dialogService.openDialog('confirm', dialogInput, assignReq);
return firstValueFrom(ref.afterClosed()); return firstValueFrom(ref.afterClosed());
} }
return assignReq(); return assignReq();
} }
async assignReviewer($event: MouseEvent, file: File, ignoreChanged = false): Promise<void> { async assignReviewer(file: File, ignoreChanged = false): Promise<void> {
await this._assignFile(WorkflowFileStatuses.UNDER_REVIEW, $event, file, ignoreChanged); await this._assignFile(WorkflowFileStatuses.UNDER_REVIEW, file, ignoreChanged);
} }
async assignApprover($event: MouseEvent, file: File, ignoreChanged = false): Promise<void> { async assignApprover(file: File, ignoreChanged = false): Promise<void> {
await this._assignFile(WorkflowFileStatuses.UNDER_APPROVAL, $event, file, ignoreChanged); await this._assignFile(WorkflowFileStatuses.UNDER_APPROVAL, file, ignoreChanged);
} }
private async _assignFile(targetStatus: WorkflowFileStatus, $event: MouseEvent, file: File, ignoreChanged = false): Promise<void> { private async _assignFile(targetStatus: WorkflowFileStatus, file: File, ignoreChanged = false): Promise<void> {
$event?.stopPropagation();
const currentUserId = this.currentUser.id; const currentUserId = this.currentUser.id;
const currentDossier = this._activeDossiersService.find(file.dossierId); const currentDossier = this._activeDossiersService.find(file.dossierId);
const eligibleUsersIds = this._getUserIds(targetStatus, currentDossier); const eligibleUsersIds = this._getUserIds(targetStatus, currentDossier);
@ -71,14 +69,14 @@ export class FileAssignService {
await this._makeAssignFileRequest(eligibleUsersIds[0], targetStatus, [file]); await this._makeAssignFileRequest(eligibleUsersIds[0], targetStatus, [file]);
} else { } else {
const data = { targetStatus, files: [file], ignoreChanged }; const data = { targetStatus, files: [file], ignoreChanged };
this._dialogService.openDialog('assignFile', null, data); this._dialogService.openDialog('assignFile', data);
} }
} else { } else {
if (eligibleUsersIds.length === 1) { if (eligibleUsersIds.length === 1) {
await this._makeAssignFileRequest(eligibleUsersIds[0], targetStatus, [file]); await this._makeAssignFileRequest(eligibleUsersIds[0], targetStatus, [file]);
} else { } else {
const data = { targetStatus, files: [file], ignoreChanged, withCurrentUserAsDefault: true }; const data = { targetStatus, files: [file], ignoreChanged, withCurrentUserAsDefault: true };
this._dialogService.openDialog('assignFile', null, data); this._dialogService.openDialog('assignFile', data);
} }
} }
} }

View File

@ -24,6 +24,7 @@ import {
SideNavComponent, SideNavComponent,
SmallChipComponent, SmallChipComponent,
StatusBarComponent, StatusBarComponent,
StopPropagationDirective,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { DossiersListingActionsComponent } from './components/dossiers-listing-actions/dossiers-listing-actions.component'; import { DossiersListingActionsComponent } from './components/dossiers-listing-actions/dossiers-listing-actions.component';
@ -61,6 +62,7 @@ const services = [FileAssignService];
SmallChipComponent, SmallChipComponent,
StatusBarComponent, StatusBarComponent,
SideNavComponent, SideNavComponent,
StopPropagationDirective,
], ],
}) })
export class SharedDossiersModule {} export class SharedDossiersModule {}

View File

@ -1,5 +1,5 @@
<iqser-circle-button <iqser-circle-button
(action)="downloadFiles($event)" (action)="downloadFiles()"
[buttonId]="buttonId" [buttonId]="buttonId"
[disabled]="disabled || !canDownloadFiles || invalidDownload" [disabled]="disabled || !canDownloadFiles || invalidDownload"
[tooltipClass]="tooltipClass" [tooltipClass]="tooltipClass"

View File

@ -42,8 +42,7 @@ export class FileDownloadBtnComponent implements OnChanges {
this.tooltip = this.canDownloadFiles ? _('dossier-overview.download-file') : _('dossier-overview.download-file-disabled'); this.tooltip = this.canDownloadFiles ? _('dossier-overview.download-file') : _('dossier-overview.download-file-disabled');
} }
async downloadFiles($event: MouseEvent) { async downloadFiles() {
$event.stopPropagation();
const ref = this._dialog.open<DownloadDialogComponent, DownloadDialogData, DownloadDialogResult>(DownloadDialogComponent, { const ref = this._dialog.open<DownloadDialogComponent, DownloadDialogData, DownloadDialogResult>(DownloadDialogComponent, {
...defaultDialogConfig, ...defaultDialogConfig,
data: { dossier: this.dossier, files: this.files }, data: { dossier: this.dossier, files: this.files },

View File

@ -29,7 +29,6 @@
<div *ngIf="btn.type === 'toggle'" class="iqser-input-group"> <div *ngIf="btn.type === 'toggle'" class="iqser-input-group">
<mat-slide-toggle <mat-slide-toggle
(change)="btn.action()" (change)="btn.action()"
(click)="$event.stopPropagation()"
[checked]="btn.checked" [checked]="btn.checked"
[disabled]="btn.disabled" [disabled]="btn.disabled"
[id]="btn.id" [id]="btn.id"
@ -37,6 +36,7 @@
[matTooltip]="btn.tooltip | translate" [matTooltip]="btn.tooltip | translate"
[ngClass]="btn.class" [ngClass]="btn.class"
color="primary" color="primary"
stopPropagation
></mat-slide-toggle> ></mat-slide-toggle>
</div> </div>
</ng-container> </ng-container>

View File

@ -70,7 +70,7 @@ export class ExpandableFileActionsComponent implements OnChanges {
// Patch download button // Patch download button
const downloadBtn = this.actions.find(btn => btn.type === ActionTypes.downloadBtn); const downloadBtn = this.actions.find(btn => btn.type === ActionTypes.downloadBtn);
if (downloadBtn) { if (downloadBtn) {
downloadBtn.action = ($event: MouseEvent) => this._downloadFiles($event, downloadBtn.files, downloadBtn.dossier); downloadBtn.action = () => this._downloadFiles(downloadBtn.files, downloadBtn.dossier);
downloadBtn.disabled = !this._permissionsService.canDownloadFiles(downloadBtn.files, downloadBtn.dossier); downloadBtn.disabled = !this._permissionsService.canDownloadFiles(downloadBtn.files, downloadBtn.dossier);
} }
} }
@ -81,8 +81,8 @@ export class ExpandableFileActionsComponent implements OnChanges {
this.matMenu.closeMenu(); this.matMenu.closeMenu();
} }
private async _downloadFiles($event: MouseEvent, files: File[], dossier: Dossier) { // TODO: this doesn't look like its called
$event.stopPropagation(); private async _downloadFiles(files: File[], dossier: Dossier) {
const ref = this._dialog.open<DownloadDialogComponent, DownloadDialogData, DownloadDialogResult>(DownloadDialogComponent, { const ref = this._dialog.open<DownloadDialogComponent, DownloadDialogData, DownloadDialogResult>(DownloadDialogComponent, {
...defaultDialogConfig, ...defaultDialogConfig,
data: { dossier, files }, data: { dossier, files },

View File

@ -1,11 +1,18 @@
<div class="label-header"> <div class="label-header">
<div class="all-caps-label">{{ label }}</div> <div class="all-caps-label">{{ label }}</div>
<div class="actions"> <div class="actions">
<div (click)="selectAll($event)" [class.disabled]="disabled" class="all-caps-label primary pointer" translate="actions.all"></div>
<div <div
(click)="deselectAll($event)" (click)="selectAll()"
[class.disabled]="disabled" [class.disabled]="disabled"
class="all-caps-label primary pointer" class="all-caps-label primary pointer"
stopPropagation
translate="actions.all"
></div>
<div
(click)="deselectAll()"
[class.disabled]="disabled"
class="all-caps-label primary pointer"
stopPropagation
translate="actions.none" translate="actions.none"
></div> ></div>
</div> </div>

View File

@ -85,8 +85,7 @@ export class SelectComponent implements AfterViewInit, ControlValueAccessor {
this.disabled = isDisabled; this.disabled = isDisabled;
} }
selectAll($event) { selectAll() {
$event.stopPropagation();
this.chipList._chips.forEach(chip => { this.chipList._chips.forEach(chip => {
if (!chip.selected) { if (!chip.selected) {
chip.toggleSelected(true); chip.toggleSelected(true);
@ -94,8 +93,7 @@ export class SelectComponent implements AfterViewInit, ControlValueAccessor {
}); });
} }
deselectAll($event?) { deselectAll() {
$event?.stopPropagation();
this.chipList._chips.forEach(chip => { this.chipList._chips.forEach(chip => {
if (chip.selected) { if (chip.selected) {
chip.toggleSelected(true); chip.toggleSelected(true);

View File

@ -51,6 +51,6 @@ export class TeamMembersComponent {
openEditDossierDialog(): void { openEditDossierDialog(): void {
const data = { dossierId: this.dossierId, section: 'members' }; const data = { dossierId: this.dossierId, section: 'members' };
this._dialogService.openDialog('editDossier', null, data); this._dialogService.openDialog('editDossier', data);
} }
} }

View File

@ -84,7 +84,7 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
if (savedDossier) { if (savedDossier) {
await this._router.navigate([savedDossier.routerLink]); await this._router.navigate([savedDossier.routerLink]);
if (options?.addMembers) { if (options?.addMembers) {
this._dialogService.openDialog('editDossier', null, { this._dialogService.openDialog('editDossier', {
dossierId: savedDossier.id, dossierId: savedDossier.id,
section: 'members', section: 'members',
}); });

View File

@ -16,6 +16,7 @@ import {
IqserScrollbarModule, IqserScrollbarModule,
IqserUsersModule, IqserUsersModule,
SmallChipComponent, SmallChipComponent,
StopPropagationDirective,
} from '@iqser/common-ui'; } from '@iqser/common-ui';
import { SelectComponent } from './components/select/select.component'; import { SelectComponent } from './components/select/select.component';
import { NavigateLastDossiersScreenDirective } from './directives/navigate-last-dossiers-screen.directive'; import { NavigateLastDossiersScreenDirective } from './directives/navigate-last-dossiers-screen.directive';
@ -95,6 +96,7 @@ const deleteThisWhenAllComponentsAreStandalone = [DonutChartComponent];
CircleButtonComponent, CircleButtonComponent,
IconButtonComponent, IconButtonComponent,
SmallChipComponent, SmallChipComponent,
StopPropagationDirective,
], ],
exports: [...modules, ...components, ...utils, ...deleteThisWhenAllComponentsAreStandalone], exports: [...modules, ...components, ...utils, ...deleteThisWhenAllComponentsAreStandalone],
providers: [ providers: [

View File

@ -41,7 +41,8 @@ export class TrashDialogService extends DialogService<DialogType> {
itemsCount: items.length, itemsCount: items.length,
}, },
}); });
this.openDialog('confirm', null, data, async () => {
this.openDialog('confirm', data, async () => {
this._loadingService.start(); this._loadingService.start();
await firstValueFrom(this._trashService.hardDelete(items)); await firstValueFrom(this._trashService.hardDelete(items));
this._loadingService.stop(); this._loadingService.stop();

@ -1 +1 @@
Subproject commit 655874989bafa3b7017ceb94e1088c7f9fddd0a5 Subproject commit a2e40583e3b3f731cee202bd621545994a87ff7f