diff --git a/apps/red-ui/src/app/app-routing.module.ts b/apps/red-ui/src/app/app-routing.module.ts
index de57e29c3..713f365da 100644
--- a/apps/red-ui/src/app/app-routing.module.ts
+++ b/apps/red-ui/src/app/app-routing.module.ts
@@ -16,7 +16,7 @@ import { CompositeRouteGuard, DEFAULT_REDIRECT_KEY, IqserPermissionsGuard, Iqser
import { TenantSelectComponent } from '@iqser/common-ui/lib/tenants';
import { doesNotHaveAnyRole, hasAnyRole, IqserAuthGuard } from '@iqser/common-ui/lib/users';
import { CustomRouteReuseStrategy } from '@iqser/common-ui/lib/utils';
-import { ARCHIVE_ROUTE, BreadcrumbTypes, DOSSIER_ID, DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE, FILE_ID } from '@red/domain';
+import { ARCHIVE_ROUTE, BreadcrumbTypes, DOSSIER_ID, DOSSIER_TEMPLATE_ID, DOSSIERS_ROUTE, FILE_ID } from '@red/domain';
import { RedRoleGuard } from '@users/red-role.guard';
import { Roles } from '@users/roles';
import { mainGuard } from '@utils/main.guard';
@@ -81,7 +81,6 @@ const dossierTemplateIdRoutes: IqserRoutes = [
canActivate: [CompositeRouteGuard, loadArchivedDossiersGuard()],
data: {
routeGuards: [FeaturesGuard],
- features: [DOSSIERS_ARCHIVE],
},
},
{
diff --git a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts
index d0b3e4df2..a5c674642 100644
--- a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts
+++ b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts
@@ -8,8 +8,7 @@ import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-se
import { filter, map, startWith } from 'rxjs/operators';
import { getConfig, IqserPermissionsService } from '@iqser/common-ui';
import { BreadcrumbsService } from '@services/breadcrumbs.service';
-import { FeaturesService } from '@services/features.service';
-import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@red/domain';
+import { ARCHIVE_ROUTE, DOSSIERS_ROUTE } from '@red/domain';
import { Roles } from '@users/roles';
import { REDDocumentViewer } from '../../modules/pdf-viewer/services/document-viewer.service';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@@ -36,7 +35,6 @@ export class BaseScreenComponent {
{
text: this._translateService.instant('search.active-dossiers'),
icon: 'red:enter',
- hide: () => !this._featuresService.isEnabled(DOSSIERS_ARCHIVE),
action: (query): void => this.#search(query, [], true),
},
{
@@ -58,7 +56,6 @@ export class BaseScreenComponent {
private readonly _router: Router,
activatedRoute: ActivatedRoute,
private readonly _translateService: TranslateService,
- private readonly _featuresService: FeaturesService,
readonly permissionsService: IqserPermissionsService,
readonly userService: UserService,
readonly userPreferenceService: UserPreferenceService,
diff --git a/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts b/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts
index aa0830d0c..be5b01235 100644
--- a/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts
+++ b/apps/red-ui/src/app/models/file/annotation-permissions.utils.ts
@@ -1,6 +1,6 @@
import { AnnotationPermissions } from '@models/file/annotation.permissions';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
-import { Dictionary, LogEntryEngines, SuperTypes } from '@red/domain';
+import { Dictionary, SuperTypes } from '@red/domain';
export const canUndo = (annotation: AnnotationWrapper, isApprover: boolean) => !isApprover && annotation.pending;
@@ -16,7 +16,11 @@ export const canForceRedaction = (annotation: AnnotationWrapper, canAddRedaction
export const canAcceptRecommendation = (annotation: AnnotationWrapper) => annotation.isRecommendation && !annotation.pending;
export const canMarkAsFalsePositive = (annotation: AnnotationWrapper, annotationEntity: Dictionary) =>
- annotation.canBeMarkedAsFalsePositive && !annotation.hasBeenResizedLocally && annotationEntity?.hasDictionary;
+ annotation.canBeMarkedAsFalsePositive &&
+ !annotation.hasBeenResizedLocally &&
+ !annotation.isRemovedLocally &&
+ !annotation.hasBeenForcedRedaction &&
+ annotationEntity?.hasDictionary;
export const canRemoveOnlyHere = (annotation: AnnotationWrapper, canAddRedaction: boolean, autoAnalysisDisabled: boolean) =>
canAddRedaction &&
diff --git a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html
index ad1f6dd44..b6cfb0efd 100644
--- a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html
+++ b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.html
@@ -11,12 +11,6 @@
-
-
- {{ 'preferences-screen.form.open-structured-view-by-default' | translate }}
-
-
-
@@ -37,6 +31,11 @@
{{ 'preferences-screen.form.help-mode-dialog' | translate }}
+
+
+ {{ 'preferences-screen.form.overwrite-file-option' | translate }}
+
+
diff --git a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.ts b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.ts
index 269fe712f..36b1edc02 100644
--- a/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.ts
+++ b/apps/red-ui/src/app/modules/account/screens/preferences/preferences.component.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import {
@@ -23,11 +23,11 @@ import { MatCheckbox } from '@angular/material/checkbox';
interface PreferencesForm {
// preferences
autoExpandFiltersOnActions: boolean;
- openScmDialogByDefault: boolean;
tableExtractionType: string;
// warnings preferences
loadAllAnnotationsWarning: boolean;
helpModeDialog: boolean;
+ overwriteFileOption: boolean;
[k: string]: any;
}
@@ -58,6 +58,12 @@ const Screens = {
],
})
export class PreferencesComponent extends BaseFormComponent implements OnInit {
+ readonly #formBuilder = inject(FormBuilder);
+ readonly #permissionsService = inject(IqserPermissionsService);
+ readonly #changeRef = inject(ChangeDetectorRef);
+ readonly #loadingService = inject(LoadingService);
+ readonly #userPreferenceService = inject(UserPreferenceService);
+
readonly form: FormGroup>;
readonly currentScreen: Screen;
readonly screens = Screens;
@@ -66,81 +72,87 @@ export class PreferencesComponent extends BaseFormComponent implements OnInit {
readonly config = getConfig();
readonly isIqserDevMode = isIqserDevMode();
- constructor(
- route: ActivatedRoute,
- readonly userPreferenceService: UserPreferenceService,
- private readonly _formBuilder: FormBuilder,
- private readonly _permissionsService: IqserPermissionsService,
- private readonly _changeRef: ChangeDetectorRef,
- private readonly _loadingService: LoadingService,
- ) {
+ get #isOverwriteFileOptionActive() {
+ return !(this.#userPreferenceService.getOverwriteFileOption() === 'undefined');
+ }
+
+ constructor(route: ActivatedRoute) {
super();
- this.form = this._formBuilder.group({
+ this.form = this.#formBuilder.group({
// preferences
- autoExpandFiltersOnActions: [this.userPreferenceService.getAutoExpandFiltersOnActions()],
- openScmDialogByDefault: [this.userPreferenceService.getOpenScmDialogByDefault()],
- tableExtractionType: [this.userPreferenceService.getTableExtractionType()],
+ autoExpandFiltersOnActions: [this.#userPreferenceService.getAutoExpandFiltersOnActions()],
+ tableExtractionType: [this.#userPreferenceService.getTableExtractionType()],
// warnings preferences
- loadAllAnnotationsWarning: [this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)],
- helpModeDialog: [this.userPreferenceService.getBool(KEYS.helpModeDialog)],
+ loadAllAnnotationsWarning: [this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)],
+ helpModeDialog: [this.#userPreferenceService.getBool(KEYS.helpModeDialog)],
+ overwriteFileOption: [this.#isOverwriteFileOptionActive],
});
- if (!this._permissionsService.has(Roles.managePreferences)) {
+ if (!this.#permissionsService.has(Roles.managePreferences)) {
this.form.disable();
}
- if (!this._permissionsService.has(Roles.getTables)) {
+ if (!this.#permissionsService.has(Roles.getTables)) {
this.form.controls.tableExtractionType.disable();
}
+ if (!this.#isOverwriteFileOptionActive) {
+ this.form.controls.overwriteFileOption.disable();
+ }
+
this.initialFormValue = this.form.getRawValue();
this.currentScreen = route.snapshot.data.screen;
}
ngOnInit() {
- this._loadingService.stop();
+ this.#loadingService.stop();
}
async save(): Promise {
- if (this.form.controls.autoExpandFiltersOnActions.value !== this.userPreferenceService.getAutoExpandFiltersOnActions()) {
- await this.userPreferenceService.toggleAutoExpandFiltersOnActions();
- }
- if (this.form.controls.openScmDialogByDefault.value !== this.userPreferenceService.getOpenScmDialogByDefault()) {
- await this.userPreferenceService.toggleOpenScmDialogByDefault();
+ if (this.form.controls.autoExpandFiltersOnActions.value !== this.#userPreferenceService.getAutoExpandFiltersOnActions()) {
+ await this.#userPreferenceService.toggleAutoExpandFiltersOnActions();
}
- if (this.form.controls.tableExtractionType.value !== this.userPreferenceService.getTableExtractionType()) {
- await this.userPreferenceService.save(PreferencesKeys.tableExtractionType, this.form.controls.tableExtractionType.value);
+ if (this.form.controls.tableExtractionType.value !== this.#userPreferenceService.getTableExtractionType()) {
+ await this.#userPreferenceService.save(PreferencesKeys.tableExtractionType, this.form.controls.tableExtractionType.value);
}
if (
this.form.controls.loadAllAnnotationsWarning.value !==
- this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)
+ this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning)
) {
- await this.userPreferenceService.save(
+ await this.#userPreferenceService.save(
PreferencesKeys.loadAllAnnotationsWarning,
String(this.form.controls.loadAllAnnotationsWarning.value),
);
}
- if (this.form.controls.helpModeDialog.value !== this.userPreferenceService.getBool(KEYS.helpModeDialog)) {
- await this.userPreferenceService.save(KEYS.helpModeDialog, String(this.form.controls.helpModeDialog.value));
+ if (this.form.controls.helpModeDialog.value !== this.#userPreferenceService.getBool(KEYS.helpModeDialog)) {
+ await this.#userPreferenceService.save(KEYS.helpModeDialog, String(this.form.controls.helpModeDialog.value));
}
- await this.userPreferenceService.reload();
+ if (this.form.controls.overwriteFileOption.enabled && !this.form.controls.overwriteFileOption.value) {
+ await this.#userPreferenceService.saveOverwriteFileOption('undefined');
+ }
+
+ await this.#userPreferenceService.reload();
this.#patchValues();
this.initialFormValue = this.form.getRawValue();
- this._changeRef.markForCheck();
+ this.#changeRef.markForCheck();
}
#patchValues() {
this.form.patchValue({
- autoExpandFiltersOnActions: this.userPreferenceService.getAutoExpandFiltersOnActions(),
- openScmDialogByDefault: this.userPreferenceService.getOpenScmDialogByDefault(),
- tableExtractionType: this.userPreferenceService.getTableExtractionType(),
- loadAllAnnotationsWarning: this.userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning),
- helpModeDialog: this.userPreferenceService.getBool(KEYS.helpModeDialog),
+ autoExpandFiltersOnActions: this.#userPreferenceService.getAutoExpandFiltersOnActions(),
+ tableExtractionType: this.#userPreferenceService.getTableExtractionType(),
+ loadAllAnnotationsWarning: this.#userPreferenceService.getBool(PreferencesKeys.loadAllAnnotationsWarning),
+ helpModeDialog: this.#userPreferenceService.getBool(KEYS.helpModeDialog),
+ overwriteFileOption: this.#isOverwriteFileOptionActive,
});
+
+ if (!this.#isOverwriteFileOptionActive) {
+ this.form.controls.overwriteFileOption.disable();
+ }
}
}
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.html b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.html
index 6b8f9f46d..65ed43f9d 100644
--- a/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.html
+++ b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.html
@@ -6,9 +6,11 @@
-
+
{{ entry.key | humanize }}
- {{ entry.value }}
+
+
{{ entry.value | json }}
+
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.ts
index d038df97a..9de2f9c16 100644
--- a/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/admin/dialogs/audit-info-dialog/audit-info-dialog.component.ts
@@ -1,4 +1,4 @@
-import { KeyValue, KeyValuePipe, NgForOf } from '@angular/common';
+import { JsonPipe, KeyValue, KeyValuePipe, NgForOf } from '@angular/common';
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { BaseDialogComponent, CircleButtonComponent, HumanizePipe } from '@iqser/common-ui';
@@ -17,7 +17,7 @@ type OrderFn = (a: KeyValue, b: KeyValue) => num
styleUrls: ['./audit-info-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
- imports: [TranslateModule, NgForOf, KeyValuePipe, HumanizePipe, CircleButtonComponent],
+ imports: [TranslateModule, NgForOf, KeyValuePipe, HumanizePipe, CircleButtonComponent, JsonPipe],
})
export class AuditInfoDialogComponent extends BaseDialogComponent {
constructor(
diff --git a/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.html b/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.html
index 7f371474f..dbd2a0752 100644
--- a/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.html
+++ b/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.html
@@ -19,7 +19,7 @@
-
+
- @for (component of componentDefinitions; track component) {
-
-
-
-
- {{ component.rank }}
-
-
{{ component.displayName }}
-
- @if (permissionsService.canEditEntities()) {
-
- }
-
+
+ @for (component of componentDefinitions; track component) {
+
+
+
+
+ {{ component.rank }}
+
+
{{ component.displayName }}
+
+ @if (permissionsService.canEditEntities()) {
+
+ }
+ @if (selectedComponent?.id === component.id) {
+
+ }
+
-
- }
+ }
+
@if (selectedComponent) {
diff --git a/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.scss b/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.scss
index 80af0380b..54a237251 100644
--- a/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.scss
+++ b/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.scss
@@ -32,6 +32,10 @@
align-items: center;
gap: 5px;
+ iqser-circle-button {
+ visibility: hidden;
+ }
+
.arrow-right {
transform: scale(0.7);
}
@@ -40,6 +44,7 @@
.content-container {
background-color: var(--iqser-grey-6);
+ height: 100vh;
.content-header {
display: flex;
@@ -58,7 +63,7 @@
.content {
display: flex;
gap: 20px;
- height: 100%;
+ overflow: hidden;
.components-list {
flex: 1;
@@ -69,8 +74,15 @@
height: 30px;
}
+ .list-content {
+ overflow-y: auto;
+ height: calc(100vh - 30px);
+ outline: none;
+ }
+
.list-item {
height: 80px;
+ transition: background 0.3s ease;
}
.header,
@@ -95,6 +107,10 @@
}
}
}
+
+ .list-item:hover > .item-content > .right-content > iqser-circle-button {
+ visibility: visible;
+ }
}
section {
@@ -112,6 +128,9 @@
}
.cdk-drag-preview {
+ .list-item {
+ transition: background 0.3s ease;
+ }
.item-content {
@extend %item-content-style;
}
diff --git a/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.ts b/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.ts
index 31130e284..bf078ecaf 100644
--- a/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/component-definitions/component-definitions.component.ts
@@ -1,12 +1,5 @@
import { Component, OnInit, signal } from '@angular/core';
-import {
- BaseFormComponent,
- CircleButtonComponent,
- IconButtonComponent,
- IqserDialog,
- listingProvidersFactory,
- LoadingService,
-} from '@iqser/common-ui';
+import { BaseFormComponent, CircleButtonComponent, IconButtonComponent, listingProvidersFactory, LoadingService } from '@iqser/common-ui';
import { ComponentDefinitionsService } from '@services/entity-services/component-definitions.service';
import { firstValueFrom } from 'rxjs';
import { getParam } from '@common-ui/utils';
@@ -50,7 +43,6 @@ export default class ComponentDefinitionsComponent extends BaseFormComponent imp
constructor(
private readonly _loadingService: LoadingService,
private readonly _componentDefinitionsService: ComponentDefinitionsService,
- private readonly _dialog: IqserDialog,
private readonly _formBuilder: FormBuilder,
private readonly _dialogService: AdminDialogService,
protected readonly permissionsService: PermissionsService,
@@ -96,13 +88,15 @@ export default class ComponentDefinitionsComponent extends BaseFormComponent imp
}
async drop(event: CdkDragDrop) {
- moveItemInArray(this.#componentDefinitions(), event.previousIndex, event.currentIndex);
+ if (event.isPointerOverContainer) {
+ moveItemInArray(this.#componentDefinitions(), event.previousIndex, event.currentIndex);
- const componentIds = this.#componentDefinitions().map(c => c.id);
- const componentDefinitions = await firstValueFrom(
- this._componentDefinitionsService.reorderComponentDefinitions(this.#dossierTemplateId, componentIds),
- );
- this.#componentDefinitions.set(componentDefinitions);
+ const componentIds = this.#componentDefinitions().map(c => c.id);
+ const componentDefinitions = await firstValueFrom(
+ this._componentDefinitionsService.reorderComponentDefinitions(this.#dossierTemplateId, componentIds),
+ );
+ this.#componentDefinitions.set(componentDefinitions);
+ }
}
async deleteComponent(componentId: string) {
@@ -119,8 +113,8 @@ export default class ComponentDefinitionsComponent extends BaseFormComponent imp
#getForm() {
return this._formBuilder.group({
- displayName: [this.selectedComponent.displayName, Validators.required],
- description: [this.selectedComponent.description],
+ displayName: [this.selectedComponent?.displayName, Validators.required],
+ description: [this.selectedComponent?.description],
});
}
diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html
index 9f62ba6d0..8283e05a8 100644
--- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html
+++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html
@@ -29,9 +29,8 @@