Compare commits

...

13 Commits

29 changed files with 240 additions and 203 deletions

View File

@ -1,7 +1,6 @@
import { NgModule } from '@angular/core';
import { RouteReuseStrategy, RouterModule } from '@angular/router';
import { ifNotLoggedIn } from '@common-ui/tenants/guards/if-not-logged-in.guard';
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
import { BaseScreenComponent } from '@components/base-screen/base-screen.component';
import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component';
import { DashboardGuard } from '@guards/dashboard-guard.service';
@ -23,6 +22,7 @@ import { Roles } from '@users/roles';
import { mainGuard } from '@utils/main.guard';
import { webViewerLoadedGuard } from './modules/pdf-viewer/services/webviewer-loaded.guard';
import { ACTIVE_DOSSIERS_SERVICE } from './tokens';
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
const dossierTemplateIdRoutes: IqserRoutes = [
{

View File

@ -7,7 +7,6 @@ import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ServiceWorkerModule } from '@angular/service-worker';
import { GET_TENANT_FROM_PATH_FN, UI_ROOT } from '@common-ui/utils';
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
import { BaseScreenComponent } from '@components/base-screen/base-screen.component';
import { BreadcrumbsComponent } from '@components/breadcrumbs/breadcrumbs.component';
import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component';
@ -69,6 +68,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { PdfViewerModule } from './modules/pdf-viewer/pdf-viewer.module';
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from './tokens';
import { AuthErrorComponent } from '@components/auth-error/auth-error.component';
export const appModuleFactory = (config: AppConfig) => {
@NgModule({

View File

@ -2,17 +2,17 @@
<p *ngIf="!adminName && !adminUrl" class="heading-xl" translate="auth-error.heading"></p>
<p
*ngIf="adminName && adminUrl"
[innerHTML]="'auth-error.heading-with-name-and-link' | translate : { adminName: adminName, adminUrl: adminUrl }"
[innerHTML]="'auth-error.heading-with-name-and-link' | translate: { adminName: adminName, adminUrl: adminUrl }"
class="heading-xl"
></p>
<p
*ngIf="adminName && !adminUrl"
[innerHTML]="'auth-error.heading-with-name' | translate : { adminName: adminName }"
[innerHTML]="'auth-error.heading-with-name' | translate: { adminName: adminName }"
class="heading-xl"
></p>
<p
*ngIf="!adminName && adminUrl"
[innerHTML]="'auth-error.heading-with-link' | translate : { adminName: adminName }"
[innerHTML]="'auth-error.heading-with-link' | translate: { adminName: adminName }"
class="heading-xl"
></p>
<a (click)="userService.logout()" translate="auth-error.logout"></a>

View File

@ -25,7 +25,6 @@ import {
SuperTypes,
} from '@red/domain';
import { annotationTypesTranslations } from '@translations/annotation-types-translations';
import { log } from '@common-ui/utils';
export class AnnotationWrapper implements IListable {
id: string;

View File

@ -28,7 +28,7 @@
</div>
<div class="iqser-input-group">
<a [href]="changePasswordUrl" target="_blank"> {{ 'user-profile-screen.actions.change-password' | translate }}</a>
<a (click)="resetPassword()" target="_blank"> {{ 'user-profile-screen.actions.change-password' | translate }}</a>
</div>
<div *ngIf="devMode" class="iqser-input-group">

View File

@ -1,11 +1,9 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { DomSanitizer } from '@angular/platform-browser';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { BaseFormComponent, getConfig, IqserPermissionsService, LanguageService, LoadingService, Toaster } from '@iqser/common-ui';
import { TenantsService } from '@iqser/common-ui/lib/tenants';
import { BaseFormComponent, IqserPermissionsService, LanguageService, LoadingService, Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { AppConfig, IProfile } from '@red/domain';
import { IProfile } from '@red/domain';
import { languagesTranslations } from '@translations/languages-translations';
import { Roles } from '@users/roles';
import { UserPreferenceService } from '@users/user-preference.service';
@ -22,10 +20,8 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
#profileModel: IProfile;
readonly translations = languagesTranslations;
readonly devMode = this._userPreferenceService.isIqserDevMode;
readonly changePasswordUrl: string;
constructor(
domSanitizer: DomSanitizer,
private readonly _userService: UserService,
private readonly _loadingService: LoadingService,
private readonly _dialogService: UserProfileDialogService,
@ -39,9 +35,6 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
) {
super();
this._loadingService.start();
const tenant = inject(TenantsService).activeTenantId;
const realmUrl = `${getConfig<AppConfig>().OAUTH_URL}/realms/${tenant}`;
this.changePasswordUrl = `${realmUrl}/account/password`;
}
get languageChanged(): boolean {
@ -115,6 +108,10 @@ export class UserProfileScreenComponent extends BaseFormComponent implements OnI
}
}
async resetPassword() {
await this._userService.createResetPasswordAction();
}
private _getForm(): UntypedFormGroup {
return this._formBuilder.group({
email: ['', [Validators.required, Validators.email]],

View File

@ -104,7 +104,12 @@ export class AuditScreenComponent extends ListingComponent<Audit> implements OnI
const from = this.form.get('from').value;
let to = this.form.get('to').value;
if (to) {
to = to.clone().add(1, 'd');
const hoursLeft = new Date(to).getHours();
const minutesLeft = new Date(to).getMinutes();
to = to
.clone()
.add(24 - hoursLeft - 1, 'h')
.add(60 - minutesLeft - 1);
}
const logsRequestBody: IAuditSearchRequest = {
pageSize: PAGE_SIZE,

View File

@ -7,5 +7,6 @@
[initialEntries]="initialEntries$ | async"
[isLeavingPage]="isLeavingPage"
[selectedDictionaryType]="entityType"
[activeEntryType]="activeEntryType"
[type]="type"
></redaction-dictionary-manager>

View File

@ -79,4 +79,8 @@ export class DictionaryScreenComponent implements OnInit {
this._loadingService.stop();
}
}
get activeEntryType() {
return DICTIONARY_TO_ENTRY_TYPE_MAP[this.type];
}
}

View File

@ -9,4 +9,5 @@ export enum LicenseFeatures {
PDFTRON = 'pdftron',
ANALYSIS_CAPACITY_BYTES = 'analysisCapacityBytes',
RETENTION_CAPACITY_BYTES = 'retentionCapacityBytes',
SUPPORT_MS_OFFICE_FORMATS = 'supportMSOfficeFormats',
}

View File

@ -25,9 +25,10 @@ export class AnnotationCardComponent {
((this.annotation.isModifyDictionary &&
!this.annotation.isRemovedLocally &&
!this.annotation.hasBeenForcedHint &&
(this.annotation.lastManualChange !== ManualRedactionTypes.LEGAL_BASIS_CHANGE &&
this.annotation.lastManualChange !== ManualRedactionTypes.RESIZE_LOCALLY)) ||
this.annotation.type === ImageCategory.SIGNATURE)
this.annotation.lastManualChange !== ManualRedactionTypes.LEGAL_BASIS_CHANGE &&
this.annotation.lastManualChange !== ManualRedactionTypes.RESIZE_LOCALLY) ||
this.annotation.type === ImageCategory.SIGNATURE ||
this.annotation.IMAGE_HINT)
);
}
}

View File

@ -6,32 +6,32 @@
</div>
<iqser-initials-avatar
*ngIf="!editingReviewer"
*ngIf="!state.isEditingReviewer()"
[id]="'assignee'"
[user]="file.assignee"
[withName]="!!file.assignee"
></iqser-initials-avatar>
<div
(click)="editingReviewer = true"
*ngIf="!editingReviewer && _canAssignReviewer()"
(click)="state.isEditingReviewer.set(true)"
*ngIf="!state.isEditingReviewer() && _canAssignReviewer()"
[id]="'assign-reviewer'"
[translate]="'file-preview.assign-reviewer'"
class="assign-reviewer pointer"
></div>
<redaction-assign-user-dropdown
(cancel)="editingReviewer = false"
(cancel)="state.isEditingReviewer.set(false)"
(save)="assignReviewer(file, $event)"
*ngIf="editingReviewer"
*ngIf="state.isEditingReviewer()"
[options]="_usersOptions()"
[value]="file.assignee"
iqserStopPropagation
></redaction-assign-user-dropdown>
<div *ngIf="!editingReviewer && _canAssign()" class="assign-actions-wrapper">
<div *ngIf="!state.isEditingReviewer() && _canAssign()" class="assign-actions-wrapper">
<iqser-circle-button
(action)="editingReviewer = true"
(action)="state.isEditingReviewer.set(true)"
*ngIf="_canAssignOrUnassign() && !!file.assignee"
[attr.help-mode-key]="'editor_assign_user'"
[buttonId]="'change-assignee'"

View File

@ -45,7 +45,6 @@ export class UserManagementComponent implements OnInit, OnDestroy {
? _('file-preview.change-reviewer')
: _('file-preview.assign-reviewer');
});
editingReviewer = false;
constructor(
readonly fileAssignService: FileAssignService,
@ -76,7 +75,7 @@ export class UserManagementComponent implements OnInit, OnDestroy {
const translateParams = { reviewerName: this.userService.getName(assigneeId), filename: file.filename };
this.toaster.success(_('assignment.reviewer'), { params: translateParams });
this.editingReviewer = false;
this.state.isEditingReviewer.set(false);
}
ngOnInit() {
@ -90,21 +89,21 @@ export class UserManagementComponent implements OnInit, OnDestroy {
@Bind()
handleViewerClick() {
this.ngZone.run(() => {
this.editingReviewer = false;
this.state.isEditingReviewer.set(false);
});
}
@HostListener('document:click')
clickOutside() {
if (this.editingReviewer) {
this.editingReviewer = false;
if (this.state.isEditingReviewer()) {
this.state.isEditingReviewer.set(false);
}
}
@HostListener('document:keyup', ['$event'])
handleEsc($event: KeyboardEvent) {
if ($event.key === 'Escape' && this.editingReviewer) {
this.editingReviewer = false;
if ($event.key === 'Escape' && this.state.isEditingReviewer()) {
this.state.isEditingReviewer.set(false);
}
}

View File

@ -94,7 +94,7 @@
</div>
<div class="right-container">
<redaction-file-preview-right-container iqserDisableStopPropagation></redaction-file-preview-right-container>
<redaction-file-preview-right-container [iqserDisableStopPropagation]="state.isEditingReviewer()"></redaction-file-preview-right-container>
</div>
</div>
</section>

View File

@ -1,5 +1,5 @@
import { HttpEvent, HttpEventType, HttpProgressEvent, HttpResponse } from '@angular/common/http';
import { computed, effect, inject, Injectable, Signal } from '@angular/core';
import { computed, effect, inject, Injectable, signal, Signal } from '@angular/core';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { LoadingService, wipeCache } from '@iqser/common-ui';
import { getParam } from '@iqser/common-ui/lib/utils';
@ -45,6 +45,7 @@ export class FilePreviewStateService {
readonly dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
readonly fileId = getParam(FILE_ID);
readonly updateExcludedPagesStyle = computed(() => this.file().excludedPages);
readonly isEditingReviewer = signal(false);
constructor(
private readonly _permissionsService: PermissionsService,

View File

@ -265,6 +265,7 @@ export class FileActionsComponent implements OnChanges {
tooltip: _('dossier-overview.ocr-file'),
icon: 'iqser:ocr',
show: this.showOCR,
helpModeKey: 'automatic_text_recognition',
},
{
id: 'reanalyse-file-btn',

View File

@ -5,7 +5,7 @@ import { interval, Subject, Subscription } from 'rxjs';
import { ConfigService } from '@services/config.service';
import { TranslateService } from '@ngx-translate/core';
import { IFileUploadResult, OverwriteFileOption, OverwriteFileOptions } from '@red/domain';
import { isAcceptedFileType, isCsv, isZip } from '@utils/file-drop-utils';
import { isAcceptedFileType, isCsv, isDocument, isZip } from '@utils/file-drop-utils';
import { ErrorMessageService, GenericService, Toaster } from '@iqser/common-ui';
import { FilesMapService } from '@services/files/files-map.service';
import { switchMap, tap, throttleTime } from 'rxjs/operators';
@ -13,6 +13,8 @@ import { FilesService } from '@services/files/files.service';
import { UploadDownloadDialogService } from './upload-download-dialog.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { HeadersConfiguration } from '@iqser/common-ui/lib/utils';
import { LicenseService } from '@services/license.service';
import { LicenseFeatures } from '../../admin/screens/license/utils/constants';
export interface ActiveUpload {
subscription: Subscription;
@ -39,6 +41,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
private readonly _configService: ConfigService,
private readonly _dialogService: UploadDownloadDialogService,
private readonly _errorMessageService: ErrorMessageService,
private readonly _licenseService: LicenseService,
private readonly _toaster: Toaster,
) {
super();
@ -72,6 +75,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
const maxSizeMB = this._configService.values.MAX_FILE_SIZE_MB;
const maxSizeBytes = maxSizeMB * 1024 * 1024;
const dossierFiles = this._filesMapService.get(dossierId);
const supportMsOfficeFormats = this._licenseService.getFeature(LicenseFeatures.SUPPORT_MS_OFFICE_FORMATS)?.value as boolean;
let option: OverwriteFileOption = localStorage.getItem('overwriteFileOption') as OverwriteFileOption;
for (let idx = 0; idx < files.length; ++idx) {
const file = files[idx];
@ -115,7 +119,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
continue;
}
}
if (!isAcceptedFileType(file)) {
if (!isAcceptedFileType(file, supportMsOfficeFormats)) {
file.completed = true;
file.error = {
message: this._translateService.instant('upload-status.error.file-type'),

View File

@ -10,6 +10,7 @@ import { inject, Injectable, OnDestroy } from '@angular/core';
import { DashboardStatsService } from '../dossier-templates/dashboard-stats.service';
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
import { List } from '@iqser/common-ui/lib/utils';
import { DossiersCacheService } from '@services/dossiers/dossiers-cache.service';
@Injectable({ providedIn: 'root' })
export class DossiersChangesService extends GenericService<Dossier> implements OnDestroy {
@ -18,6 +19,7 @@ export class DossiersChangesService extends GenericService<Dossier> implements O
readonly #archivedDossiersService = inject(ArchivedDossiersService);
readonly #dashboardStatsService = inject(DashboardStatsService);
readonly #logger = inject(NGXLogger);
readonly #dossierCache = inject(DossiersCacheService);
protected readonly _defaultModelPath = 'dossier';
loadOnlyChanged(): Observable<IDossierChanges> {
@ -72,6 +74,7 @@ export class DossiersChangesService extends GenericService<Dossier> implements O
}
#load(id: string): Observable<DossierStats[]> {
if (!this.#dossierCache.get(id)) return of([]);
const queryParams: List<QueryParam> = [{ key: 'includeArchived', value: true }];
return super._getOne([id], this._defaultModelPath, queryParams).pipe(
map(entity => new Dossier(entity)),

View File

@ -307,10 +307,7 @@ export class PermissionsService {
canEditDossierDictionary(dossier: Dossier): boolean {
return (
dossier.isActive &&
this._dossierDictionariesMapService.get(dossier.id).length > 0 &&
this.isDossierMember(dossier) &&
this._iqserPermissionsService.has(Roles.dossiers.dictionaryEntries.write)
dossier.isActive && this.isDossierMember(dossier) && this._iqserPermissionsService.has(Roles.dossiers.dictionaryEntries.write)
);
}

View File

@ -0,0 +1,6 @@
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
export const selectTenantTranslations: { [key in string]: string } = {
IS_LOGGED_OUT: _('tenant-resolve.header.youre-logged-out'),
NO_ROLE_LOG_OUT: _('tenant-resolve.header.no-role-log-out'),
} as const;

View File

@ -23,8 +23,14 @@ export class RedRoleGuard extends IqserRoleGuard {
return false;
}
// we have at least 1 RED Role -> if it's not user he must be an admin
if (currentUser.isUserAdmin && !currentUser.isAdmin && state.url.includes('admin') && !state.url.includes('users')) {
// we have at least 1 RED Role -> if it's not user he must be an admin or a manager
if (
currentUser.isUserAdmin &&
!currentUser.isManager &&
!currentUser.isAdmin &&
state.url.includes('admin') &&
!state.url.includes('users')
) {
this._logger.warn('[GUARD] Redirect to users page');
await this._router.navigate(['/main/admin/users']);
return false;

View File

@ -8,10 +8,9 @@ const validDocumentMimeTypes = [
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.ms-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/pdf',
];
const validDocumentExtensions = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'];
const validDocumentExtensions = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'];
export function isPdf(file: FileUploadModel): boolean {
return file.file.type?.toLowerCase() === 'application/pdf' || file.file.name.toLowerCase().endsWith('.pdf');
@ -32,8 +31,8 @@ export function isDocument(file: FileUploadModel): boolean {
export type Files = FileList | File[];
export function isAcceptedFileType(file: FileUploadModel): boolean {
return isPdf(file) || isZip(file) || isDocument(file) || isCsv(file);
export function isAcceptedFileType(file: FileUploadModel, supportMsOfficeFormats = false): boolean {
return isPdf(file) || isZip(file) || isCsv(file) || (isDocument(file) && supportMsOfficeFormats);
}
export function convertFiles(files: FileList | File[], dossier: Dossier): FileUploadModel[] {

View File

@ -506,6 +506,11 @@
"documentKey": "dossier_stop_analysis",
"scrollableParentView": "VIRTUAL_SCROLL"
},
{
"elementKey": "dossier_automatic_text_recognition",
"documentKey": "dossier_automatic_text_recognition",
"scrollableParentView": "VIRTUAL_SCROLL"
},
{
"elementKey": "dossier_download",
"documentKey": "dossier_download",
@ -591,6 +596,10 @@
"elementKey": "editor_close",
"documentKey": "editor_close"
},
{
"elementKey": "editor_automatic_text_recognition",
"documentKey": "editor_automatic_text_recognition"
},
{
"elementKey": "scm_edit_DIALOG",
"documentKey": "scm_edit",

View File

@ -255,9 +255,6 @@
"watermarks": "Watermarks"
},
"analysis-disabled": "",
"annotation": {
"pending": "(Pending analysis)"
},
"annotation-actions": {
"accept-recommendation": {
"label": "Empfehlung annehmen"
@ -316,14 +313,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"
@ -336,15 +333,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"
},
@ -376,6 +373,9 @@
"skipped": "Übersprungen",
"text-highlight": "Earmark"
},
"annotation": {
"pending": "(Pending analysis)"
},
"archived-dossiers-listing": {
"no-data": {
"title": "No archived dossiers."
@ -581,18 +581,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 redactions.",
"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": {
@ -601,6 +597,10 @@
"question": "Analysis required to detect new redactions 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?",
@ -945,13 +945,13 @@
"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"
},
"start-auto-analysis": "Enable auto-analysis",
"stop-auto-analysis": "Stop auto-analysis",
"table-col-names": {
@ -1020,14 +1020,6 @@
"total-documents": "Anzahl der Dokumente",
"total-people": "<strong>{count}</strong> {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",
@ -1063,6 +1055,14 @@
"title": "{length} {length, plural, one{Dossier-Vorlage} other{Dossier-Vorlagen}}"
}
},
"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.<br>Contact your app admin to define one.",
@ -1248,15 +1248,6 @@
"title": "{length} {length, plural, one{Wörterbuch} other{Wörterbücher}}"
}
},
"entity": {
"info": {
"actions": {
"revert": "Revert",
"save": "Save changes"
},
"heading": "Edit entity"
}
},
"entity-rules-screen": {
"error": {
"generic": "Something went wrong... Entity rules update failed!"
@ -1270,19 +1261,28 @@
"title": "Entity rule editor",
"warning-text": "Warning: experimental feature!"
},
"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": {
@ -1300,12 +1300,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",
@ -1316,6 +1310,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": {
@ -1531,15 +1531,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",
@ -1549,6 +1540,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",
@ -1819,13 +1819,6 @@
"user-promoted-to-approver": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> zum Genehmiger ernannt!",
"user-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> 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",
@ -1839,6 +1832,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",
@ -1856,7 +1850,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",
@ -1864,6 +1857,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",
@ -1955,16 +1955,16 @@
"warnings-subtitle": "Do not show again options",
"warnings-title": "Prompts and dialogs settings"
},
"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": {
@ -2191,12 +2191,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",
@ -2220,6 +2214,12 @@
"no-match": "Keine Dokumente entsprechen Ihren aktuellen Filtern.",
"table-header": "{length} {length, plural, one{Suchergebnis} other{Suchergebnisse}}"
},
"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": {
@ -2239,6 +2239,7 @@
"header": {
"first-time": "Sign in for the first time to a workspace",
"join-another-domain": "Or join another workspace",
"no-role-log-out": "",
"sign-in-previous-domain": "Sign in to a previously used workspace",
"youre-logged-out": "You have successfully been logged out."
},
@ -2470,4 +2471,4 @@
}
},
"yesterday": "Gestern"
}
}

View File

@ -2239,6 +2239,7 @@
"header": {
"first-time": "Sign in for the first time to a workspace",
"join-another-domain": "Or join another workspace",
"no-role-log-out": "User role missing. Please ask your administrator to assign roles before logging in again.",
"sign-in-previous-domain": "Sign in to a previously used workspace",
"youre-logged-out": "You have successfully been logged out."
},
@ -2470,4 +2471,4 @@
}
},
"yesterday": "Yesterday"
}
}

View File

@ -255,9 +255,6 @@
"watermarks": "Watermarks"
},
"analysis-disabled": "Analysis disabled",
"annotation": {
"pending": "(Pending analysis)"
},
"annotation-actions": {
"accept-recommendation": {
"label": "Empfehlung annehmen"
@ -316,14 +313,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"
@ -336,15 +333,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"
},
@ -376,6 +373,9 @@
"skipped": "Übersprungen",
"text-highlight": "Earmark"
},
"annotation": {
"pending": "(Pending analysis)"
},
"archived-dossiers-listing": {
"no-data": {
"title": "No archived dossiers."
@ -581,18 +581,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": {
@ -601,6 +597,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?",
@ -945,13 +945,13 @@
"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"
},
"start-auto-analysis": "Enable auto-analysis",
"stop-auto-analysis": "Stop auto-analysis",
"table-col-names": {
@ -1020,14 +1020,6 @@
"total-documents": "Anzahl der Dokumente",
"total-people": "<strong>{count}</strong> {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",
@ -1063,6 +1055,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.<br>Contact your app admin to define one.",
@ -1248,15 +1248,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!"
@ -1270,19 +1261,28 @@
"title": "Entity rule editor",
"warning-text": "Warning: experimental feature!"
},
"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": {
@ -1300,12 +1300,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",
@ -1316,6 +1310,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": {
@ -1531,15 +1531,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",
@ -1549,6 +1540,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",
@ -1819,13 +1819,6 @@
"user-promoted-to-approver": "<b>{user}</b> wurde im Dossier <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> zum Genehmiger ernannt!",
"user-removed-as-dossier-member": "<b>{user}</b> wurde als Mitglied von: <b>{dossierHref, select, null{{dossierName}} other{<a href=\"{dossierHref}\" target=\"_blank\">{dossierName}</a>}}</b> 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",
@ -1839,6 +1832,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",
@ -1856,7 +1850,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",
@ -1864,6 +1857,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",
@ -1955,16 +1955,16 @@
"warnings-subtitle": "Do not show again options",
"warnings-title": "Prompts and dialogs settings"
},
"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": {
@ -2191,12 +2191,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",
@ -2220,6 +2214,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": {
@ -2239,6 +2239,7 @@
"header": {
"first-time": "Sign in for the first time to a workspace",
"join-another-domain": "Or join another workspace",
"no-role-log-out": "",
"sign-in-previous-domain": "Sign in to a previously used workspace",
"youre-logged-out": "You have successfully been logged out."
},
@ -2470,4 +2471,4 @@
}
},
"yesterday": "Gestern"
}
}

View File

@ -459,8 +459,8 @@
"to": "to"
},
"auth-error": {
"heading": "Your user is successfully logged in but has no role assigned yet. Please contact your DocuMine administrator to assign appropriate roles.",
"heading-with-link": "Your user is successfully logged in but has no role assigned yet. Please contact <a href={adminUrl} target=_blank >your DocuMine administrator</a> to assign appropriate roles!",
"heading": "Your user is successfully logged in but has no role assigned yet. Please contact your RedactManager administrator to assign appropriate roles.",
"heading-with-link": "Your user is successfully logged in but has no role assigned yet. Please contact <a href={adminUrl} target=_blank >your RedactManager administrator</a> to assign appropriate roles!",
"heading-with-name": "Your user is successfully logged in but has no role assigned yet. Please contact {adminName} to assign appropriate roles.",
"heading-with-name-and-link": "Your user is successfully logged in but has no role assigned yet. Please contact <a href={adminUrl} target=_blank >{adminName}</a> to assign appropriate roles.",
"logout": "Logout"
@ -2239,6 +2239,7 @@
"header": {
"first-time": "Sign in for the first time to a workspace",
"join-another-domain": "Or join another workspace",
"no-role-log-out": "User role missing. Please ask your administrator to assign roles before logging in again.",
"sign-in-previous-domain": "Sign in to a previously used workspace",
"youre-logged-out": "You have successfully been logged out."
},
@ -2470,4 +2471,4 @@
}
},
"yesterday": "Yesterday"
}
}

@ -1 +1 @@
Subproject commit 42cc494e2f3ff18182198bced1320b40c8b41d5e
Subproject commit a2d30f0a652650325eba1c333a2790527d054c08

View File

@ -1,7 +1,7 @@
export interface ILicenseFeature {
readonly name: string;
readonly type: string;
readonly value: string;
readonly value: string | boolean;
}
export interface ILicense {