Merge branch 'master' into VM/RED-6801
This commit is contained in:
commit
fa4238b06c
@ -144,7 +144,7 @@ export const appModuleFactory = (config: AppConfig) => {
|
||||
enabled: false,
|
||||
},
|
||||
PDF: {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
},
|
||||
FILE: {
|
||||
enabled: true,
|
||||
@ -155,6 +155,15 @@ export const appModuleFactory = (config: AppConfig) => {
|
||||
STATS: {
|
||||
enabled: false,
|
||||
},
|
||||
REDACTION_LOG: {
|
||||
enabled: false,
|
||||
},
|
||||
VIEWED_PAGES: {
|
||||
enabled: false,
|
||||
},
|
||||
PAGES: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
} as ILoggerConfig,
|
||||
},
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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>
|
||||
@ -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);
|
||||
}
|
||||
@ -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,
|
||||
},
|
||||
@ -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>
|
||||
@ -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;
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
<ng-container *ngIf="configService.listingMode$ | async as mode">
|
||||
<div (click)="editFileAttribute($event)" [ngClass]="{ 'workflow-attribute': mode === 'workflow' }" class="file-attribute">
|
||||
<div
|
||||
(mousedown)="handleControlClick($event)"
|
||||
(click)="editFileAttribute($event)"
|
||||
[ngClass]="{ 'workflow-attribute': mode === 'workflow' }"
|
||||
class="file-attribute"
|
||||
>
|
||||
<div [ngClass]="{ 'workflow-value': mode === 'workflow' }" class="value">
|
||||
<b *ngIf="mode === 'workflow' && !isInEditMode"> {{ fileAttribute.label }}: </b>
|
||||
<span
|
||||
|
||||
@ -82,6 +82,12 @@ export class FileAttributeComponent extends BaseFormComponent implements OnDestr
|
||||
}
|
||||
}
|
||||
|
||||
handleControlClick($event: MouseEvent) {
|
||||
if ($event.ctrlKey) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.#subscriptions.unsubscribe();
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { AfterViewInit, Component, inject, Input } from '@angular/core';
|
||||
import { List } from '@iqser/common-ui/lib/utils';
|
||||
import { PdfViewer } from '../../../pdf-viewer/services/pdf-viewer.service';
|
||||
import { MultiSelectService } from '../../services/multi-select.service';
|
||||
@ -7,13 +7,14 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { FilePreviewStateService } from '../../services/file-preview-state.service';
|
||||
import { ViewedPagesMapService } from '@services/files/viewed-pages-map.service';
|
||||
import { ViewedPage } from '@red/domain';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-pages',
|
||||
templateUrl: './pages.component.html',
|
||||
styleUrls: ['./pages.component.scss'],
|
||||
})
|
||||
export class PagesComponent {
|
||||
export class PagesComponent implements AfterViewInit {
|
||||
readonly #state = inject(FilePreviewStateService);
|
||||
readonly #multiSelectService = inject(MultiSelectService);
|
||||
readonly #listingService = inject(AnnotationsListingService);
|
||||
@ -22,6 +23,22 @@ export class PagesComponent {
|
||||
@Input({ required: true }) displayedAnnotations: Map<number, AnnotationWrapper[]>;
|
||||
readonly viewedPages$ = inject(ViewedPagesMapService).get$(this.#state.fileId);
|
||||
|
||||
ngAfterViewInit() {
|
||||
setTimeout(() => {
|
||||
this.scrollToLastViewedPage();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
scrollToLastViewedPage() {
|
||||
const currentPdfPage = this._pdf.currentPage();
|
||||
scrollIntoView(document.getElementById(`quick-nav-page-${currentPdfPage}`), {
|
||||
behavior: 'smooth',
|
||||
scrollMode: 'if-needed',
|
||||
block: 'start',
|
||||
inline: 'start',
|
||||
});
|
||||
}
|
||||
|
||||
pageSelectedByClick($event: number): void {
|
||||
this._pdf.navigateTo($event);
|
||||
}
|
||||
|
||||
@ -43,14 +43,14 @@ export function chronologicallyBy<T>(property: (x: T) => string) {
|
||||
|
||||
@Injectable()
|
||||
export class FileDataService extends EntitiesService<AnnotationWrapper, AnnotationWrapper> {
|
||||
readonly #annotations = signal<AnnotationWrapper[]>([]);
|
||||
readonly #earmarks = signal<Map<number, AnnotationWrapper[]>>(new Map());
|
||||
#originalViewedPages: ViewedPage[] = [];
|
||||
protected readonly _entityClass = AnnotationWrapper;
|
||||
missingTypes = new Set<string>();
|
||||
readonly earmarks: Signal<Map<number, AnnotationWrapper[]>>;
|
||||
readonly annotations: Signal<AnnotationWrapper[]>;
|
||||
readonly annotations$: Observable<AnnotationWrapper[]>;
|
||||
protected readonly _entityClass = AnnotationWrapper;
|
||||
readonly #annotations = signal<AnnotationWrapper[]>([]);
|
||||
readonly #earmarks = signal<Map<number, AnnotationWrapper[]>>(new Map());
|
||||
#originalViewedPages: ViewedPage[] = [];
|
||||
|
||||
constructor(
|
||||
private readonly _state: FilePreviewStateService,
|
||||
@ -155,12 +155,12 @@ export class FileDataService extends EntitiesService<AnnotationWrapper, Annotati
|
||||
async #loadViewedPages(file: File) {
|
||||
if (!this._permissionsService.canMarkPagesAsViewed(file)) {
|
||||
this._viewedPagesMapService.set(file.fileId, []);
|
||||
this._logger.info('[VIEWED-PAGES] Cannot mark pages as viewed, skip loading viewed pages');
|
||||
this._logger.info('[VIEWED_PAGES] Cannot mark pages as viewed, skip loading viewed pages');
|
||||
return;
|
||||
}
|
||||
|
||||
this.#originalViewedPages = await this._viewedPagesService.load(file.dossierId, file.fileId);
|
||||
this._logger.info('[VIEWED-PAGES] Loaded viewed pages', this.#originalViewedPages);
|
||||
this._logger.info('[VIEWED_PAGES] Loaded viewed pages', this.#originalViewedPages);
|
||||
this._viewedPagesMapService.set(file.fileId, this.#originalViewedPages);
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ export class PdfProxyService {
|
||||
readonly #visibilityIcon = this._convertPath('/assets/icons/general/visibility.svg');
|
||||
readonly #falsePositiveIcon = this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg');
|
||||
readonly #addRedactionIcon = this._iqserPermissionsService.has(Roles.getRss)
|
||||
? this._convertPath('/assets/icons/general/pdftron-action-add-component.svg')
|
||||
? this._convertPath('/assets/icons/general/pdftron-action-add-annotation.svg')
|
||||
: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg');
|
||||
readonly #addHintIcon = this._convertPath('/assets/icons/general/pdftron-action-add-hint.svg');
|
||||
readonly annotationSelected$ = this.#annotationSelected$;
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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 ?? []),
|
||||
|
||||
@ -76,12 +76,11 @@ export class DownloadDialogComponent extends IqserDialogComponent<DownloadDialog
|
||||
}
|
||||
|
||||
get invalidDownload() {
|
||||
const hasReportTypes = this.form.controls.reportTemplateIds.value.length;
|
||||
const downloadFileTypes = this.form.controls.downloadFileTypes.value;
|
||||
const onlyRedactedVersionSelected =
|
||||
downloadFileTypes.length && downloadFileTypes.every(type => type === DownloadFileTypes.REDACTED);
|
||||
|
||||
return !hasReportTypes || (onlyRedactedVersionSelected && !this.hasApprovedFiles);
|
||||
return onlyRedactedVersionSelected && !this.hasApprovedFiles;
|
||||
}
|
||||
|
||||
override get valid() {
|
||||
|
||||
@ -35,7 +35,7 @@ export class DossiersChangesService extends GenericService<Dossier> implements O
|
||||
changes.map(change => this.#load(change.dossierId).pipe(removeIfNotFound(change.dossierId)));
|
||||
|
||||
return this.hasChangesDetails$().pipe(
|
||||
tap(changes => this.#logger.info('[CHANGES] Dossier changes', changes)),
|
||||
tap(changes => this.#logger.info('[DOSSIERS_CHANGES] Found changes', changes)),
|
||||
switchMap(dossierChanges =>
|
||||
forkJoin([...load(dossierChanges), this.#dashboardStatsService.loadAll().pipe(take(1))]).pipe(map(() => dossierChanges)),
|
||||
),
|
||||
@ -45,9 +45,13 @@ export class DossiersChangesService extends GenericService<Dossier> implements O
|
||||
hasChangesDetails$(): Observable<IDossierChanges> {
|
||||
const body = { value: this._lastCheckedForChanges.get(ROOT_CHANGES_KEY) };
|
||||
const dateBeforeRequest = new Date(Date.now() - LAST_CHECKED_OFFSET).toISOString();
|
||||
|
||||
this.#logger.info('[DOSSIERS_CHANGES] Check with Last Checked Date', body.value);
|
||||
|
||||
return this._post<IDossierChanges>(body, `${this._defaultModelPath}/changes/details`).pipe(
|
||||
filter(changes => changes.length > 0),
|
||||
tap(() => this._lastCheckedForChanges.set(ROOT_CHANGES_KEY, dateBeforeRequest)),
|
||||
tap(() => this.#logger.info('[DOSSIERS_CHANGES] Save Last Checked Date value', dateBeforeRequest)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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",
|
||||
@ -1639,6 +1638,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",
|
||||
@ -1654,6 +1663,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",
|
||||
@ -1668,15 +1678,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",
|
||||
|
||||
@ -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",
|
||||
@ -1639,6 +1638,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",
|
||||
@ -1654,6 +1663,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",
|
||||
@ -1668,15 +1678,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",
|
||||
|
||||
@ -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",
|
||||
@ -1639,6 +1638,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",
|
||||
@ -1654,6 +1663,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",
|
||||
@ -1668,15 +1678,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",
|
||||
|
||||
@ -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",
|
||||
@ -1639,6 +1638,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",
|
||||
@ -1654,6 +1663,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",
|
||||
@ -1668,15 +1678,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",
|
||||
@ -1941,7 +1942,7 @@
|
||||
"title": "Redact text"
|
||||
}
|
||||
},
|
||||
"redaction-abbreviation": "C",
|
||||
"redaction-abbreviation": "A",
|
||||
"references": "{count} {count, plural, one{reference} other{references}}",
|
||||
"remove-redaction": {
|
||||
"dialog": {
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="16px" version="1.1" viewBox="0 0 16 16" width="16px"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd" id="Redacted" stroke="none" stroke-width="1">
|
||||
<rect fill="#283241" height="16" id="Rectangle" width="16" x="0" y="0"></rect>
|
||||
<text fill="#FFFFFF" font-family="Inter-SemiBold, Inter" font-size="11" font-weight="500"
|
||||
id="H">
|
||||
<tspan x="4.421875" y="12">A</tspan>
|
||||
</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 519 B |
@ -2,8 +2,8 @@
|
||||
<svg height="16px" version="1.1" viewBox="0 0 16 16" width="16px"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd" id="Redacted" stroke="none" stroke-width="1">
|
||||
<circle fill="#94989f" cx="8" cy="8" r="8" />
|
||||
<text fill="#FFFFFF" font-family="Arial, Helvetica, sans-serif" font-size="11" font-weight="500"
|
||||
<circle cx="8" cy="8" fill="#94989f" r="8" />
|
||||
<text fill="#FFFFFF" font-family="Inter-SemiBold, Inter" font-size="11" font-weight="500"
|
||||
id="H">
|
||||
<tspan x="4" y="12">H</tspan>
|
||||
</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 486 B After Width: | Height: | Size: 479 B |
@ -3,7 +3,7 @@
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g fill="none" fill-rule="evenodd" id="Redacted" stroke="none" stroke-width="1">
|
||||
<rect fill="#283241" height="16" id="Rectangle" width="16" x="0" y="0"></rect>
|
||||
<text fill="#FFFFFF" font-family="Arial, Helvetica, sans-serif" font-size="11" font-weight="500"
|
||||
<text fill="#FFFFFF" font-family="Inter-SemiBold, Inter" font-size="11" font-weight="500"
|
||||
id="H">
|
||||
<tspan x="4.421875" y="12">R</tspan>
|
||||
</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 526 B After Width: | Height: | Size: 519 B |
@ -1,4 +1,4 @@
|
||||
FROM node:18.12-buster as builder
|
||||
FROM node:20.4-buster as builder
|
||||
|
||||
WORKDIR /ng-app
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit e69f8b3f0df8701bbc3dbc79e2239aaad3acc889
|
||||
Subproject commit fd4491b2a39792ffe3ef76155c1572a45e38406e
|
||||
Loading…
x
Reference in New Issue
Block a user