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

View File

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

View File

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

View File

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

View File

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

View File

@ -99,7 +99,7 @@
<div class="cell">
<div class="action-buttons">
<iqser-circle-button
(action)="openAuditDetails($event, log)"
(action)="openAuditDetails(log)"
*ngIf="log.hasDetails"
[tooltip]="'audit-screen.action.info' | translate"
[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 {
return this._formBuilder.group({
category: [this.ALL_CATEGORIES],
@ -136,8 +140,4 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
}
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="action-buttons">
<iqser-circle-button
(action)="openEditColorDialog($event, entity)"
(action)="openEditColorDialog(entity)"
*allow="roles.colors.write; if: currentUser.isAdmin"
[iqserHelpMode]="'default_colors'"
[overlappingElements]="['USER_MENU']"

View File

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

View File

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

View File

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

View File

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

View File

@ -52,7 +52,7 @@
></iqser-input-with-action>
<iqser-icon-button
(action)="openAddStateDialog($event)"
(action)="openAddStateDialog()"
*ngIf="permissionsService.canPerformDossierStatesActions()"
[iqserHelpMode]="'create_new_dossier_state'"
[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));
}
openAddStateDialog($event: MouseEvent) {
$event.stopPropagation();
openAddStateDialog() {
this._dialog.open<AddEditDossierStateDialogComponent, AddEditDossierStateDialogData>(AddEditDossierStateDialogComponent, {
...defaultDialogConfig,
data: {

View File

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

View File

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

View File

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

View File

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

View File

@ -39,7 +39,7 @@
<ng-template #bulkActions>
<iqser-circle-button
(action)="openDeleteEntitiesDialog($event)"
(action)="openDeleteEntitiesDialog()"
*ngIf="permissionsService.canDeleteEntities(listingService.selected)"
[tooltip]="'entities-listing.bulk.delete' | translate"
[type]="circleButtonTypes.dark"
@ -58,8 +58,8 @@
(action)="openAddEntityDialog()"
*ngIf="permissionsService.canEditEntities()"
[iqserHelpMode]="'create_new_entity'"
[overlappingElements]="['USER_MENU']"
[label]="'entities-listing.add-new' | translate"
[overlappingElements]="['USER_MENU']"
[type]="iconButtonTypes.primary"
icon="iqser:plus"
></iqser-icon-button>
@ -101,7 +101,7 @@
<div class="action-buttons">
<div [iqserHelpMode]="'edit_delete_entities'" [overlappingElements]="['USER_MENU']">
<iqser-circle-button
(action)="openDeleteEntitiesDialog($event, [dict])"
(action)="openDeleteEntitiesDialog([dict])"
*ngIf="permissionsService.canDeleteEntities(dict)"
[tooltip]="'entities-listing.action.delete' | translate"
[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()));
}
openDeleteEntitiesDialog($event?: MouseEvent, types = this.listingService.selected) {
this._dialogService.openDialog('confirm', $event, null, async () => {
openDeleteEntitiesDialog(types = this.listingService.selected) {
this._dialogService.openDialog('confirm', null, async () => {
this._loadingService.start();
await firstValueFrom(
this._dictionaryService.deleteDictionaries(
@ -62,8 +62,8 @@ export class EntitiesListingScreenComponent extends ListingComponent<Dictionary>
});
}
openAddEntityDialog($event?: MouseEvent) {
this._dialogService.openDialog('addEntity', $event, { dossierTemplateId: this.#dossierTemplateId });
openAddEntityDialog() {
this._dialogService.openDialog('addEntity', { dossierTemplateId: this.#dossierTemplateId });
}
private _loadDictionaryData(): void {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -51,13 +51,13 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
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 data = new ConfirmationDialogInput({
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);
});
}

View File

@ -108,7 +108,7 @@ export class AdminDialogService extends DialogService<DialogType> {
super(_dialog);
}
deleteUsers(userIds: string[], $event?: MouseEvent, cb?: () => Promise<void> | void): void {
deleteUsers(userIds: string[], cb?: () => Promise<void> | void): void {
const data = new ConfirmationDialogInput({
title: _('confirm-delete-users.title'),
question: _('confirm-delete-users.warning'),
@ -123,7 +123,7 @@ export class AdminDialogService extends DialogService<DialogType> {
toastMessage: _('confirm-delete-users.toast-error'),
});
this.openDialog('confirm', $event, data, async result => {
this.openDialog('confirm', data, async result => {
if (result === ConfirmOptions.CONFIRM) {
this._loadingService.start();
await firstValueFrom(this._userService.delete(userIds));
@ -138,7 +138,6 @@ export class AdminDialogService extends DialogService<DialogType> {
dossierTemplateId: string,
impactedTemplatesRef: TemplateRef<unknown>,
type: 'dossier' | 'file',
$event: MouseEvent,
cb: () => Promise<void> | void,
): Promise<void> {
this._loadingService.start();
@ -175,6 +174,7 @@ export class AdminDialogService extends DialogService<DialogType> {
toastMessage: _('confirm-delete-attribute.toast-error'),
translateParams: { reportsCount: uniqueTemplates.length, count: attributes.length, name: attributes[0].label },
});
if (templates.length) {
data.checkboxes.push({
value: false,
@ -183,7 +183,8 @@ export class AdminDialogService extends DialogService<DialogType> {
extraContentData: { templates: uniqueTemplates },
});
}
this.openDialog('confirm', $event, data, async () => {
this.openDialog('confirm', data, async () => {
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']">
<iqser-circle-button
(action)="openDeleteDossierTemplateDialog()"
[buttonId]="'delete-dossier-template-btn-' + dossierTemplateId"
(action)="openDeleteDossierTemplateDialog($event)"
[tooltip]="'dossier-templates-listing.action.delete' | translate"
[type]="circleButtonTypes.dark"
icon="iqser:trash"
[type]="circleButtonTypes.dark"
></iqser-circle-button>
<iqser-circle-button
(action)="openEditCloneDossierTemplateDialog(true)"
[buttonId]="'copy-dossier-template-btn-' + dossierTemplateId"
(action)="openEditCloneDossierTemplateDialog($event, true)"
[tooltip]="'dossier-templates-listing.action.clone' | translate"
icon="iqser:copy"
[type]="circleButtonTypes.dark"
icon="iqser:copy"
></iqser-circle-button>
<iqser-circle-button
(action)="openEditCloneDossierTemplateDialog()"
[buttonId]="'edit-dossier-template-btn-' + dossierTemplateId"
(action)="openEditCloneDossierTemplateDialog($event)"
[tooltip]="'dossier-templates-listing.action.edit' | translate"
icon="iqser:edit"
[type]="circleButtonTypes.dark"
icon="iqser:edit"
></iqser-circle-button>
</div>
</div>

View File

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

View File

@ -24,6 +24,6 @@ export class TemplateStatsComponent {
) {}
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 {
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));
});
}

View File

@ -7,7 +7,7 @@
<ng-container *ngIf="(isEditingFileAttribute$ | async) === false || isInEditMode">
<div *ngIf="!isInEditMode; else input" class="edit-button">
<iqser-circle-button
(action)="editFileAttribute($event)"
(action)="editFileAttribute()"
*ngIf="permissionsService.canEditFileAttributes(file, dossier)"
[disabled]="!fileAttribute.editable"
[icon]="'iqser:edit'"
@ -15,8 +15,9 @@
id="edit-attribute-button"
></iqser-circle-button>
</div>
<ng-template #input>
<div (click)="$event?.stopPropagation()" class="edit-input">
<div class="edit-input" stopPropagation>
<form (submit)="save()" [formGroup]="form">
<iqser-dynamic-input
(closedDatepicker)="closedDatepicker = $event"
@ -24,17 +25,11 @@
[formControlName]="fileAttribute.id"
[id]="fileAttribute.id"
[type]="fileAttribute.type"
>
</iqser-dynamic-input>
></iqser-dynamic-input>
<iqser-circle-button
(action)="save($event)"
[disabled]="disabled"
[icon]="'iqser:check'"
class="save"
></iqser-circle-button>
<iqser-circle-button (action)="save()" [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>
</div>
</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 {
return this.fileAttribute.type === FileAttributeConfigTypes.DATE;
}
@ -71,28 +62,20 @@ export class FileAttributeComponent extends BaseFormComponent implements OnInit
return JSON.stringify(this.file.fileAttributes.attributeIdToValue) === '{}';
}
#initFileAttributes() {
const configs = this._fileAttributesService.getFileAttributeConfig(this.file.dossierTemplateId).fileAttributeConfigs;
configs.forEach(config => (this.file.fileAttributes.attributeIdToValue[config.id] = null));
ngOnInit(): void {
if (this.#noFileAttributes) {
this.#initFileAttributes();
}
this.form = this.#getForm();
this.initialFormValue = this.form.getRawValue();
}
async editFileAttribute($event: MouseEvent): Promise<void> {
$event?.stopPropagation();
async editFileAttribute(): Promise<void> {
this.#toggleEdit();
}
#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);
}
async save($event?: MouseEvent): Promise<void> {
$event?.stopPropagation();
async save() {
const rawFormValue = this.form.getRawValue();
const fileAttrValue = rawFormValue[this.fileAttribute.id];
const attributeIdToValue = {
@ -113,14 +96,35 @@ export class FileAttributeComponent extends BaseFormComponent implements OnInit
this.#toggleEdit();
}
close($event?: MouseEvent): void {
$event?.stopPropagation();
close(): void {
if (this.isInEditMode) {
this.form = this.#getForm();
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) {
return this.isDate ? attrValue && dayjs(attrValue).format('YYYY-MM-DD') : attrValue;
}
@ -140,11 +144,4 @@ export class FileAttributeComponent extends BaseFormComponent implements OnInit
input.focus();
}, 100);
}
@HostListener('document:click')
clickOutside() {
if (this.isInEditMode && this.closedDatepicker) {
this.close();
}
}
}

View File

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

View File

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

View File

@ -47,7 +47,6 @@ export class BulkActionsService {
delete(files: File[]) {
this._dialogService.openDialog(
'confirm',
null,
new ConfirmationDialogInput({
title: _('confirmation-dialog.delete-file.title'),
question: _('confirmation-dialog.delete-file.question'),
@ -98,7 +97,6 @@ export class BulkActionsService {
if (foundAnalysisRequiredFile || foundUpdatedFile) {
this._dialogService.openDialog(
'confirm',
null,
new ConfirmationDialogInput({
title: foundAnalysisRequiredFile
? _('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 {
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 {
this._dialogService.openDialog('addDossier', null, { dossierTemplateId });
this._dialogService.openDialog('addDossier', { dossierTemplateId });
}
private _quickFilters(entities: Dossier[]): NestedFilter[] {

View File

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

View File

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

View File

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

View File

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

View File

@ -8,12 +8,13 @@
<div class="comment-actions">
<iqser-circle-button
(action)="deleteComment($event, comment)"
(action)="deleteComment(comment)"
*ngIf="permissionsService.canDeleteComment(comment, ctx.file, ctx.dossier)"
[iconSize]="10"
[size]="20"
class="pointer"
icon="iqser:trash"
stopPropagation
></iqser-circle-button>
</div>
</div>
@ -30,5 +31,10 @@
width="full"
></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>

View File

@ -71,13 +71,11 @@ export class CommentsComponent extends ContextComponent<CommentsContext> impleme
this._loadingService.stop();
}
toggleExpandComments($event?: MouseEvent): void {
$event?.stopPropagation();
toggleExpandComments(): void {
this._commentingService.toggle(this.annotation.id);
}
async deleteComment($event: MouseEvent, comment: IComment): Promise<void> {
$event.stopPropagation();
async deleteComment(comment: IComment): Promise<void> {
this._loadingService.start();
const { dossierId, fileId } = this._stateService;
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) {
this._dialogService.openDialog('documentInfo', null, file);
this._dialogService.openDialog('documentInfo', file);
}
isDate(attribute: FileAttribute) {

View File

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

View File

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

View File

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

View File

@ -320,7 +320,6 @@ export class FilePreviewScreenComponent
this.state.dialogRef = this._dialogService.openDialog(
'manualAnnotation',
null,
{ manualRedactionEntryWrapper, dossierId: this.dossierId, file },
(result: { annotations: ManualRedactionEntryWrapper[]; dictionary?: Dictionary }) => {
const selectedAnnotations = this._annotationManager.selected;
@ -422,7 +421,7 @@ export class FilePreviewScreenComponent
}
openRSSView(file: File) {
this._dialogService.openDialog('rss', null, { file });
this._dialogService.openDialog('rss', { file });
}
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(
switchMap(async (result: ConfirmOptions) => {
const doNotShowWarningAgain = result === ConfirmOptions.SECOND_CONFIRM;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@
{{ 'search-screen.missing' | translate }}:<span *ngFor="let term of unmatched"
>&nbsp;<s>{{ term }}</s></span
>.&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
>
</span>

View File

@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SearchScreenComponent } from './search-screen/search-screen.component';
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 { TranslateModule } from '@ngx-translate/core';
import { SearchItemTemplateComponent } from './search-item-template/search-item-template.component';
@ -19,6 +19,7 @@ const routes = [{ path: '', component: SearchScreenComponent }];
TranslateModule,
IqserListingModule,
StatusBarComponent,
StopPropagationDirective,
],
})
export class SearchModule {}

View File

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

View File

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

View File

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

View File

@ -74,7 +74,7 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
openEditDetailsDialog(): void {
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();
});
}

View File

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

View File

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

View File

@ -139,7 +139,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
dossiersCount: 1,
},
});
this._dialogService.openDialog('confirm', null, data, async () => {
this._dialogService.openDialog('confirm', data, async () => {
this._loadingService.start();
await firstValueFrom(this._trashService.deleteDossier(this.dossier));
this._editDossierDialogRef.close();
@ -165,7 +165,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
checkboxes: [{ value: false, label: _('confirm-archive-dossier.checkbox.documents') }],
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) {
this._loadingService.start();
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.multiple'),
});
const ref = this._dialogService.openDialog('confirm', null, dialogInput, assignReq);
const ref = this._dialogService.openDialog('confirm', dialogInput, assignReq);
return firstValueFrom(ref.afterClosed());
}
return assignReq();
}
async assignReviewer($event: MouseEvent, file: File, ignoreChanged = false): Promise<void> {
await this._assignFile(WorkflowFileStatuses.UNDER_REVIEW, $event, file, ignoreChanged);
async assignReviewer(file: File, ignoreChanged = false): Promise<void> {
await this._assignFile(WorkflowFileStatuses.UNDER_REVIEW, file, ignoreChanged);
}
async assignApprover($event: MouseEvent, file: File, ignoreChanged = false): Promise<void> {
await this._assignFile(WorkflowFileStatuses.UNDER_APPROVAL, $event, file, ignoreChanged);
async assignApprover(file: File, ignoreChanged = false): Promise<void> {
await this._assignFile(WorkflowFileStatuses.UNDER_APPROVAL, file, ignoreChanged);
}
private async _assignFile(targetStatus: WorkflowFileStatus, $event: MouseEvent, file: File, ignoreChanged = false): Promise<void> {
$event?.stopPropagation();
private async _assignFile(targetStatus: WorkflowFileStatus, file: File, ignoreChanged = false): Promise<void> {
const currentUserId = this.currentUser.id;
const currentDossier = this._activeDossiersService.find(file.dossierId);
const eligibleUsersIds = this._getUserIds(targetStatus, currentDossier);
@ -71,14 +69,14 @@ export class FileAssignService {
await this._makeAssignFileRequest(eligibleUsersIds[0], targetStatus, [file]);
} else {
const data = { targetStatus, files: [file], ignoreChanged };
this._dialogService.openDialog('assignFile', null, data);
this._dialogService.openDialog('assignFile', data);
}
} else {
if (eligibleUsersIds.length === 1) {
await this._makeAssignFileRequest(eligibleUsersIds[0], targetStatus, [file]);
} else {
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,
SmallChipComponent,
StatusBarComponent,
StopPropagationDirective,
} from '@iqser/common-ui';
import { TranslateModule } from '@ngx-translate/core';
import { DossiersListingActionsComponent } from './components/dossiers-listing-actions/dossiers-listing-actions.component';
@ -61,6 +62,7 @@ const services = [FileAssignService];
SmallChipComponent,
StatusBarComponent,
SideNavComponent,
StopPropagationDirective,
],
})
export class SharedDossiersModule {}

View File

@ -1,5 +1,5 @@
<iqser-circle-button
(action)="downloadFiles($event)"
(action)="downloadFiles()"
[buttonId]="buttonId"
[disabled]="disabled || !canDownloadFiles || invalidDownload"
[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');
}
async downloadFiles($event: MouseEvent) {
$event.stopPropagation();
async downloadFiles() {
const ref = this._dialog.open<DownloadDialogComponent, DownloadDialogData, DownloadDialogResult>(DownloadDialogComponent, {
...defaultDialogConfig,
data: { dossier: this.dossier, files: this.files },

View File

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

View File

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

View File

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

View File

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

View File

@ -51,6 +51,6 @@ export class TeamMembersComponent {
openEditDossierDialog(): void {
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) {
await this._router.navigate([savedDossier.routerLink]);
if (options?.addMembers) {
this._dialogService.openDialog('editDossier', null, {
this._dialogService.openDialog('editDossier', {
dossierId: savedDossier.id,
section: 'members',
});

View File

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

View File

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

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