Prettify project
This commit is contained in:
parent
d50146a441
commit
ef92ff8072
@ -1,4 +1,2 @@
|
||||
<router-outlet></router-outlet>
|
||||
<redaction-full-page-loading-indicator
|
||||
[displayed]="loadingService.isLoading | async"
|
||||
></redaction-full-page-loading-indicator>
|
||||
<redaction-full-page-loading-indicator [displayed]="loadingService.isLoading | async"></redaction-full-page-loading-indicator>
|
||||
|
||||
@ -1,15 +1,8 @@
|
||||
<section>
|
||||
<p
|
||||
*ngIf="!configuredAdminName && !configuredAdminUrl"
|
||||
class="heading-xl"
|
||||
translate="auth-error.heading"
|
||||
></p>
|
||||
<p *ngIf="!configuredAdminName && !configuredAdminUrl" class="heading-xl" translate="auth-error.heading"></p>
|
||||
<p
|
||||
*ngIf="configuredAdminName && configuredAdminUrl"
|
||||
[innerHTML]="
|
||||
'auth-error.heading-with-name-and-link'
|
||||
| translate: { adminName: configuredAdminName, adminUrl: configuredAdminUrl }
|
||||
"
|
||||
[innerHTML]="'auth-error.heading-with-name-and-link' | translate: { adminName: configuredAdminName, adminUrl: configuredAdminUrl }"
|
||||
class="heading-xl"
|
||||
></p>
|
||||
<p
|
||||
|
||||
@ -11,15 +11,10 @@ export class AuthErrorComponent implements OnInit {
|
||||
configuredAdminName: string;
|
||||
configuredAdminUrl: string;
|
||||
|
||||
constructor(
|
||||
private readonly _userService: UserService,
|
||||
private readonly _appConfigService: AppConfigService
|
||||
) {}
|
||||
constructor(private readonly _userService: UserService, private readonly _appConfigService: AppConfigService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.configuredAdminName = this._appConfigService.getConfig(
|
||||
AppConfigKey.ADMIN_CONTACT_NAME
|
||||
);
|
||||
this.configuredAdminName = this._appConfigService.getConfig(AppConfigKey.ADMIN_CONTACT_NAME);
|
||||
this.configuredAdminUrl = this._appConfigService.getConfig(AppConfigKey.ADMIN_CONTACT_URL);
|
||||
}
|
||||
|
||||
|
||||
@ -6,11 +6,7 @@
|
||||
<mat-icon svgIcon="red:menu"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuNav="matMenu">
|
||||
<button
|
||||
mat-menu-item
|
||||
routerLink="/main/dossiers"
|
||||
translate="top-bar.navigation-items.dossiers"
|
||||
></button>
|
||||
<button mat-menu-item routerLink="/main/dossiers" translate="top-bar.navigation-items.dossiers"></button>
|
||||
<button
|
||||
*ngIf="appStateService.activeDossier"
|
||||
[routerLink]="'/main/dossiers/' + appStateService.activeDossierId"
|
||||
@ -20,22 +16,14 @@
|
||||
</button>
|
||||
<button
|
||||
*ngIf="appStateService.activeFile"
|
||||
[routerLink]="
|
||||
'/main/dossiers/' +
|
||||
appStateService.activeDossierId +
|
||||
'/file/' +
|
||||
appStateService.activeFile.fileId
|
||||
"
|
||||
[routerLink]="'/main/dossiers/' + appStateService.activeDossierId + '/file/' + appStateService.activeFile.fileId"
|
||||
mat-menu-item
|
||||
>
|
||||
{{ appStateService.activeFile.filename }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="permissionsService.isUser()"
|
||||
class="menu flex-2 visible-lg breadcrumbs-container"
|
||||
>
|
||||
<div *ngIf="permissionsService.isUser()" class="menu flex-2 visible-lg breadcrumbs-container">
|
||||
<a
|
||||
*ngIf="dossiersView"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
@ -49,15 +37,8 @@
|
||||
{{ 'top-bar.navigation-items.back' | translate }}
|
||||
</a>
|
||||
<ng-container *ngIf="dossiersView">
|
||||
<mat-icon
|
||||
*ngIf="!appStateService.activeDossier"
|
||||
class="primary"
|
||||
svgIcon="red:arrow-down"
|
||||
></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="appStateService.activeDossier"
|
||||
svgIcon="red:arrow-right"
|
||||
></mat-icon>
|
||||
<mat-icon *ngIf="!appStateService.activeDossier" class="primary" svgIcon="red:arrow-down"></mat-icon>
|
||||
<mat-icon *ngIf="appStateService.activeDossier" svgIcon="red:arrow-right"></mat-icon>
|
||||
<a
|
||||
*ngIf="appStateService.activeDossier"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
@ -70,12 +51,7 @@
|
||||
<mat-icon *ngIf="appStateService.activeFile" svgIcon="red:arrow-right"></mat-icon>
|
||||
<a
|
||||
*ngIf="appStateService.activeFile"
|
||||
[routerLink]="
|
||||
'/main/dossiers/' +
|
||||
appStateService.activeDossierId +
|
||||
'/file/' +
|
||||
appStateService.activeFile.fileId
|
||||
"
|
||||
[routerLink]="'/main/dossiers/' + appStateService.activeDossierId + '/file/' + appStateService.activeFile.fileId"
|
||||
class="breadcrumb"
|
||||
routerLinkActive="active"
|
||||
>
|
||||
@ -90,26 +66,13 @@
|
||||
<div class="app-name">{{ titleService.getTitle() }}</div>
|
||||
</div>
|
||||
<div class="menu right flex-2">
|
||||
<redaction-notifications
|
||||
*ngIf="userPreferenceService.areDevFeaturesEnabled"
|
||||
class="mr-8"
|
||||
></redaction-notifications>
|
||||
<redaction-notifications *ngIf="userPreferenceService.areDevFeaturesEnabled" class="mr-8"></redaction-notifications>
|
||||
|
||||
<redaction-user-button
|
||||
[matMenuTriggerFor]="userMenu"
|
||||
[showDot]="showPendingDownloadsDot"
|
||||
[user]="user"
|
||||
></redaction-user-button>
|
||||
<redaction-user-button [matMenuTriggerFor]="userMenu" [showDot]="showPendingDownloadsDot" [user]="user"></redaction-user-button>
|
||||
|
||||
<mat-menu #userMenu="matMenu" xPosition="before">
|
||||
<ng-container *ngFor="let item of userMenuItems; trackBy: trackByName">
|
||||
<button
|
||||
(click)="(item.action)"
|
||||
*ngIf="item.show"
|
||||
[routerLink]="item.routerLink"
|
||||
mat-menu-item
|
||||
translate
|
||||
>
|
||||
<button (click)="(item.action)" *ngIf="item.show" [routerLink]="item.routerLink" mat-menu-item translate>
|
||||
{{ item.name }}
|
||||
</button>
|
||||
</ng-container>
|
||||
@ -124,10 +87,6 @@
|
||||
<div class="divider"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="userPreferenceService.areDevFeaturesEnabled"
|
||||
class="dev-mode"
|
||||
translate="dev-mode"
|
||||
></div>
|
||||
<div *ngIf="userPreferenceService.areDevFeaturesEnabled" class="dev-mode" translate="dev-mode"></div>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@ -1,14 +1,5 @@
|
||||
<redaction-circle-button
|
||||
[matMenuTriggerFor]="overlay"
|
||||
[showDot]="hasUnread"
|
||||
icon="red:notification"
|
||||
></redaction-circle-button>
|
||||
<mat-menu
|
||||
#overlay="matMenu"
|
||||
backdropClass="notifications-backdrop"
|
||||
class="notifications-menu"
|
||||
xPosition="before"
|
||||
>
|
||||
<redaction-circle-button [matMenuTriggerFor]="overlay" [showDot]="hasUnread" icon="red:notification"></redaction-circle-button>
|
||||
<mat-menu #overlay="matMenu" backdropClass="notifications-backdrop" class="notifications-menu" xPosition="before">
|
||||
<div *ngFor="let group of groupedNotifications | sortBy: 'desc':'dateString'">
|
||||
<div class="all-caps-label">{{ day(group) }}</div>
|
||||
<div
|
||||
@ -24,10 +15,7 @@
|
||||
</div>
|
||||
<div
|
||||
(click)="toggleRead(notification, $event)"
|
||||
[matTooltip]="
|
||||
(notification.read ? 'notifications.mark-unread' : 'notifications.mark-read')
|
||||
| translate
|
||||
"
|
||||
[matTooltip]="(notification.read ? 'notifications.mark-unread' : 'notifications.mark-read') | translate"
|
||||
class="dot"
|
||||
matTooltipPosition="before"
|
||||
></div>
|
||||
|
||||
@ -2,20 +2,8 @@
|
||||
<div *ngIf="title" [attr.aria-label]="title" [class]="options.titleClass">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div
|
||||
*ngIf="message && options.enableHtml"
|
||||
[class]="options.messageClass"
|
||||
[innerHTML]="message"
|
||||
aria-live="polite"
|
||||
role="alert"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="message && !options.enableHtml"
|
||||
[attr.aria-label]="message"
|
||||
[class]="options.messageClass"
|
||||
aria-live="polite"
|
||||
role="alert"
|
||||
>
|
||||
<div *ngIf="message && options.enableHtml" [class]="options.messageClass" [innerHTML]="message" aria-live="polite" role="alert"></div>
|
||||
<div *ngIf="message && !options.enableHtml" [attr.aria-label]="message" [class]="options.messageClass" aria-live="polite" role="alert">
|
||||
{{ message }}
|
||||
</div>
|
||||
|
||||
|
||||
@ -7,10 +7,7 @@ import { Toast, ToastPackage, ToastrService } from 'ngx-toastr';
|
||||
styleUrls: ['./toast.component.scss']
|
||||
})
|
||||
export class ToastComponent extends Toast {
|
||||
constructor(
|
||||
protected readonly _toastrService: ToastrService,
|
||||
readonly toastPackage: ToastPackage
|
||||
) {
|
||||
constructor(protected readonly _toastrService: ToastrService, readonly toastPackage: ToastPackage) {
|
||||
super(_toastrService, toastPackage);
|
||||
}
|
||||
|
||||
|
||||
@ -23,15 +23,10 @@
|
||||
<input formControlName="lastName" name="lastName" type="text" />
|
||||
</div>
|
||||
<div class="red-input-group">
|
||||
<label
|
||||
translate="top-bar.navigation-items.my-account.children.language.label"
|
||||
></label>
|
||||
<label translate="top-bar.navigation-items.my-account.children.language.label"></label>
|
||||
<mat-select formControlName="language">
|
||||
<mat-option *ngFor="let language of languages" [value]="language">
|
||||
{{
|
||||
'top-bar.navigation-items.my-account.children.language.' +
|
||||
language | translate
|
||||
}}
|
||||
{{ 'top-bar.navigation-items.my-account.children.language.' + language | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</div>
|
||||
@ -47,15 +42,11 @@
|
||||
>
|
||||
{{ 'user-profile.actions.save' | translate }}
|
||||
</button>
|
||||
<a [href]="changePasswordUrl" target="_blank">
|
||||
{{ 'user-profile.actions.change-password' | translate }}</a
|
||||
>
|
||||
<a [href]="changePasswordUrl" target="_blank"> {{ 'user-profile.actions.change-password' | translate }}</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<redaction-full-page-loading-indicator
|
||||
[displayed]="!viewReady"
|
||||
></redaction-full-page-loading-indicator>
|
||||
<redaction-full-page-loading-indicator [displayed]="!viewReady"></redaction-full-page-loading-indicator>
|
||||
|
||||
@ -7,10 +7,7 @@ import { LoadingService } from '@services/loading.service';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CompositeRouteGuard implements CanActivate {
|
||||
constructor(
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _loadingService: LoadingService
|
||||
) {}
|
||||
constructor(protected readonly _injector: Injector, private readonly _loadingService: LoadingService) {}
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
|
||||
this._loadingService.start();
|
||||
@ -24,10 +21,7 @@ export class CompositeRouteGuard implements CanActivate {
|
||||
if (canActivateResult instanceof Promise) {
|
||||
canActivateResult = from(canActivateResult);
|
||||
}
|
||||
if (
|
||||
typeof canActivateResult === 'boolean' ||
|
||||
canActivateResult instanceof UrlTree
|
||||
) {
|
||||
if (typeof canActivateResult === 'boolean' || canActivateResult instanceof UrlTree) {
|
||||
canActivateResult = of(canActivateResult);
|
||||
}
|
||||
|
||||
|
||||
@ -31,11 +31,7 @@ export class AnnotationPermissions {
|
||||
);
|
||||
}
|
||||
|
||||
static forUser(
|
||||
isApprover: boolean,
|
||||
user: UserWrapper,
|
||||
annotations: AnnotationWrapper | AnnotationWrapper[]
|
||||
) {
|
||||
static forUser(isApprover: boolean, user: UserWrapper, annotations: AnnotationWrapper | AnnotationWrapper[]) {
|
||||
if (!isArray(annotations)) {
|
||||
annotations = [annotations];
|
||||
}
|
||||
@ -44,38 +40,26 @@ export class AnnotationPermissions {
|
||||
|
||||
for (const annotation of annotations) {
|
||||
const permissions: AnnotationPermissions = new AnnotationPermissions();
|
||||
permissions.canUndo =
|
||||
(!isApprover && annotation.isSuggestion) ||
|
||||
(isApprover && annotation.isUndoableActionForApprover);
|
||||
permissions.canUndo = (!isApprover && annotation.isSuggestion) || (isApprover && annotation.isUndoableActionForApprover);
|
||||
|
||||
permissions.canForceRedaction = annotation.isSkipped && !permissions.canUndo;
|
||||
|
||||
permissions.canAcceptRecommendation = annotation.isRecommendation;
|
||||
|
||||
permissions.canMarkAsFalsePositive =
|
||||
annotation.canBeMarkedAsFalsePositive && !annotation.force;
|
||||
permissions.canMarkTextOnlyAsFalsePositive =
|
||||
annotation.canBeMarkedAsFalsePositiveWithTextOnly && !annotation.force;
|
||||
permissions.canMarkAsFalsePositive = annotation.canBeMarkedAsFalsePositive && !annotation.force;
|
||||
permissions.canMarkTextOnlyAsFalsePositive = annotation.canBeMarkedAsFalsePositiveWithTextOnly && !annotation.force;
|
||||
|
||||
permissions.canRemoveOrSuggestToRemoveOnlyHere =
|
||||
annotation.isRedacted && !annotation.force;
|
||||
permissions.canRemoveOrSuggestToRemoveOnlyHere = annotation.isRedacted && !annotation.force;
|
||||
permissions.canRemoveOrSuggestToRemoveFromDictionary =
|
||||
annotation.isRedacted &&
|
||||
!annotation.isManualRedaction &&
|
||||
annotation.isModifyDictionary &&
|
||||
!annotation.force;
|
||||
annotation.isRedacted && !annotation.isManualRedaction && annotation.isModifyDictionary && !annotation.force;
|
||||
|
||||
permissions.canAcceptSuggestion =
|
||||
isApprover && (annotation.isSuggestion || annotation.isDeclinedSuggestion);
|
||||
permissions.canAcceptSuggestion = isApprover && (annotation.isSuggestion || annotation.isDeclinedSuggestion);
|
||||
permissions.canRejectSuggestion =
|
||||
isApprover &&
|
||||
(annotation.isSuggestion ||
|
||||
(annotation.isReadyForAnalysis &&
|
||||
!permissions.canUndo &&
|
||||
annotation.superType !== 'pending-analysis'));
|
||||
(annotation.isReadyForAnalysis && !permissions.canUndo && annotation.superType !== 'pending-analysis'));
|
||||
|
||||
permissions.canChangeLegalBasis =
|
||||
!annotation.isManualRedaction && annotation.isRedacted;
|
||||
permissions.canChangeLegalBasis = !annotation.isManualRedaction && annotation.isRedacted;
|
||||
|
||||
permissions.canRecategorizeImage = annotation.isImage;
|
||||
|
||||
|
||||
@ -77,19 +77,13 @@ export class FileDataModel {
|
||||
|
||||
const reasonAnnotationIds = [];
|
||||
this.redactionLog.redactionLogEntry?.forEach(redactionLogEntry => {
|
||||
if (
|
||||
redactionLogEntry.manual &&
|
||||
(redactionLogEntry.status === 'APPROVED' ||
|
||||
redactionLogEntry.status === 'REQUESTED')
|
||||
) {
|
||||
if (redactionLogEntry.manual && (redactionLogEntry.status === 'APPROVED' || redactionLogEntry.status === 'REQUESTED')) {
|
||||
// for dictionary entries -> I.E accepted recommendations or false positives,
|
||||
// check reason
|
||||
reasonAnnotationIds.push(redactionLogEntry.reason);
|
||||
}
|
||||
|
||||
const existingChangeLogEntry = this.redactionChangeLog?.redactionLogEntry?.find(
|
||||
rle => rle.id === redactionLogEntry.id
|
||||
);
|
||||
const existingChangeLogEntry = this.redactionChangeLog?.redactionLogEntry?.find(rle => rle.id === redactionLogEntry.id);
|
||||
|
||||
// copy the redactionLog Entry
|
||||
const redactionLogEntryWrapper: RedactionLogEntryWrapper = {};
|
||||
|
||||
@ -14,9 +14,7 @@ export class FileStatusWrapper {
|
||||
this.searchField = fileStatus.filename;
|
||||
|
||||
if (fileAttributesConfig) {
|
||||
const primary = fileAttributesConfig.fileAttributeConfigs?.find(
|
||||
c => c.primaryAttribute
|
||||
);
|
||||
const primary = fileAttributesConfig.fileAttributeConfigs?.find(c => c.primaryAttribute);
|
||||
if (primary && fileStatus.fileAttributes?.attributeIdToValue) {
|
||||
this.primaryAttribute = fileStatus.fileAttributes?.attributeIdToValue[primary.id];
|
||||
this.searchField += ' ' + this.primaryAttribute;
|
||||
@ -120,9 +118,7 @@ export class FileStatusWrapper {
|
||||
}
|
||||
|
||||
get status() {
|
||||
return this.fileStatus.status === 'REPROCESS' || this.fileStatus.status === 'FULLREPROCESS'
|
||||
? 'PROCESSING'
|
||||
: this.fileStatus.status;
|
||||
return this.fileStatus.status === 'REPROCESS' || this.fileStatus.status === 'FULLREPROCESS' ? 'PROCESSING' : this.fileStatus.status;
|
||||
}
|
||||
|
||||
get numberOfPages() {
|
||||
|
||||
@ -5,16 +5,9 @@ export class ManualAnnotationResponse {
|
||||
annotationId;
|
||||
commentId;
|
||||
|
||||
constructor(
|
||||
public manualRedactionEntryWrapper: ManualRedactionEntryWrapper,
|
||||
public manualAddResponse: ManualAddResponse
|
||||
) {
|
||||
this.annotationId = manualAddResponse?.annotationId
|
||||
? manualAddResponse.annotationId
|
||||
: new Date().getTime();
|
||||
this.commentId = manualAddResponse?.commentId
|
||||
? manualAddResponse.commentId
|
||||
: new Date().getTime();
|
||||
constructor(public manualRedactionEntryWrapper: ManualRedactionEntryWrapper, public manualAddResponse: ManualAddResponse) {
|
||||
this.annotationId = manualAddResponse?.annotationId ? manualAddResponse.annotationId : new Date().getTime();
|
||||
this.commentId = manualAddResponse?.commentId ? manualAddResponse.commentId : new Date().getTime();
|
||||
}
|
||||
|
||||
get dictionary() {
|
||||
|
||||
@ -10,9 +10,7 @@
|
||||
<mat-icon svgIcon="red:arrow-right"></mat-icon>
|
||||
<a
|
||||
[class.active]="!appStateService.activeDictionaryType"
|
||||
[routerLink]="
|
||||
'/main/admin/dossier-templates/' + appStateService.activeDossierTemplateId
|
||||
"
|
||||
[routerLink]="'/main/admin/dossier-templates/' + appStateService.activeDossierTemplateId"
|
||||
class="breadcrumb ml-0"
|
||||
>
|
||||
{{ appStateService.activeDossierTemplate.name }}
|
||||
|
||||
@ -12,13 +12,7 @@ import {
|
||||
|
||||
import { curveLinear } from 'd3-shape';
|
||||
import { scaleBand, scaleLinear, scalePoint, scaleTime } from 'd3-scale';
|
||||
import {
|
||||
BaseChartComponent,
|
||||
calculateViewDimensions,
|
||||
ColorHelper,
|
||||
LineSeriesComponent,
|
||||
ViewDimensions
|
||||
} from '@swimlane/ngx-charts';
|
||||
import { BaseChartComponent, calculateViewDimensions, ColorHelper, LineSeriesComponent, ViewDimensions } from '@swimlane/ngx-charts';
|
||||
|
||||
@Component({
|
||||
// eslint-disable-next-line @angular-eslint/component-selector
|
||||
@ -277,9 +271,7 @@ export class ComboChartComponent extends BaseChartComponent {
|
||||
if (this.bandwidth === undefined) {
|
||||
this.bandwidth = width - this.barPadding;
|
||||
}
|
||||
const offset = Math.floor(
|
||||
(width + this.barPadding - (this.bandwidth + this.barPadding) * domain.length) / 2
|
||||
);
|
||||
const offset = Math.floor((width + this.barPadding - (this.bandwidth + this.barPadding) * domain.length) / 2);
|
||||
|
||||
if (this.scaleType === 'time') {
|
||||
scale = scaleTime().range([0, width]).domain(domain);
|
||||
@ -344,12 +336,7 @@ export class ComboChartComponent extends BaseChartComponent {
|
||||
domain = this.yDomain;
|
||||
}
|
||||
this.colors = new ColorHelper(this.scheme, this.schemeType, domain, this.customColors);
|
||||
this.colorsLine = new ColorHelper(
|
||||
this.colorSchemeLine,
|
||||
this.schemeType,
|
||||
domain,
|
||||
this.customColors
|
||||
);
|
||||
this.colorsLine = new ColorHelper(this.colorSchemeLine, this.schemeType, domain, this.customColors);
|
||||
}
|
||||
|
||||
getLegendOptions() {
|
||||
@ -387,9 +374,7 @@ export class ComboChartComponent extends BaseChartComponent {
|
||||
}
|
||||
|
||||
onActivate(item) {
|
||||
const idx = this.activeEntries.findIndex(
|
||||
d => d.name === item.name && d.value === item.value && d.series === item.series
|
||||
);
|
||||
const idx = this.activeEntries.findIndex(d => d.name === item.name && d.value === item.value && d.series === item.series);
|
||||
if (idx > -1) {
|
||||
return;
|
||||
}
|
||||
@ -399,9 +384,7 @@ export class ComboChartComponent extends BaseChartComponent {
|
||||
}
|
||||
|
||||
onDeactivate(item) {
|
||||
const idx = this.activeEntries.findIndex(
|
||||
d => d.name === item.name && d.value === item.value && d.series === item.series
|
||||
);
|
||||
const idx = this.activeEntries.findIndex(d => d.name === item.name && d.value === item.value && d.series === item.series);
|
||||
|
||||
this.activeEntries.splice(idx, 1);
|
||||
this.activeEntries = [...this.activeEntries];
|
||||
|
||||
@ -1,11 +1,4 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core';
|
||||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
import { formatLabel } from '@swimlane/ngx-charts';
|
||||
|
||||
@ -158,10 +151,7 @@ export class ComboSeriesVerticalComponent implements OnChanges {
|
||||
bar.gradientStops = this.colors.getLinearGradientStops(value);
|
||||
} else {
|
||||
bar.color = this.colors.getColor(bar.offset1);
|
||||
bar.gradientStops = this.colors.getLinearGradientStops(
|
||||
bar.offset1,
|
||||
bar.offset0
|
||||
);
|
||||
bar.gradientStops = this.colors.getLinearGradientStops(bar.offset1, bar.offset0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,9 +179,7 @@ export class ComboSeriesVerticalComponent implements OnChanges {
|
||||
|
||||
isActive(entry): boolean {
|
||||
if (!this.activeEntries) return false;
|
||||
const item = this.activeEntries.find(
|
||||
d => entry.name === d.name && entry.series === d.series
|
||||
);
|
||||
const item = this.activeEntries.find(d => entry.name === d.name && entry.series === d.series);
|
||||
return item !== undefined;
|
||||
}
|
||||
|
||||
|
||||
@ -58,9 +58,7 @@
|
||||
<textarea
|
||||
formControlName="description"
|
||||
name="description"
|
||||
placeholder="{{
|
||||
'add-edit-dictionary.form.description-placeholder' | translate
|
||||
}}"
|
||||
placeholder="{{ 'add-edit-dictionary.form.description-placeholder' | translate }}"
|
||||
redactionHasScrollbar
|
||||
rows="4"
|
||||
type="text"
|
||||
@ -85,31 +83,18 @@
|
||||
</div>
|
||||
|
||||
<div class="red-input-group">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
formControlName="addToDictionaryAction"
|
||||
name="addToDictionaryAction"
|
||||
>
|
||||
<mat-checkbox color="primary" formControlName="addToDictionaryAction" name="addToDictionaryAction">
|
||||
{{ 'add-edit-dictionary.form.add-to-dictionary-action' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="dictionaryForm.invalid || !changed"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="dictionaryForm.invalid || !changed" color="primary" mat-flat-button type="submit">
|
||||
{{ 'add-edit-dictionary.save' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
<section class="dialog">
|
||||
<div class="dialog-header heading-l">
|
||||
{{
|
||||
(dossierTemplate
|
||||
? 'add-edit-dossier-template.title.edit'
|
||||
: 'add-edit-dossier-template.title.new'
|
||||
) | translate: { name: dossierTemplate?.name }
|
||||
(dossierTemplate ? 'add-edit-dossier-template.title.edit' : 'add-edit-dossier-template.title.new')
|
||||
| translate: { name: dossierTemplate?.name }
|
||||
}}
|
||||
</div>
|
||||
|
||||
@ -15,9 +13,7 @@
|
||||
<input
|
||||
formControlName="name"
|
||||
name="name"
|
||||
placeholder="{{
|
||||
'add-edit-dossier-template.form.name-placeholder' | translate
|
||||
}}"
|
||||
placeholder="{{ 'add-edit-dossier-template.form.name-placeholder' | translate }}"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
@ -27,9 +23,7 @@
|
||||
<textarea
|
||||
formControlName="description"
|
||||
name="description"
|
||||
placeholder="{{
|
||||
'add-edit-dossier-template.form.description-placeholder' | translate
|
||||
}}"
|
||||
placeholder="{{ 'add-edit-dossier-template.form.description-placeholder' | translate }}"
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
@ -46,12 +40,7 @@
|
||||
{{ 'add-edit-dossier-template.form.valid-from' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-checkbox
|
||||
(change)="hasValidTo = !hasValidTo"
|
||||
[checked]="hasValidTo"
|
||||
class="filter-menu-checkbox"
|
||||
color="primary"
|
||||
>
|
||||
<mat-checkbox (change)="hasValidTo = !hasValidTo" [checked]="hasValidTo" class="filter-menu-checkbox" color="primary">
|
||||
{{ 'add-edit-dossier-template.form.valid-to' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
@ -59,11 +48,7 @@
|
||||
<div>
|
||||
<div class="red-input-group datepicker-wrapper">
|
||||
<ng-container *ngIf="hasValidFrom">
|
||||
<input
|
||||
[matDatepicker]="fromPicker"
|
||||
formControlName="validFrom"
|
||||
placeholder="dd/mm/yy"
|
||||
/>
|
||||
<input [matDatepicker]="fromPicker" formControlName="validFrom" placeholder="dd/mm/yy" />
|
||||
<mat-datepicker-toggle [for]="fromPicker" matSuffix>
|
||||
<mat-icon matDatepickerToggleIcon svgIcon="red:calendar"></mat-icon>
|
||||
</mat-datepicker-toggle>
|
||||
@ -73,11 +58,7 @@
|
||||
|
||||
<div class="red-input-group datepicker-wrapper">
|
||||
<ng-container *ngIf="hasValidTo">
|
||||
<input
|
||||
[matDatepicker]="toPicker"
|
||||
formControlName="validTo"
|
||||
placeholder="dd/mm/yy"
|
||||
/>
|
||||
<input [matDatepicker]="toPicker" formControlName="validTo" placeholder="dd/mm/yy" />
|
||||
<mat-datepicker-toggle [for]="toPicker" matSuffix>
|
||||
<mat-icon matDatepickerToggleIcon svgIcon="red:calendar"></mat-icon>
|
||||
</mat-datepicker-toggle>
|
||||
@ -94,8 +75,7 @@
|
||||
'report-type.label'
|
||||
| translate
|
||||
: {
|
||||
length: this.dossierTemplateForm.controls['reportTypes'].value
|
||||
.length
|
||||
length: this.dossierTemplateForm.controls['reportTypes'].value.length
|
||||
}
|
||||
"
|
||||
[options]="reportTypesEnum"
|
||||
@ -108,8 +88,7 @@
|
||||
'download-type.label'
|
||||
| translate
|
||||
: {
|
||||
length: this.dossierTemplateForm.controls['downloadFileTypes']
|
||||
.value.length
|
||||
length: this.dossierTemplateForm.controls['downloadFileTypes'].value.length
|
||||
}
|
||||
"
|
||||
[options]="downloadTypesEnum"
|
||||
@ -120,20 +99,11 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="dossierTemplateForm.invalid || !changed"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="dossierTemplateForm.invalid || !changed" color="primary" mat-flat-button type="submit">
|
||||
{{ 'add-edit-dossier-template.save' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -40,19 +40,11 @@ export class AddEditDossierTemplateDialogComponent {
|
||||
this.dossierTemplate?.validTo ? moment(this.dossierTemplate?.validTo) : null,
|
||||
this._requiredIfValidator(() => this.hasValidTo)
|
||||
],
|
||||
downloadFileTypes: [
|
||||
this.dossierTemplate
|
||||
? this.dossierTemplate.downloadFileTypes
|
||||
: ['PREVIEW', 'REDACTED']
|
||||
],
|
||||
downloadFileTypes: [this.dossierTemplate ? this.dossierTemplate.downloadFileTypes : ['PREVIEW', 'REDACTED']],
|
||||
reportTypes: [
|
||||
this.dossierTemplate
|
||||
? this.dossierTemplate.reportTypes
|
||||
: [
|
||||
'WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE',
|
||||
'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE',
|
||||
'EXCEL_MULTI_FILE'
|
||||
],
|
||||
: ['WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE', 'WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE', 'EXCEL_MULTI_FILE'],
|
||||
Validators.required
|
||||
]
|
||||
});
|
||||
@ -77,9 +69,7 @@ export class AddEditDossierTemplateDialogComponent {
|
||||
}
|
||||
if (
|
||||
this.hasValidFrom &&
|
||||
!moment(this.dossierTemplate.validFrom).isSame(
|
||||
moment(this.dossierTemplateForm.get('validFrom').value)
|
||||
)
|
||||
!moment(this.dossierTemplate.validFrom).isSame(moment(this.dossierTemplateForm.get('validFrom').value))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -89,9 +79,7 @@ export class AddEditDossierTemplateDialogComponent {
|
||||
}
|
||||
if (
|
||||
this.hasValidTo &&
|
||||
!moment(this.dossierTemplate.validTo).isSame(
|
||||
moment(this.dossierTemplateForm.get('validTo').value)
|
||||
)
|
||||
!moment(this.dossierTemplate.validTo).isSame(moment(this.dossierTemplateForm.get('validTo').value))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -110,9 +98,7 @@ export class AddEditDossierTemplateDialogComponent {
|
||||
validFrom: this.hasValidFrom ? this.dossierTemplateForm.get('validFrom').value : null,
|
||||
validTo: this.hasValidTo ? this.dossierTemplateForm.get('validTo').value : null
|
||||
};
|
||||
await this._dossierTemplateController
|
||||
.createOrUpdateDossierTemplate(dossierTemplate)
|
||||
.toPromise();
|
||||
await this._dossierTemplateController.createOrUpdateDossierTemplate(dossierTemplate).toPromise();
|
||||
await this._appStateService.loadAllDossierTemplates();
|
||||
await this._appStateService.loadDictionaryData();
|
||||
this.dialogRef.close(dossierTemplate);
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
<section class="dialog">
|
||||
<div class="dialog-header heading-l">
|
||||
{{
|
||||
(fileAttribute
|
||||
? 'add-edit-file-attribute.title.edit'
|
||||
: 'add-edit-file-attribute.title.new'
|
||||
) | translate: { name: fileAttribute?.label }
|
||||
(fileAttribute ? 'add-edit-file-attribute.title.edit' : 'add-edit-file-attribute.title.new')
|
||||
| translate: { name: fileAttribute?.label }
|
||||
}}
|
||||
</div>
|
||||
|
||||
@ -25,9 +23,7 @@
|
||||
<input
|
||||
formControlName="csvColumnHeader"
|
||||
name="csvColumnHeader"
|
||||
placeholder="{{
|
||||
'add-edit-file-attribute.form.column-header-placeholder' | translate
|
||||
}}"
|
||||
placeholder="{{ 'add-edit-file-attribute.form.column-header-placeholder' | translate }}"
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
@ -49,31 +45,18 @@
|
||||
</div>
|
||||
|
||||
<div class="red-input-group mt-0">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
formControlName="primaryAttribute"
|
||||
name="primaryAttribute"
|
||||
>
|
||||
<mat-checkbox color="primary" formControlName="primaryAttribute" name="primaryAttribute">
|
||||
{{ 'add-edit-file-attribute.form.primary' | translate }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="fileAttributeForm.invalid || !changed"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="fileAttributeForm.invalid || !changed" color="primary" mat-flat-button type="submit">
|
||||
{{ 'add-edit-file-attribute.save' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -13,11 +13,7 @@ export class AddEditFileAttributeDialogComponent {
|
||||
fileAttributeForm: FormGroup;
|
||||
fileAttribute: FileAttributeConfig;
|
||||
dossierTemplateId: string;
|
||||
readonly typeOptions = [
|
||||
FileAttributeConfig.TypeEnum.TEXT,
|
||||
FileAttributeConfig.TypeEnum.NUMBER,
|
||||
FileAttributeConfig.TypeEnum.DATE
|
||||
];
|
||||
readonly typeOptions = [FileAttributeConfig.TypeEnum.TEXT, FileAttributeConfig.TypeEnum.NUMBER, FileAttributeConfig.TypeEnum.DATE];
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
@ -32,10 +28,7 @@ export class AddEditFileAttributeDialogComponent {
|
||||
this.fileAttributeForm = this._formBuilder.group({
|
||||
label: [this.fileAttribute?.label, Validators.required],
|
||||
csvColumnHeader: [this.fileAttribute?.csvColumnHeader, Validators.required],
|
||||
type: [
|
||||
this.fileAttribute?.type || FileAttributeConfig.TypeEnum.TEXT,
|
||||
Validators.required
|
||||
],
|
||||
type: [this.fileAttribute?.type || FileAttributeConfig.TypeEnum.TEXT, Validators.required],
|
||||
readonly: [this.fileAttribute ? !this.fileAttribute.editable : false],
|
||||
primaryAttribute: [this.fileAttribute?.primaryAttribute]
|
||||
});
|
||||
|
||||
@ -13,9 +13,5 @@
|
||||
[user]="user"
|
||||
></redaction-reset-password>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -10,10 +10,7 @@ import { User } from '@redaction/red-ui-http';
|
||||
export class AddEditUserDialogComponent {
|
||||
resettingPassword = false;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<AddEditUserDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public user: User
|
||||
) {}
|
||||
constructor(public dialogRef: MatDialogRef<AddEditUserDialogComponent>, @Inject(MAT_DIALOG_DATA) public user: User) {}
|
||||
|
||||
toggleResetPassword() {
|
||||
this.resettingPassword = !this.resettingPassword;
|
||||
|
||||
@ -1,8 +1,4 @@
|
||||
<div
|
||||
[translateParams]="{ userName: userName }"
|
||||
[translate]="'reset-password-dialog.header'"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
<div [translateParams]="{ userName: userName }" [translate]="'reset-password-dialog.header'" class="dialog-header heading-l"></div>
|
||||
|
||||
<form (submit)="save()" [formGroup]="passwordForm">
|
||||
<div class="dialog-content">
|
||||
@ -17,10 +13,6 @@
|
||||
{{ 'reset-password-dialog.actions.save' | translate }}
|
||||
</button>
|
||||
|
||||
<div
|
||||
(click)="toggleResetPassword.emit()"
|
||||
class="all-caps-label cancel"
|
||||
translate="reset-password-dialog.actions.cancel"
|
||||
></div>
|
||||
<div (click)="toggleResetPassword.emit()" class="all-caps-label cancel" translate="reset-password-dialog.actions.cancel"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
<section class="dialog">
|
||||
<div class="dialog-header heading-l">
|
||||
{{
|
||||
'confirm-delete-file-attribute.title.' + type
|
||||
| translate: { name: fileAttribute?.label }
|
||||
}}
|
||||
{{ 'confirm-delete-file-attribute.title.' + type | translate: { name: fileAttribute?.label } }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="showToast" class="inline-dialog-toast toast-error">
|
||||
@ -30,15 +27,7 @@
|
||||
<button (click)="deleteFileAttribute()" color="primary" mat-flat-button>
|
||||
{{ 'confirm-delete-file-attribute.delete.' + type | translate }}
|
||||
</button>
|
||||
<div
|
||||
(click)="cancel()"
|
||||
[translate]="'confirm-delete-file-attribute.cancel.' + type"
|
||||
class="all-caps-label cancel"
|
||||
></div>
|
||||
<div (click)="cancel()" [translate]="'confirm-delete-file-attribute.cancel.' + type" class="all-caps-label cancel"></div>
|
||||
</div>
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -17,10 +17,7 @@
|
||||
[class.error]="!checkbox.value && showToast"
|
||||
color="primary"
|
||||
>
|
||||
{{
|
||||
'confirm-delete-users.' + checkbox.label
|
||||
| translate: { dossiersCount: dossiersCount }
|
||||
}}
|
||||
{{ 'confirm-delete-users.' + checkbox.label | translate: { dossiersCount: dossiersCount } }}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
||||
@ -28,15 +25,7 @@
|
||||
<button (click)="deleteUser()" color="primary" mat-flat-button>
|
||||
{{ 'confirm-delete-users.delete.' + type | translate }}
|
||||
</button>
|
||||
<div
|
||||
(click)="cancel()"
|
||||
[translate]="'confirm-delete-users.cancel.' + type"
|
||||
class="all-caps-label cancel"
|
||||
></div>
|
||||
<div (click)="cancel()" [translate]="'confirm-delete-users.cancel.' + type" class="all-caps-label cancel"></div>
|
||||
</div>
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
<section class="dialog">
|
||||
<div
|
||||
[translate]="'default-colors-screen.types.' + this.colorKey"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
<div [translate]="'default-colors-screen.types.' + this.colorKey" class="dialog-header heading-l"></div>
|
||||
|
||||
<form (submit)="saveColors()" [formGroup]="colorForm">
|
||||
<div class="dialog-content">
|
||||
@ -23,10 +20,7 @@
|
||||
class="input-icon"
|
||||
>
|
||||
<mat-icon
|
||||
*ngIf="
|
||||
!colorForm.get('color').value ||
|
||||
colorForm.get('color').value?.length === 0
|
||||
"
|
||||
*ngIf="!colorForm.get('color').value || colorForm.get('color').value?.length === 0"
|
||||
svgIcon="red:color-picker"
|
||||
></mat-icon>
|
||||
</div>
|
||||
@ -34,20 +28,11 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="colorForm.invalid || !changed"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="colorForm.invalid || !changed" color="primary" mat-flat-button type="submit">
|
||||
{{ 'edit-color-dialog.save' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -47,15 +47,11 @@ export class EditColorDialogComponent {
|
||||
};
|
||||
|
||||
try {
|
||||
await this._dictionaryControllerService
|
||||
.setColors(colors, this._dossierTemplateId)
|
||||
.toPromise();
|
||||
await this._dictionaryControllerService.setColors(colors, this._dossierTemplateId).toPromise();
|
||||
this._dialogRef.close(true);
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant('edit-color-dialog.success', {
|
||||
color: this._translateService.instant(
|
||||
'default-colors-screen.types.' + this.colorKey
|
||||
)
|
||||
color: this._translateService.instant('default-colors-screen.types.' + this.colorKey)
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
|
||||
@ -23,17 +23,9 @@
|
||||
<button [disabled]="authForm.invalid" color="primary" mat-flat-button type="submit">
|
||||
{{ 'smtp-auth-config.actions.save' | translate }}
|
||||
</button>
|
||||
<div
|
||||
class="all-caps-label cancel"
|
||||
mat-dialog-close
|
||||
translate="smtp-auth-config.actions.cancel"
|
||||
></div>
|
||||
<div class="all-caps-label cancel" mat-dialog-close translate="smtp-auth-config.actions.cancel"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -61,16 +61,7 @@ export class AuditScreenComponent {
|
||||
}
|
||||
|
||||
private _updateDateFilters(value): boolean {
|
||||
if (
|
||||
applyIntervalConstraints(
|
||||
value,
|
||||
this._previousFrom,
|
||||
this._previousTo,
|
||||
this.filterForm,
|
||||
'from',
|
||||
'to'
|
||||
)
|
||||
) {
|
||||
if (applyIntervalConstraints(value, this._previousFrom, this._previousTo, this.filterForm, 'from', 'to')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -36,14 +36,7 @@
|
||||
tooltipPosition="below"
|
||||
></redaction-circle-button>
|
||||
|
||||
<input
|
||||
#fileInput
|
||||
(change)="upload($event)"
|
||||
accept="text/plain"
|
||||
class="file-upload-input"
|
||||
hidden
|
||||
type="file"
|
||||
/>
|
||||
<input #fileInput (change)="upload($event)" accept="text/plain" class="file-upload-input" hidden type="file" />
|
||||
|
||||
<redaction-circle-button
|
||||
[routerLink]="['..']"
|
||||
@ -98,16 +91,11 @@
|
||||
</div>
|
||||
|
||||
<div *ngIf="!!dictionary.description" class="pb-32 mt-20">
|
||||
<div
|
||||
class="heading"
|
||||
translate="dictionary-overview.dictionary-details.description"
|
||||
></div>
|
||||
<div class="heading" translate="dictionary-overview.dictionary-details.description"></div>
|
||||
<div class="mt-8">{{ dictionary.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<redaction-full-page-loading-indicator
|
||||
[displayed]="processing"
|
||||
></redaction-full-page-loading-indicator>
|
||||
<redaction-full-page-loading-indicator [displayed]="processing"></redaction-full-page-loading-indicator>
|
||||
|
||||
@ -29,10 +29,7 @@ export class DigitalSignatureScreenComponent {
|
||||
}
|
||||
|
||||
get hasDigitalSignatureSet() {
|
||||
return (
|
||||
this.digitalSignatureExists ||
|
||||
!!this.digitalSignatureForm.get('base64EncodedPrivateKey').value
|
||||
);
|
||||
return this.digitalSignatureExists || !!this.digitalSignatureForm.get('base64EncodedPrivateKey').value;
|
||||
}
|
||||
|
||||
saveDigitalSignature() {
|
||||
@ -58,17 +55,13 @@ export class DigitalSignatureScreenComponent {
|
||||
error => {
|
||||
if (error.status === 400) {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant(
|
||||
'digital-signature-screen.action.certificate-not-valid-error'
|
||||
),
|
||||
this._translateService.instant('digital-signature-screen.action.certificate-not-valid-error'),
|
||||
null,
|
||||
NotificationType.ERROR
|
||||
);
|
||||
} else {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant(
|
||||
'digital-signature-screen.action.save-error'
|
||||
),
|
||||
this._translateService.instant('digital-signature-screen.action.save-error'),
|
||||
null,
|
||||
NotificationType.ERROR
|
||||
);
|
||||
@ -82,9 +75,7 @@ export class DigitalSignatureScreenComponent {
|
||||
() => {
|
||||
this.loadDigitalSignatureAndInitializeForm();
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant(
|
||||
'digital-signature-screen.action.delete-success'
|
||||
),
|
||||
this._translateService.instant('digital-signature-screen.action.delete-success'),
|
||||
null,
|
||||
NotificationType.SUCCESS
|
||||
);
|
||||
@ -139,9 +130,7 @@ export class DigitalSignatureScreenComponent {
|
||||
certificateName: [this.digitalSignature.certificateName, Validators.required],
|
||||
contactInfo: this.digitalSignature.contactInfo,
|
||||
location: this.digitalSignature.location,
|
||||
keySecret: this.digitalSignatureExists
|
||||
? null
|
||||
: [this.digitalSignature.password, Validators.required],
|
||||
keySecret: this.digitalSignatureExists ? null : [this.digitalSignature.password, Validators.required],
|
||||
reason: this.digitalSignature.reason,
|
||||
base64EncodedPrivateKey: this.digitalSignatureExists
|
||||
? null
|
||||
|
||||
@ -8,12 +8,7 @@
|
||||
<div class="breadcrumb" translate="license-information"></div>
|
||||
|
||||
<div class="actions">
|
||||
<button
|
||||
(click)="sendMail()"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
translate="license-info-screen.email-report"
|
||||
></button>
|
||||
<button (click)="sendMail()" color="primary" mat-flat-button translate="license-info-screen.email-report"></button>
|
||||
<redaction-circle-button
|
||||
*ngIf="permissionsService.isUser()"
|
||||
class="ml-6"
|
||||
@ -46,10 +41,7 @@
|
||||
<div class="row">
|
||||
<div translate="license-info-screen.copyright-claim-title"></div>
|
||||
<div>
|
||||
{{
|
||||
'license-info-screen.copyright-claim-text'
|
||||
| translate: { currentYear: currentYear }
|
||||
}}
|
||||
{{ 'license-info-screen.copyright-claim-text' | translate: { currentYear: currentYear } }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -64,10 +56,7 @@
|
||||
<!-- <div>Future feature: we will provide that with the /info endpoint</div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div
|
||||
class="section-title all-caps-label"
|
||||
translate="license-info-screen.licensing-details"
|
||||
></div>
|
||||
<div class="section-title all-caps-label" translate="license-info-screen.licensing-details"></div>
|
||||
|
||||
<div class="row">
|
||||
<div translate="license-info-screen.licensed-to"></div>
|
||||
@ -92,28 +81,18 @@
|
||||
<div>{{ currentInfo.numberOfAnalyzedPages }}</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="section-title all-caps-label"
|
||||
translate="license-info-screen.usage-details"
|
||||
></div>
|
||||
<div class="section-title all-caps-label" translate="license-info-screen.usage-details"></div>
|
||||
|
||||
<div class="row">
|
||||
<div>
|
||||
{{
|
||||
'license-info-screen.total-analyzed'
|
||||
| translate: { date: totalInfo.startDate | date: 'longDate' }
|
||||
}}
|
||||
{{ 'license-info-screen.total-analyzed' | translate: { date: totalInfo.startDate | date: 'longDate' } }}
|
||||
</div>
|
||||
<div>{{ totalInfo.numberOfAnalyzedPages }}</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div translate="license-info-screen.current-analyzed"></div>
|
||||
<div>
|
||||
{{ currentInfo.numberOfAnalyzedPages }} ({{
|
||||
analysisPercentageOfLicense | number: '1.0-2'
|
||||
}}%)
|
||||
</div>
|
||||
<div>{{ currentInfo.numberOfAnalyzedPages }} ({{ analysisPercentageOfLicense | number: '1.0-2' }}%)</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!!unlicensedInfo" class="row">
|
||||
@ -151,6 +130,4 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<redaction-full-page-loading-indicator
|
||||
[displayed]="!viewReady"
|
||||
></redaction-full-page-loading-indicator>
|
||||
<redaction-full-page-loading-indicator [displayed]="!viewReady"></redaction-full-page-loading-indicator>
|
||||
|
||||
@ -63,9 +63,7 @@ export class LicenseInformationScreenComponent implements OnInit {
|
||||
const unlicensedConfig = {
|
||||
startDate: endDate.toDate()
|
||||
};
|
||||
promises.push(
|
||||
this._licenseReportController.licenseReport(unlicensedConfig).toPromise()
|
||||
);
|
||||
promises.push(this._licenseReportController.licenseReport(unlicensedConfig).toPromise());
|
||||
}
|
||||
|
||||
Promise.all(promises).then(reports => {
|
||||
@ -73,8 +71,7 @@ export class LicenseInformationScreenComponent implements OnInit {
|
||||
this.viewReady = true;
|
||||
this.analysisPercentageOfLicense =
|
||||
this.totalLicensedNumberOfPages > 0
|
||||
? (this.currentInfo.numberOfAnalyzedPages / this.totalLicensedNumberOfPages) *
|
||||
100
|
||||
? (this.currentInfo.numberOfAnalyzedPages / this.totalLicensedNumberOfPages) * 100
|
||||
: 100;
|
||||
});
|
||||
}
|
||||
@ -92,9 +89,7 @@ export class LicenseInformationScreenComponent implements OnInit {
|
||||
pages: this.totalLicensedNumberOfPages
|
||||
})
|
||||
].join('%0D%0A');
|
||||
window.location.href = `mailto:${this.appConfigService.getConfig(
|
||||
'LICENSE_EMAIL'
|
||||
)}?subject=${subject}&body=${body}`;
|
||||
window.location.href = `mailto:${this.appConfigService.getConfig('LICENSE_EMAIL')}?subject=${subject}&body=${body}`;
|
||||
}
|
||||
|
||||
private async _setMonthlyStats(startDate: moment.Moment, endDate: moment.Moment) {
|
||||
|
||||
@ -44,9 +44,7 @@ export class RulesScreenComponent extends ComponentHasChanges {
|
||||
private readonly _activatedRoute: ActivatedRoute
|
||||
) {
|
||||
super(_translateService);
|
||||
this._appStateService.activateDossierTemplate(
|
||||
_activatedRoute.snapshot.params.dossierTemplateId
|
||||
);
|
||||
this._appStateService.activateDossierTemplate(_activatedRoute.snapshot.params.dossierTemplateId);
|
||||
this._initialize();
|
||||
}
|
||||
|
||||
@ -78,9 +76,7 @@ export class RulesScreenComponent extends ComponentHasChanges {
|
||||
|
||||
@debounce()
|
||||
codeEditorTextChanged() {
|
||||
const newDecorations = this.currentLines
|
||||
.filter(entry => this._isNew(entry))
|
||||
.map(entry => this._makeDecorationFor(entry));
|
||||
const newDecorations = this.currentLines.filter(entry => this._isNew(entry)).map(entry => this._makeDecorationFor(entry));
|
||||
|
||||
this._decorations = this._codeEditor.deltaDecorations(this._decorations, newDecorations);
|
||||
}
|
||||
@ -153,14 +149,12 @@ export class RulesScreenComponent extends ComponentHasChanges {
|
||||
}
|
||||
|
||||
private _initialize() {
|
||||
this._rulesControllerService
|
||||
.downloadRules(this._appStateService.activeDossierTemplateId)
|
||||
.subscribe(
|
||||
rules => {
|
||||
this.currentLines = this.initialLines = rules.rules.split('\n');
|
||||
this.revert();
|
||||
},
|
||||
() => (this.processing = false)
|
||||
);
|
||||
this._rulesControllerService.downloadRules(this._appStateService.activeDossierTemplateId).subscribe(
|
||||
rules => {
|
||||
this.currentLines = this.initialLines = rules.rules.split('\n');
|
||||
this.revert();
|
||||
},
|
||||
() => (this.processing = false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,51 +79,37 @@ export class SmtpConfigScreenComponent implements OnInit {
|
||||
|
||||
async ngOnInit() {
|
||||
await this._loadData();
|
||||
this.generalSettings = await this._generalSettingsControllerService
|
||||
.getGeneralConfigurations()
|
||||
.toPromise();
|
||||
this.generalSettings = await this._generalSettingsControllerService.getGeneralConfigurations().toPromise();
|
||||
this._initialGeneralSettings = Object.assign({}, this.generalSettings);
|
||||
}
|
||||
|
||||
async save() {
|
||||
this.viewReady = false;
|
||||
await this._smtpConfigService
|
||||
.updateSMTPConfiguration(this.configForm.getRawValue())
|
||||
.toPromise();
|
||||
await this._smtpConfigService.updateSMTPConfiguration(this.configForm.getRawValue()).toPromise();
|
||||
this._initialValue = this.configForm.getRawValue();
|
||||
this.viewReady = true;
|
||||
}
|
||||
|
||||
async saveGeneralConfig() {
|
||||
this.viewReady = false;
|
||||
await this._generalSettingsControllerService
|
||||
.updateGeneralConfigurations(this.generalSettings)
|
||||
.toPromise();
|
||||
await this._generalSettingsControllerService.updateGeneralConfigurations(this.generalSettings).toPromise();
|
||||
this.viewReady = true;
|
||||
}
|
||||
|
||||
openAuthConfigDialog(skipDisableOnCancel?: boolean) {
|
||||
this._dialogService.openDialog(
|
||||
'smtpAuthConfig',
|
||||
null,
|
||||
this.configForm.getRawValue(),
|
||||
null,
|
||||
authConfig => {
|
||||
if (authConfig) {
|
||||
this.configForm.patchValue(authConfig);
|
||||
} else if (!skipDisableOnCancel) {
|
||||
this.configForm.patchValue({ auth: false }, { emitEvent: false });
|
||||
}
|
||||
this._dialogService.openDialog('smtpAuthConfig', null, this.configForm.getRawValue(), null, authConfig => {
|
||||
if (authConfig) {
|
||||
this.configForm.patchValue(authConfig);
|
||||
} else if (!skipDisableOnCancel) {
|
||||
this.configForm.patchValue({ auth: false }, { emitEvent: false });
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async testConnection() {
|
||||
this.viewReady = false;
|
||||
try {
|
||||
await this._smtpConfigService
|
||||
.testSMTPConfiguration(this.configForm.getRawValue())
|
||||
.toPromise();
|
||||
await this._smtpConfigService.testSMTPConfiguration(this.configForm.getRawValue()).toPromise();
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant('smtp-config-screen.test.success'),
|
||||
undefined,
|
||||
@ -142,9 +128,7 @@ export class SmtpConfigScreenComponent implements OnInit {
|
||||
|
||||
private async _loadData() {
|
||||
try {
|
||||
this._initialValue = await this._smtpConfigService
|
||||
.getCurrentSMTPConfiguration()
|
||||
.toPromise();
|
||||
this._initialValue = await this._smtpConfigService.getCurrentSMTPConfiguration().toPromise();
|
||||
this.configForm.patchValue(this._initialValue, { emitEvent: false });
|
||||
} catch (e) {
|
||||
} finally {
|
||||
|
||||
@ -50,24 +50,14 @@ export class AppConfigService {
|
||||
}
|
||||
|
||||
loadAppConfig(): Observable<any> {
|
||||
this._cacheApiService
|
||||
.getCachedValue(AppConfigKey.FRONTEND_APP_VERSION)
|
||||
.then(async lastVersion => {
|
||||
console.log(
|
||||
'[REDACTION] Last app version: ',
|
||||
lastVersion,
|
||||
' current version ',
|
||||
this.version
|
||||
);
|
||||
if (lastVersion !== this.version) {
|
||||
console.log('[REDACTION] Version-missmatch - wiping caches!');
|
||||
await wipeCaches();
|
||||
}
|
||||
await this._cacheApiService.cacheValue(
|
||||
AppConfigKey.FRONTEND_APP_VERSION,
|
||||
this.version
|
||||
);
|
||||
});
|
||||
this._cacheApiService.getCachedValue(AppConfigKey.FRONTEND_APP_VERSION).then(async lastVersion => {
|
||||
console.log('[REDACTION] Last app version: ', lastVersion, ' current version ', this.version);
|
||||
if (lastVersion !== this.version) {
|
||||
console.log('[REDACTION] Version-missmatch - wiping caches!');
|
||||
await wipeCaches();
|
||||
}
|
||||
await this._cacheApiService.cacheValue(AppConfigKey.FRONTEND_APP_VERSION, this.version);
|
||||
});
|
||||
|
||||
return this._httpClient.get<any>('/assets/config/config.json').pipe(
|
||||
tap(config => {
|
||||
|
||||
@ -7,11 +7,7 @@ import { KeycloakAngularModule, KeycloakOptions, KeycloakService } from 'keycloa
|
||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
||||
import { BASE_HREF } from '../../tokens';
|
||||
|
||||
export function keycloakInitializer(
|
||||
keycloak: KeycloakService,
|
||||
appConfigService: AppConfigService,
|
||||
baseUrl
|
||||
) {
|
||||
export function keycloakInitializer(keycloak: KeycloakService, appConfigService: AppConfigService, baseUrl) {
|
||||
return () =>
|
||||
appConfigService
|
||||
.loadAppConfig()
|
||||
@ -30,15 +26,12 @@ export function keycloakInitializer(
|
||||
initOptions: {
|
||||
checkLoginIframe: false,
|
||||
onLoad: 'check-sso',
|
||||
silentCheckSsoRedirectUri:
|
||||
window.location.origin + baseUrl + '/assets/oauth/silent-refresh.html',
|
||||
silentCheckSsoRedirectUri: window.location.origin + baseUrl + '/assets/oauth/silent-refresh.html',
|
||||
flow: 'standard'
|
||||
},
|
||||
enableBearerInterceptor: true
|
||||
};
|
||||
return keycloak
|
||||
.init(options)
|
||||
.then(() => configureAutomaticRedirectToLoginScreen(keycloak));
|
||||
return keycloak.init(options).then(() => configureAutomaticRedirectToLoginScreen(keycloak));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -27,10 +27,7 @@ export class RedRoleGuard implements CanActivate {
|
||||
if (
|
||||
this._userService.user.isUserAdmin &&
|
||||
!this._userService.user.isAdmin &&
|
||||
!(
|
||||
state.url.startsWith('/main/admin/users') ||
|
||||
state.url.startsWith('/main/my-profile')
|
||||
)
|
||||
!(state.url.startsWith('/main/admin/users') || state.url.startsWith('/main/my-profile'))
|
||||
) {
|
||||
this._router.navigate(['/main/admin/users']);
|
||||
obs.next(false);
|
||||
|
||||
@ -42,10 +42,7 @@
|
||||
>
|
||||
</redaction-circle-button>
|
||||
|
||||
<redaction-file-download-btn
|
||||
[dossier]="dossier"
|
||||
[file]="selectedFiles"
|
||||
></redaction-file-download-btn>
|
||||
<redaction-file-download-btn [dossier]="dossier" [file]="selectedFiles"></redaction-file-download-btn>
|
||||
|
||||
<!-- Approved-->
|
||||
<redaction-circle-button
|
||||
|
||||
@ -35,15 +35,13 @@ export class CommentsComponent {
|
||||
addComment(): void {
|
||||
const value = this.commentForm.value.value;
|
||||
if (value) {
|
||||
this._manualAnnotationService
|
||||
.addComment(value, this.annotation.id)
|
||||
.subscribe(commentResponse => {
|
||||
this.annotation.comments.push({
|
||||
text: value,
|
||||
id: commentResponse.commentId,
|
||||
user: this._userService.userId
|
||||
});
|
||||
this._manualAnnotationService.addComment(value, this.annotation.id).subscribe(commentResponse => {
|
||||
this.annotation.comments.push({
|
||||
text: value,
|
||||
id: commentResponse.commentId,
|
||||
user: this._userService.userId
|
||||
});
|
||||
});
|
||||
this.commentForm.reset();
|
||||
}
|
||||
}
|
||||
@ -54,14 +52,12 @@ export class CommentsComponent {
|
||||
}
|
||||
|
||||
deleteComment(comment: Comment): void {
|
||||
this._manualAnnotationService
|
||||
.deleteComment(comment.id, this.annotation.id)
|
||||
.subscribe(() => {
|
||||
this.annotation.comments.splice(this.annotation.comments.indexOf(comment), 1);
|
||||
if (!this.annotation.comments.length) {
|
||||
this._hidden = true;
|
||||
}
|
||||
});
|
||||
this._manualAnnotationService.deleteComment(comment.id, this.annotation.id).subscribe(() => {
|
||||
this.annotation.comments.splice(this.annotation.comments.indexOf(comment), 1);
|
||||
if (!this.annotation.comments.length) {
|
||||
this._hidden = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
isCommentOwner(comment: Comment): boolean {
|
||||
|
||||
@ -26,30 +26,20 @@
|
||||
<div class="section small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:folder"></mat-icon>
|
||||
<span>{{
|
||||
'file-preview.tabs.document-info.details.dossier'
|
||||
| translate: { dossierName: dossier.name }
|
||||
}}</span>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.dossier' | translate: { dossierName: dossier.name } }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:document"></mat-icon>
|
||||
<span>{{
|
||||
'file-preview.tabs.document-info.details.pages'
|
||||
| translate: { pages: file.numberOfPages }
|
||||
}}</span>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.pages' | translate: { pages: file.numberOfPages } }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon svgIcon="red:calendar"></mat-icon>
|
||||
<span>{{
|
||||
'file-preview.tabs.document-info.details.created-on'
|
||||
| translate: { date: file.added | date: 'mediumDate' }
|
||||
}}</span>
|
||||
<span>{{ 'file-preview.tabs.document-info.details.created-on' | translate: { date: file.added | date: 'mediumDate' } }}</span>
|
||||
</div>
|
||||
<div *ngIf="dossier.dossier.dueDate">
|
||||
<mat-icon svgIcon="red:lightning"></mat-icon>
|
||||
<span>{{
|
||||
'file-preview.tabs.document-info.details.due'
|
||||
| translate: { date: dossier.dossier.dueDate | date: 'mediumDate' }
|
||||
'file-preview.tabs.document-info.details.due' | translate: { date: dossier.dossier.dueDate | date: 'mediumDate' }
|
||||
}}</span>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@ -14,10 +14,7 @@ export class DocumentInfoComponent {
|
||||
|
||||
fileAttributesConfig: FileAttributesConfig;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dialogService: DossiersDialogService
|
||||
) {
|
||||
constructor(private readonly _appStateService: AppStateService, private readonly _dialogService: DossiersDialogService) {
|
||||
this.fileAttributesConfig = this._appStateService.activeFileAttributesConfig;
|
||||
}
|
||||
|
||||
|
||||
@ -16,9 +16,5 @@
|
||||
type="dark-bg"
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-file-download-btn
|
||||
[dossier]="dossier"
|
||||
[file]="dossier.files"
|
||||
type="dark-bg"
|
||||
></redaction-file-download-btn>
|
||||
<redaction-file-download-btn [dossier]="dossier" [file]="dossier.files" type="dark-bg"></redaction-file-download-btn>
|
||||
</div>
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
<div *ngIf="screen === 'dossier-overview'" [class.active]="actionMenuOpen" class="action-buttons">
|
||||
<ng-container *ngTemplateOutlet="actions"></ng-container>
|
||||
<redaction-status-bar
|
||||
*ngIf="fileStatus.isWorkable"
|
||||
[config]="statusBarConfig"
|
||||
></redaction-status-bar>
|
||||
<redaction-status-bar *ngIf="fileStatus.isWorkable" [config]="statusBarConfig"></redaction-status-bar>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="screen === 'file-preview'">
|
||||
@ -94,11 +91,7 @@
|
||||
*ngIf="permissionsService.isReadyForApproval(fileStatus)"
|
||||
[disabled]="!permissionsService.canApprove(fileStatus)"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="
|
||||
permissionsService.canApprove(fileStatus)
|
||||
? 'dossier-overview.approve'
|
||||
: 'dossier-overview.approve-disabled'
|
||||
"
|
||||
[tooltip]="permissionsService.canApprove(fileStatus) ? 'dossier-overview.approve' : 'dossier-overview.approve-disabled'"
|
||||
[type]="buttonType"
|
||||
icon="red:approved"
|
||||
></redaction-circle-button>
|
||||
|
||||
@ -1,34 +1,14 @@
|
||||
<div class="needs-work">
|
||||
<redaction-annotation-icon
|
||||
*ngIf="reanalysisRequired()"
|
||||
[color]="analysisColor"
|
||||
label="A"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="hasUpdates"
|
||||
[color]="updatedColor"
|
||||
label="U"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon *ngIf="reanalysisRequired()" [color]="analysisColor" label="A" type="square"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon *ngIf="hasUpdates" [color]="updatedColor" label="U" type="square"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="needsWorkInput.hasRedactions"
|
||||
[color]="redactionColor"
|
||||
label="R"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="hasImages"
|
||||
[color]="imageColor"
|
||||
label="I"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="needsWorkInput.hintsOnly"
|
||||
[color]="hintColor"
|
||||
label="H"
|
||||
type="circle"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon *ngIf="hasImages" [color]="imageColor" label="I" type="square"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon *ngIf="needsWorkInput.hintsOnly" [color]="hintColor" label="H" type="circle"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="needsWorkInput.hasRequests"
|
||||
[color]="suggestionColor"
|
||||
|
||||
@ -12,10 +12,7 @@ import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
export class NeedsWorkBadgeComponent {
|
||||
@Input() needsWorkInput: FileStatusWrapper | DossierWrapper;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _permissionsService: PermissionsService
|
||||
) {}
|
||||
constructor(private readonly _appStateService: AppStateService, private readonly _permissionsService: PermissionsService) {}
|
||||
|
||||
get suggestionColor() {
|
||||
return this._getDictionaryColor('suggestion');
|
||||
@ -50,10 +47,7 @@ export class NeedsWorkBadgeComponent {
|
||||
}
|
||||
|
||||
get hasAnnotationComments(): boolean {
|
||||
return (
|
||||
this.needsWorkInput instanceof FileStatusWrapper &&
|
||||
(<any>this.needsWorkInput).hasAnnotationComments
|
||||
);
|
||||
return this.needsWorkInput instanceof FileStatusWrapper && (<any>this.needsWorkInput).hasAnnotationComments;
|
||||
}
|
||||
|
||||
reanalysisRequired() {
|
||||
|
||||
@ -1,13 +1,4 @@
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges
|
||||
} from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { ViewedPages, ViewedPagesControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
@ -104,11 +95,7 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
|
||||
|
||||
private _markPageRead() {
|
||||
this._viewedPagesControllerService
|
||||
.addPage(
|
||||
{ page: this.number },
|
||||
this._appStateService.activeDossierId,
|
||||
this._appStateService.activeFileId
|
||||
)
|
||||
.addPage({ page: this.number }, this._appStateService.activeDossierId, this._appStateService.activeFileId)
|
||||
.subscribe(() => {
|
||||
this.viewedPages?.pages?.push(this.number);
|
||||
});
|
||||
@ -116,11 +103,7 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
|
||||
|
||||
private _markPageUnread() {
|
||||
this._viewedPagesControllerService
|
||||
.removePage(
|
||||
this._appStateService.activeDossierId,
|
||||
this._appStateService.activeFileId,
|
||||
this.number
|
||||
)
|
||||
.removePage(this._appStateService.activeDossierId, this._appStateService.activeFileId, this.number)
|
||||
.subscribe(() => {
|
||||
this.viewedPages?.pages?.splice(this.viewedPages?.pages?.indexOf(this.number), 1);
|
||||
});
|
||||
|
||||
@ -2,12 +2,7 @@
|
||||
<div #viewer [id]="fileStatus.fileId" class="viewer"></div>
|
||||
</div>
|
||||
|
||||
<input
|
||||
#compareFileInput
|
||||
(change)="uploadFile($event.target['files'])"
|
||||
class="file-upload-input"
|
||||
type="file"
|
||||
/>
|
||||
<input #compareFileInput (change)="uploadFile($event.target['files'])" class="file-upload-input" type="file" />
|
||||
|
||||
<div *ngIf="utils?.totalPages && utils?.currentPage" class="pagination noselect">
|
||||
<div (click)="utils.previousPage()">
|
||||
|
||||
@ -1,15 +1,7 @@
|
||||
<button
|
||||
(click)="scroll(buttonType.TOP)"
|
||||
[hidden]="!showScroll(buttonType.TOP)"
|
||||
class="scroll-button top pointer"
|
||||
>
|
||||
<button (click)="scroll(buttonType.TOP)" [hidden]="!showScroll(buttonType.TOP)" class="scroll-button top pointer">
|
||||
<mat-icon svgIcon="red:arrow-down-o"></mat-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
(click)="scroll(buttonType.BOTTOM)"
|
||||
[hidden]="!showScroll(buttonType.BOTTOM)"
|
||||
class="scroll-button bottom pointer"
|
||||
>
|
||||
<button (click)="scroll(buttonType.BOTTOM)" [hidden]="!showScroll(buttonType.BOTTOM)" class="scroll-button bottom pointer">
|
||||
<mat-icon svgIcon="red:arrow-down-o"></mat-icon>
|
||||
</button>
|
||||
|
||||
@ -20,9 +20,7 @@ export class ScrollButtonComponent {
|
||||
itemSize: number;
|
||||
|
||||
scroll(type: ButtonType): void {
|
||||
const viewportSize =
|
||||
(this.scrollViewport?.getViewportSize() - this.itemSize) *
|
||||
(type === ButtonType.TOP ? -1 : 1);
|
||||
const viewportSize = (this.scrollViewport?.getViewportSize() - this.itemSize) * (type === ButtonType.TOP ? -1 : 1);
|
||||
const scrollOffset = this.scrollViewport?.measureScrollOffset('top');
|
||||
this.scrollViewport?.scrollToOffset(scrollOffset + viewportSize, 'smooth');
|
||||
}
|
||||
|
||||
@ -51,12 +51,7 @@ export class TeamMembersManagerComponent implements OnInit {
|
||||
get membersSelectOptions() {
|
||||
const searchQuery = this.searchForm.get('query').value;
|
||||
return this.userService.eligibleUsers
|
||||
.filter(user =>
|
||||
this.userService
|
||||
.getNameForId(user.userId)
|
||||
.toLowerCase()
|
||||
.includes(searchQuery.toLowerCase())
|
||||
)
|
||||
.filter(user => this.userService.getNameForId(user.userId).toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
.filter(user => this.selectedOwnerId !== user.userId)
|
||||
.map(user => user.userId);
|
||||
}
|
||||
@ -76,10 +71,7 @@ export class TeamMembersManagerComponent implements OnInit {
|
||||
const initialApprovers = this.dossierWrapper.approverIds.sort();
|
||||
const currentApprovers = this.selectedApproversList.sort();
|
||||
|
||||
return (
|
||||
this._compareLists(initialMembers, currentMembers) ||
|
||||
this._compareLists(initialApprovers, currentApprovers)
|
||||
);
|
||||
return this._compareLists(initialMembers, currentMembers) || this._compareLists(initialApprovers, currentApprovers);
|
||||
}
|
||||
|
||||
isOwner(userId: string): boolean {
|
||||
|
||||
@ -6,20 +6,12 @@
|
||||
[class.large-spacing]="largeSpacing"
|
||||
class="member"
|
||||
>
|
||||
<redaction-initials-avatar
|
||||
[userId]="userId"
|
||||
color="gray"
|
||||
size="large"
|
||||
></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [userId]="userId" color="gray" size="large"></redaction-initials-avatar>
|
||||
<div *ngIf="canRemoveMember(userId)" class="remove">
|
||||
<mat-icon svgIcon="red:close"></mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="overflowCount && !expandedTeam"
|
||||
[class.large-spacing]="largeSpacing"
|
||||
class="member pointer"
|
||||
>
|
||||
<div *ngIf="overflowCount && !expandedTeam" [class.large-spacing]="largeSpacing" class="member pointer">
|
||||
<div (click)="toggleExpandedTeam()" class="oval large white-dark">+{{ overflowCount }}</div>
|
||||
</div>
|
||||
<redaction-circle-button
|
||||
@ -34,9 +26,4 @@
|
||||
>
|
||||
</redaction-circle-button>
|
||||
</div>
|
||||
<div
|
||||
(click)="toggleExpandedTeam()"
|
||||
*ngIf="expandedTeam"
|
||||
class="all-caps-label see-less pointer"
|
||||
translate="dossier-details.see-less"
|
||||
></div>
|
||||
<div (click)="toggleExpandedTeam()" *ngIf="expandedTeam" class="all-caps-label see-less pointer" translate="dossier-details.see-less"></div>
|
||||
|
||||
@ -27,15 +27,11 @@ export class TeamMembersComponent {
|
||||
}
|
||||
|
||||
get displayedMembers(): string[] {
|
||||
return this.expandedTeam || !this.overflowCount
|
||||
? this.memberIds
|
||||
: this.memberIds.slice(0, this.maxTeamMembersBeforeExpand - 1);
|
||||
return this.expandedTeam || !this.overflowCount ? this.memberIds : this.memberIds.slice(0, this.maxTeamMembersBeforeExpand - 1);
|
||||
}
|
||||
|
||||
get overflowCount() {
|
||||
return this.memberIds.length > this.maxTeamMembersBeforeExpand
|
||||
? this.memberIds.length - (this.maxTeamMembersBeforeExpand - 1)
|
||||
: 0;
|
||||
return this.memberIds.length > this.maxTeamMembersBeforeExpand ? this.memberIds.length - (this.maxTeamMembersBeforeExpand - 1) : 0;
|
||||
}
|
||||
|
||||
toggleExpandedTeam() {
|
||||
|
||||
@ -1,5 +1 @@
|
||||
<redaction-annotation-icon
|
||||
[color]="color"
|
||||
[label]="label"
|
||||
[type]="type"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon [color]="color" [label]="label" [type]="type"></redaction-annotation-icon>
|
||||
|
||||
@ -11,12 +11,7 @@
|
||||
label="R"
|
||||
type="hexagon"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="filter.key === 'hint'"
|
||||
[color]="dictionaryColor"
|
||||
label="H"
|
||||
type="circle"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon *ngIf="filter.key === 'hint'" [color]="dictionaryColor" label="H" type="circle"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="filter.key === 'manual-redaction'"
|
||||
[color]="dictionaryColor"
|
||||
@ -47,24 +42,14 @@
|
||||
label="S"
|
||||
type="rhombus"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="filter.key === 'none'"
|
||||
color="transparent"
|
||||
label="-"
|
||||
type="none"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon *ngIf="filter.key === 'none'" color="transparent" label="-" type="none"></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="filter.key === 'updated'"
|
||||
[color]="dictionaryColor"
|
||||
label="U"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon
|
||||
*ngIf="filter.key === 'image'"
|
||||
[color]="dictionaryColor"
|
||||
label="I"
|
||||
type="square"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon *ngIf="filter.key === 'image'" [color]="dictionaryColor" label="I" type="square"></redaction-annotation-icon>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="filter.icon">
|
||||
|
||||
@ -35,10 +35,7 @@ export class AddDossierDialogComponent {
|
||||
},
|
||||
{
|
||||
validators: control =>
|
||||
control.value.reportTypes?.length > 0 ||
|
||||
control.value.downloadFileTypes?.length > 0
|
||||
? null
|
||||
: { downloadPackage: true }
|
||||
control.value.reportTypes?.length > 0 || control.value.downloadFileTypes?.length > 0 ? null : { downloadPackage: true }
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -62,9 +59,7 @@ export class AddDossierDialogComponent {
|
||||
async saveDossier() {
|
||||
const dossier: Dossier = this._formToObject();
|
||||
|
||||
const foundDossier = this._appStateService.allDossiers.find(
|
||||
p => p.dossier.dossierId === dossier.dossierId
|
||||
);
|
||||
const foundDossier = this._appStateService.allDossiers.find(p => p.dossier.dossierId === dossier.dossierId);
|
||||
if (foundDossier) {
|
||||
dossier.memberIds = foundDossier.memberIds;
|
||||
}
|
||||
@ -85,9 +80,7 @@ export class AddDossierDialogComponent {
|
||||
|
||||
dossierTemplateChanged(dossierTemplateId) {
|
||||
// get current selected dossierTemplate
|
||||
const dossierTemplate = this.dossierTemplates.find(
|
||||
r => r.dossierTemplateId === dossierTemplateId
|
||||
);
|
||||
const dossierTemplate = this.dossierTemplates.find(r => r.dossierTemplateId === dossierTemplateId);
|
||||
if (dossierTemplate) {
|
||||
// update dropdown values
|
||||
this.dossierForm.patchValue(
|
||||
|
||||
@ -1,21 +1,13 @@
|
||||
<section class="dialog">
|
||||
<div
|
||||
[translate]="'assign-' + data.mode + '-owner.dialog.title'"
|
||||
class="dialog-header heading-l"
|
||||
></div>
|
||||
<div [translate]="'assign-' + data.mode + '-owner.dialog.title'" class="dialog-header heading-l"></div>
|
||||
|
||||
<form (submit)="saveUsers()" [formGroup]="usersForm">
|
||||
<div class="dialog-content">
|
||||
<div class="red-input-group w-300 required">
|
||||
<mat-form-field floatLabel="always">
|
||||
<mat-label>{{
|
||||
'assign-' + data.mode + '-owner.dialog.single-user' | translate
|
||||
}}</mat-label>
|
||||
<mat-label>{{ 'assign-' + data.mode + '-owner.dialog.single-user' | translate }}</mat-label>
|
||||
<mat-select formControlName="singleUser">
|
||||
<mat-option
|
||||
*ngFor="let userId of singleUsersSelectOptions"
|
||||
[value]="userId"
|
||||
>
|
||||
<mat-option *ngFor="let userId of singleUsersSelectOptions" [value]="userId">
|
||||
{{ userService.getNameForId(userId) }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
@ -24,26 +16,13 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="!usersForm.valid || !changed"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="!usersForm.valid || !changed" color="primary" mat-flat-button type="submit">
|
||||
{{ 'assign-' + data.mode + '-owner.dialog.save' | translate }}
|
||||
</button>
|
||||
|
||||
<div
|
||||
[translate]="'assign-' + data.mode + '-owner.dialog.cancel'"
|
||||
class="all-caps-label pointer cancel"
|
||||
mat-dialog-close
|
||||
></div>
|
||||
<div [translate]="'assign-' + data.mode + '-owner.dialog.cancel'" class="all-caps-label pointer cancel" mat-dialog-close></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -111,15 +111,9 @@ export class AssignReviewerApproverDialogComponent {
|
||||
uniqueReviewers.add(file.currentReviewer);
|
||||
}
|
||||
}
|
||||
let singleUser =
|
||||
uniqueReviewers.size === 1
|
||||
? uniqueReviewers.values().next().value
|
||||
: this.userService.userId;
|
||||
let singleUser = uniqueReviewers.size === 1 ? uniqueReviewers.values().next().value : this.userService.userId;
|
||||
|
||||
singleUser =
|
||||
this.singleUsersSelectOptions.indexOf(singleUser) >= 0
|
||||
? singleUser
|
||||
: this.singleUsersSelectOptions[0];
|
||||
singleUser = this.singleUsersSelectOptions.indexOf(singleUser) >= 0 ? singleUser : this.singleUsersSelectOptions[0];
|
||||
|
||||
this.usersForm = this._formBuilder.group({
|
||||
singleUser: [singleUser, Validators.required]
|
||||
|
||||
@ -6,17 +6,11 @@
|
||||
<div class="red-input-group required w-400">
|
||||
<label translate="change-legal-basis-dialog.content.reason"></label>
|
||||
<mat-select
|
||||
[placeholder]="
|
||||
'change-legal-basis-dialog.content.reason-placeholder' | translate
|
||||
"
|
||||
[placeholder]="'change-legal-basis-dialog.content.reason-placeholder' | translate"
|
||||
class="full-width"
|
||||
formControlName="reason"
|
||||
>
|
||||
<mat-option
|
||||
*ngFor="let option of legalOptions"
|
||||
[matTooltip]="option.description"
|
||||
[value]="option"
|
||||
>
|
||||
<mat-option *ngFor="let option of legalOptions" [matTooltip]="option.description" [value]="option">
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
@ -24,45 +18,22 @@
|
||||
|
||||
<div class="red-input-group w-400">
|
||||
<label translate="change-legal-basis-dialog.content.legalBasis"></label>
|
||||
<input
|
||||
[value]="legalBasisForm.get('reason').value?.legalBasis"
|
||||
disabled
|
||||
type="text"
|
||||
/>
|
||||
<input [value]="legalBasisForm.get('reason').value?.legalBasis" disabled type="text" />
|
||||
</div>
|
||||
|
||||
<div [class.required]="!isDocumentAdmin" class="red-input-group w-300">
|
||||
<label translate="change-legal-basis-dialog.content.comment"></label>
|
||||
<textarea
|
||||
formControlName="comment"
|
||||
name="comment"
|
||||
redactionHasScrollbar
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
<textarea formControlName="comment" name="comment" redactionHasScrollbar rows="4" type="text"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="!legalBasisForm.valid || !changed"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="!legalBasisForm.valid || !changed" color="primary" mat-flat-button type="submit">
|
||||
{{ 'change-legal-basis-dialog.actions.save' | translate }}
|
||||
</button>
|
||||
<div
|
||||
class="all-caps-label cancel"
|
||||
mat-dialog-close
|
||||
translate="change-legal-basis-dialog.actions.cancel"
|
||||
></div>
|
||||
<div class="all-caps-label cancel" mat-dialog-close translate="change-legal-basis-dialog.actions.cancel"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -34,9 +34,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
|
||||
) {}
|
||||
|
||||
get changed(): boolean {
|
||||
return (
|
||||
this.legalBasisForm.get('reason').value.legalBasis !== this.annotations[0].legalBasis
|
||||
);
|
||||
return this.legalBasisForm.get('reason').value.legalBasis !== this.annotations[0].legalBasis;
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
@ -59,9 +57,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
|
||||
.sort((a, b) => a.label.localeCompare(b.label));
|
||||
|
||||
this.legalBasisForm.patchValue({
|
||||
reason: this.legalOptions.find(
|
||||
option => option.legalBasis === this.annotations[0].legalBasis
|
||||
)
|
||||
reason: this.legalOptions.find(option => option.legalBasis === this.annotations[0].legalBasis)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -9,20 +9,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="documentInfoForm.invalid"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="documentInfoForm.invalid" color="primary" mat-flat-button type="submit">
|
||||
{{ 'document-info.save' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import {
|
||||
FileAttributeConfig,
|
||||
FileAttributesControllerService,
|
||||
FileStatus
|
||||
} from '@redaction/red-ui-http';
|
||||
import { FileAttributeConfig, FileAttributesControllerService, FileStatus } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
@ -34,9 +30,7 @@ export class DocumentInfoDialogComponent implements OnInit {
|
||||
|
||||
async ngOnInit() {
|
||||
this.attributes = (
|
||||
await this._fileAttributesService
|
||||
.getFileAttributesConfiguration(this._dossier.dossierTemplateId)
|
||||
.toPromise()
|
||||
await this._fileAttributesService.getFileAttributesConfiguration(this._dossier.dossierTemplateId).toPromise()
|
||||
).fileAttributeConfigs.filter(attr => attr.editable);
|
||||
const formConfig = this.attributes.reduce(
|
||||
(acc, attr) => ({
|
||||
@ -53,9 +47,7 @@ export class DocumentInfoDialogComponent implements OnInit {
|
||||
...this.file.fileAttributes?.attributeIdToValue,
|
||||
...this.documentInfoForm.getRawValue()
|
||||
};
|
||||
await this._fileAttributesService
|
||||
.setFileAttributes({ attributeIdToValue }, this.file.dossierId, this.file.fileId)
|
||||
.toPromise();
|
||||
await this._fileAttributesService.setFileAttributes({ attributeIdToValue }, this.file.dossierId, this.file.fileId).toPromise();
|
||||
this.file.fileAttributes = { attributeIdToValue };
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
|
||||
@ -12,26 +12,13 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="!canEdit || !dictionaryManager.hasChanges"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="!canEdit || !dictionaryManager.hasChanges" color="primary" mat-flat-button type="submit">
|
||||
{{ 'dossier-dictionary-dialog.save-changes' | translate }}
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="all-caps-label pointer cancel"
|
||||
mat-dialog-close
|
||||
translate="dossier-dictionary-dialog.cancel"
|
||||
></div>
|
||||
<div class="all-caps-label pointer cancel" mat-dialog-close translate="dossier-dictionary-dialog.cancel"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -1,4 +1 @@
|
||||
<redaction-team-members-manager
|
||||
(save)="updatedDossier($event)"
|
||||
[dossierWrapper]="dossierWrapper"
|
||||
></redaction-team-members-manager>
|
||||
<redaction-team-members-manager (save)="updatedDossier($event)" [dossierWrapper]="dossierWrapper"></redaction-team-members-manager>
|
||||
|
||||
@ -1,25 +1,16 @@
|
||||
<section class="dialog">
|
||||
<form (submit)="handleForceRedaction()" [formGroup]="redactionForm">
|
||||
<div
|
||||
class="dialog-header heading-l"
|
||||
translate="manual-annotation.dialog.header.force"
|
||||
></div>
|
||||
<div class="dialog-header heading-l" translate="manual-annotation.dialog.header.force"></div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<div class="red-input-group required w-400">
|
||||
<label translate="manual-annotation.dialog.content.reason"></label>
|
||||
<mat-select
|
||||
[placeholder]="
|
||||
'manual-annotation.dialog.content.reason-placeholder' | translate
|
||||
"
|
||||
[placeholder]="'manual-annotation.dialog.content.reason-placeholder' | translate"
|
||||
class="full-width"
|
||||
formControlName="reason"
|
||||
>
|
||||
<mat-option
|
||||
*ngFor="let option of legalOptions"
|
||||
[matTooltip]="option.description"
|
||||
[value]="option"
|
||||
>
|
||||
<mat-option *ngFor="let option of legalOptions" [matTooltip]="option.description" [value]="option">
|
||||
{{ option.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
@ -27,22 +18,12 @@
|
||||
|
||||
<div class="red-input-group w-400">
|
||||
<label translate="manual-annotation.dialog.content.legalBasis"></label>
|
||||
<input
|
||||
[value]="redactionForm.get('reason').value?.legalBasis"
|
||||
disabled
|
||||
type="text"
|
||||
/>
|
||||
<input [value]="redactionForm.get('reason').value?.legalBasis" disabled type="text" />
|
||||
</div>
|
||||
|
||||
<div [class.required]="!isDocumentAdmin" class="red-input-group w-300">
|
||||
<label translate="manual-annotation.dialog.content.comment"></label>
|
||||
<textarea
|
||||
formControlName="comment"
|
||||
name="comment"
|
||||
redactionHasScrollbar
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
<textarea formControlName="comment" name="comment" redactionHasScrollbar rows="4" type="text"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -53,9 +34,5 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -19,9 +19,7 @@
|
||||
<div *ngIf="!isDictionaryRequest" class="red-input-group required w-400">
|
||||
<label translate="manual-annotation.dialog.content.reason"></label>
|
||||
<mat-select
|
||||
[placeholder]="
|
||||
'manual-annotation.dialog.content.reason-placeholder' | translate
|
||||
"
|
||||
[placeholder]="'manual-annotation.dialog.content.reason-placeholder' | translate"
|
||||
class="full-width"
|
||||
formControlName="reason"
|
||||
>
|
||||
@ -38,28 +36,15 @@
|
||||
|
||||
<div *ngIf="!isDictionaryRequest" class="red-input-group w-400">
|
||||
<label translate="manual-annotation.dialog.content.legalBasis"></label>
|
||||
<input
|
||||
[value]="redactionForm.get('reason').value?.legalBasis"
|
||||
disabled
|
||||
type="text"
|
||||
/>
|
||||
<input [value]="redactionForm.get('reason').value?.legalBasis" disabled type="text" />
|
||||
</div>
|
||||
|
||||
<div [class.required]="!isDocumentAdmin" class="red-input-group w-300">
|
||||
<label translate="manual-annotation.dialog.content.comment"></label>
|
||||
<textarea
|
||||
formControlName="comment"
|
||||
name="comment"
|
||||
redactionHasScrollbar
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
<textarea formControlName="comment" name="comment" redactionHasScrollbar rows="4" type="text"></textarea>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="isDictionaryRequest && !isFalsePositiveRequest"
|
||||
class="red-input-group required w-300"
|
||||
>
|
||||
<div *ngIf="isDictionaryRequest && !isFalsePositiveRequest" class="red-input-group required w-300">
|
||||
<label translate="manual-annotation.dialog.content.dictionary"></label>
|
||||
|
||||
<mat-select formControlName="dictionary">
|
||||
@ -85,9 +70,5 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -18,36 +18,17 @@
|
||||
|
||||
<div [class.required]="!isDocumentAdmin" class="red-input-group w-300">
|
||||
<label translate="recategorize-image-dialog.content.comment"></label>
|
||||
<textarea
|
||||
formControlName="comment"
|
||||
name="comment"
|
||||
redactionHasScrollbar
|
||||
rows="4"
|
||||
type="text"
|
||||
></textarea>
|
||||
<textarea formControlName="comment" name="comment" redactionHasScrollbar rows="4" type="text"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
[disabled]="!recategorizeImageForm.valid || !changed"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
type="submit"
|
||||
>
|
||||
<button [disabled]="!recategorizeImageForm.valid || !changed" color="primary" mat-flat-button type="submit">
|
||||
{{ 'recategorize-image-dialog.actions.save' | translate }}
|
||||
</button>
|
||||
<div
|
||||
class="all-caps-label cancel"
|
||||
mat-dialog-close
|
||||
translate="recategorize-image-dialog.actions.cancel"
|
||||
></div>
|
||||
<div class="all-caps-label cancel" mat-dialog-close translate="recategorize-image-dialog.actions.cancel"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -49,9 +49,5 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -21,44 +21,25 @@ export class AnnotationActionsService {
|
||||
private readonly _dialogService: DossiersDialogService
|
||||
) {}
|
||||
|
||||
acceptSuggestion(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
acceptSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
$event?.stopPropagation();
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.approveRequest(
|
||||
annotation.id,
|
||||
annotation.isModifyDictionary
|
||||
),
|
||||
this._manualAnnotationService.approveRequest(annotation.id, annotation.isModifyDictionary),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
rejectSuggestion(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
rejectSuggestion($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
$event?.stopPropagation();
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.declineOrRemoveRequest(annotation),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
this._processObsAndEmit(this._manualAnnotationService.declineOrRemoveRequest(annotation), annotation, annotationsChanged);
|
||||
});
|
||||
}
|
||||
|
||||
forceRedaction(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
forceRedaction($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
$event?.stopPropagation();
|
||||
this._dialogService.openForceRedactionDialog($event, request => {
|
||||
annotations.forEach(annotation => {
|
||||
@ -74,28 +55,16 @@ export class AnnotationActionsService {
|
||||
});
|
||||
}
|
||||
|
||||
changeLegalBasis(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
this._dialogService.openChangeLegalBasisDialog(
|
||||
$event,
|
||||
annotations,
|
||||
(data: { comment: string; legalBasis: string }) => {
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.changeLegalBasis(
|
||||
annotation.annotationId,
|
||||
data.legalBasis,
|
||||
data.comment
|
||||
),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
changeLegalBasis($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
this._dialogService.openChangeLegalBasisDialog($event, annotations, (data: { comment: string; legalBasis: string }) => {
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.changeLegalBasis(annotation.annotationId, data.legalBasis, data.comment),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
suggestRemoveAnnotation(
|
||||
@ -104,97 +73,55 @@ export class AnnotationActionsService {
|
||||
removeFromDictionary: boolean,
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
this._dialogService.openRemoveFromDictionaryDialog(
|
||||
$event,
|
||||
annotations,
|
||||
removeFromDictionary,
|
||||
() => {
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.removeOrSuggestRemoveAnnotation(
|
||||
annotation,
|
||||
removeFromDictionary
|
||||
),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
this._dialogService.openRemoveFromDictionaryDialog($event, annotations, removeFromDictionary, () => {
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.removeOrSuggestRemoveAnnotation(annotation, removeFromDictionary),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
markAsFalsePositive(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
markAsFalsePositive($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
annotations.forEach(annotation => {
|
||||
const permissions = AnnotationPermissions.forUser(
|
||||
this._permissionsService.isApprover(),
|
||||
this._permissionsService.currentUser,
|
||||
annotation
|
||||
);
|
||||
const value = permissions.canMarkTextOnlyAsFalsePositive
|
||||
? annotation.value
|
||||
: this._getFalsePositiveText(annotation);
|
||||
const value = permissions.canMarkTextOnlyAsFalsePositive ? annotation.value : this._getFalsePositiveText(annotation);
|
||||
|
||||
this._markAsFalsePositive($event, annotation, value, annotationsChanged);
|
||||
});
|
||||
}
|
||||
|
||||
recategorizeImage(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
this._dialogService.openRecategorizeImageDialog(
|
||||
$event,
|
||||
annotations,
|
||||
(data: { type: string; comment: string }) => {
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.recategorizeImage(
|
||||
annotation.annotationId,
|
||||
data.type,
|
||||
data.comment
|
||||
),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
undoDirectAction(
|
||||
$event: MouseEvent,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
$event?.stopPropagation();
|
||||
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.undoRequest(annotation),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
recategorizeImage($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
this._dialogService.openRecategorizeImageDialog($event, annotations, (data: { type: string; comment: string }) => {
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.recategorizeImage(annotation.annotationId, data.type, data.comment),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
convertRecommendationToAnnotation(
|
||||
$event: any,
|
||||
annotations: AnnotationWrapper[],
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
undoDirectAction($event: MouseEvent, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
$event?.stopPropagation();
|
||||
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.addRecommendation(annotation),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
this._processObsAndEmit(this._manualAnnotationService.undoRequest(annotation), annotation, annotationsChanged);
|
||||
});
|
||||
}
|
||||
|
||||
convertRecommendationToAnnotation($event: any, annotations: AnnotationWrapper[], annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
$event?.stopPropagation();
|
||||
|
||||
annotations.forEach(annotation => {
|
||||
this._processObsAndEmit(this._manualAnnotationService.addRecommendation(annotation), annotation, annotationsChanged);
|
||||
});
|
||||
}
|
||||
|
||||
@ -206,15 +133,10 @@ export class AnnotationActionsService {
|
||||
|
||||
const annotationPermissions = annotations.map(a => ({
|
||||
annotation: a,
|
||||
permissions: AnnotationPermissions.forUser(
|
||||
this._permissionsService.isApprover(),
|
||||
this._permissionsService.currentUser,
|
||||
a
|
||||
)
|
||||
permissions: AnnotationPermissions.forUser(this._permissionsService.isApprover(), this._permissionsService.currentUser, a)
|
||||
}));
|
||||
|
||||
const canRecategorizeImage =
|
||||
annotations.length === 1 && annotationPermissions[0].permissions.canRecategorizeImage;
|
||||
const canRecategorizeImage = annotations.length === 1 && annotationPermissions[0].permissions.canRecategorizeImage;
|
||||
if (canRecategorizeImage) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
@ -236,9 +158,7 @@ export class AnnotationActionsService {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
img: this._convertPath('/assets/icons/general/remove-from-dict.svg'),
|
||||
title: this._translateService.instant(
|
||||
'annotation-actions.remove-annotation.remove-from-dict'
|
||||
),
|
||||
title: this._translateService.instant('annotation-actions.remove-annotation.remove-from-dict'),
|
||||
onClick: () => {
|
||||
this._ngZone.run(() => {
|
||||
this.suggestRemoveAnnotation(null, annotations, true, annotationsChanged);
|
||||
@ -247,33 +167,21 @@ export class AnnotationActionsService {
|
||||
});
|
||||
}
|
||||
|
||||
const canAcceptRecommendation = annotationPermissions.reduce(
|
||||
(acc, next) => acc && next.permissions.canAcceptRecommendation,
|
||||
true
|
||||
);
|
||||
const canAcceptRecommendation = annotationPermissions.reduce((acc, next) => acc && next.permissions.canAcceptRecommendation, true);
|
||||
if (canAcceptRecommendation) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
img: this._convertPath('/assets/icons/general/check.svg'),
|
||||
title: this._translateService.instant(
|
||||
'annotation-actions.accept-recommendation.label'
|
||||
),
|
||||
title: this._translateService.instant('annotation-actions.accept-recommendation.label'),
|
||||
onClick: () => {
|
||||
this._ngZone.run(() => {
|
||||
this.convertRecommendationToAnnotation(
|
||||
null,
|
||||
annotations,
|
||||
annotationsChanged
|
||||
);
|
||||
this.convertRecommendationToAnnotation(null, annotations, annotationsChanged);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const canAcceptSuggestion = annotationPermissions.reduce(
|
||||
(acc, next) => acc && next.permissions.canAcceptSuggestion,
|
||||
true
|
||||
);
|
||||
const canAcceptSuggestion = annotationPermissions.reduce((acc, next) => acc && next.permissions.canAcceptSuggestion, true);
|
||||
if (canAcceptSuggestion) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
@ -287,10 +195,7 @@ export class AnnotationActionsService {
|
||||
});
|
||||
}
|
||||
|
||||
const canUndo = annotationPermissions.reduce(
|
||||
(acc, next) => acc && next.permissions.canUndo,
|
||||
true
|
||||
);
|
||||
const canUndo = annotationPermissions.reduce((acc, next) => acc && next.permissions.canUndo, true);
|
||||
if (canUndo) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
@ -305,19 +210,14 @@ export class AnnotationActionsService {
|
||||
}
|
||||
|
||||
const canMarkAsFalsePositive = annotationPermissions.reduce(
|
||||
(acc, next) =>
|
||||
acc &&
|
||||
(next.permissions.canMarkAsFalsePositive ||
|
||||
next.permissions.canMarkTextOnlyAsFalsePositive),
|
||||
(acc, next) => acc && (next.permissions.canMarkAsFalsePositive || next.permissions.canMarkTextOnlyAsFalsePositive),
|
||||
true
|
||||
);
|
||||
if (canMarkAsFalsePositive) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
img: this._convertPath('/assets/icons/general/thumb-down.svg'),
|
||||
title: this._translateService.instant(
|
||||
'annotation-actions.remove-annotation.false-positive'
|
||||
),
|
||||
title: this._translateService.instant('annotation-actions.remove-annotation.false-positive'),
|
||||
onClick: () => {
|
||||
this._ngZone.run(() => {
|
||||
this.markAsFalsePositive(null, annotations, annotationsChanged);
|
||||
@ -326,10 +226,7 @@ export class AnnotationActionsService {
|
||||
});
|
||||
}
|
||||
|
||||
const canForceRedaction = annotationPermissions.reduce(
|
||||
(acc, next) => acc && next.permissions.canForceRedaction,
|
||||
true
|
||||
);
|
||||
const canForceRedaction = annotationPermissions.reduce((acc, next) => acc && next.permissions.canForceRedaction, true);
|
||||
if (canForceRedaction) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
@ -343,10 +240,7 @@ export class AnnotationActionsService {
|
||||
});
|
||||
}
|
||||
|
||||
const canRejectSuggestion = annotationPermissions.reduce(
|
||||
(acc, next) => acc && next.permissions.canRejectSuggestion,
|
||||
true
|
||||
);
|
||||
const canRejectSuggestion = annotationPermissions.reduce((acc, next) => acc && next.permissions.canRejectSuggestion, true);
|
||||
if (canRejectSuggestion) {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
@ -368,9 +262,7 @@ export class AnnotationActionsService {
|
||||
availableActions.push({
|
||||
type: 'actionButton',
|
||||
img: this._convertPath('/assets/icons/general/trash.svg'),
|
||||
title: this._translateService.instant(
|
||||
'annotation-actions.remove-annotation.only-here'
|
||||
),
|
||||
title: this._translateService.instant('annotation-actions.remove-annotation.only-here'),
|
||||
onClick: () => {
|
||||
this._ngZone.run(() => {
|
||||
this.suggestRemoveAnnotation(null, annotations, false, annotationsChanged);
|
||||
@ -382,11 +274,7 @@ export class AnnotationActionsService {
|
||||
return availableActions;
|
||||
}
|
||||
|
||||
private _processObsAndEmit(
|
||||
obs: Observable<any>,
|
||||
annotation: AnnotationWrapper,
|
||||
annotationsChanged: EventEmitter<AnnotationWrapper>
|
||||
) {
|
||||
private _processObsAndEmit(obs: Observable<any>, annotation: AnnotationWrapper, annotationsChanged: EventEmitter<AnnotationWrapper>) {
|
||||
obs.subscribe(
|
||||
() => {
|
||||
annotationsChanged.emit(annotation);
|
||||
@ -426,11 +314,7 @@ export class AnnotationActionsService {
|
||||
falsePositiveRequest.addToDictionary = true;
|
||||
falsePositiveRequest.comment = { text: 'False Positive' };
|
||||
|
||||
this._processObsAndEmit(
|
||||
this._manualAnnotationService.addAnnotation(falsePositiveRequest),
|
||||
annotation,
|
||||
annotationsChanged
|
||||
);
|
||||
this._processObsAndEmit(this._manualAnnotationService.addAnnotation(falsePositiveRequest), annotation, annotationsChanged);
|
||||
}
|
||||
|
||||
private _convertPath(path: string): string {
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
||||
import {
|
||||
Rectangle,
|
||||
RedactionLogControllerService,
|
||||
SectionGrid,
|
||||
SectionRectangle
|
||||
} from '@redaction/red-ui-http';
|
||||
import { Rectangle, RedactionLogControllerService, SectionGrid, SectionRectangle } from '@redaction/red-ui-http';
|
||||
import { hexToRgb } from '@utils/functions';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
@ -27,9 +22,7 @@ export class AnnotationDrawService {
|
||||
) {
|
||||
const annotations = [];
|
||||
annotationWrappers.forEach(annotation => {
|
||||
annotations.push(
|
||||
this.computeAnnotation(activeViewer, annotation, hideSkipped, compareMode)
|
||||
);
|
||||
annotations.push(this.computeAnnotation(activeViewer, annotation, hideSkipped, compareMode));
|
||||
});
|
||||
|
||||
const annotationManager = activeViewer.annotManager;
|
||||
@ -38,10 +31,7 @@ export class AnnotationDrawService {
|
||||
|
||||
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
||||
this._redactionLogControllerService
|
||||
.getSectionGrid(
|
||||
this._appStateService.activeDossierId,
|
||||
this._appStateService.activeFileId
|
||||
)
|
||||
.getSectionGrid(this._appStateService.activeDossierId, this._appStateService.activeFileId)
|
||||
.subscribe(sectionGrid => {
|
||||
this.drawSections(activeViewer, sectionGrid);
|
||||
});
|
||||
@ -53,9 +43,7 @@ export class AnnotationDrawService {
|
||||
for (const page of Object.keys(sectionGrid.rectanglesPerPage)) {
|
||||
const sectionRectangles: SectionRectangle[] = sectionGrid.rectanglesPerPage[page];
|
||||
sectionRectangles.forEach(sectionRectangle => {
|
||||
sections.push(
|
||||
this.computeSection(activeViewer, parseInt(page, 10), sectionRectangle)
|
||||
);
|
||||
sections.push(this.computeSection(activeViewer, parseInt(page, 10), sectionRectangle));
|
||||
// sectionRectangle.tableCells?.forEach(cell =>{
|
||||
// sections.push(this.computeSection(activeViewer, parseInt(page, 10), cell));
|
||||
// })
|
||||
@ -66,11 +54,7 @@ export class AnnotationDrawService {
|
||||
annotationManager.drawAnnotationsFromList(sections);
|
||||
}
|
||||
|
||||
computeSection(
|
||||
activeViewer: WebViewerInstance,
|
||||
pageNumber: number,
|
||||
sectionRectangle: SectionRectangle
|
||||
) {
|
||||
computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) {
|
||||
const rectangleAnnot = new activeViewer.Annotations.RectangleAnnotation();
|
||||
const pageHeight = activeViewer.docViewer.getPageHeight(pageNumber);
|
||||
const rectangle = {
|
||||
@ -97,44 +81,25 @@ export class AnnotationDrawService {
|
||||
hideSkipped: boolean = false,
|
||||
compareMode: boolean = false
|
||||
) {
|
||||
const pageNumber = compareMode
|
||||
? annotationWrapper.pageNumber * 2 - 1
|
||||
: annotationWrapper.pageNumber;
|
||||
const pageNumber = compareMode ? annotationWrapper.pageNumber * 2 - 1 : annotationWrapper.pageNumber;
|
||||
const highlight = new activeViewer.Annotations.TextHighlightAnnotation();
|
||||
highlight.PageNumber = pageNumber;
|
||||
highlight.StrokeColor = this.getColor(
|
||||
activeViewer,
|
||||
annotationWrapper.superType,
|
||||
annotationWrapper.dictionary
|
||||
);
|
||||
highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.dictionary);
|
||||
highlight.setContents(annotationWrapper.content);
|
||||
highlight.Quads = this._rectanglesToQuads(
|
||||
annotationWrapper.positions,
|
||||
activeViewer,
|
||||
pageNumber
|
||||
);
|
||||
highlight.Quads = this._rectanglesToQuads(annotationWrapper.positions, activeViewer, pageNumber);
|
||||
highlight.Id = annotationWrapper.id;
|
||||
highlight.ReadOnly = true;
|
||||
// change log entries are drawn lighter
|
||||
highlight.Opacity = annotationWrapper.isChangeLogRemoved ? 0.2 : 1;
|
||||
highlight.Hidden =
|
||||
annotationWrapper.isChangeLogRemoved ||
|
||||
(hideSkipped && annotationWrapper.isSkipped) ||
|
||||
annotationWrapper.isOCR;
|
||||
highlight.Hidden = annotationWrapper.isChangeLogRemoved || (hideSkipped && annotationWrapper.isSkipped) || annotationWrapper.isOCR;
|
||||
|
||||
highlight.setCustomData('redacto-manager', true);
|
||||
highlight.setCustomData('redaction', annotationWrapper.isRedacted);
|
||||
highlight.setCustomData('skipped', annotationWrapper.isSkipped);
|
||||
highlight.setCustomData('changeLog', annotationWrapper.isChangeLogEntry);
|
||||
highlight.setCustomData('changeLogRemoved', annotationWrapper.isChangeLogRemoved);
|
||||
highlight.setCustomData(
|
||||
'redactionColor',
|
||||
this.getColor(activeViewer, 'redaction', 'redaction')
|
||||
);
|
||||
highlight.setCustomData(
|
||||
'annotationColor',
|
||||
this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.dictionary)
|
||||
);
|
||||
highlight.setCustomData('redactionColor', this.getColor(activeViewer, 'redaction', 'redaction'));
|
||||
highlight.setCustomData('annotationColor', this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.dictionary));
|
||||
|
||||
return highlight;
|
||||
}
|
||||
@ -174,20 +139,12 @@ export class AnnotationDrawService {
|
||||
return new activeViewer.CoreControls.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||
}
|
||||
|
||||
private _rectanglesToQuads(
|
||||
positions: Rectangle[],
|
||||
activeViewer: WebViewerInstance,
|
||||
pageNumber: number
|
||||
): any[] {
|
||||
private _rectanglesToQuads(positions: Rectangle[], activeViewer: WebViewerInstance, pageNumber: number): any[] {
|
||||
const pageHeight = activeViewer.docViewer.getPageHeight(pageNumber);
|
||||
return positions.map(p => this._rectangleToQuad(p, activeViewer, pageHeight));
|
||||
}
|
||||
|
||||
private _rectangleToQuad(
|
||||
rectangle: Rectangle,
|
||||
activeViewer: WebViewerInstance,
|
||||
pageHeight: number
|
||||
): any {
|
||||
private _rectangleToQuad(rectangle: Rectangle, activeViewer: WebViewerInstance, pageHeight: number): any {
|
||||
const x1 = rectangle.topLeft.x;
|
||||
const y1 = pageHeight - (rectangle.topLeft.y + rectangle.height);
|
||||
|
||||
|
||||
@ -24,8 +24,7 @@ export class AnnotationProcessingService {
|
||||
checked: false,
|
||||
topLevelFilter: true,
|
||||
filters: [],
|
||||
checker: (annotation: AnnotationWrapper) =>
|
||||
annotation?.legalBasisChangeValue?.length > 0
|
||||
checker: (annotation: AnnotationWrapper) => annotation?.legalBasisChangeValue?.length > 0
|
||||
}
|
||||
];
|
||||
}
|
||||
@ -35,10 +34,7 @@ export class AnnotationProcessingService {
|
||||
const filters: FilterModel[] = [];
|
||||
|
||||
annotations?.forEach(a => {
|
||||
const topLevelFilter =
|
||||
a.superType !== 'hint' &&
|
||||
a.superType !== 'redaction' &&
|
||||
a.superType !== 'recommendation';
|
||||
const topLevelFilter = a.superType !== 'hint' && a.superType !== 'redaction' && a.superType !== 'recommendation';
|
||||
const key = topLevelFilter ? a.superType : a.superType + a.dictionary;
|
||||
const filter = filterMap.get(key);
|
||||
if (filter) {
|
||||
@ -96,9 +92,7 @@ export class AnnotationProcessingService {
|
||||
if (
|
||||
!this._matchesAll(
|
||||
secondaryFlatFilters,
|
||||
f =>
|
||||
(!!f.checker && f.checker(annotation)) ||
|
||||
this._checkByFilterKey(f, annotation)
|
||||
f => (!!f.checker && f.checker(annotation)) || this._checkByFilterKey(f, annotation)
|
||||
)
|
||||
) {
|
||||
continue;
|
||||
@ -127,11 +121,7 @@ export class AnnotationProcessingService {
|
||||
return obj;
|
||||
}
|
||||
|
||||
private _createParentFilter(
|
||||
key: string,
|
||||
filterMap: Map<string, FilterModel>,
|
||||
filters: FilterModel[]
|
||||
) {
|
||||
private _createParentFilter(key: string, filterMap: Map<string, FilterModel>, filters: FilterModel[]) {
|
||||
const filter: FilterModel = {
|
||||
key: key,
|
||||
topLevelFilter: true,
|
||||
@ -155,10 +145,7 @@ export class AnnotationProcessingService {
|
||||
return filterBy ? flatFilters.filter(f => filterBy(f)) : flatFilters;
|
||||
}
|
||||
|
||||
private _matchesOne = (
|
||||
filters: FilterModel[],
|
||||
condition: (filter: FilterModel) => boolean
|
||||
): boolean => {
|
||||
private _matchesOne = (filters: FilterModel[], condition: (filter: FilterModel) => boolean): boolean => {
|
||||
if (filters.length === 0) return true;
|
||||
|
||||
for (const filter of filters) {
|
||||
@ -168,10 +155,7 @@ export class AnnotationProcessingService {
|
||||
return false;
|
||||
};
|
||||
|
||||
private _matchesAll = (
|
||||
filters: FilterModel[],
|
||||
condition: (filter: FilterModel) => boolean
|
||||
): boolean => {
|
||||
private _matchesAll = (filters: FilterModel[], condition: (filter: FilterModel) => boolean): boolean => {
|
||||
if (filters.length === 0) return true;
|
||||
|
||||
for (const filter of filters) {
|
||||
@ -183,13 +167,9 @@ export class AnnotationProcessingService {
|
||||
|
||||
private _checkByFilterKey = (filter: FilterModel, annotation: AnnotationWrapper) => {
|
||||
const superType = annotation.superType;
|
||||
const isNotTopLevelFilter =
|
||||
superType === 'hint' || superType === 'redaction' || superType === 'recommendation';
|
||||
const isNotTopLevelFilter = superType === 'hint' || superType === 'redaction' || superType === 'recommendation';
|
||||
|
||||
return (
|
||||
filter.key === superType ||
|
||||
(filter.key === annotation.dictionary && isNotTopLevelFilter)
|
||||
);
|
||||
return filter.key === superType || (filter.key === annotation.dictionary && isNotTopLevelFilter);
|
||||
};
|
||||
|
||||
private _sortAnnotations(annotations: AnnotationWrapper[]): AnnotationWrapper[] {
|
||||
|
||||
@ -47,11 +47,7 @@ export class FileActionService {
|
||||
}
|
||||
}
|
||||
|
||||
assignDossierApprover(
|
||||
file?: FileStatusWrapper,
|
||||
callback?: Function,
|
||||
ignoreDialogChanges = false
|
||||
) {
|
||||
assignDossierApprover(file?: FileStatusWrapper, callback?: Function, ignoreDialogChanges = false) {
|
||||
this._dialogService.openAssignFileToUserDialog(
|
||||
file ? [file] : [this._appStateService.activeFile],
|
||||
'approver',
|
||||
@ -65,11 +61,7 @@ export class FileActionService {
|
||||
);
|
||||
}
|
||||
|
||||
assignDossierReviewer(
|
||||
file?: FileStatusWrapper,
|
||||
callback?: Function,
|
||||
ignoreDialogChanges = false
|
||||
) {
|
||||
assignDossierReviewer(file?: FileStatusWrapper, callback?: Function, ignoreDialogChanges = false) {
|
||||
this._dialogService.openAssignFileToUserDialog(
|
||||
file ? [file] : [this._appStateService.activeFile],
|
||||
'reviewer',
|
||||
@ -88,10 +80,7 @@ export class FileActionService {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
|
||||
const atLeastOneFileHasReviewer = fileStatus.reduce(
|
||||
(acc, fs) => acc || !!fs.currentReviewer,
|
||||
false
|
||||
);
|
||||
const atLeastOneFileHasReviewer = fileStatus.reduce((acc, fs) => acc || !!fs.currentReviewer, false);
|
||||
if (atLeastOneFileHasReviewer) {
|
||||
this._dialogService.openAssignFileToMeDialog(async () => {
|
||||
await this._assignReviewerToCurrentUser(fileStatus, callback);
|
||||
@ -148,22 +137,15 @@ export class FileActionService {
|
||||
}
|
||||
|
||||
private _openAssignReviewerDialog(file?: FileStatusWrapper, callback?: Function) {
|
||||
this._dialogService.openAssignFileToUserDialog(
|
||||
file ? [file] : [this._appStateService.activeFile],
|
||||
'reviewer',
|
||||
async () => {
|
||||
await this._appStateService.reloadActiveDossierFiles();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
this._dialogService.openAssignFileToUserDialog(file ? [file] : [this._appStateService.activeFile], 'reviewer', async () => {
|
||||
await this._appStateService.reloadActiveDossierFiles();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private async _assignReviewerToCurrentUser(
|
||||
fileStatus: FileStatusWrapper | FileStatusWrapper[],
|
||||
callback?: Function
|
||||
) {
|
||||
private async _assignReviewerToCurrentUser(fileStatus: FileStatusWrapper | FileStatusWrapper[], callback?: Function) {
|
||||
if (!isArray(fileStatus)) {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
|
||||
@ -77,12 +77,7 @@ export class ManualAnnotationService {
|
||||
return obs.pipe(
|
||||
tap(
|
||||
() => this._notify(this._getMessage(mode)),
|
||||
error =>
|
||||
this._notify(
|
||||
this._getMessage(mode, modifyDictionary, true),
|
||||
NotificationType.ERROR,
|
||||
error
|
||||
)
|
||||
error => this._notify(this._getMessage(mode, modifyDictionary, true), NotificationType.ERROR, error)
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -124,9 +119,7 @@ export class ManualAnnotationService {
|
||||
// /manualRedaction/redaction/legalBasisChange
|
||||
// /manualRedaction/request/legalBasis
|
||||
changeLegalBasis(annotationId: string, legalBasis: string, comment?: string) {
|
||||
const mode: Mode = this._permissionsService.isApprover()
|
||||
? 'change-legal-basis'
|
||||
: 'request-change-legal-basis';
|
||||
const mode: Mode = this._permissionsService.isApprover() ? 'change-legal-basis' : 'request-change-legal-basis';
|
||||
return this._makeRequest(mode, { annotationId, legalBasis, comment });
|
||||
}
|
||||
|
||||
@ -134,9 +127,7 @@ export class ManualAnnotationService {
|
||||
// /manualRedaction/redaction/recategorize
|
||||
// /manualRedaction/request/recategorize
|
||||
recategorizeImage(annotationId: string, type: string, comment: string) {
|
||||
const mode: Mode = this._permissionsService.isApprover()
|
||||
? 'recategorize-image'
|
||||
: 'request-image-recategorization';
|
||||
const mode: Mode = this._permissionsService.isApprover() ? 'recategorize-image' : 'request-image-recategorization';
|
||||
return this._makeRequest(mode, { annotationId, type, comment });
|
||||
}
|
||||
|
||||
@ -145,21 +136,14 @@ export class ManualAnnotationService {
|
||||
// /manualRedaction/request/add
|
||||
addAnnotation(manualRedactionEntry: AddRedactionRequest) {
|
||||
const mode: Mode = this._permissionsService.isApprover() ? 'add' : 'suggest';
|
||||
return this._makeRequest(
|
||||
mode,
|
||||
manualRedactionEntry,
|
||||
null,
|
||||
manualRedactionEntry.addToDictionary
|
||||
);
|
||||
return this._makeRequest(mode, manualRedactionEntry, null, manualRedactionEntry.addToDictionary);
|
||||
}
|
||||
|
||||
// this wraps
|
||||
// /manualRedaction/redaction/force
|
||||
// /manualRedaction/request/force
|
||||
forceRedaction(request: ForceRedactionRequest) {
|
||||
const mode: Mode = this._permissionsService.isApprover()
|
||||
? 'force-redaction'
|
||||
: 'request-force-redaction';
|
||||
const mode: Mode = this._permissionsService.isApprover() ? 'force-redaction' : 'request-force-redaction';
|
||||
return this._makeRequest(mode, request);
|
||||
}
|
||||
|
||||
@ -167,21 +151,11 @@ export class ManualAnnotationService {
|
||||
// /manualRedaction/approve
|
||||
approveRequest(annotationId: string, addToDictionary: boolean = false) {
|
||||
// for only here - approve the request
|
||||
return this._makeRequest(
|
||||
'approve',
|
||||
{ addOrRemoveFromDictionary: addToDictionary },
|
||||
annotationId,
|
||||
addToDictionary
|
||||
);
|
||||
return this._makeRequest('approve', { addOrRemoveFromDictionary: addToDictionary }, annotationId, addToDictionary);
|
||||
}
|
||||
|
||||
undoRequest(annotationWrapper: AnnotationWrapper) {
|
||||
return this._makeRequest(
|
||||
'undo',
|
||||
annotationWrapper.id,
|
||||
null,
|
||||
annotationWrapper.isModifyDictionary
|
||||
);
|
||||
return this._makeRequest('undo', annotationWrapper.id, null, annotationWrapper.isModifyDictionary);
|
||||
}
|
||||
|
||||
// this wraps
|
||||
@ -189,21 +163,13 @@ export class ManualAnnotationService {
|
||||
// /manualRedaction/undo
|
||||
declineOrRemoveRequest(annotationWrapper: AnnotationWrapper) {
|
||||
const mode: Mode = this._permissionsService.isApprover() ? 'decline' : 'undo';
|
||||
return this._makeRequest(
|
||||
mode,
|
||||
annotationWrapper.id,
|
||||
null,
|
||||
annotationWrapper.isModifyDictionary
|
||||
);
|
||||
return this._makeRequest(mode, annotationWrapper.id, null, annotationWrapper.isModifyDictionary);
|
||||
}
|
||||
|
||||
// this wraps
|
||||
// /manualRedaction/redaction/remove/
|
||||
// /manualRedaction/request/remove/
|
||||
removeOrSuggestRemoveAnnotation(
|
||||
annotationWrapper: AnnotationWrapper,
|
||||
removeFromDictionary: boolean = false
|
||||
) {
|
||||
removeOrSuggestRemoveAnnotation(annotationWrapper: AnnotationWrapper, removeFromDictionary: boolean = false) {
|
||||
let mode: Mode,
|
||||
body: any,
|
||||
removeDict = false;
|
||||
@ -258,15 +224,10 @@ export class ManualAnnotationService {
|
||||
}
|
||||
|
||||
private _notify(key: string, type: NotificationType = NotificationType.SUCCESS, data?: any) {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant(key, data),
|
||||
null,
|
||||
type,
|
||||
{
|
||||
positionClass: 'toast-file-preview',
|
||||
actions: []
|
||||
}
|
||||
);
|
||||
this._notificationService.showToastNotification(this._translateService.instant(key, data), null, type, {
|
||||
positionClass: 'toast-file-preview',
|
||||
actions: []
|
||||
});
|
||||
}
|
||||
|
||||
private _getMessage(mode: Mode, modifyDictionary?: boolean, error: boolean = false) {
|
||||
|
||||
@ -37,9 +37,7 @@ export class PdfViewerDataService {
|
||||
this._man.getManualRedaction(dossierId, fileId).subscribe();
|
||||
|
||||
const file$ = this.downloadOriginalFile(this._appStateService.activeFile);
|
||||
const reactionLog$ = this._redactionLogControllerService
|
||||
.getRedactionLogPreview(dossierId, fileId)
|
||||
.pipe(catchError(() => of({})));
|
||||
const reactionLog$ = this._redactionLogControllerService.getRedactionLogPreview(dossierId, fileId).pipe(catchError(() => of({})));
|
||||
const redactionChangeLog$ = this._redactionLogControllerService
|
||||
.getRedactionChangeLog(dossierId, fileId)
|
||||
.pipe(catchError(() => of({})));
|
||||
@ -53,10 +51,7 @@ export class PdfViewerDataService {
|
||||
getViewedPagesForActiveFile() {
|
||||
if (this._permissionsService.canMarkPagesAsViewed()) {
|
||||
return this._viewedPagesControllerService
|
||||
.getViewedPages(
|
||||
this._appStateService.activeDossierId,
|
||||
this._appStateService.activeFileId
|
||||
)
|
||||
.getViewedPages(this._appStateService.activeDossierId, this._appStateService.activeFileId)
|
||||
.pipe(catchError(() => of({ pages: [] })));
|
||||
}
|
||||
return of({ pages: [] });
|
||||
|
||||
@ -3,13 +3,7 @@ import { stampPDFPage } from '../../../utils/page-stamper';
|
||||
const processPage = async (pageNumber, document1, document2, mergedDocument, PDFNet) => {
|
||||
const document1PageCount = await document1.getPageCount();
|
||||
if (document1PageCount >= pageNumber) {
|
||||
await mergedDocument.insertPages(
|
||||
pageNumber * 2,
|
||||
document1,
|
||||
pageNumber,
|
||||
pageNumber,
|
||||
PDFNet.PDFDoc.InsertFlag.e_none
|
||||
);
|
||||
await mergedDocument.insertPages(pageNumber * 2, document1, pageNumber, pageNumber, PDFNet.PDFDoc.InsertFlag.e_none);
|
||||
} else {
|
||||
const pageToCopy = await document2.getPage(pageNumber);
|
||||
const blankPage = await mergedDocument.pageCreate(await pageToCopy.getCropBox());
|
||||
@ -49,9 +43,7 @@ export const loadCompareDocumentWrapper = async (
|
||||
await processPage(idx, compareDocument, currentDocument, mergedDocument, PDFNet);
|
||||
}
|
||||
|
||||
const buffer = await mergedDocument.saveMemoryBuffer(
|
||||
PDFNet.SDFDoc.SaveOptions.e_linearized
|
||||
);
|
||||
const buffer = await mergedDocument.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_linearized);
|
||||
|
||||
const mergedDocumentBuffer = new Blob([buffer], {
|
||||
type: 'application/pdf'
|
||||
|
||||
@ -9,10 +9,7 @@ import { DomSanitizer } from '@angular/platform-browser';
|
||||
exports: [MatIconModule]
|
||||
})
|
||||
export class IconsModule {
|
||||
constructor(
|
||||
private readonly _iconRegistry: MatIconRegistry,
|
||||
private readonly _sanitizer: DomSanitizer
|
||||
) {
|
||||
constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) {
|
||||
const icons = [
|
||||
'add',
|
||||
'analyse',
|
||||
|
||||
@ -27,10 +27,5 @@
|
||||
</div>
|
||||
|
||||
<ng-template #avatar let-userId="userId">
|
||||
<redaction-initials-avatar
|
||||
[userId]="userId"
|
||||
[withName]="true"
|
||||
color="gray"
|
||||
size="small"
|
||||
></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [userId]="userId" [withName]="true" color="gray" size="small"></redaction-initials-avatar>
|
||||
</ng-template>
|
||||
|
||||
@ -1,8 +1,4 @@
|
||||
<div
|
||||
[matTooltipClass]="tooltipClass"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
[matTooltip]="tooltip | translate"
|
||||
>
|
||||
<div [matTooltipClass]="tooltipClass" [matTooltipPosition]="tooltipPosition" [matTooltip]="tooltip | translate">
|
||||
<button
|
||||
(click)="performAction($event)"
|
||||
[class.dark-bg]="type === 'dark-bg'"
|
||||
|
||||
@ -1,13 +1,4 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
|
||||
@Component({
|
||||
|
||||
@ -3,11 +3,7 @@
|
||||
[disabled]="disabled || !canDownloadFiles"
|
||||
[tooltipClass]="tooltipClass"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="
|
||||
canDownloadFiles
|
||||
? 'dossier-overview.download-file'
|
||||
: 'dossier-overview.download-file-disabled'
|
||||
"
|
||||
[tooltip]="canDownloadFiles ? 'dossier-overview.download-file' : 'dossier-overview.download-file-disabled'"
|
||||
[type]="type"
|
||||
icon="red:download"
|
||||
></redaction-circle-button>
|
||||
|
||||
@ -36,25 +36,17 @@ export class FileDownloadBtnComponent {
|
||||
return this._permissionsService.canDownloadFiles(this.file);
|
||||
}
|
||||
|
||||
return (
|
||||
this.file.length > 0 &&
|
||||
this.file.reduce(
|
||||
(acc, file) => acc && this._permissionsService.canDownloadFiles(file),
|
||||
true
|
||||
)
|
||||
);
|
||||
return this.file.length > 0 && this.file.reduce((acc, file) => acc && this._permissionsService.canDownloadFiles(file), true);
|
||||
}
|
||||
|
||||
downloadFiles($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this._fileDownloadService
|
||||
.downloadFiles(Array.isArray(this.file) ? this.file : [this.file], this.dossier)
|
||||
.subscribe(() => {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant('download-status.queued', {
|
||||
baseUrl: this._baseHref
|
||||
})
|
||||
);
|
||||
});
|
||||
this._fileDownloadService.downloadFiles(Array.isArray(this.file) ? this.file : [this.file], this.dossier).subscribe(() => {
|
||||
this._notificationService.showToastNotification(
|
||||
this._translateService.instant('download-status.queued', {
|
||||
baseUrl: this._baseHref
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
<button [class.overlay]="showDot" mat-button>
|
||||
<redaction-initials-avatar
|
||||
[userId]="user.userId"
|
||||
[withName]="true"
|
||||
size="small"
|
||||
></redaction-initials-avatar>
|
||||
<redaction-initials-avatar [userId]="user.userId" [withName]="true" size="small"></redaction-initials-avatar>
|
||||
<mat-icon svgIcon="red:arrow-down"></mat-icon>
|
||||
</button>
|
||||
<div *ngIf="showDot" class="dot"></div>
|
||||
|
||||
@ -1,9 +1,4 @@
|
||||
<div
|
||||
#wrapper
|
||||
[class.inactive]="!active && !indeterminate"
|
||||
[class.red-bg]="type === 'red-bg'"
|
||||
class="wrapper"
|
||||
>
|
||||
<div #wrapper [class.inactive]="!active && !indeterminate" [class.red-bg]="type === 'red-bg'" class="wrapper">
|
||||
<mat-icon *ngIf="active && !indeterminate" svgIcon="red:radio-selected"></mat-icon>
|
||||
<mat-icon *ngIf="indeterminate" svgIcon="red:radio-indeterminate"></mat-icon>
|
||||
</div>
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import {
|
||||
Component,
|
||||
ElementRef,
|
||||
HostBinding,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { Component, ElementRef, HostBinding, Input, OnChanges, OnInit, ViewChild } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-round-checkbox',
|
||||
|
||||
@ -1,5 +1 @@
|
||||
<redaction-annotation-icon
|
||||
[color]="color"
|
||||
[label]="label"
|
||||
[type]="type"
|
||||
></redaction-annotation-icon>
|
||||
<redaction-annotation-icon [color]="color" [label]="label" [type]="type"></redaction-annotation-icon>
|
||||
|
||||
@ -19,14 +19,8 @@ export class DictionaryAnnotationIconComponent implements OnChanges {
|
||||
|
||||
ngOnChanges(): void {
|
||||
if (this.dictionaryKey) {
|
||||
const typeValue: TypeValueWrapper = this._appStateService.getDictionaryTypeValue(
|
||||
this.dictionaryKey,
|
||||
this.dossierTemplateId
|
||||
);
|
||||
this.color = this._appStateService.getDictionaryColor(
|
||||
this.dictionaryKey,
|
||||
this.dossierTemplateId
|
||||
);
|
||||
const typeValue: TypeValueWrapper = this._appStateService.getDictionaryTypeValue(this.dictionaryKey, this.dossierTemplateId);
|
||||
this.color = this._appStateService.getDictionaryColor(this.dictionaryKey, this.dossierTemplateId);
|
||||
this.type = typeValue.hint ? 'circle' : 'square';
|
||||
this.label = this.dictionaryKey[0].toUpperCase();
|
||||
}
|
||||
|
||||
@ -80,8 +80,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
.subscribe(entries => {
|
||||
this.diffEditorText = entries;
|
||||
this.showDiffEditor = true;
|
||||
if (this.showDiffEditor)
|
||||
this._diffEditor?.getOriginalEditor().setValue(this.diffEditorText);
|
||||
if (this.showDiffEditor) this._diffEditor?.getOriginalEditor().setValue(this.diffEditorText);
|
||||
});
|
||||
}
|
||||
|
||||
@ -136,9 +135,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
|
||||
@debounce()
|
||||
codeEditorTextChanged() {
|
||||
const newDecorations = this.currentEntries
|
||||
.filter(entry => this._isNew(entry))
|
||||
.map(entry => this._getDecoration(entry));
|
||||
const newDecorations = this.currentEntries.filter(entry => this._isNew(entry)).map(entry => this._getDecoration(entry));
|
||||
|
||||
this._decorations = this._codeEditor.deltaDecorations(this._decorations, newDecorations);
|
||||
}
|
||||
@ -162,13 +159,11 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
}
|
||||
|
||||
private _applySearchDecorations() {
|
||||
this._searchDecorations =
|
||||
this._codeEditor?.deltaDecorations(this._searchDecorations, []) || [];
|
||||
this._searchDecorations = this._codeEditor?.deltaDecorations(this._searchDecorations, []) || [];
|
||||
|
||||
const decorations = this.findMatches.map(match => this._getSearchDecoration(match));
|
||||
|
||||
this._searchDecorations =
|
||||
this._codeEditor?.deltaDecorations(this._searchDecorations, decorations) || [];
|
||||
this._searchDecorations = this._codeEditor?.deltaDecorations(this._searchDecorations, decorations) || [];
|
||||
}
|
||||
|
||||
private _getMatches(text: string): FindMatch[] {
|
||||
@ -199,15 +194,8 @@ export class DictionaryManagerComponent implements OnChanges, OnInit {
|
||||
this._codeEditor.revealLineInCenter(range.startLineNumber, SMOOTH_SCROLL);
|
||||
}
|
||||
|
||||
private _onDossierChanged({
|
||||
dossierId,
|
||||
dossierTemplateId
|
||||
}: DossierWrapper): Observable<string> {
|
||||
const dictionary$ = this._dictionaryControllerService.getDictionaryForType(
|
||||
dossierTemplateId,
|
||||
'dossier_redaction',
|
||||
dossierId
|
||||
);
|
||||
private _onDossierChanged({ dossierId, dossierTemplateId }: DossierWrapper): Observable<string> {
|
||||
const dictionary$ = this._dictionaryControllerService.getDictionaryForType(dossierTemplateId, 'dossier_redaction', dossierId);
|
||||
|
||||
return dictionary$.pipe(map(data => this._toString(data.entries)));
|
||||
}
|
||||
|
||||
@ -1,12 +1,4 @@
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
TemplateRef
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, TemplateRef } from '@angular/core';
|
||||
import { FilterModel } from './model/filter.model';
|
||||
import { handleCheckedValue } from './utils/filter-utils';
|
||||
import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox';
|
||||
@ -42,10 +34,7 @@ export class PopupFilterComponent implements OnChanges {
|
||||
atLeastOneFilterIsExpandable = false;
|
||||
atLeastOneSecondaryFilterIsExpandable = false;
|
||||
|
||||
constructor(
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _translateService: TranslateService
|
||||
) {}
|
||||
constructor(private readonly _changeDetectorRef: ChangeDetectorRef, private readonly _translateService: TranslateService) {}
|
||||
|
||||
get hasActiveFilters(): boolean {
|
||||
return !!this._allFilters.find(f => f.checked || f.indeterminate);
|
||||
@ -57,9 +46,7 @@ export class PopupFilterComponent implements OnChanges {
|
||||
|
||||
ngOnChanges(): void {
|
||||
this.atLeastOneFilterIsExpandable = !!this.primaryFilters?.find(f => this.isExpandable(f));
|
||||
this.atLeastOneSecondaryFilterIsExpandable = !!this.secondaryFilters?.find(f =>
|
||||
this.isExpandable(f)
|
||||
);
|
||||
this.atLeastOneSecondaryFilterIsExpandable = !!this.secondaryFilters?.find(f => this.isExpandable(f));
|
||||
}
|
||||
|
||||
filterCheckboxClicked($event: any, filter: FilterModel, parent?: FilterModel) {
|
||||
|
||||
@ -1,11 +1,4 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy } from '@angular/core';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { User } from '@redaction/red-ui-http';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@ -1,9 +1,4 @@
|
||||
<div
|
||||
(click)="selectPage(currentPage - 1)"
|
||||
[class.disabled]="currentPage < 2"
|
||||
class="page"
|
||||
translate="pagination.previous"
|
||||
></div>
|
||||
<div (click)="selectPage(currentPage - 1)" [class.disabled]="currentPage < 2" class="page" translate="pagination.previous"></div>
|
||||
<span>|</span>
|
||||
<div
|
||||
(click)="selectPage(page)"
|
||||
@ -15,9 +10,4 @@
|
||||
{{ displayValue(page) }}
|
||||
</div>
|
||||
<span>|</span>
|
||||
<div
|
||||
(click)="selectPage(currentPage + 1)"
|
||||
[class.disabled]="currentPage === totalPages - 1"
|
||||
class="page"
|
||||
translate="pagination.next"
|
||||
></div>
|
||||
<div (click)="selectPage(currentPage + 1)" [class.disabled]="currentPage === totalPages - 1" class="page" translate="pagination.next"></div>
|
||||
|
||||
@ -50,11 +50,7 @@ export class PaginationComponent {
|
||||
if (Math.max(1, this.currentPage - 1) > 1) {
|
||||
this.displayedPages.push('...');
|
||||
}
|
||||
for (
|
||||
let page = Math.max(1, this.currentPage - 1);
|
||||
page <= Math.min(this.currentPage + 1, this.totalPages - 1);
|
||||
++page
|
||||
) {
|
||||
for (let page = Math.max(1, this.currentPage - 1); page <= Math.min(this.currentPage + 1, this.totalPages - 1); ++page) {
|
||||
this.displayedPages.push(page);
|
||||
}
|
||||
if (Math.min(this.currentPage + 1, this.totalPages - 1) !== this.totalPages - 1) {
|
||||
|
||||
@ -1,26 +1,13 @@
|
||||
<div class="label-header">
|
||||
<div class="all-caps-label">{{ label }}</div>
|
||||
<div class="actions">
|
||||
<div
|
||||
(click)="selectAll($event)"
|
||||
class="all-caps-label primary pointer"
|
||||
translate="actions.all"
|
||||
></div>
|
||||
<div
|
||||
(click)="deselectAll($event)"
|
||||
class="all-caps-label primary pointer"
|
||||
translate="actions.none"
|
||||
></div>
|
||||
<div (click)="selectAll($event)" class="all-caps-label primary pointer" translate="actions.all"></div>
|
||||
<div (click)="deselectAll($event)" class="all-caps-label primary pointer" translate="actions.none"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-chip-list [disabled]="disabled" [multiple]="multiple" class="options flex-center" selectable>
|
||||
<mat-chip
|
||||
#chip="matChip"
|
||||
(click)="toggleSelection(chip)"
|
||||
*ngFor="let option of options"
|
||||
[value]="option"
|
||||
>
|
||||
<mat-chip #chip="matChip" (click)="toggleSelection(chip)" *ngFor="let option of options" [value]="option">
|
||||
{{ translatePrefix + option | translate }}
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
|
||||
@ -23,10 +23,7 @@
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<div
|
||||
[style]="'height: ' + size + 'px; width: ' + size + 'px; padding: ' + strokeWidth + 'px;'"
|
||||
class="text-container"
|
||||
>
|
||||
<div [style]="'height: ' + size + 'px; width: ' + size + 'px; padding: ' + strokeWidth + 'px;'" class="text-container">
|
||||
<div class="heading-xl">{{ displayedDataTotal }}</div>
|
||||
<div class="mt-5">{{ subtitle | translate }}</div>
|
||||
</div>
|
||||
@ -45,10 +42,7 @@
|
||||
length: val.value,
|
||||
color: val.color,
|
||||
label: getLabel(val),
|
||||
cssClass:
|
||||
val.color === 'PROCESSING' || val.color === 'OCR_PROCESSING'
|
||||
? 'loading'
|
||||
: ''
|
||||
cssClass: val.color === 'PROCESSING' || val.color === 'OCR_PROCESSING' ? 'loading' : ''
|
||||
}
|
||||
]"
|
||||
[small]="true"
|
||||
|
||||
@ -86,9 +86,7 @@ export class SimpleDoughnutChartComponent<T> implements OnChanges {
|
||||
}
|
||||
|
||||
getLabel(config: DoughnutChartConfig): string {
|
||||
return this.totalType === 'sum'
|
||||
? `${config.value} ${config.label}`
|
||||
: `${config.label} (${config.value} ${this.counterText})`;
|
||||
return this.totalType === 'sum' ? `${config.value} ${config.label}` : `${config.label} (${config.value} ${this.counterText})`;
|
||||
}
|
||||
|
||||
selectValue(key: string) {
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
<div [ngClass]="{ small: small }" class="rectangle-container">
|
||||
<div
|
||||
*ngFor="let rect of config"
|
||||
[style]="'flex: ' + (rect.length || 1) + ';'"
|
||||
class="section-wrapper"
|
||||
>
|
||||
<div *ngFor="let rect of config" [style]="'flex: ' + (rect.length || 1) + ';'" class="section-wrapper">
|
||||
<div
|
||||
[className]="'rectangle ' + rect.color"
|
||||
[ngStyle]="{
|
||||
|
||||
@ -14,12 +14,7 @@
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button
|
||||
(click)="confirm()"
|
||||
[disabled]="config.requireInput && confirmationDoesNotMatch()"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
>
|
||||
<button (click)="confirm()" [disabled]="config.requireInput && confirmationDoesNotMatch()" color="primary" mat-flat-button>
|
||||
{{ config.confirmationText }}
|
||||
</button>
|
||||
<div (click)="deny()" class="all-caps-label cancel">
|
||||
@ -27,9 +22,5 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<redaction-circle-button
|
||||
class="dialog-close"
|
||||
icon="red:close"
|
||||
mat-dialog-close
|
||||
></redaction-circle-button>
|
||||
<redaction-circle-button class="dialog-close" icon="red:close" mat-dialog-close></redaction-circle-button>
|
||||
</section>
|
||||
|
||||
@ -48,8 +48,7 @@ export class ConfirmationDialogComponent {
|
||||
) {
|
||||
this.config = _confirmationDialogInput ?? new ConfirmationDialogInput();
|
||||
this.config = this.translate(this.config);
|
||||
this.inputLabel =
|
||||
this.translate(this._inputLabelKey) + ` '${this.config.confirmationText}'`;
|
||||
this.inputLabel = this.translate(this._inputLabelKey) + ` '${this.config.confirmationText}'`;
|
||||
}
|
||||
|
||||
get isDeleteAction() {
|
||||
@ -78,12 +77,9 @@ export class ConfirmationDialogComponent {
|
||||
translate<T extends ConfirmationDialogInput | string>(obj: T): T {
|
||||
const translateKeys = ['title', 'question', 'details', 'confirmationText', 'denyText'];
|
||||
|
||||
if (typeof obj === 'string')
|
||||
return this._translateService.instant(obj, this.config.translateParams);
|
||||
if (typeof obj === 'string') return this._translateService.instant(obj, this.config.translateParams);
|
||||
|
||||
const stringKeys = Object.keys(obj).filter(
|
||||
key => typeof key === 'string' && !!obj[key] && translateKeys.includes(key)
|
||||
);
|
||||
const stringKeys = Object.keys(obj).filter(key => typeof key === 'string' && !!obj[key] && translateKeys.includes(key));
|
||||
stringKeys.forEach(key => (obj[key] = this.translate(obj[key])));
|
||||
|
||||
return obj;
|
||||
|
||||
@ -10,10 +10,7 @@ export class HasScrollbarDirective implements AfterContentChecked {
|
||||
constructor(private readonly _elementRef: ElementRef) {}
|
||||
|
||||
get hasScrollbar() {
|
||||
return (
|
||||
this._elementRef?.nativeElement.clientHeight <
|
||||
this._elementRef?.nativeElement.scrollHeight
|
||||
);
|
||||
return this._elementRef?.nativeElement.clientHeight < this._elementRef?.nativeElement.scrollHeight;
|
||||
}
|
||||
|
||||
ngAfterContentChecked() {
|
||||
|
||||
@ -1,11 +1,4 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Directive,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
Input,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/core';
|
||||
import { debounce } from '@utils/debounce';
|
||||
|
||||
@Directive({
|
||||
@ -32,9 +25,7 @@ export class SyncWidthDirective implements AfterViewInit, OnDestroy {
|
||||
@debounce(10)
|
||||
matchWidth() {
|
||||
const headerItems = this._elementRef.nativeElement.children;
|
||||
const tableRows = this._elementRef.nativeElement.parentElement.getElementsByClassName(
|
||||
this.redactionSyncWidth
|
||||
);
|
||||
const tableRows = this._elementRef.nativeElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
|
||||
|
||||
if (!tableRows || !tableRows.length) {
|
||||
return;
|
||||
@ -48,12 +39,8 @@ export class SyncWidthDirective implements AfterViewInit, OnDestroy {
|
||||
|
||||
for (let idx = 0; idx < length - hasExtraColumns - 1; ++idx) {
|
||||
if (headerItems[idx]) {
|
||||
headerItems[idx].style.width = `${
|
||||
tableRow.children[idx].getBoundingClientRect().width
|
||||
}px`;
|
||||
headerItems[idx].style.minWidth = `${
|
||||
tableRow.children[idx].getBoundingClientRect().width
|
||||
}px`;
|
||||
headerItems[idx].style.width = `${tableRow.children[idx].getBoundingClientRect().width}px`;
|
||||
headerItems[idx].style.minWidth = `${tableRow.children[idx].getBoundingClientRect().width}px`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user