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.html b/apps/red-ui/src/app/components/base-screen/base-screen.component.html index c6b7b8f21..650655105 100644 --- a/apps/red-ui/src/app/components/base-screen/base-screen.component.html +++ b/apps/red-ui/src/app/components/base-screen/base-screen.component.html @@ -9,7 +9,7 @@ -
+ {{ 'file-preview.tabs.annotations.the-filters' | translate }} + } @else if (state.componentReferenceIds?.length === 0) { + {{ 'file-preview.tabs.annotations.no-annotations' | translate }} + } + }
@@ -253,7 +224,7 @@ - + @@ -261,7 +232,7 @@ + + +
+
+ + + {{ listingService.selectedLength$ | async }} selected + + +
+ + +
+
diff --git a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts index 4cb63a58d..a6e0675a4 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/file-workload/file-workload.component.ts @@ -1,5 +1,16 @@ import { AsyncPipe, NgIf, NgTemplateOutlet } from '@angular/common'; -import { ChangeDetectorRef, Component, computed, effect, ElementRef, HostListener, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { + ChangeDetectorRef, + Component, + computed, + effect, + ElementRef, + HostListener, + OnDestroy, + OnInit, + TemplateRef, + viewChild, +} from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatIcon } from '@angular/material/icon'; import { MatTooltip } from '@angular/material/tooltip'; @@ -78,8 +89,9 @@ const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']; ], }) export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, OnDestroy { - @ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef; - @ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef; + private readonly _annotationsElement = viewChild('annotationsElement'); + private readonly _quickNavigationElement = viewChild('quickNavigation'); + readonly multiSelectTemplate = viewChild>('multiSelect'); readonly #isIqserDevMode = this._userPreferenceService.isIqserDevMode; protected readonly iconButtonTypes = IconButtonTypes; protected readonly circleButtonTypes = CircleButtonTypes; @@ -90,9 +102,11 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On protected readonly currentPageIsExcluded = computed(() => this.state.file().excludedPages.includes(this.pdf.currentPage())); protected readonly translations = workloadTranslations; protected readonly isDocumine = getConfig().IS_DOCUMINE; - displayedAnnotations = new Map(); - displayedPages: number[] = []; - pagesPanelActive = true; + protected displayedAnnotations = new Map(); + protected displayedPages: number[] = []; + protected pagesPanelActive = true; + protected enabledFilters = []; + #displayedPagesChanged = false; constructor( readonly filterService: FilterService, @@ -176,11 +190,14 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On this.fileDataService.all$, primary$, secondary$, + this.state.componentReferenceIds$, this.listingService.selected$, this._pageRotationService.rotations$, ]).pipe( delay(0), - map(([annotations, primary, secondary]) => this.#filterAnnotations(annotations, primary, secondary)), + map(([annotations, primary, secondary, componentReferenceIds]) => + this.#filterAnnotations(annotations, primary, secondary, componentReferenceIds), + ), map(annotations => this.#mapListItemsFromAnnotationWrapperArray(annotations)), tap(annotations => this.#scrollToFirstAnnotationPage(annotations)), ); @@ -275,18 +292,20 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } scrollAnnotationsToPage(page: number, mode: 'always' | 'if-needed' = 'if-needed'): void { - if (this._annotationsElement) { - const elements: HTMLElement[] = this._annotationsElement.nativeElement.querySelectorAll(`div[anotation-page-header="${page}"]`); + if (this._annotationsElement()) { + const elements: HTMLElement[] = this._annotationsElement().nativeElement.querySelectorAll( + `div[anotation-page-header="${page}"]`, + ); FileWorkloadComponent._scrollToFirstElement(elements, mode); } } @Debounce() scrollToSelectedAnnotation(): void { - if (this.listingService.selected.length === 0 || !this._annotationsElement) { + if (this.listingService.selected.length === 0 || !this._annotationsElement()) { return; } - const elements: HTMLElement[] = this._annotationsElement.nativeElement.querySelectorAll( + const elements: HTMLElement[] = this._annotationsElement().nativeElement.querySelectorAll( `[annotation-id="${this._firstSelectedAnnotation?.id}"]`, ); FileWorkloadComponent._scrollToFirstElement(elements); @@ -399,10 +418,12 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On annotations: AnnotationWrapper[], primary: INestedFilter[], secondary: INestedFilter[] = [], + componentReferenceIds: string[], ): Map { const onlyPageWithAnnotations = this.viewModeService.onlyPagesWithAnnotations(); if (!primary || primary.length === 0) { - this.displayedPages = onlyPageWithAnnotations ? [] : this.#allPages; + const pages = onlyPageWithAnnotations ? [] : this.#allPages; + this.#setDisplayedPages(pages); return; } @@ -410,24 +431,30 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On annotations = annotations.filter(a => !a.isRemoved); } - if (this.isDocumine && !this.#isIqserDevMode) { - annotations = annotations.filter(a => !a.isOCR); + if (this.isDocumine) { + if (!this.#isIqserDevMode) { + annotations = annotations.filter(a => !a.isOCR); + } + if (componentReferenceIds) { + annotations = annotations.filter(a => componentReferenceIds.includes(a.id)); + } } this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(annotations, primary, secondary); const pagesThatDisplayAnnotations = [...this.displayedAnnotations.keys()]; - const enabledFilters = this.filterService.enabledFlatFilters; - if (enabledFilters.some(f => f.id === 'pages-without-annotations')) { - if (enabledFilters.length === 1 && !onlyPageWithAnnotations) { - this.displayedPages = this.#allPages.filter(page => !pagesThatDisplayAnnotations.includes(page)); + this.enabledFilters = this.filterService.enabledFlatFilters; + if (this.enabledFilters.some(f => f.id === 'pages-without-annotations')) { + if (this.enabledFilters.length === 1 && !onlyPageWithAnnotations) { + const pages = this.#allPages.filter(page => !pagesThatDisplayAnnotations.includes(page)); + this.#setDisplayedPages(pages); } else { - this.displayedPages = []; + this.#setDisplayedPages([]); } this.displayedAnnotations.clear(); - } else if (enabledFilters.length || onlyPageWithAnnotations) { - this.displayedPages = pagesThatDisplayAnnotations; + } else if (this.enabledFilters.length || onlyPageWithAnnotations || componentReferenceIds) { + this.#setDisplayedPages(pagesThatDisplayAnnotations); } else { - this.displayedPages = this.#allPages; + this.#setDisplayedPages(this.#allPages); } this.displayedPages.sort((a, b) => a - b); @@ -501,8 +528,8 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } #scrollQuickNavigationToPage(page: number) { - if (this._quickNavigationElement) { - const elements: HTMLElement[] = this._quickNavigationElement.nativeElement.querySelectorAll(`#quick-nav-page-${page}`); + if (this._quickNavigationElement()) { + const elements: HTMLElement[] = this._quickNavigationElement().nativeElement.querySelectorAll(`#quick-nav-page-${page}`); FileWorkloadComponent._scrollToFirstElement(elements); } } @@ -523,9 +550,25 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On } #scrollToFirstAnnotationPage(annotations: Map[]>) { - if (this.isDocumine && annotations.size && !this.displayedPages.includes(this.pdf.currentPage())) { + if (this.isDocumine && annotations.size && this.#displayedPagesChanged && !this.displayedPages.includes(this.pdf.currentPage())) { const page = annotations.keys().next().value; this.pdf.navigateTo(page); } } + + #setDisplayedPages(newDisplayedPages: number[]) { + if (!this.#samePages(newDisplayedPages)) { + this.displayedPages = newDisplayedPages; + this.#displayedPagesChanged = true; + return; + } + this.#displayedPagesChanged = false; + } + + #samePages(newDisplayedPages: number[]) { + return ( + this.displayedPages.length === newDisplayedPages.length && + this.displayedPages.every((value, index) => value === newDisplayedPages[index]) + ); + } } diff --git a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.html b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.html index fff85d262..faa6c3677 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.html +++ b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.html @@ -1,9 +1,9 @@
- - + +
-
+
{{ 'component-management.table-header.component' | translate }}
diff --git a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts index 4cc3bb5bf..0ec8d38ea 100644 --- a/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/components/structured-component-management/structured-component-management.component.ts @@ -3,7 +3,6 @@ import { List } from '@common-ui/utils'; import { IconButtonTypes, LoadingService } from '@iqser/common-ui'; import { ComponentLogEntry, Dictionary, File, IComponentLogEntry, WorkflowFileStatuses } from '@red/domain'; import { ComponentLogService } from '@services/files/component-log.service'; -import { UserPreferenceService } from '@users/user-preference.service'; import { combineLatest, firstValueFrom, Observable } from 'rxjs'; import { EditableStructuredComponentValueComponent } from '../editable-structured-component-value/editable-structured-component-value.component'; import { FilterService, PopupFilterComponent } from '@common-ui/filtering'; @@ -23,7 +22,6 @@ import { TranslateModule } from '@ngx-translate/core'; export class StructuredComponentManagementComponent implements OnInit { protected readonly componentLogData = signal(undefined); protected readonly componentLogData$ = toObservable(this.componentLogData); - protected readonly openScmDialogByDefault = signal(this.userPreferences.getOpenScmDialogByDefault()); protected readonly iconButtonTypes = IconButtonTypes; protected displayedComponents$: Observable; @Input() file: File; @@ -35,7 +33,6 @@ export class StructuredComponentManagementComponent implements OnInit { private readonly _loadingService: LoadingService, private readonly _componentLogFilterService: ComponentLogFilterService, private readonly _filterService: FilterService, - readonly userPreferences: UserPreferenceService, ) {} get canEdit() { @@ -54,12 +51,6 @@ export class StructuredComponentManagementComponent implements OnInit { } } - async toggleOpenScmDialogByDefault() { - await this.userPreferences.toggleOpenScmDialogByDefault(); - await this.userPreferences.reload(); - this.openScmDialogByDefault.set(this.userPreferences.getOpenScmDialogByDefault()); - } - async revertOverride(originalKey: string) { this._loadingService.start(); await firstValueFrom( diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/edit-annotation-dialog/edit-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/edit-annotation-dialog/edit-annotation-dialog.component.html index 47979cbd3..9c1f26c13 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/edit-annotation-dialog/edit-annotation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/edit-annotation-dialog/edit-annotation-dialog.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html index 3d7fe1b1c..1cef8cb15 100644 --- a/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html +++ b/apps/red-ui/src/app/modules/file-preview/dialogs/docu-mine/remove-annotation-dialog/remove-annotation-dialog.component.html @@ -1,4 +1,4 @@ -
+
SuperTypeSorter[a.id] - SuperTypeSorter[b.id]); } @@ -272,19 +268,4 @@ export class AnnotationProcessingService { return first.pageNumber < second.pageNumber ? -1 : 1; }); } - - #createNoAnnotationsFilter(filterMap: Map, filters: INestedFilter[]) { - const childFilter: IFilter = { - id: 'no-annotations-filter', - label: 'no-annotations-filter', - checked: false, - matches: 1, - skipTranslation: true, - hidden: true, - }; - - const newChildFilter = new Filter(childFilter); - filterMap.set('no-annotations-filter', newChildFilter); - filters[0]?.children.push(newChildFilter); - } } diff --git a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts index 6f584dd5d..50b8f579e 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/file-preview-state.service.ts @@ -14,7 +14,7 @@ import { FilesMapService } from '@services/files/files-map.service'; import { FilesService } from '@services/files/files.service'; import { PermissionsService } from '@services/permissions.service'; import { NGXLogger } from 'ngx-logger'; -import { firstValueFrom, from, merge, Observable, of, pairwise, Subject, switchMap } from 'rxjs'; +import { BehaviorSubject, firstValueFrom, from, merge, Observable, of, pairwise, Subject, switchMap } from 'rxjs'; import { filter, map, startWith, tap, withLatestFrom } from 'rxjs/operators'; import { ViewModeService } from './view-mode.service'; @@ -41,6 +41,8 @@ export class FilePreviewStateService { readonly isWritable: Signal; readonly dossierDictionary: Signal; readonly blob$: Observable; + readonly componentReferenceIds$: Observable; + readonly #componentReferenceIds$ = new BehaviorSubject(null); readonly dossierId = getParam(DOSSIER_ID); readonly dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); readonly fileId = getParam(FILE_ID); @@ -62,6 +64,7 @@ export class FilePreviewStateService { this.dossier = toSignal(dossiersServiceResolver().getEntityChanged$(this.dossierId)); this.file$ = inject(FilesMapService).watch$(this.dossierId, this.fileId); this.file = toSignal(this.file$); + this.componentReferenceIds$ = this.#componentReferenceIds$.asObservable(); this.excludedPages = signal(this.file().excludedPages); this.isWritable = computed(() => { const isWritable = this._permissionsService.canPerformAnnotationActions(this.file(), this.dossier()); @@ -91,6 +94,10 @@ export class FilePreviewStateService { ); } + set componentReferenceIds(ids: string[]) { + this.#componentReferenceIds$.next(ids); + } + get dictionaries(): Dictionary[] { const dictionaries = this._dictionariesMapService.get(this.dossierTemplateId); if (this.dossierDictionary()) { @@ -126,6 +133,10 @@ export class FilePreviewStateService { ); } + get componentReferenceIds() { + return this.#componentReferenceIds$.getValue(); + } + reloadBlob(): void { this.#reloadBlob$.next(true); } diff --git a/apps/red-ui/src/app/modules/pdf-viewer/components/paginator/paginator.component.html b/apps/red-ui/src/app/modules/pdf-viewer/components/paginator/paginator.component.html index 221d497fe..006a7bc77 100644 --- a/apps/red-ui/src/app/modules/pdf-viewer/components/paginator/paginator.component.html +++ b/apps/red-ui/src/app/modules/pdf-viewer/components/paginator/paginator.component.html @@ -1,4 +1,8 @@ - diff --git a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts index aead21c11..19a721f98 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts @@ -51,6 +51,7 @@ export class FileActionsComponent implements OnChanges { @Input() maxWidth: number; @Input() minWidth: number; @Input() helpModeKeyPrefix: 'dossier' | 'editor' = 'dossier'; + @Input() singleEntityAction = false; readonly currentUser = getCurrentUser(); toggleTooltip?: string; assignTooltip?: string; @@ -119,6 +120,16 @@ export class FileActionsComponent implements OnChanges { private get _buttons(): Action[] { const actions: Action[] = [ + { + id: 'btn-download_file', + type: ActionTypes.downloadBtn, + files: [this.file], + dossier: this.dossier, + tooltipClass: 'small', + show: this.showDownload, + disabled: this.file.processingStatus === ProcessingFileStatuses.ERROR, + helpModeKey: this.#isDocumine ? 'download_document' : 'download', + }, { id: 'btn-delete_file', type: ActionTypes.circleBtn, @@ -155,16 +166,6 @@ export class FileActionsComponent implements OnChanges { show: this.showImportRedactions && !this._iqserPermissionsService.has(Roles.getRss), helpModeKey: 'import_redactions', }, - { - id: 'btn-download_file', - type: ActionTypes.downloadBtn, - files: [this.file], - dossier: this.dossier, - tooltipClass: 'small', - show: this.showDownload, - disabled: this.file.processingStatus === ProcessingFileStatuses.ERROR, - helpModeKey: 'download', - }, { id: 'btn-toggle_document_info', type: ActionTypes.circleBtn, diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html index 2df56956c..9659eeb5d 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html +++ b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.html @@ -1,10 +1,31 @@ - +@if (dropdownButton()) { + +} @else { + +} + + + + + + diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts index 8fde993b4..83b6089e4 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts @@ -1,48 +1,67 @@ -import { Component, inject, Input, OnChanges } from '@angular/core'; +import { booleanAttribute, Component, computed, inject, input, Input, OnChanges, ViewChild } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { CircleButtonComponent, CircleButtonType, CircleButtonTypes, IqserDialog, Toaster } from '@iqser/common-ui'; -import { Dossier, File, ProcessingFileStatuses } from '@red/domain'; +import { CircleButtonComponent, CircleButtonType, CircleButtonTypes, getConfig, IqserDialog, Toaster } from '@iqser/common-ui'; +import { Dossier, File, IFile, ProcessingFileStatuses } from '@red/domain'; import { PermissionsService } from '@services/permissions.service'; import { DownloadDialogComponent } from '@shared/dialogs/download-dialog/download-dialog.component'; import { FileDownloadService } from '@upload-download/services/file-download.service'; import { APP_BASE_HREF } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; +import { MatMenu, MatMenuItem, MatMenuTrigger } from '@angular/material/menu'; +import { firstValueFrom } from 'rxjs'; +import { ComponentLogService } from '@services/files/component-log.service'; @Component({ selector: 'redaction-file-download-btn', templateUrl: './file-download-btn.component.html', standalone: true, - imports: [CircleButtonComponent, TranslateModule], + imports: [CircleButtonComponent, TranslateModule, MatMenu, MatMenuItem, MatMenuTrigger], }) export class FileDownloadBtnComponent implements OnChanges { - @Input({ required: true }) files: File[]; - @Input({ required: true }) dossier: Dossier; - @Input({ required: true }) buttonId: string; - @Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above'; - @Input() type: CircleButtonType = CircleButtonTypes.default; - @Input() tooltipClass: string; - @Input() disabled = false; + readonly files = input.required(); + readonly dossier = input.required(); + readonly buttonId = input.required(); + readonly tooltipPosition = input<'above' | 'below' | 'before' | 'after'>('above'); + readonly type = input(CircleButtonTypes.default); + readonly tooltipClass = input(); + readonly disabled = input(false); + readonly singleFileDownload = input(false); + readonly dossierDownload = input(false, { transform: booleanAttribute }); + readonly dropdownButton = computed(() => this.isDocumine && (this.dossierDownload() || this.singleFileDownload())); tooltip: string; canDownloadFiles: boolean; invalidDownload = false; readonly #appBaseHref = inject(APP_BASE_HREF); + protected readonly isDocumine = getConfig().IS_DOCUMINE; + @ViewChild(MatMenuTrigger) menuTrigger: MatMenuTrigger; constructor( private readonly _permissionsService: PermissionsService, private readonly _fileDownloadService: FileDownloadService, + private readonly _componentLogService: ComponentLogService, private readonly _dialog: IqserDialog, private readonly _toaster: Toaster, ) {} ngOnChanges(): void { - this.invalidDownload = this.files.some(file => file.processingStatus === ProcessingFileStatuses.ERROR); - this.canDownloadFiles = this._permissionsService.canDownloadFiles(this.files, this.dossier); - this.tooltip = this.canDownloadFiles ? _('dossier-overview.download-file') : _('dossier-overview.download-file-disabled'); + this.invalidDownload = this.files().some(file => file.processingStatus === ProcessingFileStatuses.ERROR); + this.canDownloadFiles = this._permissionsService.canDownloadFiles(this.files(), this.dossier()); + if (this.canDownloadFiles) { + if (this.isDocumine && !this.dropdownButton()) { + this.tooltip = _('dossier-overview.report-download'); + } else { + this.tooltip = _('dossier-overview.download-file'); + } + } else { + this.tooltip = _('dossier-overview.download-file-disabled'); + } } - async downloadFiles() { + async downloadFiles($event?: MouseEvent) { + $event?.stopImmediatePropagation(); + this.menuTrigger?.closeMenu(); const ref = this._dialog.openDefault(DownloadDialogComponent, { - data: { dossier: this.dossier, files: this.files }, + data: { dossier: this.dossier(), files: this.files() }, }); const result = await ref.result(); if (!result) { @@ -50,8 +69,8 @@ export class FileDownloadBtnComponent implements OnChanges { } const downloadRequest = this._fileDownloadService.downloadFiles({ - dossierId: this.dossier.id, - fileIds: this.files.map(f => f.id), + dossierId: this.dossier().id, + fileIds: this.files().map(f => f.id), ...result, }); @@ -63,4 +82,18 @@ export class FileDownloadBtnComponent implements OnChanges { ) .catch(() => this._toaster.error(_('download-status.error'))); } + + downloadComponentAsJSON($event: MouseEvent) { + $event.stopImmediatePropagation(); + this.menuTrigger?.closeMenu(); + const fileToDownload = !this.dossierDownload() ? this.files()[0] : null; + return firstValueFrom(this._componentLogService.exportJSON(this.dossier().dossierTemplateId, this.dossier().id, fileToDownload)); + } + + async downloadComponentAsXML($event: MouseEvent) { + $event.stopImmediatePropagation(); + this.menuTrigger?.closeMenu(); + const fileToDownload = !this.dossierDownload() ? this.files()[0] : null; + return firstValueFrom(this._componentLogService.exportXML(this.dossier().dossierTemplateId, this.dossier().id, fileToDownload)); + } } diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html index b7e7f9e05..9fa619fa1 100644 --- a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.html @@ -1,14 +1,3 @@ -@if (isDocumine) { - -} - @@ -84,8 +74,3 @@ - - - - - diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts index dc211ba1d..40206c988 100644 --- a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts @@ -1,6 +1,6 @@ -import { Component, inject, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; +import { booleanAttribute, Component, inject, input, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; import { Action, ActionTypes, Dossier, File } from '@red/domain'; -import { CircleButtonComponent, CircleButtonType, getConfig, IqserDialog, StopPropagationDirective, Toaster } from '@iqser/common-ui'; +import { CircleButtonComponent, CircleButtonType, IqserDialog, StopPropagationDirective, Toaster } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { FileDownloadService } from '@upload-download/services/file-download.service'; import { PermissionsService } from '@services/permissions.service'; @@ -13,8 +13,6 @@ import { FileDownloadBtnComponent } from '@shared/components/buttons/file-downlo import { MatSlideToggle } from '@angular/material/slide-toggle'; import { MatTooltip } from '@angular/material/tooltip'; import { MatIcon } from '@angular/material/icon'; -import { firstValueFrom } from 'rxjs'; -import { ComponentLogService } from '@services/files/component-log.service'; @Component({ selector: 'redaction-expandable-file-actions', @@ -46,13 +44,12 @@ export class ExpandableFileActionsComponent implements OnChanges { @Input() tooltipPosition: IqserTooltipPosition; @Input() helpModeKeyPrefix: 'dossier' | 'editor'; @Input() isDossierOverviewWorkflow = false; - @Input() file: File; + @Input() singleEntityAction = false; displayedButtons: Action[]; hiddenButtons: Action[]; expanded = false; @ViewChild(MatMenuTrigger) readonly matMenu: MatMenuTrigger; readonly trackBy = trackByFactory(); - readonly isDocumine = getConfig().IS_DOCUMINE; readonly #appBaseHref = inject(APP_BASE_HREF); constructor( @@ -60,7 +57,6 @@ export class ExpandableFileActionsComponent implements OnChanges { private readonly _toaster: Toaster, private readonly _permissionsService: PermissionsService, private readonly _dialog: IqserDialog, - private readonly _componentLogService: ComponentLogService, ) {} ngOnChanges(changes: SimpleChanges) { @@ -129,12 +125,4 @@ export class ExpandableFileActionsComponent implements OnChanges { params: { downloadHref: `${this.#appBaseHref}/main/downloads` }, }); } - - downloadComponentAsJSON() { - return firstValueFrom(this._componentLogService.exportJSON(this.file.dossierTemplateId, this.file.dossierId, this.file)); - } - - async downloadComponentAsXML() { - return firstValueFrom(this._componentLogService.exportXML(this.file.dossierTemplateId, this.file.dossierId, this.file)); - } } diff --git a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts index bc8e9b2fe..6593826e8 100644 --- a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts @@ -1,12 +1,11 @@ import { inject, Injectable } from '@angular/core'; -import { ARCHIVE_ROUTE, Dossier, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@red/domain'; +import { ARCHIVE_ROUTE, Dossier, DOSSIERS_ROUTE } from '@red/domain'; import { catchError, switchMap, tap } from 'rxjs/operators'; import { Observable, of } from 'rxjs'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { ActiveDossiersService } from './active-dossiers.service'; import { DossiersService } from './dossiers.service'; import { FilesMapService } from '../files/files-map.service'; -import { FeaturesService } from '../features.service'; import { Router } from '@angular/router'; @Injectable({ providedIn: 'root' }) @@ -15,7 +14,6 @@ export class ArchivedDossiersService extends DossiersService { protected readonly _defaultModelPath = 'archived-dossiers'; readonly #activeDossiersService = inject(ActiveDossiersService); readonly #filesMapService = inject(FilesMapService); - readonly #featuresService = inject(FeaturesService); readonly #router = inject(Router); archive(dossiers: Dossier[]): Observable { @@ -46,7 +44,7 @@ export class ArchivedDossiersService extends DossiersService { } loadAll(): Observable { - return this.#featuresService.isEnabled(DOSSIERS_ARCHIVE) ? super.loadAll() : of([]); + return super.loadAll(); } #removeFromActiveDossiers(archivedDossiersIds: string[]): void { diff --git a/apps/red-ui/src/app/services/permissions.service.ts b/apps/red-ui/src/app/services/permissions.service.ts index 69191b669..f1c283543 100644 --- a/apps/red-ui/src/app/services/permissions.service.ts +++ b/apps/red-ui/src/app/services/permissions.service.ts @@ -4,7 +4,6 @@ import { DashboardStats, Dictionary, Dossier, - DOSSIERS_ARCHIVE, DossierTemplate, File, IComment, @@ -13,7 +12,6 @@ import { WorkflowFileStatus, WorkflowFileStatuses, } from '@red/domain'; -import { FeaturesService } from '@services/features.service'; import { FilesMapService } from '@services/files/files-map.service'; import { Roles } from '@users/roles'; import { UserPreferenceService } from '@users/user-preference.service'; @@ -27,7 +25,6 @@ export class PermissionsService { constructor( private readonly _userService: UserService, private readonly _filesMapService: FilesMapService, - private readonly _featuresService: FeaturesService, private readonly _userPreferenceService: UserPreferenceService, private readonly _iqserPermissionsService: IqserPermissionsService, private readonly _dossierTemplatesService: DossierTemplatesService, @@ -290,12 +287,7 @@ export class PermissionsService { } canArchiveDossier(dossier: Dossier): boolean { - return ( - this._iqserPermissionsService.has(Roles.dossiers.archived) && - this._featuresService.isEnabled(DOSSIERS_ARCHIVE) && - dossier.isActive && - this.isOwner(dossier) - ); + return this._iqserPermissionsService.has(Roles.dossiers.archived) && dossier.isActive && this.isOwner(dossier); } canEditDossier(dossier: Dossier): boolean { diff --git a/apps/red-ui/src/app/users/user-preference.service.ts b/apps/red-ui/src/app/users/user-preference.service.ts index 4b05ce78c..f2fd00d34 100644 --- a/apps/red-ui/src/app/users/user-preference.service.ts +++ b/apps/red-ui/src/app/users/user-preference.service.ts @@ -10,7 +10,6 @@ export const PreferencesKeys = { filesListingMode: 'Files-Listing-Mode', autoExpandFiltersOnActions: 'Auto-Expand-Filters-On-Actions', loadAllAnnotationsWarning: 'Load-All-Annotations-Warning', - openScmDialogByDefault: 'Open-Structured-Component-Management-By-Default', tableExtractionType: 'Table-Extraction-Type', addRedactionDefaultOption: 'Add-Redaction-Default', addHintDefaultOption: 'Add-Hint-Default', @@ -65,15 +64,6 @@ export class UserPreferenceService extends IqserUserPreferenceService { await this.save(PreferencesKeys.autoExpandFiltersOnActions, nextValue); } - getOpenScmDialogByDefault(): boolean { - return this._getAttribute(PreferencesKeys.openScmDialogByDefault, 'false') === 'true'; - } - - async toggleOpenScmDialogByDefault(): Promise { - const nextValue = (!this.getOpenScmDialogByDefault()).toString(); - await this.save(PreferencesKeys.openScmDialogByDefault, nextValue); - } - getBool(key: string, defaultValue = 'false') { return this._getAttribute(key, defaultValue) === 'true'; } diff --git a/apps/red-ui/src/assets/features/features.json b/apps/red-ui/src/assets/features/features.json index bbcfecc3a..0a8585355 100644 --- a/apps/red-ui/src/assets/features/features.json +++ b/apps/red-ui/src/assets/features/features.json @@ -1,8 +1,3 @@ { - "features": [ - { - "name": "DOSSIERS_ARCHIVE", - "minVersion": "3.3.0" - } - ] + "features": [] } diff --git a/apps/red-ui/src/assets/help-mode/help-mode-keys.json b/apps/red-ui/src/assets/help-mode/help-mode-keys.json index bab5118aa..06209d4b4 100644 --- a/apps/red-ui/src/assets/help-mode/help-mode-keys.json +++ b/apps/red-ui/src/assets/help-mode/help-mode-keys.json @@ -651,6 +651,11 @@ "documentKey": "workload_filter", "overlappingElements": ["USER_MENU", "DOCUMENT_INFO"] }, + { + "elementKey": "filter_annotations", + "documentKey": "filter_annotations", + "overlappingElements": ["USER_MENU", "DOCUMENT_INFO"] + }, { "elementKey": "workload_bulk_selection", "documentKey": "workload_bulk_selection", @@ -692,5 +697,86 @@ { "elementKey": "document_list_view", "documentKey": "document_list" + }, + { + "elementKey": "editor_edit_component", + "documentKey": "editor_edit_component", + "scrollableParentView": "COMPONENTS_VIEW" + }, + { + "elementKey": "edit_component", + "documentKey": "edit_component" + }, + { + "elementKey": "add_component_value", + "documentKey": "add_component_value" + }, + { + "elementKey": "undo_component_change", + "documentKey": "undo_component_change" + }, + { + "elementKey": "change_component_order", + "documentKey": "change_component_order" + }, + { + "elementKey": "remove_component_value", + "documentKey": "remove_component_value" + }, + { + "elementKey": "filter_components", + "documentKey": "filter_components" + }, + { + "elementKey": "annotations_list", + "documentKey": "annotations_list" + }, + { + "elementKey": "components_table", + "documentKey": "components_table" + }, + { + "elementKey": "components_table", + "documentKey": "components_table" + }, + { + "elementKey": "remove_annotation_DIALOG", + "documentKey": "remove_annotation" + }, + { + "elementKey": "edit_annotation_DIALOG", + "documentKey": "edit_annotation" + }, + { + "elementKey": "dossier_download_dossier", + "documentKey": "dossier_download_dossier", + "overlappingElements": ["USER_MENU"] + }, + { + "elementKey": "dossier_download_document", + "documentKey": "dossier_download_document", + "scrollableParentView": "VIRTUAL_SCROLL" + }, + { + "elementKey": "template_download_dossier", + "documentKey": "template_download_dossier", + "scrollableParentView": "VIRTUAL_SCROLL" + }, + { + "elementKey": "editor_download_document", + "documentKey": "editor_download_document", + "overlappingElements": ["USER_MENU"] + }, + { + "elementKey": "rule_editors", + "documentKey": "rule_editors" + }, + { + "elementKey": "component_mappings", + "documentKey": "component_mappings" + }, + { + "elementKey": "components_management", + "documentKey": "components_management" } ] diff --git a/apps/red-ui/src/assets/i18n/redact/de.json b/apps/red-ui/src/assets/i18n/redact/de.json index 91a25aeb1..8161f7c92 100644 --- a/apps/red-ui/src/assets/i18n/redact/de.json +++ b/apps/red-ui/src/assets/i18n/redact/de.json @@ -100,6 +100,7 @@ "dialog": { "title": "{type, select, add{Neues Komponenten-Mapping erstellen} edit{Komponenten-Mapping bearbeiten} other{}}" }, + "disabled-file-options": "", "form": { "delimiter": "", "delimiter-placeholder": "", @@ -272,9 +273,6 @@ "watermarks": "Wasserzeichen" }, "analysis-disabled": "", - "annotation": { - "pending": "(Analyse steht aus)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -330,14 +328,14 @@ "error": "Rekategorisierung des Bilds fehlgeschlagen: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", - "success": "Schwärzung wurde entfernt" - }, "remove-hint": { "error": "Entfernen des Hinweises fehlgeschlagen: {error}", "success": "Hinweis wurde entfernt" }, + "remove": { + "error": "Entfernen der Schwärzung fehlgeschlagen: {error}", + "success": "Schwärzung wurde entfernt" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "Rücksetzung erfolgreich" @@ -350,15 +348,15 @@ "remove-highlights": { "label": "Ausgewählte Markierungen entfernen" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Neue Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "Referenzen anzeigen" }, @@ -392,6 +390,9 @@ "skipped": "Ignorierte Schwärzung", "text-highlight": "Markierung" }, + "annotation": { + "pending": "(Analyse steht aus)" + }, "annotations": "Annotationen", "archived-dossiers-listing": { "no-data": { @@ -535,9 +536,8 @@ "title": "{length} {length, plural, one{Komponente} other{Komponenten}}" }, "component-download": { - "disabled-tooltip": "", "json": "", - "tooltip": "", + "report": "", "xml": "" }, "component-management": { @@ -587,8 +587,7 @@ "success": { "generic": "" }, - "title": "", - "warning-text": "" + "title": "" }, "configurations": "Konfiguration", "confirm-archive-dossier": { @@ -637,18 +636,14 @@ "warning": "Warnung: Wiederherstellung des Benutzers nicht möglich." }, "confirmation-dialog": { - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", - "title": "Warnung!" - }, "approve-file-without-analysis": { "confirmationText": "Ohne Analyse freigeben", "denyText": "Abbrechen", "question": "Analyse zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung!" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen, die sich durch die Reanalyse ergeben haben.

