RED-6830: Fixes for license information

This commit is contained in:
Adina Țeudan 2023-07-19 19:29:40 +03:00
parent 7995c72fe5
commit 858809a80e
17 changed files with 283 additions and 257 deletions

View File

@ -41,6 +41,7 @@ export class ChartComponent implements OnChanges {
text: this.yAxisLabel,
padding: { bottom: 20 },
},
min: 0,
},
y1: {
display: this.secondaryAxis,
@ -50,6 +51,7 @@ export class ChartComponent implements OnChanges {
text: this.yAxisLabelRight,
padding: { bottom: 20 },
},
min: 0,
},
},
plugins: {

View File

@ -0,0 +1,62 @@
<div class="grid-container">
<div class="section-title all-caps-label" translate="license-info-screen.capacity-details"></div>
<div class="row">
<div translate="license-info-screen.capacity.active-documents"></div>
<div>{{ licenseService.currentLicenseReport.activeFilesUploadedBytes | size }}</div>
</div>
<div class="row">
<div translate="license-info-screen.capacity.archived-documents"></div>
<div>{{ licenseService.currentLicenseReport.archivedFilesUploadedBytes | size }}</div>
</div>
<div class="row">
<div translate="license-info-screen.capacity.trash-documents"></div>
<div>{{ licenseService.currentLicenseReport.trashFilesUploadedBytes | size }}</div>
</div>
<div class="row">
<div translate="license-info-screen.capacity.all-documents"></div>
<div>
{{ licenseService.currentLicenseReport.totalFilesUploadedBytes | size }}
<ng-container *ngIf="uploadedBytesCapacityPercentage !== -1">
({{ uploadedBytesCapacityPercentage | number : '1.0-2' }}%)
</ng-container>
</div>
</div>
<div class="donut-chart-wrapper pl-20">
<redaction-donut-chart
*ngIf="uploadedBytesCapacityPercentage !== -1"
[config]="donutChartConfig"
[direction]="'row'"
[radius]="80"
[strokeWidth]="15"
[subtitleTemplate]="capacitySubtitles"
[totalType]="'sum'"
[valueFormatter]="size"
></redaction-donut-chart>
</div>
<div class="row">
<redaction-chart
*ngIf="data$ | async as data"
[datasets]="data.datasets"
[labels]="data.labels"
[reverseLegend]="true"
[valueFormatter]="formatSize"
></redaction-chart>
</div>
</div>
<ng-template #capacitySubtitles>
<span *ngIf="uploadedBytesCapacityPercentage <= 100; else exceeded">
{{ 'license-info-screen.capacity.storage-capacity' | translate }}
</span>
<ng-template #exceeded>
<span class="exceeded-capacity">
{{ 'license-info-screen.capacity.exceeded-capacity' | translate }}
</span>
</ng-template>
</ng-template>

View File

@ -0,0 +1,49 @@
:host {
display: contents;
}
.grid-container {
width: calc(100% - 40px);
display: grid;
grid-template-columns: 1fr 2fr 2fr;
margin: 20px;
.donut-chart-wrapper {
grid-row: 2 / span 4;
grid-column: 3;
width: fit-content;
}
.row {
display: contents;
> div {
padding: 8px 20px;
&:first-of-type {
font-weight: 600;
}
}
&:hover {
> div {
background-color: var(--iqser-alt-background);
}
}
}
.section-title {
grid-column: span 3;
padding: 20px 20px 8px;
margin-bottom: 8px;
border-bottom: 1px solid var(--iqser-separator);
}
redaction-chart {
grid-column: span 3;
}
}
.exceeded-capacity {
color: var(--iqser-red-1);
}

View File

@ -10,15 +10,15 @@ import { getLabelsFromLicense, getLineConfig } from '../../utils/functions';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@Component({
selector: 'red-license-storage',
templateUrl: './license-storage.component.html',
styleUrls: ['./license-storage.component.scss'],
selector: 'red-license-capacity',
templateUrl: './license-capacity.component.html',
styleUrls: ['./license-capacity.component.scss'],
})
export class LicenseStorageComponent {
export class LicenseCapacityComponent {
readonly formatSize = size;
uploadedBytesCapacityPercentage = -1;
donutChartConfig: DonutChartConfig[] = [];
readonly data$ = this.licenseService.licenseData$.pipe(
readonly data$ = this.licenseService.selectedLicense$.pipe(
map(() => this.licenseService.currentLicenseReport),
tap(license => {
this.uploadedBytesCapacityPercentage = this.#getUploadedBytesCapacityPercentage(license);
@ -44,22 +44,22 @@ export class LicenseStorageComponent {
{
value: license.activeFilesUploadedBytes,
color: ChartGreen,
label: this._translateService.instant(_('license-info-screen.storage.active-documents')),
label: this._translateService.instant(_('license-info-screen.capacity.active-documents')),
},
{
value: license.archivedFilesUploadedBytes,
color: ChartBlue,
label: this._translateService.instant(_('license-info-screen.storage.archived-documents')),
label: this._translateService.instant(_('license-info-screen.capacity.archived-documents')),
},
{
value: license.trashFilesUploadedBytes,
color: ChartRed,
label: this._translateService.instant(_('license-info-screen.storage.trash-documents')),
label: this._translateService.instant(_('license-info-screen.capacity.trash-documents')),
},
{
value: this.licenseService.uploadedBytesCapacity - license.totalFilesUploadedBytes,
value: Math.max(this.licenseService.uploadedBytesCapacity - license.totalFilesUploadedBytes, 0),
color: ChartGrey,
label: this._translateService.instant(_('license-info-screen.storage.unused')),
label: this._translateService.instant(_('license-info-screen.capacity.unused')),
},
];
}
@ -70,25 +70,25 @@ export class LicenseStorageComponent {
return [
{
data: monthlyData.flatMap(d => d.activeFilesUploadedBytes),
label: this._translateService.instant('license-info-screen.storage.active-documents'),
label: this._translateService.instant('license-info-screen.capacity.active-documents'),
...getLineConfig(ChartGreen, false, 'origin'),
stack: 'storage',
},
{
data: monthlyData.flatMap(d => d.archivedFilesUploadedBytes),
label: this._translateService.instant('license-info-screen.storage.archived-documents'),
label: this._translateService.instant('license-info-screen.capacity.archived-documents'),
...getLineConfig(ChartBlue, false, '-1'),
stack: 'storage',
},
{
data: monthlyData.flatMap(d => d.trashFilesUploadedBytes),
label: this._translateService.instant('license-info-screen.storage.trash-documents'),
label: this._translateService.instant('license-info-screen.capacity.trash-documents'),
...getLineConfig(ChartRed, false, '-1'),
stack: 'storage',
},
{
data: monthlyData.flatMap(d => d.activeFilesUploadedBytes + d.archivedFilesUploadedBytes + d.trashFilesUploadedBytes),
label: this._translateService.instant('license-info-screen.storage.all-documents'),
label: this._translateService.instant('license-info-screen.capacity.all-documents'),
...getLineConfig(ChartBlack, true, false),
borderWidth: 2,
},

View File

@ -1,48 +0,0 @@
<div class="section-title all-caps-label" translate="license-info-screen.storage-details"></div>
<div class="row">
<div translate="license-info-screen.storage.active-documents"></div>
<div>{{ licenseService.currentLicenseReport.activeFilesUploadedBytes | size }}</div>
</div>
<div class="row">
<div translate="license-info-screen.storage.archived-documents"></div>
<div>{{ licenseService.currentLicenseReport.archivedFilesUploadedBytes | size }}</div>
</div>
<div class="row">
<div translate="license-info-screen.storage.trash-documents"></div>
<div>{{ licenseService.currentLicenseReport.trashFilesUploadedBytes | size }}</div>
</div>
<div class="row">
<div translate="license-info-screen.storage.all-documents"></div>
<div>
{{ licenseService.currentLicenseReport.totalFilesUploadedBytes | size }}
<ng-container *ngIf="uploadedBytesCapacityPercentage !== -1">
({{ uploadedBytesCapacityPercentage | number : '1.0-2' }}%)
</ng-container>
</div>
</div>
<div class="donut-chart-wrapper pl-20">
<redaction-donut-chart
*ngIf="uploadedBytesCapacityPercentage !== -1"
[config]="donutChartConfig"
[direction]="'row'"
[radius]="80"
[strokeWidth]="15"
[subtitles]="['license-info-screen.storage.storage-capacity' | translate]"
[totalType]="'sum'"
[valueFormatter]="size"
></redaction-donut-chart>
</div>
<div class="row">
<redaction-chart
*ngIf="data$ | async as data"
[datasets]="data.datasets"
[labels]="data.labels"
[reverseLegend]="true"
[valueFormatter]="formatSize"
></redaction-chart>
</div>

View File

@ -1,38 +0,0 @@
:host {
display: contents;
}
.donut-chart-wrapper {
grid-row: 11 / span 4;
grid-column: 3;
width: fit-content;
}
.row {
display: contents;
> div {
padding: 8px 20px;
&:first-of-type {
font-weight: 600;
}
}
&:hover {
> div {
background-color: var(--iqser-alt-background);
}
}
}
.section-title {
grid-column: span 3;
padding: 20px 20px 8px;
margin-bottom: 8px;
border-bottom: 1px solid var(--iqser-separator);
}
redaction-chart {
grid-column: span 3;
}

View File

@ -1,41 +1,43 @@
<div class="section-title all-caps-label" translate="license-info-screen.usage-details"></div>
<div class="grid-container">
<div class="section-title all-caps-label" translate="license-info-screen.usage-details"></div>
<div class="row">
<div translate="license-info-screen.current-analyzed"></div>
<div>
{{ licenseService.analyzedPagesInCurrentLicensingPeriod }}
({{ analysisPercentageOfLicense$ | async | number : '1.0-2' }}%)
<div class="row">
<div translate="license-info-screen.current-analyzed"></div>
<div>
{{ licenseService.analyzedPagesInCurrentLicensingPeriod }}
({{ analysisPercentageOfLicense$ | async | number : '1.0-2' }}%)
</div>
</div>
<div class="row">
<div translate="license-info-screen.ocr-analyzed-pages"></div>
<div>{{ licenseService.currentLicenseReport.numberOfOcrPages }}</div>
</div>
<div *ngIf="!!licenseService.unlicensedPages" class="row">
<div translate="license-info-screen.unlicensed-analyzed"></div>
<div>{{ licenseService.unlicensedPages }}</div>
</div>
<div class="row">
<div [innerHTML]="'license-info-screen.total-analyzed' | translate"></div>
<div>{{ licenseService.allLicensesReport.numberOfAnalyzedPages }}</div>
</div>
<div class="row">
<div [innerHTML]="'license-info-screen.total-ocr-analyzed' | translate"></div>
<div>{{ licenseService.allLicensesReport.numberOfOcrPages }}</div>
</div>
<div class="row">
<redaction-chart
*ngIf="data$ | async as data"
[datasets]="data.datasets"
[labels]="data.labels"
[secondaryAxis]="true"
[yAxisLabelRight]="'license-info-screen.pages.total-pages' | translate"
[yAxisLabel]="'license-info-screen.pages.pages-per-month' | translate"
></redaction-chart>
</div>
</div>
<div class="row">
<div translate="license-info-screen.ocr-analyzed-pages"></div>
<div>{{ licenseService.currentLicenseReport.numberOfOcrPages }}</div>
</div>
<div *ngIf="!!licenseService.unlicensedPages" class="row">
<div translate="license-info-screen.unlicensed-analyzed"></div>
<div>{{ licenseService.unlicensedPages }}</div>
</div>
<div class="row">
<div [innerHTML]="'license-info-screen.total-analyzed' | translate"></div>
<div>{{ licenseService.allLicensesReport.numberOfAnalyzedPages }}</div>
</div>
<div class="row">
<div [innerHTML]="'license-info-screen.total-ocr-analyzed' | translate"></div>
<div>{{ licenseService.allLicensesReport.numberOfOcrPages }}</div>
</div>
<div class="row">
<redaction-chart
*ngIf="data$ | async as data"
[datasets]="data.datasets"
[labels]="data.labels"
[secondaryAxis]="true"
[yAxisLabelRight]="'license-info-screen.pages.total-pages' | translate"
[yAxisLabel]="'license-info-screen.pages.pages-per-month' | translate"
></redaction-chart>
</div>

View File

@ -2,35 +2,42 @@
display: contents;
}
.row {
display: contents;
.grid-container {
width: calc(100% - 40px);
display: grid;
grid-template-columns: 1fr 2fr 2fr;
margin: 20px;
> div {
padding: 8px 20px;
.row {
display: contents;
&:first-of-type {
font-weight: 600;
}
&:nth-child(2) {
grid-column: span 2;
}
}
&:hover {
> div {
background-color: var(--iqser-alt-background);
padding: 8px 20px;
&:first-of-type {
font-weight: 600;
}
&:nth-child(2) {
grid-column: span 2;
}
}
&:hover {
> div {
background-color: var(--iqser-alt-background);
}
}
}
}
.section-title {
grid-column: span 3;
padding: 20px 20px 8px;
margin-bottom: 8px;
border-bottom: 1px solid var(--iqser-separator);
}
.section-title {
grid-column: span 3;
padding: 20px 20px 8px;
margin-bottom: 8px;
border-bottom: 1px solid var(--iqser-separator);
}
redaction-chart {
grid-column: span 3;
redaction-chart {
grid-column: span 3;
}
}

View File

@ -61,9 +61,14 @@
<div>{{ licenseService.totalLicensedNumberOfPages }}</div>
</div>
<red-license-storage></red-license-storage>
<red-license-usage></red-license-usage>
<div *ngIf="licenseService.uploadedBytesCapacity" class="row">
<div>{{ 'license-info-screen.licensed-capacity' | translate }}</div>
<div>{{ licenseService.uploadedBytesCapacity | size }}</div>
</div>
</div>
<red-license-usage></red-license-usage>
<red-license-capacity></red-license-capacity>
</div>
</div>
</div>

View File

@ -10,7 +10,7 @@ import { CommonModule } from '@angular/common';
import { LicenseService } from '@services/license.service';
import { ChartComponent } from './components/chart/chart.component';
import { NgChartsModule } from 'ng2-charts';
import { LicenseStorageComponent } from './components/license-storage/license-storage.component';
import { LicenseCapacityComponent } from './components/license-storage/license-capacity.component';
import { LicenseUsageComponent } from './components/license-usage/license-usage.component';
import { DonutChartComponent } from '@shared/components/donut-chart/donut-chart.component';
@ -25,7 +25,7 @@ const routes: Routes = [
];
@NgModule({
declarations: [LicenseScreenComponent, LicenseSelectComponent, ChartComponent, LicenseStorageComponent, LicenseUsageComponent],
declarations: [LicenseScreenComponent, LicenseSelectComponent, ChartComponent, LicenseCapacityComponent, LicenseUsageComponent],
imports: [
RouterModule.forChild(routes),
CommonModule,

View File

@ -21,6 +21,10 @@
<div class="heading-xl">{{ getFormattedValue(displayedDataTotal) }}</div>
<div *ngIf="subtitles.length === 1" class="mt-5">{{ subtitles[0] }}</div>
<div *ngIf="subtitleTemplate as t" class="mt-5">
<ng-container *ngTemplateOutlet="t"></ng-container>
</div>
<mat-select
(selectionChange)="subtitleChanged.emit(subtitles.indexOf($event.value))"
*ngIf="subtitles.length > 1"

View File

@ -1,9 +1,9 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Optional, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, OnInit, Optional, Output, TemplateRef } from '@angular/core';
import { DonutChartConfig } from '@red/domain';
import { IqserHelpModeModule } from '@iqser/common-ui';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { AsyncPipe, NgForOf, NgIf } from '@angular/common';
import { AsyncPipe, NgForOf, NgIf, NgTemplateOutlet } from '@angular/common';
import { MatSelectModule } from '@angular/material/select';
import { FilterService, INestedFilter } from '@iqser/common-ui/lib/filtering';
import { get, shareLast } from '@iqser/common-ui/lib/utils';
@ -14,10 +14,10 @@ import { StatusBarComponent } from '@iqser/common-ui/lib/shared';
templateUrl: './donut-chart.component.html',
styleUrls: ['./donut-chart.component.scss'],
standalone: true,
imports: [NgForOf, NgIf, MatSelectModule, IqserHelpModeModule, StatusBarComponent, AsyncPipe],
imports: [NgForOf, NgIf, MatSelectModule, IqserHelpModeModule, StatusBarComponent, AsyncPipe, NgTemplateOutlet],
})
export class DonutChartComponent implements OnChanges, OnInit {
@Input() subtitles: string[];
@Input() subtitles: string[] = [];
@Input() config: DonutChartConfig[] = [];
@Input() radius = 85;
@Input() strokeWidth = 20;
@ -27,6 +27,7 @@ export class DonutChartComponent implements OnChanges, OnInit {
@Input() filterKey;
@Input() helpModeKey;
@Input() valueFormatter?: (value: number) => string;
@Input() subtitleTemplate?: TemplateRef<any>;
@Output() readonly subtitleChanged = new EventEmitter<number>();
@ -36,10 +37,6 @@ export class DonutChartComponent implements OnChanges, OnInit {
size = 0;
filters$: Observable<INestedFilter[]>;
constructor(@Optional() readonly filterService: FilterService) {
// TODO: move this component to a separate module, split into smaller components, improve filters
}
get circumference(): number {
return 2 * Math.PI * this.radius;
}
@ -52,6 +49,10 @@ export class DonutChartComponent implements OnChanges, OnInit {
return this.totalType === 'sum' ? this.dataTotal : this.config.length;
}
constructor(@Optional() readonly filterService: FilterService) {
// TODO: move this component to a separate module, split into smaller components, improve filters
}
ngOnInit() {
const filterModels$ = this.filterService?.getFilterModels$(this.filterKey).pipe(
map(filters => filters ?? []),

View File

@ -40,11 +40,6 @@ const defaultOnError: ILicenses = {
providedIn: 'root',
})
export class LicenseService extends GenericService<ILicenseReport> {
readonly #licenseData$ = new BehaviorSubject<ILicenses | undefined>(undefined);
readonly #selectedLicense$ = new BehaviorSubject<ILicense | undefined>(undefined);
readonly #logger = inject(NGXLogger);
readonly #toaster = inject(Toaster);
protected readonly _defaultModelPath = 'report';
readonly licenseData$: Observable<ILicenses>;
readonly selectedLicense$: Observable<ILicense>;
activeLicenseId: string;
@ -53,29 +48,21 @@ export class LicenseService extends GenericService<ILicenseReport> {
allLicensesReport: ILicenseReport = {};
unlicensedPages = 0;
analyzedPagesInCurrentLicensingPeriod = 0;
uploadedBytesCapacity = 0;
constructor() {
super();
this.selectedLicense$ = this.#selectedLicense$.pipe(filter(license => !!license));
this.licenseData$ = this.#licenseData$.pipe(
filter(licenses => !!licenses),
tap(data => (this.activeLicenseId = data.activeLicense)),
tap(() => {
const activeLicense = this.activeLicense;
if (!activeLicense) {
return;
}
const uploadedBytesCapacity = this.activeLicense.features.find(f => f.name === 'uploadedBytesCapacity')?.value;
this.uploadedBytesCapacity = uploadedBytesCapacity ? parseInt(uploadedBytesCapacity, 10) : 0;
}),
);
}
protected readonly _defaultModelPath = 'report';
readonly #licenseData$ = new BehaviorSubject<ILicenses | undefined>(undefined);
readonly #selectedLicense$ = new BehaviorSubject<ILicense | undefined>(undefined);
readonly #logger = inject(NGXLogger);
readonly #toaster = inject(Toaster);
get selectedLicense() {
return this.#selectedLicense$.value;
}
get uploadedBytesCapacity(): number {
const uploadedBytesCapacity = this.selectedLicense.features.find(f => f.name === 'uploadedBytesCapacity')?.value || '0';
return parseInt(uploadedBytesCapacity, 10);
}
get activeLicense() {
if (!this.#licenseData$.value) {
return undefined;
@ -94,6 +81,15 @@ export class LicenseService extends GenericService<ILicenseReport> {
return activeLicense.features.find(f => f.name === 'pdftron').value;
}
constructor() {
super();
this.selectedLicense$ = this.#selectedLicense$.pipe(filter(license => !!license));
this.licenseData$ = this.#licenseData$.pipe(
filter(licenses => !!licenses),
tap(data => (this.activeLicenseId = data.activeLicense)),
);
}
async loadLicenseData(license: ILicense = this.selectedLicense) {
this.totalLicensedNumberOfPages = this.getTotalLicensedNumberOfPages(license);

View File

@ -208,9 +208,6 @@
"accept-recommendation": {
"label": "Empfehlung annehmen"
},
"accept-suggestion": {
"label": "Genehmigen und zum Wörterbuch hinzufügen"
},
"convert-highlights": {
"label": ""
},
@ -328,7 +325,6 @@
}
},
"recategorize-image": "neu kategorisieren",
"reject-suggestion": "Vorschlag ablehnen",
"remove-annotation": {
"remove-redaction": ""
},
@ -477,7 +473,6 @@
"heading-with-name-and-link": "Ihr Benutzer verfügt nicht über die erforderlichen RED-*-Rollen, um auf diese Applikation zugreifen zu können. Bitte kontaktieren Sie <a href={adminUrl} target=_blank >{adminName}</a>, um den Zugang anzufordern!",
"logout": "Ausloggen"
},
"by": "von",
"change-legal-basis-dialog": {
"actions": {
"cancel": "Abbrechen",
@ -1638,6 +1633,16 @@
},
"license-info-screen": {
"backend-version": "Backend-Version der Anwendung",
"capacity-details": "",
"capacity": {
"active-documents": "",
"all-documents": "",
"archived-documents": "",
"exceeded-capacity": "",
"storage-capacity": "",
"trash-documents": "",
"unused": ""
},
"copyright-claim-text": "Copyright © 2020 - {currentYear} knecon AG (powered by IQSER)",
"copyright-claim-title": "Copyright",
"current-analyzed": "In aktuellem Lizenzzeitraum analysierte Seiten",
@ -1653,6 +1658,7 @@
"end-user-license-text": "Die Nutzung dieses Produkts unterliegt den Bedingungen der Endbenutzer-Lizenzvereinbarung für den RedactManager, sofern darin nichts anderweitig festgelegt.",
"end-user-license-title": "Endbenutzer-Lizenzvereinbarung",
"license-title": "",
"licensed-capacity": "",
"licensed-page-count": "Anzahl der lizenzierten Seiten",
"licensed-to": "Lizenziert für",
"licensing-details": "Lizenzdetails",
@ -1667,15 +1673,6 @@
"active": "Aktiv",
"inactive": ""
},
"storage-details": "",
"storage": {
"active-documents": "",
"all-documents": "",
"archived-documents": "",
"storage-capacity": "",
"trash-documents": "",
"unused": ""
},
"total-analyzed": "Seit {date} insgesamt analysierte Seiten",
"total-ocr-analyzed": "",
"unlicensed-analyzed": "Über Lizenz hinaus analysierte Seiten",

View File

@ -208,9 +208,6 @@
"accept-recommendation": {
"label": "Accept Recommendation"
},
"accept-suggestion": {
"label": "Approve Suggestion"
},
"convert-highlights": {
"label": "Convert Selected Earmarks"
},
@ -328,7 +325,6 @@
}
},
"recategorize-image": "Recategorize",
"reject-suggestion": "Reject Suggestion",
"remove-annotation": {
"remove-redaction": "Remove"
},
@ -477,7 +473,6 @@
"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"
},
"by": "by",
"change-legal-basis-dialog": {
"actions": {
"cancel": "Cancel",
@ -1638,6 +1633,16 @@
},
"license-info-screen": {
"backend-version": "Backend Application Version",
"capacity-details": "Capacity Details",
"capacity": {
"active-documents": "Active Documents",
"all-documents": "Retention Capacity Used",
"archived-documents": "Archived Documents",
"exceeded-capacity": "Exceeded Capacity",
"storage-capacity": "Capacity",
"trash-documents": "Documents in Trash",
"unused": "Unused Storage"
},
"copyright-claim-text": "Copyright © 2020 - {currentYear} knecon AG (powered by IQSER)",
"copyright-claim-title": "Copyright Claim",
"current-analyzed": "Analyzed Pages in Licensing Period",
@ -1653,6 +1658,7 @@
"end-user-license-text": "The use of this product is subject to the terms of the Redaction End User Agreement, unless otherwise specified therein.",
"end-user-license-title": "End User License Agreement",
"license-title": "License Title",
"licensed-capacity": "Licensed Capacity",
"licensed-page-count": "Licensed Pages",
"licensed-to": "Licensed to",
"licensing-details": "Licensing Details",
@ -1667,15 +1673,6 @@
"active": "Active",
"inactive": "Inactive"
},
"storage-details": "Storage Details",
"storage": {
"active-documents": "Active Documents",
"all-documents": "Total Storage Used",
"archived-documents": "Archived Documents",
"storage-capacity": "Storage Capacity",
"trash-documents": "Documents in Trash",
"unused": "Unused Storage"
},
"total-analyzed": "Total Analyzed Pages",
"total-ocr-analyzed": "Total OCR Processed Pages",
"unlicensed-analyzed": "Unlicensed Analyzed Pages",

View File

@ -473,7 +473,6 @@
"heading-with-name-and-link": "Ihr Benutzer verfügt nicht über die erforderlichen RED-*-Rollen, um auf diese Applikation zugreifen zu können. Bitte kontaktieren Sie <a href={adminUrl} target=_blank >{adminName}</a>, um den Zugang anzufordern!",
"logout": "Ausloggen"
},
"by": "von",
"change-legal-basis-dialog": {
"actions": {
"cancel": "Abbrechen",
@ -1634,6 +1633,16 @@
},
"license-info-screen": {
"backend-version": "Backend-Version der Anwendung",
"capacity-details": "",
"capacity": {
"active-documents": "",
"all-documents": "",
"archived-documents": "",
"exceeded-capacity": "",
"storage-capacity": "",
"trash-documents": "",
"unused": ""
},
"copyright-claim-text": "Copyright © 2020 - {currentYear} knecon AG (powered by IQSER)",
"copyright-claim-title": "Copyright",
"current-analyzed": "In aktuellem Lizenzzeitraum analysierte Seiten",
@ -1649,6 +1658,7 @@
"end-user-license-text": "Die Nutzung dieses Produkts unterliegt den Bedingungen der Endbenutzer-Lizenzvereinbarung für den RedactManager, sofern darin nichts anderweitig festgelegt.",
"end-user-license-title": "Endbenutzer-Lizenzvereinbarung",
"license-title": "",
"licensed-capacity": "",
"licensed-page-count": "Anzahl der lizenzierten Seiten",
"licensed-to": "Lizenziert für",
"licensing-details": "Lizenzdetails",
@ -1663,15 +1673,6 @@
"active": "Aktiv",
"inactive": ""
},
"storage-details": "",
"storage": {
"active-documents": "",
"all-documents": "",
"archived-documents": "",
"storage-capacity": "",
"trash-documents": "",
"unused": ""
},
"total-analyzed": "Seit {date} insgesamt analysierte Seiten",
"total-ocr-analyzed": "",
"unlicensed-analyzed": "Über Lizenz hinaus analysierte Seiten",
@ -2069,12 +2070,6 @@
"undo": ""
},
"annotations": "",
"table-header": {
"annotation": "",
"component": "",
"transformation": "",
"value": ""
},
"title": ""
},
"rules-screen": {

View File

@ -473,7 +473,6 @@
"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"
},
"by": "by",
"change-legal-basis-dialog": {
"actions": {
"cancel": "Cancel",
@ -1634,6 +1633,16 @@
},
"license-info-screen": {
"backend-version": "Backend Application Version",
"capacity-details": "Capacity Details",
"capacity": {
"active-documents": "Active Documents",
"all-documents": "Retention Capacity Used",
"archived-documents": "Archived Documents",
"exceeded-capacity": "Exceeded Capacity",
"storage-capacity": "Capacity",
"trash-documents": "Documents in Trash",
"unused": "Unused Storage"
},
"copyright-claim-text": "Copyright © 2020 - {currentYear} knecon AG (powered by IQSER)",
"copyright-claim-title": "Copyright Claim",
"current-analyzed": "Analyzed Pages in Licensing Period",
@ -1649,6 +1658,7 @@
"end-user-license-text": "The use of this product is subject to the terms of the Component End User Agreement, unless otherwise specified therein.",
"end-user-license-title": "End User License Agreement",
"license-title": "License Title",
"licensed-capacity": "Licensed Capacity",
"licensed-page-count": "Licensed pages",
"licensed-to": "Licensed to",
"licensing-details": "Licensing Details",
@ -1663,15 +1673,6 @@
"active": "Active",
"inactive": "Inactive"
},
"storage-details": "Storage Details",
"storage": {
"active-documents": "Active Documents",
"all-documents": "Total Storage Used",
"archived-documents": "Archived Documents",
"storage-capacity": "Storage Capacity",
"trash-documents": "Documents in Trash",
"unused": "Unused Storage"
},
"total-analyzed": "Total Analyzed Pages Since {date}",
"total-ocr-analyzed": "Total OCR Processed Pages Since {date}",
"unlicensed-analyzed": "Unlicensed Analyzed Pages",
@ -2069,12 +2070,6 @@
"undo": "Undo to: {value}"
},
"annotations": "<strong>{type}</strong> found on {pageCount, plural, one{page} other{pages}} {pages} by rule #{ruleNumber}",
"table-header": {
"annotation-references": "Annotation references",
"component": "Component",
"transformation-rule": "Transformation rule",
"value": "Value"
},
"title": "Structured Component Management"
},
"rules-screen": {