Möchten Sie es trotzdem freigeben?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -657,6 +652,10 @@ "question": "Für mindestens eine Datei ist ein Analyselauf zur Erkennung neuer Schwärzungen erforderlich.", "title": "Warnung" }, + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen, die im Zuge einer Reanalyse hinzugefügt wurden.

Möchen Sie die Dateien wirklich freigeben?", + "title": "Warnung!" + }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft.

Möchten Sie sich die Datei dennoch zuweisen?", @@ -1026,13 +1025,14 @@ "recent": "Neu ({hours} h)", "unassigned": "Keinem Bearbeiter zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Einplanung der Dateien für die Reanalyse fehlgeschlagen. Bitte versuchen Sie es noch einmal.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, + "report-download": "", "start-auto-analysis": "Auto-Analyse aktivieren", "stop-auto-analysis": "Auto-Analyse anhalten", "table-col-names": { @@ -1102,14 +1102,6 @@ "total-documents": "Dokumente", "total-people": "{count} {count, plural, one{Benutzer} other {Benutzer}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Aktiv", - "inactive": "Inaktiv", - "incomplete": "Unvollständig" - } - }, "dossier-templates-listing": { "action": { "clone": "Vorlage klonen", @@ -1144,6 +1136,14 @@ "title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Aktiv", + "inactive": "Inaktiv", + "incomplete": "Unvollständig" + } + }, "dossier-watermark-selector": { "heading": "Wasserzeichen auf Dokumenten", "no-watermark": "Kein Wasserzeichen in der Dossier-Vorlage verfügbar:
Bitten Sie Ihren Admin, eines zu konfigurieren.", @@ -1339,15 +1339,6 @@ "title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Zurücksetzen", - "save": "Änderungen speichern" - }, - "heading": "Entität bearbeiten" - } - }, "entity-rules-screen": { "error": { "generic": "Fehler: Aktualisierung der Entitätsregeln fehlgeschlagen." @@ -1359,22 +1350,30 @@ "generic": "Die Entitätsregeln wurden aktualisiert." }, "title": "Entitätsregeln-Editor", - "warning-text": "Warnung: experimentelle Funktion!", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} in Regeln gefunden" }, + "entity": { + "info": { + "actions": { + "revert": "Zurücksetzen", + "save": "Änderungen speichern" + }, + "heading": "Entität bearbeiten" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1392,12 +1391,6 @@ }, "exact-date": "{day}. {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", - "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1408,6 +1401,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Aktualisierung des Werts für das Datei-Attribut fehlgeschlagen. Bitte versuchen Sie es noch einmal.", + "success": "Der Wert für das Dateiattribut wurde erfolgreich aktualisiert." + } + }, "file-attributes-configurations": { "cancel": "Abbrechen", "form": { @@ -1625,15 +1624,6 @@ "csv": "Die Datei-Attribute wurden erfolgreich aus der hochgeladenen CSV-Datei importiert." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nur Hinweise", - "image": "Bilder", - "none": "Keine Annotationen", - "redaction": "Schwärzungen", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1643,6 +1633,15 @@ "unseen-pages": "Nur Annotationen auf ungesehenen Seiten", "with-comments": "Nur Annotationen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nur Hinweise", + "image": "Bilder", + "none": "Keine Annotationen", + "redaction": "Schwärzungen", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Bearbeiter", "documents-status": "Dokumentenstatus", @@ -1921,13 +1920,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Benachrichtigungen", - "deleted-dossier": "Gelöschtes Dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail-Benachrichtigungen", @@ -1941,6 +1933,7 @@ "dossier": "Benachrichtigungen zu Dossiers", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen werde", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Prüfer zugewiesen werde", @@ -1958,7 +1951,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, bei welchen Aktivitäten Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofort", @@ -1966,6 +1958,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Benachrichtigungen", + "deleted-dossier": "Gelöschtes Dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Als {type, select, read{gelesen} unread{ungelesen} other{}} markieren" + }, "ocr": { "confirmation-dialog": { "cancel": "Abbrechen", @@ -2048,7 +2047,6 @@ "auto-expand-filters-on-action": "Filter ausgehend von meinen Aktionen automatisch anpassen", "help-mode-dialog": "Dialog zur Aktivierung des Hilfemodus", "load-all-annotations-warning": "Warnung bei gleichzeitigem Laden aller Annotationen in der Miniaturansicht", - "open-structured-view-by-default": "Strukturierte Komponentenansicht standardmäßig anzeigen", "table-extraction-type": "Art der Tabellenextraktion" }, "label": "Präferenzen", @@ -2057,16 +2055,16 @@ "warnings-label": "Dialoge und Meldungen", "warnings-subtitle": "„Nicht mehr anzeigen“-Optionen" }, - "processing": { - "basic": "Verarbeitung läuft", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Ausstehend", "processed": "Verarbeitet", "processing": "Verarbeitung läuft" }, + "processing": { + "basic": "Verarbeitung läuft", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Lesemodus (archiviert)", "redact-text": { @@ -2302,12 +2300,6 @@ "red-user-admin": "Benutzeradmin", "regular": "regulärer Benutzer" }, - "search": { - "active-dossiers": "Dokumente in aktiven Dossiers", - "all-dossiers": "Alle Dokumente", - "placeholder": "Dokumente durchsuchen...", - "this-dossier": "In diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bearbeiter", @@ -2331,6 +2323,12 @@ "no-match": "Der Suchbegriff wurde in keinem der Dokumente gefunden.", "table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}" }, + "search": { + "active-dossiers": "Dokumente in aktiven Dossiers", + "all-dossiers": "Alle Dokumente", + "placeholder": "Dokumente durchsuchen...", + "this-dossier": "In diesem Dossier" + }, "seconds": "Sekunden", "size": "Größe", "smtp-auth-config": { @@ -2586,4 +2584,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/redact/en.json b/apps/red-ui/src/assets/i18n/redact/en.json index cba884999..ce30992f1 100644 --- a/apps/red-ui/src/assets/i18n/redact/en.json +++ b/apps/red-ui/src/assets/i18n/redact/en.json @@ -100,6 +100,7 @@ "dialog": { "title": "{type, select, add{Add New} edit{Edit} other{}} Component Mapping" }, + "disabled-file-options": "", "form": { "delimiter": "", "delimiter-placeholder": "", @@ -535,9 +536,8 @@ "title": "{length} {length, plural, one{component} other{components}}" }, "component-download": { - "disabled-tooltip": "", "json": "", - "tooltip": "", + "report": "", "xml": "" }, "component-management": { @@ -587,8 +587,7 @@ "success": { "generic": "" }, - "title": "", - "warning-text": "" + "title": "" }, "configurations": "Configurations", "confirm-archive-dossier": { @@ -1033,6 +1032,7 @@ "reanalyse": { "action": "Analyze file" }, + "report-download": "", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", "table-col-names": { @@ -1350,7 +1350,6 @@ "generic": "Entity rules updated." }, "title": "Entity rule editor", - "warning-text": "Warning: experimental feature!", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, "entity": { @@ -2048,7 +2047,6 @@ "auto-expand-filters-on-action": "Auto-expand filters on my actions", "help-mode-dialog": "Help mode activation dialog", "load-all-annotations-warning": "Warning regarding simultaneous loading of all annotations in thumbnails", - "open-structured-view-by-default": "Display structured component management modal by default", "table-extraction-type": "Table extraction type" }, "label": "Preferences", @@ -2586,4 +2584,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/de.json b/apps/red-ui/src/assets/i18n/scm/de.json index 9c1134212..f10837a8b 100644 --- a/apps/red-ui/src/assets/i18n/scm/de.json +++ b/apps/red-ui/src/assets/i18n/scm/de.json @@ -100,6 +100,7 @@ "dialog": { "title": "{type, select, add{Add new} edit{Edit} other{}} component mapping" }, + "disabled-file-options": "Re-upload mapping file to change", "form": { "delimiter": "CSV delimiter", "delimiter-placeholder": "CSV delimiter", @@ -272,9 +273,6 @@ "watermarks": "Watermarks" }, "analysis-disabled": "Analysis disabled", - "annotation": { - "pending": "(Pending analysis)" - }, "annotation-actions": { "accept-recommendation": { "label": "Empfehlung annehmen" @@ -330,14 +328,14 @@ "error": "Rekategorisierung des Bildes gescheitert: {error}", "success": "Bild wurde einer neuen Kategorie zugeordnet." }, - "remove": { - "error": "Fehler beim Entfernen der Schwärzung: {error}", - "success": "Schwärzung entfernt!" - }, "remove-hint": { "error": "Failed to remove hint: {error}", "success": "Hint removed!" }, + "remove": { + "error": "Fehler beim Entfernen der Schwärzung: {error}", + "success": "Schwärzung entfernt!" + }, "undo": { "error": "Die Aktion konnte nicht rückgängig gemacht werden. Fehler: {error}", "success": "erfolgreich Rückgängig gemacht" @@ -350,15 +348,15 @@ "remove-highlights": { "label": "Remove selected earmarks" }, - "resize": { - "label": "Größe ändern" - }, "resize-accept": { "label": "Größe speichern" }, "resize-cancel": { "label": "Größenänderung abbrechen" }, + "resize": { + "label": "Größe ändern" + }, "see-references": { "label": "See references" }, @@ -392,6 +390,9 @@ "skipped": "Übersprungen", "text-highlight": "Earmark" }, + "annotation": { + "pending": "(Pending analysis)" + }, "annotations": "Annotations", "archived-dossiers-listing": { "no-data": { @@ -535,10 +536,9 @@ "title": "{length} {length, plural, one{component} other{components}}" }, "component-download": { - "disabled-tooltip": "All files must be processed to be able to export the components as JSON or XML", - "json": "Download as JSON", - "tooltip": "Component download", - "xml": "Download as XML" + "json": "Components as JSON", + "report": "Report", + "xml": "Components as XML" }, "component-management": { "actions": { @@ -587,8 +587,7 @@ "success": { "generic": "Component rules updated!" }, - "title": "Component rule editor", - "warning-text": "Warning: experimental feature!" + "title": "Component rule editor" }, "configurations": "Einstellungen", "confirm-archive-dossier": { @@ -637,18 +636,14 @@ "warning": "Achtung: Diese Aktion kann nicht rückgängig gemacht werden!" }, "confirmation-dialog": { - "approve-file": { - "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", - "title": "Warnung!" - }, "approve-file-without-analysis": { "confirmationText": "Approve without analysis", "denyText": "Cancel", "question": "Analysis required to detect new components.", "title": "Warning!" }, - "approve-multiple-files": { - "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", + "approve-file": { + "question": "Dieses Dokument enthält ungesehene Änderungen. Möchten Sie es trotzdem genehmigen?", "title": "Warnung!" }, "approve-multiple-files-without-analysis": { @@ -657,6 +652,10 @@ "question": "Analysis required to detect new components for at least one file.", "title": "Warning" }, + "approve-multiple-files": { + "question": "Mindestens eine der ausgewählten Dateien enthält ungesehene Änderungen. Möchten Sie sie trotzdem genehmigen?", + "title": "Warnung!" + }, "assign-file-to-me": { "question": { "multiple": "Dieses Dokument wird gerade von einer anderen Person geprüft. Möchten Sie Reviewer werden und sich selbst dem Dokument zuweisen?", @@ -853,8 +852,8 @@ "documine-export": { "document": "Document", "document-tooltip": "Document", - "export": "Export", - "export-tooltip": "Export" + "export": "Component download", + "export-tooltip": "Component download" }, "dossier-attribute-types": { "date": "Datum", @@ -1026,13 +1025,14 @@ "recent": "Neu ({hours} h)", "unassigned": "Niemandem zugewiesen" }, - "reanalyse": { - "action": "Datei analysieren" - }, "reanalyse-dossier": { "error": "Die Dateien konnten nicht für eine Reanalyse eingeplant werden. Bitte versuchen Sie es erneut.", "success": "Dateien für Reanalyse vorgesehen." }, + "reanalyse": { + "action": "Datei analysieren" + }, + "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", "table-col-names": { @@ -1102,14 +1102,6 @@ "total-documents": "Anzahl der Dokumente", "total-people": "{count} {count, plural, one{user} other {users}}" }, - "dossier-templates": { - "label": "Dossier-Vorlagen", - "status": { - "active": "Active", - "inactive": "Inactive", - "incomplete": "Incomplete" - } - }, "dossier-templates-listing": { "action": { "clone": "Clone template", @@ -1144,6 +1136,14 @@ "title": "{length} dossier {length, plural, one{template} other{templates}}" } }, + "dossier-templates": { + "label": "Dossier-Vorlagen", + "status": { + "active": "Active", + "inactive": "Inactive", + "incomplete": "Incomplete" + } + }, "dossier-watermark-selector": { "heading": "Watermarks on documents", "no-watermark": "There is no watermark defined for the dossier template.
Contact your app admin to define one.", @@ -1339,15 +1339,6 @@ "title": "{length} {length, plural, one{entity} other{entities}}" } }, - "entity": { - "info": { - "actions": { - "revert": "Revert", - "save": "Save changes" - }, - "heading": "Edit entity" - } - }, "entity-rules-screen": { "error": { "generic": "Something went wrong... Entity rules update failed!" @@ -1359,22 +1350,30 @@ "generic": "Entity rules updated!" }, "title": "Entity rule editor", - "warning-text": "Warning: experimental feature!", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, + "entity": { + "info": { + "actions": { + "revert": "Revert", + "save": "Save changes" + }, + "heading": "Edit entity" + } + }, "error": { "deleted-entity": { "dossier": { "action": "Zurück zur Übersicht", "label": "Dieses Dossier wurde gelöscht!" }, - "file": { - "action": "Zurück zum Dossier", - "label": "Diese Datei wurde gelöscht!" - }, "file-dossier": { "action": "Zurück zur Übersicht", "label": "Das Dossier dieser Datei wurde gelöscht!" + }, + "file": { + "action": "Zurück zum Dossier", + "label": "Diese Datei wurde gelöscht!" } }, "file-preview": { @@ -1392,12 +1391,6 @@ }, "exact-date": "{day} {month} {year} um {hour}:{minute} Uhr", "file": "Datei", - "file-attribute": { - "update": { - "error": "Failed to update file attribute value!", - "success": "File attribute value has been updated successfully!" - } - }, "file-attribute-encoding-types": { "ascii": "ASCII", "iso": "ISO-8859-1", @@ -1408,6 +1401,12 @@ "number": "Nummer", "text": "Freier Text" }, + "file-attribute": { + "update": { + "error": "Failed to update file attribute value!", + "success": "File attribute value has been updated successfully!" + } + }, "file-attributes-configurations": { "cancel": "Cancel", "form": { @@ -1550,13 +1549,13 @@ "jump-to-next": "Springe zu Nächster", "jump-to-previous": "Springe zu Vorheriger", "label": "Arbeitsvorrat", - "no-annotations": "There are no available annotations.", + "no-annotations": "There are no annotations on the selected page or for the selected component.", "page-is": "Diese Seite ist", "reset": "reset", "select": "Auswählen", "select-all": "Alle", "select-none": "Keine", - "show-skipped": "", + "show-skipped": "Show skipped in document", "the-filters": "the filters", "wrong-filters": "The selected filter combination is not possible. Please adjust or" }, @@ -1625,15 +1624,6 @@ "csv": "File attributes were imported successfully from uploaded CSV file." } }, - "filter": { - "analysis": "Analyse erforderlich", - "comment": "Kommentare", - "hint": "Nut Hinweise", - "image": "Bilder", - "none": "Keine Anmerkungen", - "redaction": "Geschwärzt", - "updated": "Aktualisiert" - }, "filter-menu": { "filter-options": "Filteroptionen", "filter-types": "Filter", @@ -1643,6 +1633,15 @@ "unseen-pages": "Nur Anmerkungen auf unsichtbaren Seiten", "with-comments": "Nur Anmerkungen mit Kommentaren" }, + "filter": { + "analysis": "Analyse erforderlich", + "comment": "Kommentare", + "hint": "Nut Hinweise", + "image": "Bilder", + "none": "Keine Anmerkungen", + "redaction": "Geschwärzt", + "updated": "Aktualisiert" + }, "filters": { "assigned-people": "Beauftragt", "documents-status": "Documents state", @@ -1921,13 +1920,6 @@ "user-promoted-to-approver": "{user} wurde im Dossier {dossierHref, select, null{{dossierName}} other{{dossierName}}} zum Genehmiger ernannt!", "user-removed-as-dossier-member": "{user} wurde als Mitglied von: {dossierHref, select, null{{dossierName}} other{{dossierName}}} entfernt!" }, - "notifications": { - "button-text": "Notifications", - "deleted-dossier": "Deleted dossier", - "label": "Benachrichtigungen", - "mark-all-as-read": "Alle als gelesen markieren", - "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" - }, "notifications-screen": { "category": { "email-notifications": "E-Mail Benachrichtigungen", @@ -1941,6 +1933,7 @@ "dossier": "Dossierbezogene Benachrichtigungen", "other": "Andere Benachrichtigungen" }, + "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "options": { "ASSIGN_APPROVER": "Wenn ich einem Dokument als Genehmiger zugewiesen bin", "ASSIGN_REVIEWER": "Wenn ich einem Dokument als Überprüfer zugewiesen bin", @@ -1958,7 +1951,6 @@ "USER_PROMOTED_TO_APPROVER": "Wenn ich Genehmiger in einem Dossier werde", "USER_REMOVED_AS_DOSSIER_MEMBER": "Wenn ich die Dossier-Mitgliedschaft verliere" }, - "options-title": "Wählen Sie aus, in welcher Kategorie Sie benachrichtigt werden möchten", "schedule": { "daily": "Tägliche Zusammenfassung", "instant": "Sofortig", @@ -1966,6 +1958,13 @@ }, "title": "Benachrichtigungseinstellungen" }, + "notifications": { + "button-text": "Notifications", + "deleted-dossier": "Deleted dossier", + "label": "Benachrichtigungen", + "mark-all-as-read": "Alle als gelesen markieren", + "mark-as": "Mark as {type, select, read{read} unread{unread} other{}}" + }, "ocr": { "confirmation-dialog": { "cancel": "Cancel", @@ -2048,7 +2047,6 @@ "auto-expand-filters-on-action": "Auto expand filters on my actions", "help-mode-dialog": "Help Mode Dialog", "load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", - "open-structured-view-by-default": "Display Component View by default when opening a document", "table-extraction-type": "Table extraction type" }, "label": "Preferences", @@ -2057,16 +2055,16 @@ "warnings-label": "Prompts and dialogs", "warnings-subtitle": "Do not show again options" }, - "processing": { - "basic": "Processing", - "ocr": "OCR" - }, "processing-status": { "ocr": "OCR", "pending": "Pending", "processed": "Processed", "processing": "Processing" }, + "processing": { + "basic": "Processing", + "ocr": "OCR" + }, "readonly": "Lesemodus", "readonly-archived": "Read only (archived)", "redact-text": { @@ -2302,12 +2300,6 @@ "red-user-admin": "Benutzer-Admin", "regular": "Regulär" }, - "search": { - "active-dossiers": "ganze Plattform", - "all-dossiers": "all documents", - "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", - "this-dossier": "in diesem Dossier" - }, "search-screen": { "cols": { "assignee": "Bevollmächtigter", @@ -2331,6 +2323,12 @@ "no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.", "table-header": "{length} search {length, plural, one{result} other{results}}" }, + "search": { + "active-dossiers": "ganze Plattform", + "all-dossiers": "all documents", + "placeholder": "Nach Dokumenten oder Dokumenteninhalt suchen", + "this-dossier": "in diesem Dossier" + }, "seconds": "seconds", "size": "Size", "smtp-auth-config": { @@ -2586,4 +2584,4 @@ } }, "yesterday": "Gestern" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/assets/i18n/scm/en.json b/apps/red-ui/src/assets/i18n/scm/en.json index e8686af82..21a21c256 100644 --- a/apps/red-ui/src/assets/i18n/scm/en.json +++ b/apps/red-ui/src/assets/i18n/scm/en.json @@ -100,6 +100,7 @@ "dialog": { "title": "{type, select, add{Add new} edit{Edit} other{}} component mapping" }, + "disabled-file-options": "Re-upload mapping file to change", "form": { "delimiter": "CSV delimiter", "delimiter-placeholder": "CSV delimiter", @@ -535,10 +536,9 @@ "title": "{length} {length, plural, one{component} other{components}}" }, "component-download": { - "disabled-tooltip": "All files must be processed to be able to export the components as JSON or XML", - "json": "Download as JSON", - "tooltip": "Component download", - "xml": "Download as XML" + "json": "Components as JSON", + "report": "Report", + "xml": "Components as XML" }, "component-management": { "actions": { @@ -587,8 +587,7 @@ "success": { "generic": "Component rules updated!" }, - "title": "Component rule editor", - "warning-text": "Warning: experimental feature!" + "title": "Component rule editor" }, "configurations": "Configurations", "confirm-archive-dossier": { @@ -853,8 +852,8 @@ "documine-export": { "document": "Document", "document-tooltip": "Document", - "export": "Export", - "export-tooltip": "Export" + "export": "Component download", + "export-tooltip": "Component download" }, "dossier-attribute-types": { "date": "Date", @@ -986,7 +985,7 @@ "processing-documents": "{count} processing {count, plural, one{document} other{documents}}" } }, - "download-file": "Report download", + "download-file": "Download", "download-file-disabled": "You need to be approver in the dossier and the {count, plural, one{file needs} other{files need}} to be initially processed in order to download.", "file-listing": { "file-entry": { @@ -1033,6 +1032,7 @@ "reanalyse": { "action": "Analyze file" }, + "report-download": "Report download", "start-auto-analysis": "Enable auto-analysis", "stop-auto-analysis": "Stop auto-analysis", "table-col-names": { @@ -1168,7 +1168,7 @@ "download-includes": "Choose what is included at download:", "download-status": { "error": "The download preparation failed, please recheck the selected files and download option settings.", - "queued": "Your download has been queued, you can see all your requested downloads here: My downloads." + "queued": "Your download has been queued, you can find all your requested downloads here: My downloads." }, "download-type": { "annotated": "Annotated PDF", @@ -1350,7 +1350,6 @@ "generic": "Entity rules updated!" }, "title": "Entity rule editor", - "warning-text": "Warning: experimental feature!", "warnings-found": "{warnings, plural, one{A warning} other{{warnings} warnings}} found in rules" }, "entity": { @@ -1533,7 +1532,7 @@ }, "last-assignee": "Last assignee", "no-data": { - "title": "There have been no changes to this page." + "title": "There are no annotations on this page." }, "quick-nav": { "jump-first": "Jump to first page", @@ -1550,13 +1549,13 @@ "jump-to-next": "Jump to next", "jump-to-previous": "Jump to previous", "label": "Workload", - "no-annotations": "There are no available annotations.", + "no-annotations": "There are no annotations on the selected page or for the selected component.", "page-is": "This page is", "reset": "reset", "select": "Select", "select-all": "All", "select-none": "None", - "show-skipped": "", + "show-skipped": "Show skipped in document", "the-filters": "the filters", "wrong-filters": "The selected filter combination is not possible. Please adjust or" }, @@ -2048,7 +2047,6 @@ "auto-expand-filters-on-action": "Auto expand filters on my actions", "help-mode-dialog": "Help Mode Dialog", "load-all-annotations-warning": "Warning regarding loading all annotations at once in file preview", - "open-structured-view-by-default": "Display Component View by default when opening a document", "table-extraction-type": "Table extraction type" }, "label": "Preferences", @@ -2586,4 +2584,4 @@ } }, "yesterday": "Yesterday" -} \ No newline at end of file +} diff --git a/apps/red-ui/src/styles.scss b/apps/red-ui/src/styles.scss index da0a70cfa..9714aca6b 100644 --- a/apps/red-ui/src/styles.scss +++ b/apps/red-ui/src/styles.scss @@ -169,12 +169,16 @@ body { --iqser-app-name-font-family: OpenSans Extrabold, sans-serif; --iqser-app-name-font-size: 13px; --iqser-logo-size: 28px; + --documine-viewer-width: calc( + 100% - var(--structured-component-management-width) - var(--documine-workload-content-width) - var(--qiuck-navigation-width) - 3px + ); + --viewer-height: calc(100% - calc(var(--iqser-top-bar-height) + 50px)); } .redaction-viewer { visibility: hidden; width: calc(100% - var(--workload-width)); - height: calc(100% - calc(var(--iqser-top-bar-height) + 50px)); + height: var(--viewer-height); bottom: 0; left: 0; position: absolute; @@ -182,10 +186,8 @@ body { .documine-viewer { visibility: hidden; - width: calc( - 100% - var(--structured-component-management-width) - var(--documine-workload-content-width) - var(--qiuck-navigation-width) - 3px - ); - height: calc(100% - calc(var(--iqser-top-bar-height) + 50px)); + width: var(--documine-viewer-width); + height: var(--viewer-height); bottom: 0; right: calc(var(--qiuck-navigation-width) + 3px); position: absolute; diff --git a/libs/common-ui b/libs/common-ui index 80fceb45d..6547eb2ad 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 80fceb45dd4c860024e675d7d9ae77afd3482db9 +Subproject commit 6547eb2ad53d9df97a08210d7edb6d849e59d998 diff --git a/libs/red-domain/src/lib/dossiers/constants.ts b/libs/red-domain/src/lib/dossiers/constants.ts index 95b78f4fa..4541b260b 100644 --- a/libs/red-domain/src/lib/dossiers/constants.ts +++ b/libs/red-domain/src/lib/dossiers/constants.ts @@ -1,5 +1,4 @@ export const DOSSIER_ID = 'dossierId'; -export const DOSSIERS_ARCHIVE = 'DOSSIERS_ARCHIVE'; export const ARCHIVE_ROUTE = 'archive'; export const DOSSIERS_ROUTE = 'dossiers';