Merge branch 'master' into workflow
This commit is contained in:
commit
aeb804b591
2
.gitignore
vendored
2
.gitignore
vendored
@ -41,3 +41,5 @@ Thumbs.db
|
|||||||
version.properties
|
version.properties
|
||||||
|
|
||||||
paligo-styles/style.css*
|
paligo-styles/style.css*
|
||||||
|
|
||||||
|
migrations.json
|
||||||
|
|||||||
112
angular.json
112
angular.json
@ -19,6 +19,57 @@
|
|||||||
"@nrwl/angular:component": {}
|
"@nrwl/angular:component": {}
|
||||||
},
|
},
|
||||||
"projects": {
|
"projects": {
|
||||||
|
"common-ui": {
|
||||||
|
"projectType": "library",
|
||||||
|
"root": "libs/common-ui",
|
||||||
|
"sourceRoot": "libs/common-ui/src",
|
||||||
|
"prefix": "redaction",
|
||||||
|
"architect": {
|
||||||
|
"test": {
|
||||||
|
"builder": "@nrwl/jest:jest",
|
||||||
|
"outputs": ["coverage/libs/common-ui"],
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "libs/common-ui/jest.config.js",
|
||||||
|
"passWithNoTests": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@nrwl/linter:eslint",
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": ["libs/common-ui/src/**/*.ts", "libs/common-ui/src/**/*.html"]
|
||||||
|
},
|
||||||
|
"outputs": ["{options.outputFile}"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"red-cache": {
|
||||||
|
"projectType": "library",
|
||||||
|
"root": "libs/red-cache",
|
||||||
|
"sourceRoot": "libs/red-cache/src",
|
||||||
|
"prefix": "redaction",
|
||||||
|
"architect": {
|
||||||
|
"lint": {
|
||||||
|
"builder": "@nrwl/linter:eslint",
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": ["libs/red-cache/src/**/*.ts", "libs/red-cache/src/**/*.html"]
|
||||||
|
},
|
||||||
|
"outputs": ["{options.outputFile}"]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@nrwl/jest:jest",
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "libs/red-cache/jest.config.js",
|
||||||
|
"passWithNoTests": true
|
||||||
|
},
|
||||||
|
"outputs": ["coverage/libs/red-cache"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"style": "scss"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"red-ui": {
|
"red-ui": {
|
||||||
"projectType": "application",
|
"projectType": "application",
|
||||||
"schematics": {
|
"schematics": {
|
||||||
@ -38,6 +89,7 @@
|
|||||||
"main": "apps/red-ui/src/main.ts",
|
"main": "apps/red-ui/src/main.ts",
|
||||||
"polyfills": "apps/red-ui/src/polyfills.ts",
|
"polyfills": "apps/red-ui/src/polyfills.ts",
|
||||||
"tsConfig": "apps/red-ui/tsconfig.app.json",
|
"tsConfig": "apps/red-ui/tsconfig.app.json",
|
||||||
|
"baseHref": "/ui/",
|
||||||
"assets": [
|
"assets": [
|
||||||
"apps/red-ui/src/favicon.ico",
|
"apps/red-ui/src/favicon.ico",
|
||||||
{
|
{
|
||||||
@ -57,7 +109,10 @@
|
|||||||
},
|
},
|
||||||
"apps/red-ui/src/manifest.webmanifest"
|
"apps/red-ui/src/manifest.webmanifest"
|
||||||
],
|
],
|
||||||
"styles": ["apps/red-ui/src/styles.scss", "libs/common-ui/src/assets/styles/common.scss"],
|
"styles": ["apps/red-ui/src/styles.scss", "libs/common-ui/src/assets/styles/common-styles.scss"],
|
||||||
|
"stylePreprocessorOptions": {
|
||||||
|
"includePaths": ["./apps/red-ui/src/assets/styles", "./libs/common-ui/src/assets/styles"]
|
||||||
|
},
|
||||||
"scripts": ["node_modules/@pdftron/webviewer/webviewer.min.js"],
|
"scripts": ["node_modules/@pdftron/webviewer/webviewer.min.js"],
|
||||||
"vendorChunk": true,
|
"vendorChunk": true,
|
||||||
"extractLicenses": false,
|
"extractLicenses": false,
|
||||||
@ -120,7 +175,8 @@
|
|||||||
"builder": "@nrwl/linter:eslint",
|
"builder": "@nrwl/linter:eslint",
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": ["apps/red-ui/src/**/*.ts", "apps/red-ui/src/**/*.html"]
|
"lintFilePatterns": ["apps/red-ui/src/**/*.ts", "apps/red-ui/src/**/*.html"]
|
||||||
}
|
},
|
||||||
|
"outputs": ["{options.outputFile}"]
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"builder": "@nrwl/jest:jest",
|
"builder": "@nrwl/jest:jest",
|
||||||
@ -149,7 +205,8 @@
|
|||||||
"builder": "@nrwl/linter:eslint",
|
"builder": "@nrwl/linter:eslint",
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": ["libs/red-ui-http/src/**/*.ts", "libs/red-ui-http/src/**/*.html"]
|
"lintFilePatterns": ["libs/red-ui-http/src/**/*.ts", "libs/red-ui-http/src/**/*.html"]
|
||||||
}
|
},
|
||||||
|
"outputs": ["{options.outputFile}"]
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"builder": "@nrwl/jest:jest",
|
"builder": "@nrwl/jest:jest",
|
||||||
@ -165,55 +222,6 @@
|
|||||||
"style": "scss"
|
"style": "scss"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"red-cache": {
|
|
||||||
"projectType": "library",
|
|
||||||
"root": "libs/red-cache",
|
|
||||||
"sourceRoot": "libs/red-cache/src",
|
|
||||||
"prefix": "redaction",
|
|
||||||
"architect": {
|
|
||||||
"lint": {
|
|
||||||
"builder": "@nrwl/linter:eslint",
|
|
||||||
"options": {
|
|
||||||
"lintFilePatterns": ["libs/red-cache/src/**/*.ts", "libs/red-cache/src/**/*.html"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@nrwl/jest:jest",
|
|
||||||
"options": {
|
|
||||||
"jestConfig": "libs/red-cache/jest.config.js",
|
|
||||||
"passWithNoTests": true
|
|
||||||
},
|
|
||||||
"outputs": ["coverage/libs/red-cache"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"schematics": {
|
|
||||||
"@schematics/angular:component": {
|
|
||||||
"style": "scss"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"common-ui": {
|
|
||||||
"projectType": "library",
|
|
||||||
"root": "libs/common-ui",
|
|
||||||
"sourceRoot": "libs/common-ui/src",
|
|
||||||
"prefix": "redaction",
|
|
||||||
"architect": {
|
|
||||||
"test": {
|
|
||||||
"builder": "@nrwl/jest:jest",
|
|
||||||
"outputs": ["coverage/libs/common-ui"],
|
|
||||||
"options": {
|
|
||||||
"jestConfig": "libs/common-ui/jest.config.js",
|
|
||||||
"passWithNoTests": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"lint": {
|
|
||||||
"builder": "@nrwl/linter:eslint",
|
|
||||||
"options": {
|
|
||||||
"lintFilePatterns": ["libs/common-ui/src/**/*.ts", "libs/common-ui/src/**/*.html"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,9 +4,7 @@ module.exports = {
|
|||||||
globals: {
|
globals: {
|
||||||
'ts-jest': {
|
'ts-jest': {
|
||||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||||
astTransformers: {
|
|
||||||
before: ['jest-preset-angular/build/InlineFilesTransformer', 'jest-preset-angular/build/StripStylesTransformer']
|
|
||||||
},
|
|
||||||
tsconfig: '<rootDir>/tsconfig.spec.json'
|
tsconfig: '<rootDir>/tsconfig.spec.json'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -17,5 +15,6 @@ module.exports = {
|
|||||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||||
'jest-preset-angular/build/serializers/html-comment'
|
'jest-preset-angular/build/serializers/html-comment'
|
||||||
]
|
],
|
||||||
|
transform: { '^.+\\.(ts|js|html)$': 'jest-preset-angular' }
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,16 +30,16 @@ import { MONACO_PATH, MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
|
|||||||
import { GlobalErrorHandler } from '@utils/global-error-handler.service';
|
import { GlobalErrorHandler } from '@utils/global-error-handler.service';
|
||||||
import { REDMissingTranslationHandler } from '@utils/missing-translations-handler';
|
import { REDMissingTranslationHandler } from '@utils/missing-translations-handler';
|
||||||
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
|
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
|
||||||
import { configurationInitializer } from '@app-config/configuration.initializer';
|
import { configurationInitializer } from '@utils/configuration.initializer';
|
||||||
import { AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { SpotlightSearchComponent } from '@components/spotlight-search/spotlight-search.component';
|
import { SpotlightSearchComponent } from '@components/spotlight-search/spotlight-search.component';
|
||||||
import { PruningTranslationLoader } from '@utils/pruning-translation-loader';
|
import { PruningTranslationLoader } from '@utils/pruning-translation-loader';
|
||||||
import { DatePipe } from '@shared/pipes/date.pipe';
|
import { DatePipe } from '@shared/pipes/date.pipe';
|
||||||
import * as links from '../assets/help-mode/links.json';
|
import * as links from '../assets/help-mode/links.json';
|
||||||
import { HELP_DOCS, IqserHelpModeModule } from '@iqser/common-ui';
|
import { HELP_DOCS, IqserHelpModeModule, MAX_RETRIES_ON_SERVER_ERROR, ServerErrorInterceptor } from '@iqser/common-ui';
|
||||||
import { ServerErrorInterceptor } from '@utils/server-error-interceptor';
|
import { KeycloakService } from 'keycloak-angular';
|
||||||
|
|
||||||
export function httpLoaderFactory(httpClient: HttpClient) {
|
export function httpLoaderFactory(httpClient: HttpClient): PruningTranslationLoader {
|
||||||
return new PruningTranslationLoader(httpClient, '/assets/i18n/', '.json');
|
return new PruningTranslationLoader(httpClient, '/assets/i18n/', '.json');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ const components = [
|
|||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
multi: true,
|
multi: true,
|
||||||
useFactory: configurationInitializer,
|
useFactory: configurationInitializer,
|
||||||
deps: [Title, AppConfigService, GeneralSettingsControllerService]
|
deps: [KeycloakService, Title, ConfigService, GeneralSettingsControllerService]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: MONACO_PATH,
|
provide: MONACO_PATH,
|
||||||
@ -145,6 +145,11 @@ const components = [
|
|||||||
provide: HELP_DOCS,
|
provide: HELP_DOCS,
|
||||||
useValue: links
|
useValue: links
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: MAX_RETRIES_ON_SERVER_ERROR,
|
||||||
|
useFactory: (configService: ConfigService) => configService.values.MAX_RETRIES_ON_SERVER_ERROR,
|
||||||
|
deps: [ConfigService]
|
||||||
|
},
|
||||||
DatePipe
|
DatePipe
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
<section>
|
<section>
|
||||||
<p *ngIf="!configuredAdminName && !configuredAdminUrl" class="heading-xl" translate="auth-error.heading"></p>
|
<p *ngIf="!adminName && !adminUrl" class="heading-xl" translate="auth-error.heading"></p>
|
||||||
<p
|
<p
|
||||||
*ngIf="configuredAdminName && configuredAdminUrl"
|
*ngIf="adminName && adminUrl"
|
||||||
[innerHTML]="'auth-error.heading-with-name-and-link' | translate: { adminName: configuredAdminName, adminUrl: configuredAdminUrl }"
|
[innerHTML]="'auth-error.heading-with-name-and-link' | translate: { adminName: adminName, adminUrl: adminUrl }"
|
||||||
class="heading-xl"
|
class="heading-xl"
|
||||||
></p>
|
></p>
|
||||||
<p
|
<p
|
||||||
*ngIf="configuredAdminName && !configuredAdminUrl"
|
*ngIf="adminName && !adminUrl"
|
||||||
[innerHTML]="'auth-error.heading-with-name' | translate: { adminName: configuredAdminName }"
|
[innerHTML]="'auth-error.heading-with-name' | translate: { adminName: adminName }"
|
||||||
class="heading-xl"
|
class="heading-xl"
|
||||||
></p>
|
></p>
|
||||||
<p
|
<p
|
||||||
*ngIf="!configuredAdminName && configuredAdminUrl"
|
*ngIf="!adminName && adminUrl"
|
||||||
[innerHTML]="'auth-error.heading-with-link' | translate: { adminName: configuredAdminName }"
|
[innerHTML]="'auth-error.heading-with-link' | translate: { adminName: adminName }"
|
||||||
class="heading-xl"
|
class="heading-xl"
|
||||||
></p>
|
></p>
|
||||||
<a (click)="logout()" translate="auth-error.logout"></a>
|
<a (click)="userService.logout()" translate="auth-error.logout"></a>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -1,24 +1,15 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-auth-error',
|
selector: 'redaction-auth-error',
|
||||||
templateUrl: './auth-error.component.html',
|
templateUrl: './auth-error.component.html',
|
||||||
styleUrls: ['./auth-error.component.scss']
|
styleUrls: ['./auth-error.component.scss']
|
||||||
})
|
})
|
||||||
export class AuthErrorComponent implements OnInit {
|
export class AuthErrorComponent {
|
||||||
configuredAdminName: string;
|
adminName = this._configService.values.ADMIN_CONTACT_NAME;
|
||||||
configuredAdminUrl: string;
|
adminUrl = this._configService.values.ADMIN_CONTACT_URL;
|
||||||
|
|
||||||
constructor(private readonly _userService: UserService, private readonly _appConfigService: AppConfigService) {}
|
constructor(readonly userService: UserService, private readonly _configService: ConfigService) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.configuredAdminName = this._appConfigService.getConfig(AppConfigKey.ADMIN_CONTACT_NAME);
|
|
||||||
this.configuredAdminUrl = this._appConfigService.getConfig(AppConfigKey.ADMIN_CONTACT_URL);
|
|
||||||
}
|
|
||||||
|
|
||||||
logout() {
|
|
||||||
this._userService.logout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
@import '../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.dev-mode {
|
.dev-mode {
|
||||||
background-color: $primary;
|
background-color: variables.$primary;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
@import '../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
color: $primary;
|
color: variables.$primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat-icon {
|
mat-icon {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.mt-2 {
|
.mt-2 {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
@ -35,7 +35,7 @@
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,17 +45,17 @@
|
|||||||
height: 8px;
|
height: 8px;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: $grey-4;
|
background-color: variables.$grey-4;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
|
|
||||||
.dot {
|
.dot {
|
||||||
background-color: $grey-5;
|
background-color: variables.$grey-5;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@ -64,10 +64,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.unread {
|
&.unread {
|
||||||
background-color: rgba($primary, 0.1);
|
background-color: rgba(variables.$primary, 0.1);
|
||||||
|
|
||||||
.dot {
|
.dot {
|
||||||
background-color: $primary;
|
background-color: variables.$primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.spotlight-row {
|
.spotlight-row {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
@ -9,13 +9,13 @@
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
background-color: $white;
|
background-color: variables.$white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.highlight {
|
.highlight {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
@import '../../../assets/styles/variables';
|
|
||||||
@ -1,10 +1,10 @@
|
|||||||
@import '../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { PermissionsService } from '@services/permissions.service';
|
|||||||
import { LanguageService } from '@i18n/language.service';
|
import { LanguageService } from '@i18n/language.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { UserControllerService } from '@redaction/red-ui-http';
|
import { UserControllerService } from '@redaction/red-ui-http';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { DomSanitizer } from '@angular/platform-browser';
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
import { languagesTranslations } from '../../translations/languages-translations';
|
import { languagesTranslations } from '../../translations/languages-translations';
|
||||||
import { LoadingService } from '@iqser/common-ui';
|
import { LoadingService } from '@iqser/common-ui';
|
||||||
@ -26,7 +26,7 @@ export class UserProfileScreenComponent implements OnInit {
|
|||||||
readonly permissionsService: PermissionsService,
|
readonly permissionsService: PermissionsService,
|
||||||
private readonly _formBuilder: FormBuilder,
|
private readonly _formBuilder: FormBuilder,
|
||||||
private readonly _userService: UserService,
|
private readonly _userService: UserService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _userControllerService: UserControllerService,
|
private readonly _userControllerService: UserControllerService,
|
||||||
private readonly _languageService: LanguageService,
|
private readonly _languageService: LanguageService,
|
||||||
private readonly _domSanitizer: DomSanitizer,
|
private readonly _domSanitizer: DomSanitizer,
|
||||||
@ -42,7 +42,7 @@ export class UserProfileScreenComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.changePasswordUrl = this._domSanitizer.bypassSecurityTrustResourceUrl(
|
this.changePasswordUrl = this._domSanitizer.bypassSecurityTrustResourceUrl(
|
||||||
this._appConfigService.getConfig(AppConfigKey.OAUTH_URL) + '/account/password'
|
this._configService.values.OAUTH_URL + '/account/password'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,11 +57,10 @@ export class AnnotationWrapper {
|
|||||||
|
|
||||||
isChangeLogEntry?: boolean;
|
isChangeLogEntry?: boolean;
|
||||||
changeLogType?: 'ADDED' | 'REMOVED';
|
changeLogType?: 'ADDED' | 'REMOVED';
|
||||||
|
engines?: string[];
|
||||||
|
|
||||||
private _origin: RedactionLogEntryWrapper;
|
private _origin: RedactionLogEntryWrapper;
|
||||||
|
|
||||||
constructor() {}
|
|
||||||
|
|
||||||
get isChangeLogRemoved() {
|
get isChangeLogRemoved() {
|
||||||
return this.changeLogType === 'REMOVED';
|
return this.changeLogType === 'REMOVED';
|
||||||
}
|
}
|
||||||
@ -220,6 +219,7 @@ export class AnnotationWrapper {
|
|||||||
annotationWrapper.legalBasisValue = redactionLogEntry.legalBasis;
|
annotationWrapper.legalBasisValue = redactionLogEntry.legalBasis;
|
||||||
annotationWrapper.comments = redactionLogEntry.comments || [];
|
annotationWrapper.comments = redactionLogEntry.comments || [];
|
||||||
annotationWrapper.manual = redactionLogEntry.manual;
|
annotationWrapper.manual = redactionLogEntry.manual;
|
||||||
|
annotationWrapper.engines = redactionLogEntry.engines;
|
||||||
|
|
||||||
this._createContent(annotationWrapper, redactionLogEntry);
|
this._createContent(annotationWrapper, redactionLogEntry);
|
||||||
this._setSuperType(annotationWrapper, redactionLogEntry);
|
this._setSuperType(annotationWrapper, redactionLogEntry);
|
||||||
|
|||||||
@ -35,4 +35,5 @@ export interface RedactionLogEntryWrapper {
|
|||||||
|
|
||||||
recategorizationType?: string;
|
recategorizationType?: string;
|
||||||
legalBasisChangeValue?: string;
|
legalBasisChangeValue?: string;
|
||||||
|
engines?: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
.first-row {
|
.first-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<div [translateParams]="{ userName: userName }" [translate]="'reset-password-dialog.header'" class="dialog-header heading-l"></div>
|
<div [translateParams]="{ userName: user | name }" [translate]="'reset-password-dialog.header'" class="dialog-header heading-l"></div>
|
||||||
|
|
||||||
<form (submit)="save()" [formGroup]="passwordForm">
|
<form (submit)="save()" [formGroup]="passwordForm">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
|
|||||||
@ -23,10 +23,6 @@ export class ResetPasswordComponent {
|
|||||||
private readonly _loadingService: LoadingService
|
private readonly _loadingService: LoadingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
get userName() {
|
|
||||||
return this._userService.getNameForId(this.user.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
async save() {
|
async save() {
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
await this._userControllerService
|
await this._userControllerService
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.dialog-header {
|
.dialog-header {
|
||||||
color: $primary;
|
color: variables.$primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.dialog-header {
|
.dialog-header {
|
||||||
color: $primary;
|
color: variables.$primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
:host ::ng-deep iqser-table {
|
:host ::ng-deep iqser-table {
|
||||||
iqser-table-header {
|
iqser-table-header {
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
.header-item {
|
.header-item {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-top: 1px solid $separator;
|
border-top: 1px solid variables.$separator;
|
||||||
|
|
||||||
.all-caps-label {
|
.all-caps-label {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
.separator {
|
.separator {
|
||||||
margin-left: 14px;
|
margin-left: 14px;
|
||||||
background-color: $separator;
|
background-color: variables.$separator;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.sub-header {
|
.sub-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -13,7 +13,7 @@
|
|||||||
padding-left: 32px;
|
padding-left: 32px;
|
||||||
min-width: 376px;
|
min-width: 376px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-right: 1px solid $separator;
|
border-right: 1px solid variables.$separator;
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
@ -55,9 +55,9 @@
|
|||||||
.csv-part-header {
|
.csv-part-header {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: $white;
|
background: variables.$white;
|
||||||
border-top: 1px solid $separator;
|
border-top: 1px solid variables.$separator;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -83,14 +83,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-input-container {
|
.search-input-container {
|
||||||
background-color: $white;
|
background-color: variables.$white;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.csv-part-content {
|
.csv-part-content {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@include no-scroll-bar;
|
@include common-mixins.no-scroll-bar;
|
||||||
height: calc(100% - 49px);
|
height: calc(100% - 49px);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
@ -101,13 +101,13 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: $grey-7;
|
color: variables.$grey-7;
|
||||||
line-height: 15px;
|
line-height: 15px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
> *:not(.no-column-data) {
|
> *:not(.no-column-data) {
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 7px 16px;
|
padding: 7px 16px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -117,14 +117,14 @@
|
|||||||
> .left {
|
> .left {
|
||||||
width: 375px;
|
width: 375px;
|
||||||
min-width: 375px;
|
min-width: 375px;
|
||||||
background: $grey-2;
|
background: variables.$grey-2;
|
||||||
|
|
||||||
.csv-header-pill-content {
|
.csv-header-pill-content {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 7px 0;
|
padding: 7px 0;
|
||||||
background: $grey-2;
|
background: variables.$grey-2;
|
||||||
height: calc(100% - 64px);
|
height: calc(100% - 64px);
|
||||||
@include no-scroll-bar;
|
@include common-mixins.no-scroll-bar;
|
||||||
|
|
||||||
&.search-open {
|
&.search-open {
|
||||||
height: calc(100% - 58px - 51px);
|
height: calc(100% - 58px - 51px);
|
||||||
@ -137,7 +137,7 @@
|
|||||||
min-height: 32px;
|
min-height: 32px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background: $white;
|
background: variables.$white;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -153,26 +153,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sample {
|
.sample {
|
||||||
@include line-clamp(1);
|
@include common-mixins.line-clamp(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
background-color: $primary;
|
background-color: variables.$primary;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
border-right: 1px solid $separator;
|
border-right: 1px solid variables.$separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .center {
|
> .center {
|
||||||
width: 150px;
|
width: 150px;
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
background: $grey-2;
|
background: variables.$grey-2;
|
||||||
border-right: 1px solid $separator;
|
border-right: 1px solid variables.$separator;
|
||||||
|
|
||||||
&:not(.collapsed) iqser-circle-button {
|
&:not(.collapsed) iqser-circle-button {
|
||||||
margin-right: -8px;
|
margin-right: -8px;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
:host ::ng-deep iqser-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .table-item > div.cell {
|
:host ::ng-deep iqser-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .table-item > div.cell {
|
||||||
&.center {
|
&.center {
|
||||||
@ -6,7 +6,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.label span {
|
&.label span {
|
||||||
@include line-clamp(1);
|
@include common-mixins.line-clamp(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.read-only mat-icon {
|
&.read-only mat-icon {
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,7 +16,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.inline-input-group {
|
.inline-input-group {
|
||||||
background-color: rgba($grey-6, 0.8);
|
background-color: rgba(variables.$grey-6, 0.8);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import {
|
|||||||
SmtpConfigurationControllerService,
|
SmtpConfigurationControllerService,
|
||||||
SMTPConfigurationModel
|
SMTPConfigurationModel
|
||||||
} from '@redaction/red-ui-http';
|
} from '@redaction/red-ui-http';
|
||||||
import { AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
import { AutoUnsubscribe, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
@ -33,7 +33,7 @@ export class GeneralConfigScreenComponent extends AutoUnsubscribe implements OnI
|
|||||||
private readonly _formBuilder: FormBuilder,
|
private readonly _formBuilder: FormBuilder,
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _dialogService: AdminDialogService,
|
private readonly _dialogService: AdminDialogService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _smtpConfigService: SmtpConfigurationControllerService,
|
private readonly _smtpConfigService: SmtpConfigurationControllerService,
|
||||||
private readonly _generalSettingsControllerService: GeneralSettingsControllerService
|
private readonly _generalSettingsControllerService: GeneralSettingsControllerService
|
||||||
) {
|
) {
|
||||||
@ -112,7 +112,7 @@ export class GeneralConfigScreenComponent extends AutoUnsubscribe implements OnI
|
|||||||
|
|
||||||
await this._generalSettingsControllerService.updateGeneralConfigurations(configFormValues).toPromise();
|
await this._generalSettingsControllerService.updateGeneralConfigurations(configFormValues).toPromise();
|
||||||
this._initialGeneralConfiguration = await this._generalSettingsControllerService.getGeneralConfigurations().toPromise();
|
this._initialGeneralConfiguration = await this._generalSettingsControllerService.getGeneralConfigurations().toPromise();
|
||||||
this._appConfigService.updateDisplayName(this._initialGeneralConfiguration.displayName);
|
this._configService.updateDisplayName(this._initialGeneralConfiguration.displayName);
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,17 +16,17 @@
|
|||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div translate="license-info-screen.backend-version"></div>
|
<div translate="license-info-screen.backend-version"></div>
|
||||||
<div>{{ appConfigService.getConfig('BACKEND_APP_VERSION', '-') }}</div>
|
<div>{{ configService.values.BACKEND_APP_VERSION || '-' }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div translate="license-info-screen.frontend-version"></div>
|
<div translate="license-info-screen.frontend-version"></div>
|
||||||
<div>{{ appConfigService.getConfig('FRONTEND_APP_VERSION', '-') }}</div>
|
<div>{{ configService.values.FRONTEND_APP_VERSION || '-' }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div translate="license-info-screen.custom-app-title"></div>
|
<div translate="license-info-screen.custom-app-title"></div>
|
||||||
<div>{{ appConfigService.getConfig('APP_NAME', '-') }}</div>
|
<div>{{ configService.values.APP_NAME || '-' }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -45,14 +45,14 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div translate="license-info-screen.licensed-to"></div>
|
<div translate="license-info-screen.licensed-to"></div>
|
||||||
<div>{{ appConfigService.getConfig('LICENSE_CUSTOMER', '-') }}</div>
|
<div>{{ configService.values.LICENSE_CUSTOMER || '-' }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div translate="license-info-screen.licensing-period"></div>
|
<div translate="license-info-screen.licensing-period"></div>
|
||||||
<div>
|
<div>
|
||||||
{{ appConfigService.getConfig('LICENSE_START', '-') }} /
|
{{ configService.values.LICENSE_START || '-' }} /
|
||||||
{{ appConfigService.getConfig('LICENSE_END', '-') }}
|
{{ configService.values.LICENSE_END || '-' }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -107,8 +107,7 @@
|
|||||||
[yAxisLabelRight]="'license-info-screen.chart.total-pages' | translate"
|
[yAxisLabelRight]="'license-info-screen.chart.total-pages' | translate"
|
||||||
[yAxisLabel]="'license-info-screen.chart.pages-per-month' | translate"
|
[yAxisLabel]="'license-info-screen.chart.pages-per-month' | translate"
|
||||||
[yAxis]="true"
|
[yAxis]="true"
|
||||||
>
|
></combo-chart-component>
|
||||||
</combo-chart-component>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
> div {
|
> div {
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@
|
|||||||
grid-column: span 2;
|
grid-column: span 2;
|
||||||
padding: 20px 20px 8px;
|
padding: 20px 20px 8px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { LicenseReport, LicenseReportControllerService } from '@redaction/red-ui-http';
|
import { LicenseReport, LicenseReportControllerService } from '@redaction/red-ui-http';
|
||||||
import { AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { IconButtonTypes, LoadingService } from '@iqser/common-ui';
|
import { IconButtonTypes, LoadingService } from '@iqser/common-ui';
|
||||||
@ -29,10 +29,8 @@ export class LicenseInformationScreenComponent implements OnInit {
|
|||||||
unlicensedInfo: LicenseReport = {};
|
unlicensedInfo: LicenseReport = {};
|
||||||
totalLicensedNumberOfPages = 0;
|
totalLicensedNumberOfPages = 0;
|
||||||
analysisPercentageOfLicense = 100;
|
analysisPercentageOfLicense = 100;
|
||||||
barChart: any[] = [];
|
barChart: any[];
|
||||||
lineChartSeries: any[] = [];
|
lineChartSeries: any[] = [];
|
||||||
yAxisLabel = this._translateService.instant('license-info-screen.chart.pages-per-month');
|
|
||||||
yAxisLabelRight = this._translateService.instant('license-info-screen.chart.total-pages');
|
|
||||||
lineChartScheme = {
|
lineChartScheme = {
|
||||||
selectable: true,
|
selectable: true,
|
||||||
group: 'Ordinal',
|
group: 'Ordinal',
|
||||||
@ -45,8 +43,8 @@ export class LicenseInformationScreenComponent implements OnInit {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
readonly configService: ConfigService,
|
||||||
private readonly _userService: UserService,
|
private readonly _userService: UserService,
|
||||||
readonly appConfigService: AppConfigService,
|
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
readonly routerHistoryService: RouterHistoryService,
|
readonly routerHistoryService: RouterHistoryService,
|
||||||
private readonly _translateService: TranslateService,
|
private readonly _translateService: TranslateService,
|
||||||
@ -60,9 +58,9 @@ export class LicenseInformationScreenComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.totalLicensedNumberOfPages = this.appConfigService.getConfig('LICENSE_PAGE_COUNT', 0);
|
this.totalLicensedNumberOfPages = this.configService.values.LICENSE_PAGE_COUNT || 0;
|
||||||
const startDate = moment(this.appConfigService.getConfig('LICENSE_START'), 'DD-MM-YYYY');
|
const startDate = moment(this.configService.values.LICENSE_START, 'DD-MM-YYYY');
|
||||||
const endDate = moment(this.appConfigService.getConfig('LICENSE_END'), 'DD-MM-YYYY');
|
const endDate = moment(this.configService.values.LICENSE_END, 'DD-MM-YYYY');
|
||||||
|
|
||||||
await this._setMonthlyStats(startDate, endDate);
|
await this._setMonthlyStats(startDate, endDate);
|
||||||
|
|
||||||
@ -93,7 +91,7 @@ export class LicenseInformationScreenComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendMail(): void {
|
sendMail(): void {
|
||||||
const licenseCustomer = this.appConfigService.getConfig('LICENSE_CUSTOMER');
|
const licenseCustomer = this.configService.values.LICENSE_CUSTOMER;
|
||||||
const subject = this._translateService.instant('license-info-screen.email.title', {
|
const subject = this._translateService.instant('license-info-screen.email.title', {
|
||||||
licenseCustomer
|
licenseCustomer
|
||||||
});
|
});
|
||||||
@ -106,7 +104,7 @@ export class LicenseInformationScreenComponent implements OnInit {
|
|||||||
pages: this.totalLicensedNumberOfPages
|
pages: this.totalLicensedNumberOfPages
|
||||||
})
|
})
|
||||||
].join(lineBreak);
|
].join(lineBreak);
|
||||||
window.location.href = `mailto:${this.appConfigService.getConfig('LICENSE_EMAIL')}?subject=${subject}&body=${body}`;
|
window.location.href = `mailto:${this.configService.values.LICENSE_EMAIL}?subject=${subject}&body=${body}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _setMonthlyStats(startDate: moment.Moment, endDate: moment.Moment) {
|
private async _setMonthlyStats(startDate: moment.Moment, endDate: moment.Moment) {
|
||||||
@ -151,6 +149,7 @@ export class LicenseInformationScreenComponent implements OnInit {
|
|||||||
m = startMonth;
|
m = startMonth;
|
||||||
y = startYear;
|
y = startYear;
|
||||||
let cumulativePages = 0;
|
let cumulativePages = 0;
|
||||||
|
this.barChart = [];
|
||||||
for (const report of reports) {
|
for (const report of reports) {
|
||||||
cumulativePages += report.numberOfAnalyzedPages;
|
cumulativePages += report.numberOfAnalyzedPages;
|
||||||
this.barChart.push({
|
this.barChart.push({
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.content-container,
|
.content-container,
|
||||||
.right-container {
|
.right-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-container {
|
.right-container {
|
||||||
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
.template {
|
.template {
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
.name {
|
.name {
|
||||||
max-width: calc(100% - 100px);
|
max-width: calc(100% - 100px);
|
||||||
@include line-clamp(1);
|
@include common-mixins.line-clamp(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
@ -48,7 +48,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-4;
|
background-color: variables.$grey-4;
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -81,8 +81,8 @@
|
|||||||
grid-template-columns: 1fr 2fr;
|
grid-template-columns: 1fr 2fr;
|
||||||
|
|
||||||
.all-caps-label {
|
.all-caps-label {
|
||||||
border-top: 1px solid $separator;
|
border-top: 1px solid variables.$separator;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
padding: 8px 32px;
|
padding: 8px 32px;
|
||||||
|
|
||||||
&:nth-child(2) {
|
&:nth-child(2) {
|
||||||
@ -93,7 +93,7 @@
|
|||||||
.placeholder,
|
.placeholder,
|
||||||
.description {
|
.description {
|
||||||
padding: 16px 16px;
|
padding: 16px 16px;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
.placeholder {
|
.placeholder {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import {
|
|||||||
SortingOrders,
|
SortingOrders,
|
||||||
TableColumnConfig
|
TableColumnConfig
|
||||||
} from '@iqser/common-ui';
|
} from '@iqser/common-ui';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
import { DossiersService } from '../../../dossier/services/dossiers.service';
|
||||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||||
@ -45,14 +45,14 @@ export class TrashScreenComponent extends ListingComponent<DossierListItem> impl
|
|||||||
@ViewChild('deletedTimeTemplate', { static: true }) deletedTimeTemplate: TemplateRef<never>;
|
@ViewChild('deletedTimeTemplate', { static: true }) deletedTimeTemplate: TemplateRef<never>;
|
||||||
@ViewChild('restoreDateTemplate', { static: true }) restoreDateTemplate: TemplateRef<never>;
|
@ViewChild('restoreDateTemplate', { static: true }) restoreDateTemplate: TemplateRef<never>;
|
||||||
protected readonly _primaryKey = 'dossierName';
|
protected readonly _primaryKey = 'dossierName';
|
||||||
private readonly _deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS);
|
private readonly _deleteRetentionHours = this._configService.values.DELETE_RETENTION_HOURS;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly _injector: Injector,
|
protected readonly _injector: Injector,
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _dossiersService: DossiersService,
|
private readonly _dossiersService: DossiersService,
|
||||||
readonly routerHistoryService: RouterHistoryService,
|
readonly routerHistoryService: RouterHistoryService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _adminDialogService: AdminDialogService
|
private readonly _adminDialogService: AdminDialogService
|
||||||
) {
|
) {
|
||||||
super(_injector);
|
super(_injector);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.content-container {
|
.content-container {
|
||||||
order: 1;
|
order: 1;
|
||||||
@ -15,7 +15,7 @@
|
|||||||
min-width: 353px;
|
min-width: 353px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-right: 1px solid $separator;
|
border-right: 1px solid variables.$separator;
|
||||||
|
|
||||||
&.has-scrollbar:hover {
|
&.has-scrollbar:hover {
|
||||||
padding-right: 13px;
|
padding-right: 13px;
|
||||||
@ -32,8 +32,8 @@
|
|||||||
width: 60px;
|
width: 60px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
color: $grey-7;
|
color: variables.$grey-7;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -46,7 +46,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:not(.disabled):not(.active):hover {
|
&:not(.disabled):not(.active):hover {
|
||||||
background-color: darken($grey-6, 2);
|
background-color: darken(variables.$grey-6, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
@ -54,8 +54,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background-color: $primary;
|
background-color: variables.$primary;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.times-new-roman {
|
&.times-new-roman {
|
||||||
|
|||||||
@ -5,9 +5,8 @@ import { AppStateService } from '@state/app-state.service';
|
|||||||
import { environment } from '@environments/environment';
|
import { environment } from '@environments/environment';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { Debounce, IconButtonTypes, LoadingService } from '@iqser/common-ui';
|
import { Debounce, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||||
import { WatermarkControllerService, WatermarkModelRes } from '@redaction/red-ui-http';
|
import { WatermarkControllerService, WatermarkModelRes } from '@redaction/red-ui-http';
|
||||||
import { Toaster } from '@iqser/common-ui';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { BASE_HREF } from '../../../../tokens';
|
import { BASE_HREF } from '../../../../tokens';
|
||||||
import { stampPDFPage } from '@utils/page-stamper';
|
import { stampPDFPage } from '@utils/page-stamper';
|
||||||
@ -137,7 +136,7 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
).then(instance => {
|
).then(instance => {
|
||||||
this._instance = instance;
|
this._instance = instance;
|
||||||
|
|
||||||
instance.docViewer.on('documentLoaded', async () => {
|
instance.Core.documentViewer.on('documentLoaded', async () => {
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
await this._drawWatermark();
|
await this._drawWatermark();
|
||||||
});
|
});
|
||||||
@ -149,19 +148,19 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
.subscribe(blobData => {
|
.subscribe(blobData => {
|
||||||
this._instance.loadDocument(blobData, { filename: 'blank.pdf' });
|
this._instance.UI.loadDocument(blobData, { filename: 'blank.pdf' });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _disableElements() {
|
private _disableElements() {
|
||||||
this._instance.disableElements(['header', 'toolsHeader', 'pageNavOverlay', 'textPopup']);
|
this._instance.UI.disableElements(['header', 'toolsHeader', 'pageNavOverlay', 'textPopup']);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _drawWatermark() {
|
private async _drawWatermark() {
|
||||||
const pdfNet = this._instance.PDFNet;
|
const pdfNet = this._instance.Core.PDFNet;
|
||||||
const document = await this._instance.docViewer.getDocument().getPDFDoc();
|
const document = await this._instance.Core.documentViewer.getDocument().getPDFDoc();
|
||||||
|
|
||||||
const text = this.configForm.get('text').value || '';
|
const text = this.configForm.get('text').value || '';
|
||||||
const fontSize = this.configForm.get('fontSize').value;
|
const fontSize = this.configForm.get('fontSize').value;
|
||||||
@ -171,8 +170,8 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
const color = this.configForm.get('hexColor').value;
|
const color = this.configForm.get('hexColor').value;
|
||||||
|
|
||||||
await stampPDFPage(document, pdfNet, text, fontSize, fontType, orientation, opacity, color, [1]);
|
await stampPDFPage(document, pdfNet, text, fontSize, fontType, orientation, opacity, color, [1]);
|
||||||
this._instance.docViewer.refreshAll();
|
this._instance.Core.documentViewer.refreshAll();
|
||||||
this._instance.docViewer.updateView([0], 0);
|
this._instance.Core.documentViewer.updateView([0], 0);
|
||||||
this._changeDetectorRef.detectChanges();
|
this._changeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
|
||||||
import { AppConfigService } from './app-config.service';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [],
|
|
||||||
imports: [CommonModule, HttpClientModule],
|
|
||||||
providers: [AppConfigService]
|
|
||||||
})
|
|
||||||
export class AppConfigModule {}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { tap } from 'rxjs/operators';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { Title } from '@angular/platform-browser';
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
import packageInfo from '../../../../../../package.json';
|
|
||||||
import { CacheApiService, wipeCaches } from '@redaction/red-cache';
|
|
||||||
|
|
||||||
export enum AppConfigKey {
|
|
||||||
OAUTH_URL = 'OAUTH_URL',
|
|
||||||
OAUTH_CLIENT_ID = 'OAUTH_CLIENT_ID',
|
|
||||||
OAUTH_IDP_HINT = 'OAUTH_IDP_HINT',
|
|
||||||
API_URL = 'API_URL',
|
|
||||||
ADMIN_CONTACT_NAME = 'ADMIN_CONTACT_NAME',
|
|
||||||
ADMIN_CONTACT_URL = 'ADMIN_CONTACT_URL',
|
|
||||||
AUTO_READ_TIME = 'AUTO_READ_TIME',
|
|
||||||
SELECTION_MODE = 'SELECTION_MODE',
|
|
||||||
MAX_FILE_SIZE_MB = 'MAX_FILE_SIZE_MB',
|
|
||||||
RECENT_PERIOD_IN_HOURS = 'RECENT_PERIOD_IN_HOURS',
|
|
||||||
DELETE_RETENTION_HOURS = 'DELETE_RETENTION_HOURS',
|
|
||||||
APP_NAME = 'APP_NAME',
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
BACKEND_APP_VERSION = 'BACKEND_APP_VERSION',
|
|
||||||
FRONTEND_APP_VERSION = 'FRONTEND_APP_VERSION',
|
|
||||||
EULA_URL = 'EULA_URL',
|
|
||||||
LICENSE_CUSTOMER = 'LICENSE_CUSTOMER',
|
|
||||||
LICENSE_EMAIL = 'LICENSE_EMAIL',
|
|
||||||
LICENSE_START = 'LICENSE_START',
|
|
||||||
LICENSE_END = 'LICENSE_END',
|
|
||||||
LICENSE_PAGE_COUNT = 'LICENSE_PAGE_COUNT'
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class AppConfigService {
|
|
||||||
private _config: { [key in AppConfigKey]?: any } = {};
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private readonly _httpClient: HttpClient,
|
|
||||||
private readonly _cacheApiService: CacheApiService,
|
|
||||||
private readonly _titleService: Title
|
|
||||||
) {}
|
|
||||||
|
|
||||||
get version(): string {
|
|
||||||
return packageInfo.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
return this._httpClient.get<any>('/assets/config/config.json').pipe(
|
|
||||||
tap(config => {
|
|
||||||
console.log('[REDACTION] Started with config: ', config);
|
|
||||||
this._config = config;
|
|
||||||
this._config[AppConfigKey.FRONTEND_APP_VERSION] = this.version;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateDisplayName(name: string) {
|
|
||||||
this.setConfig(AppConfigKey.APP_NAME, name);
|
|
||||||
this._titleService.setTitle(this.getConfig(AppConfigKey.APP_NAME, 'RedactManager'));
|
|
||||||
}
|
|
||||||
|
|
||||||
setConfig(key: AppConfigKey, value: any) {
|
|
||||||
this._config[key] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
getConfig(key: AppConfigKey | string, defaultValue?: any) {
|
|
||||||
return this._config[key] ? this._config[key] : defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
import { GeneralSettingsControllerService } from '@redaction/red-ui-http';
|
|
||||||
import { catchError, mergeMap, take, tap } from 'rxjs/operators';
|
|
||||||
import { AppConfigService } from './app-config.service';
|
|
||||||
import { Title } from '@angular/platform-browser';
|
|
||||||
import { APP_BOOTSTRAPPED } from '../bootstrap/app-bootstrap';
|
|
||||||
import { of } from 'rxjs';
|
|
||||||
|
|
||||||
export function configurationInitializer(
|
|
||||||
title: Title,
|
|
||||||
appConfigService: AppConfigService,
|
|
||||||
generalSettingsControllerService: GeneralSettingsControllerService
|
|
||||||
) {
|
|
||||||
return () =>
|
|
||||||
APP_BOOTSTRAPPED.pipe(
|
|
||||||
mergeMap(() =>
|
|
||||||
generalSettingsControllerService.getGeneralConfigurations().pipe(
|
|
||||||
tap(configuration => {
|
|
||||||
appConfigService.updateDisplayName(configuration.displayName);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
),
|
|
||||||
catchError(() => {
|
|
||||||
title.setTitle('RedactManager');
|
|
||||||
return of({});
|
|
||||||
}),
|
|
||||||
take(1)
|
|
||||||
).toPromise();
|
|
||||||
}
|
|
||||||
@ -2,7 +2,7 @@ import { Inject, Injectable } from '@angular/core';
|
|||||||
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
|
||||||
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
|
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { BASE_HREF } from '../../tokens';
|
import { BASE_HREF } from '../../tokens';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -10,19 +10,20 @@ import { BASE_HREF } from '../../tokens';
|
|||||||
})
|
})
|
||||||
export class AuthGuard extends KeycloakAuthGuard {
|
export class AuthGuard extends KeycloakAuthGuard {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
|
||||||
protected readonly _router: Router,
|
protected readonly _router: Router,
|
||||||
|
private readonly _userService: UserService,
|
||||||
protected readonly _keycloak: KeycloakService,
|
protected readonly _keycloak: KeycloakService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _userService: UserService
|
@Inject(BASE_HREF) private readonly _baseHref: string
|
||||||
) {
|
) {
|
||||||
super(_router, _keycloak);
|
super(_router, _keycloak);
|
||||||
}
|
}
|
||||||
|
|
||||||
async isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
async isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
|
||||||
if (!this.authenticated) {
|
if (!this.authenticated) {
|
||||||
|
const kcIdpHint = route.queryParamMap.get('kc_idp_hint');
|
||||||
await this._keycloak.login({
|
await this._keycloak.login({
|
||||||
idpHint: this._appConfigService.getConfig(AppConfigKey.OAUTH_IDP_HINT, null),
|
idpHint: kcIdpHint ?? this._configService.values.OAUTH_IDP_HINT,
|
||||||
redirectUri: window.location.origin + this._baseHref + state.url
|
redirectUri: window.location.origin + this._baseHref + state.url
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -1,59 +1,50 @@
|
|||||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { AppConfigModule } from '@app-config/app-config.module';
|
|
||||||
|
|
||||||
import { KeycloakAngularModule, KeycloakOptions, KeycloakService } from 'keycloak-angular';
|
import { KeycloakAngularModule, KeycloakOptions, KeycloakService } from 'keycloak-angular';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { BASE_HREF } from '../../tokens';
|
import { BASE_HREF } from '../../tokens';
|
||||||
import { APP_BOOTSTRAPPED } from '../bootstrap/app-bootstrap';
|
import { environment } from '@environments/environment';
|
||||||
|
|
||||||
export function keycloakInitializer(keycloak: KeycloakService, appConfigService: AppConfigService, baseUrl) {
|
export function keycloakInitializer(keycloakService: KeycloakService, configService: ConfigService, baseUrl: string): () => Promise<void> {
|
||||||
return () =>
|
let url = configService.values.OAUTH_URL;
|
||||||
appConfigService
|
url = url.replace(/\/$/, ''); // remove trailing slash
|
||||||
.loadAppConfig()
|
const realm = url.substring(url.lastIndexOf('/') + 1, url.length);
|
||||||
.toPromise()
|
url = url.substr(0, url.lastIndexOf('/realms'));
|
||||||
.then(() => {
|
const options: KeycloakOptions = {
|
||||||
let url = appConfigService.getConfig(AppConfigKey.OAUTH_URL);
|
config: {
|
||||||
url = url.replace(/\/$/, ''); // remove trailing slash
|
url: url,
|
||||||
const realm = url.substring(url.lastIndexOf('/') + 1, url.length);
|
realm: realm,
|
||||||
url = url.substr(0, url.lastIndexOf('/realms'));
|
clientId: configService.values.OAUTH_CLIENT_ID
|
||||||
const options: KeycloakOptions = {
|
},
|
||||||
config: {
|
initOptions: {
|
||||||
url: url,
|
checkLoginIframe: false,
|
||||||
realm: realm,
|
onLoad: 'login-required',
|
||||||
clientId: appConfigService.getConfig(AppConfigKey.OAUTH_CLIENT_ID)
|
silentCheckSsoRedirectUri: environment.production
|
||||||
},
|
? window.location.origin + baseUrl + '/assets/oauth/silent-refresh.html'
|
||||||
initOptions: {
|
: null,
|
||||||
checkLoginIframe: false,
|
flow: 'standard'
|
||||||
onLoad: 'check-sso',
|
},
|
||||||
silentCheckSsoRedirectUri: window.location.origin + baseUrl + '/assets/oauth/silent-refresh.html',
|
enableBearerInterceptor: true
|
||||||
flow: 'standard'
|
};
|
||||||
},
|
return () => keycloakService.init(options).then(() => configureAutomaticRedirectToLoginScreen(keycloakService));
|
||||||
enableBearerInterceptor: true
|
|
||||||
};
|
|
||||||
return keycloak
|
|
||||||
.init(options)
|
|
||||||
.then(() => configureAutomaticRedirectToLoginScreen(keycloak))
|
|
||||||
.then(() => APP_BOOTSTRAPPED.next(true));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function configureAutomaticRedirectToLoginScreen(keyCloakService: KeycloakService) {
|
function configureAutomaticRedirectToLoginScreen(keyCloakService: KeycloakService) {
|
||||||
keyCloakService.getKeycloakInstance().onAuthRefreshError = () => {
|
keyCloakService.getKeycloakInstance().onAuthRefreshError = async () => {
|
||||||
keyCloakService.logout();
|
await keyCloakService.logout();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [],
|
imports: [CommonModule, HttpClientModule, KeycloakAngularModule],
|
||||||
imports: [CommonModule, HttpClientModule, KeycloakAngularModule, AppConfigModule],
|
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
useFactory: keycloakInitializer,
|
useFactory: keycloakInitializer,
|
||||||
multi: true,
|
multi: true,
|
||||||
deps: [KeycloakService, AppConfigService, BASE_HREF]
|
deps: [KeycloakService, ConfigService, BASE_HREF]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
import { ReplaySubject } from 'rxjs';
|
|
||||||
|
|
||||||
export const APP_BOOTSTRAPPED = new ReplaySubject<boolean>();
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.annotation-actions {
|
.annotation-actions {
|
||||||
display: none;
|
display: none;
|
||||||
@ -8,7 +8,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.confirm.active {
|
.confirm.active {
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
> *:not(:last-child) {
|
> *:not(:last-child) {
|
||||||
|
|||||||
@ -48,8 +48,8 @@ export class AnnotationActionsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get viewerAnnotations() {
|
get viewerAnnotations() {
|
||||||
if (this.viewer?.annotManager) {
|
if (this.viewer?.Core.annotationManager) {
|
||||||
return this._annotations.map(a => this.viewer?.annotManager?.getAnnotationById(a.id));
|
return this._annotations.map(a => this.viewer?.Core.annotationManager?.getAnnotationById(a.id));
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -78,15 +78,15 @@ export class AnnotationActionsComponent implements OnInit {
|
|||||||
|
|
||||||
hideAnnotation($event: MouseEvent) {
|
hideAnnotation($event: MouseEvent) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this.viewer.annotManager.hideAnnotations(this.viewerAnnotations);
|
this.viewer.Core.annotationManager.hideAnnotations(this.viewerAnnotations);
|
||||||
this.viewer.annotManager.deselectAllAnnotations();
|
this.viewer.Core.annotationManager.deselectAllAnnotations();
|
||||||
this.annotationActionsService.updateHiddenAnnotation(this.annotations, this.viewerAnnotations, true);
|
this.annotationActionsService.updateHiddenAnnotation(this.annotations, this.viewerAnnotations, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
showAnnotation($event: MouseEvent) {
|
showAnnotation($event: MouseEvent) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this.viewer.annotManager.showAnnotations(this.viewerAnnotations);
|
this.viewer.Core.annotationManager.showAnnotations(this.viewerAnnotations);
|
||||||
this.viewer.annotManager.deselectAllAnnotations();
|
this.viewer.Core.annotationManager.deselectAllAnnotations();
|
||||||
this.annotationActionsService.updateHiddenAnnotation(this.annotations, this.viewerAnnotations, false);
|
this.annotationActionsService.updateHiddenAnnotation(this.annotations, this.viewerAnnotations, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -177,7 +177,22 @@ export class DossierOverviewBulkActionsComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
approveDocuments() {
|
approveDocuments() {
|
||||||
this._performBulkAction(this._fileActionService.setFileApproved(this.selectedFiles));
|
const foundUpdatedFile = this.selectedFiles.find(file => file.hasUpdates);
|
||||||
|
if (foundUpdatedFile) {
|
||||||
|
this._dialogService.openDialog(
|
||||||
|
'confirm',
|
||||||
|
null,
|
||||||
|
new ConfirmationDialogInput({
|
||||||
|
title: _('confirmation-dialog.approve-multiple-files.title'),
|
||||||
|
question: _('confirmation-dialog.approve-multiple-files.question')
|
||||||
|
}),
|
||||||
|
() => {
|
||||||
|
this._performBulkAction(this._fileActionService.setFileApproved(this.selectedFiles));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this._performBulkAction(this._fileActionService.setFileApproved(this.selectedFiles));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assignToMe() {
|
assignToMe() {
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
<div *ngFor="let comment of annotation.comments" class="comment">
|
<div *ngFor="let comment of annotation.comments" class="comment">
|
||||||
<div class="comment-details-wrapper">
|
<div class="comment-details-wrapper">
|
||||||
<div [matTooltipPosition]="'above'" [matTooltip]="comment.date | date: 'exactDate'" class="small-label">
|
<div [matTooltipPosition]="'above'" [matTooltip]="comment.date | date: 'exactDate'" class="small-label">
|
||||||
<b> {{ getOwnerName(comment) }} </b>
|
<strong> {{ comment.user | name }} </strong>
|
||||||
{{ comment.date | date: 'sophisticatedDate' }}
|
{{ comment.date | date: 'sophisticatedDate' }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="comment-actions">
|
<div class="comment-actions">
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
(action)="deleteComment(comment)"
|
(action)="deleteComment(comment)"
|
||||||
@ -15,6 +16,7 @@
|
|||||||
></iqser-circle-button>
|
></iqser-circle-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>{{ comment.text }}</div>
|
<div>{{ comment.text }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@ -52,8 +52,4 @@ export class CommentsComponent {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getOwnerName(comment: Comment): string {
|
|
||||||
return this._userService.getNameForId(comment.user);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
@ -13,7 +13,7 @@
|
|||||||
.right-content {
|
.right-content {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -42,7 +42,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import '../../../../../assets/styles/red-components';
|
@use 'red-components';
|
||||||
@import 'libs/common-ui/src/assets/styles/texts';
|
@use 'common-texts';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
@extend .stats-subtitle;
|
@extend .stats-subtitle;
|
||||||
@ -22,7 +22,7 @@
|
|||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.header-wrapper {
|
.header-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -29,11 +29,11 @@
|
|||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background-color: rgba($primary, 0.1);
|
background-color: rgba(variables.$primary, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:last-of-type) {
|
&:not(:last-of-type) {
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<ng-container *ngTemplateOutlet="actions"></ng-container>
|
<ng-container *ngTemplateOutlet="actions"></ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-template #actions>
|
<ng-template #actions redactionLongPress (longPress)="forceReanalysisAction($event)">
|
||||||
<div *ngIf="fileStatus" class="file-actions">
|
<div *ngIf="fileStatus" class="file-actions">
|
||||||
<iqser-circle-button
|
<iqser-circle-button
|
||||||
(action)="openDocument()"
|
(action)="openDocument()"
|
||||||
@ -145,7 +145,6 @@
|
|||||||
[type]="circleButtonTypes.dark"
|
[type]="circleButtonTypes.dark"
|
||||||
icon="iqser:refresh"
|
icon="iqser:refresh"
|
||||||
></iqser-circle-button>
|
></iqser-circle-button>
|
||||||
|
|
||||||
<!-- exclude from redaction -->
|
<!-- exclude from redaction -->
|
||||||
<div class="iqser-input-group">
|
<div class="iqser-input-group">
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.file-actions {
|
.file-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@include no-scroll-bar;
|
@include common-mixins.no-scroll-bar;
|
||||||
|
|
||||||
> *:not(:last-child) {
|
> *:not(:last-child) {
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import { FileManagementControllerService, FileStatus } from '@redaction/red-ui-h
|
|||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
import { filter } from 'rxjs/operators';
|
import { filter } from 'rxjs/operators';
|
||||||
|
import { UserPreferenceService } from '../../../../services/user-preference.service';
|
||||||
|
import { LongPressEvent } from '../../../shared/directives/long-press.directive';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-file-actions',
|
selector: 'redaction-file-actions',
|
||||||
@ -55,7 +57,8 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
|||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _fileManagementControllerService: FileManagementControllerService,
|
private readonly _fileManagementControllerService: FileManagementControllerService,
|
||||||
private readonly _userService: UserService,
|
private readonly _userService: UserService,
|
||||||
private readonly _toaster: Toaster
|
private readonly _toaster: Toaster,
|
||||||
|
private readonly _userPreferenceService: UserPreferenceService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -152,8 +155,10 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
reanalyseFile($event: MouseEvent) {
|
reanalyseFile($event?: MouseEvent) {
|
||||||
$event.stopPropagation();
|
if ($event) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
}
|
||||||
this.addSubscription = this._fileActionService.reanalyseFile(this.fileStatus).subscribe(() => {
|
this.addSubscription = this._fileActionService.reanalyseFile(this.fileStatus).subscribe(() => {
|
||||||
this.reloadDossiers('reanalyse');
|
this.reloadDossiers('reanalyse');
|
||||||
});
|
});
|
||||||
@ -172,9 +177,21 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
|||||||
|
|
||||||
setFileApproved($event: MouseEvent) {
|
setFileApproved($event: MouseEvent) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
this.addSubscription = this._fileActionService.setFileApproved(this.fileStatus).subscribe(() => {
|
if (this.fileStatus.hasUpdates) {
|
||||||
this.reloadDossiers('set-approved');
|
this._dialogService.openDialog(
|
||||||
});
|
'confirm',
|
||||||
|
$event,
|
||||||
|
new ConfirmationDialogInput({
|
||||||
|
title: _('confirmation-dialog.approve-file.title'),
|
||||||
|
question: _('confirmation-dialog.approve-file.question')
|
||||||
|
}),
|
||||||
|
() => {
|
||||||
|
this._setFileApproved();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this._setFileApproved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ocrFile($event: MouseEvent) {
|
ocrFile($event: MouseEvent) {
|
||||||
@ -212,6 +229,18 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceReanalysisAction($event: LongPressEvent) {
|
||||||
|
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
||||||
|
this.canReanalyse = $event.touchEnd ? this.permissionsService.canReanalyseFile(this.fileStatus) : true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _setFileApproved() {
|
||||||
|
this.addSubscription = this._fileActionService.setFileApproved(this.fileStatus).subscribe(() => {
|
||||||
|
this.reloadDossiers('set-approved');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _setup() {
|
private _setup() {
|
||||||
this.statusBarConfig = [{ color: this.fileStatus.status, length: 1 }];
|
this.statusBarConfig = [{ color: this.fileStatus.status, length: 1 }];
|
||||||
this.tooltipPosition = this.isFilePreview ? 'below' : 'above';
|
this.tooltipPosition = this.isFilePreview ? 'below' : 'above';
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
<ng-container *ngIf="hasEnginesToShow">
|
||||||
|
<div cdkOverlayOrigin #trigger="cdkOverlayOrigin" class="chip" (mouseover)="isPopoverOpen = true" (mouseout)="isPopoverOpen = false">
|
||||||
|
<ng-container *ngFor="let engine of engines">
|
||||||
|
<mat-icon *ngIf="engine.show" [svgIcon]="engine.icon"></mat-icon>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template
|
||||||
|
cdkConnectedOverlay
|
||||||
|
[cdkConnectedOverlayOffsetY]="-8"
|
||||||
|
[cdkConnectedOverlayOrigin]="trigger"
|
||||||
|
[cdkConnectedOverlayOpen]="isPopoverOpen"
|
||||||
|
>
|
||||||
|
<div class="popover">
|
||||||
|
<ng-container *ngFor="let engine of engines">
|
||||||
|
<div *ngIf="engine.show" class="flex-align-items-center">
|
||||||
|
<mat-icon [svgIcon]="engine.icon"></mat-icon>
|
||||||
|
<span>{{ engine.description }}</span>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
@use 'variables';
|
||||||
|
|
||||||
|
.popover {
|
||||||
|
width: 260px;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: variables.$grey-1;
|
||||||
|
color: variables.$white;
|
||||||
|
|
||||||
|
mat-icon {
|
||||||
|
color: variables.$white;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding-left: 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chip {
|
||||||
|
height: 24px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: variables.$grey-6;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
mat-icon {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-icon {
|
||||||
|
opacity: 50%;
|
||||||
|
margin-left: 3px;
|
||||||
|
margin-right: 3px;
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-of-type {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-icon {
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||||
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
|
import { OnChange } from '@iqser/common-ui';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
interface Engine {
|
||||||
|
readonly icon: string;
|
||||||
|
readonly description: string;
|
||||||
|
readonly show: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Engines = readonly Engine[];
|
||||||
|
|
||||||
|
const Engines = {
|
||||||
|
DICTIONARY: 'DICTIONARY',
|
||||||
|
NER: 'NER',
|
||||||
|
RULE: 'RULE'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
type EngineName = keyof typeof Engines;
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'redaction-annotation-source',
|
||||||
|
templateUrl: './annotation-source.component.html',
|
||||||
|
styleUrls: ['./annotation-source.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
|
export class AnnotationSourceComponent {
|
||||||
|
@Input()
|
||||||
|
@OnChange<AnnotationWrapper, AnnotationSourceComponent>('updateEngines')
|
||||||
|
annotation: AnnotationWrapper;
|
||||||
|
|
||||||
|
isPopoverOpen = false;
|
||||||
|
engines: Engines;
|
||||||
|
|
||||||
|
constructor(private readonly _translateService: TranslateService) {}
|
||||||
|
|
||||||
|
get hasEnginesToShow(): boolean {
|
||||||
|
return this.engines.length && this.engines.some(source => source.show);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateEngines(): void {
|
||||||
|
this.engines = [
|
||||||
|
{
|
||||||
|
icon: 'red:dictionary',
|
||||||
|
description: this._translateService.instant('annotation-engines.dictionary'),
|
||||||
|
show: this._isBasedOn(Engines.DICTIONARY)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'red:ai',
|
||||||
|
description: this._translateService.instant('annotation-engines.ner'),
|
||||||
|
show: this._isBasedOn(Engines.NER)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'red:rule',
|
||||||
|
description: this._translateService.instant('annotation-engines.rule', { rule: this.annotation.legalBasisValue }),
|
||||||
|
show: this._isBasedOn(Engines.RULE)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private _isBasedOn(engineName: EngineName) {
|
||||||
|
return !!this.annotation.engines?.includes(engineName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
<div
|
||||||
|
(click)="annotationClicked(annotation, $event)"
|
||||||
|
*ngFor="let annotation of annotations"
|
||||||
|
[attr.annotation-id]="annotation.id"
|
||||||
|
[attr.annotation-page]="activeViewerPage"
|
||||||
|
[class.active]="isSelected(annotation.annotationId)"
|
||||||
|
[class.multi-select-active]="multiSelectActive"
|
||||||
|
class="annotation-wrapper"
|
||||||
|
>
|
||||||
|
<div class="active-bar-marker"></div>
|
||||||
|
|
||||||
|
<div [class.removed]="annotation.isChangeLogRemoved" class="annotation">
|
||||||
|
<div [matTooltip]="annotation.content" class="details" matTooltipPosition="above">
|
||||||
|
<redaction-type-annotation-icon [annotation]="annotation | log"></redaction-type-annotation-icon>
|
||||||
|
|
||||||
|
<div class="flex-1">
|
||||||
|
<div>
|
||||||
|
<strong>{{ annotation.typeLabel | translate }}</strong>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="annotation?.type !== 'manual'">
|
||||||
|
<strong>
|
||||||
|
<span>{{ annotation.descriptor | translate }}</span
|
||||||
|
>: </strong
|
||||||
|
>{{ annotation.type | humanize: false }}
|
||||||
|
</div>
|
||||||
|
<div *ngIf="annotation.shortContent && !annotation.isHint">
|
||||||
|
<strong><span translate="content"></span>: </strong>{{ annotation.shortContent }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="active-icon-marker-container">
|
||||||
|
<iqser-round-checkbox
|
||||||
|
*ngIf="multiSelectActive && isSelected(annotation.annotationId)"
|
||||||
|
[active]="true"
|
||||||
|
></iqser-round-checkbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions-wrapper">
|
||||||
|
<div
|
||||||
|
(click)="comments.toggleExpandComments($event)"
|
||||||
|
[matTooltip]="'comments.comments' | translate: { count: annotation.comments?.length }"
|
||||||
|
class="comments-counter"
|
||||||
|
matTooltipPosition="above"
|
||||||
|
>
|
||||||
|
<mat-icon svgIcon="red:comment"></mat-icon>
|
||||||
|
{{ annotation.comments.length }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="!multiSelectActive" class="actions">
|
||||||
|
<ng-container
|
||||||
|
[ngTemplateOutletContext]="{ annotation: annotation }"
|
||||||
|
[ngTemplateOutlet]="annotationActionsTemplate"
|
||||||
|
></ng-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<redaction-comments #comments [annotation]="annotation"></redaction-comments>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<redaction-annotation-source [annotation]="annotation"></redaction-annotation-source>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
@use 'variables';
|
||||||
|
|
||||||
|
:host {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotation-wrapper {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid variables.$separator;
|
||||||
|
|
||||||
|
.active-bar-marker {
|
||||||
|
min-width: 4px;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-icon-marker-container {
|
||||||
|
min-width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
&:not(.lower-height) .active-bar-marker {
|
||||||
|
background-color: variables.$primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotation {
|
||||||
|
padding: 10px 16px 8px 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&.removed {
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: variables.$grey-7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.details {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
min-height: 34px;
|
||||||
|
padding-left: 18px;
|
||||||
|
|
||||||
|
.comments-counter {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 8px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
line-height: 13px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
mat-icon {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: variables.$grey-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redaction-type-annotation-icon {
|
||||||
|
margin-top: 6px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: variables.$grey-8;
|
||||||
|
|
||||||
|
::ng-deep .annotation-actions {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redaction-annotation-source {
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
|
||||||
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
|
import { IqserEventTarget } from '@iqser/common-ui';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'redaction-annotations-list',
|
||||||
|
templateUrl: './annotations-list.component.html',
|
||||||
|
styleUrls: ['./annotations-list.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
|
export class AnnotationsListComponent {
|
||||||
|
@Input() annotations: AnnotationWrapper[];
|
||||||
|
@Input() selectedAnnotations: AnnotationWrapper[];
|
||||||
|
@Input() annotationActionsTemplate: TemplateRef<unknown>;
|
||||||
|
@Input() multiSelectActive = false;
|
||||||
|
@Input() activeViewerPage: number;
|
||||||
|
@Input() canMultiSelect = true;
|
||||||
|
|
||||||
|
@Output() readonly multiSelectActiveChange = new EventEmitter<boolean>();
|
||||||
|
@Output() readonly pagesPanelActive = new EventEmitter<boolean>();
|
||||||
|
@Output() readonly selectAnnotations = new EventEmitter<
|
||||||
|
AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }
|
||||||
|
>();
|
||||||
|
@Output() readonly deselectAnnotations = new EventEmitter<AnnotationWrapper[]>();
|
||||||
|
|
||||||
|
annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void {
|
||||||
|
if (($event.target as IqserEventTarget).localName === 'input') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.pagesPanelActive.emit(false);
|
||||||
|
if (this.isSelected(annotation.annotationId)) {
|
||||||
|
this.deselectAnnotations.emit([annotation]);
|
||||||
|
} else {
|
||||||
|
if (this.canMultiSelect && ($event.ctrlKey || $event.metaKey) && this.selectedAnnotations.length > 0) {
|
||||||
|
this.multiSelectActive = true;
|
||||||
|
this.multiSelectActiveChange.emit(true);
|
||||||
|
}
|
||||||
|
this.selectAnnotations.emit({
|
||||||
|
annotations: [annotation],
|
||||||
|
multiSelect: this.multiSelectActive
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isSelected(annotationId: string): boolean {
|
||||||
|
return !!this.selectedAnnotations?.find(a => a?.annotationId === annotationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,3 @@
|
|||||||
<!-- This is a hack to subscribe to an observable using async pipe instead of component class -->
|
|
||||||
<ng-container *ngIf="displayedAnnotations$ | async"></ng-container>
|
|
||||||
|
|
||||||
<div *ngIf="!excludePages" class="right-title heading" translate="file-preview.tabs.annotations.label">
|
<div *ngIf="!excludePages" class="right-title heading" translate="file-preview.tabs.annotations.label">
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
@ -150,8 +147,7 @@
|
|||||||
(click)="actionPerformed.emit('view-exclude-pages')"
|
(click)="actionPerformed.emit('view-exclude-pages')"
|
||||||
class="with-underline"
|
class="with-underline"
|
||||||
translate="file-preview.excluded-from-redaction"
|
translate="file-preview.excluded-from-redaction"
|
||||||
>
|
></a
|
||||||
</a
|
|
||||||
>.
|
>.
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</iqser-empty-state>
|
</iqser-empty-state>
|
||||||
@ -174,62 +170,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<div
|
<redaction-annotations-list
|
||||||
(click)="annotationClicked(annotation, $event)"
|
[canMultiSelect]="!isReadOnly"
|
||||||
*ngFor="let annotation of displayedAnnotations.get(activeViewerPage)"
|
[annotations]="(displayedAnnotations$ | async)?.get(activeViewerPage)"
|
||||||
[attr.annotation-id]="annotation.id"
|
[selectedAnnotations]="selectedAnnotations"
|
||||||
[attr.annotation-page]="activeViewerPage"
|
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||||
[class.active]="isSelected(annotation)"
|
[(multiSelectActive)]="multiSelectActive"
|
||||||
[class.multi-select-active]="multiSelectActive"
|
[activeViewerPage]="activeViewerPage"
|
||||||
class="annotation-wrapper"
|
(pagesPanelActive)="pagesPanelActive = $event"
|
||||||
>
|
(selectAnnotations)="selectAnnotations.emit($event)"
|
||||||
<div class="active-bar-marker"></div>
|
(deselectAnnotations)="deselectAnnotations.emit($event)"
|
||||||
<div [class.removed]="annotation.isChangeLogRemoved" class="annotation">
|
></redaction-annotations-list>
|
||||||
<div [matTooltip]="annotation.content" class="details" matTooltipPosition="above">
|
|
||||||
<redaction-type-annotation-icon [annotation]="annotation"></redaction-type-annotation-icon>
|
|
||||||
<div class="flex-1">
|
|
||||||
<div>
|
|
||||||
<strong>{{ annotation.typeLabel | translate }}</strong>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="annotation?.type !== 'manual'">
|
|
||||||
<strong>
|
|
||||||
<span>{{ annotation.descriptor | translate }}</span
|
|
||||||
>: </strong
|
|
||||||
>{{ annotation.type | humanize: false }}
|
|
||||||
</div>
|
|
||||||
<div *ngIf="annotation.shortContent && !annotation.isHint">
|
|
||||||
<strong><span translate="content"></span>: </strong>{{ annotation.shortContent }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="active-icon-marker-container">
|
|
||||||
<iqser-round-checkbox
|
|
||||||
*ngIf="multiSelectActive && isSelected(annotation)"
|
|
||||||
[active]="true"
|
|
||||||
></iqser-round-checkbox>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="actions-wrapper">
|
|
||||||
<div
|
|
||||||
(click)="toggleExpandComments(annotation, $event)"
|
|
||||||
[matTooltip]="'comments.comments' | translate: { count: annotation.comments?.length }"
|
|
||||||
class="comments-counter"
|
|
||||||
matTooltipPosition="above"
|
|
||||||
>
|
|
||||||
<mat-icon svgIcon="red:comment"></mat-icon>
|
|
||||||
{{ annotation.comments.length }}
|
|
||||||
</div>
|
|
||||||
<div *ngIf="!multiSelectActive" class="actions">
|
|
||||||
<ng-container
|
|
||||||
[ngTemplateOutletContext]="{ annotation: annotation }"
|
|
||||||
[ngTemplateOutlet]="annotationActionsTemplate"
|
|
||||||
></ng-container>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<redaction-comments [annotation]="annotation"></redaction-comments>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.read-only {
|
.read-only {
|
||||||
padding: 13px 16px;
|
padding: 13px 16px;
|
||||||
background-color: $primary;
|
background-color: variables.$primary;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
.read-only-text {
|
.read-only-text {
|
||||||
@ -48,12 +48,12 @@
|
|||||||
|
|
||||||
.multi-select {
|
.multi-select {
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
background: $primary;
|
background: variables.$primary;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 8px 0 16px;
|
padding: 0 8px 0 16px;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
|
|
||||||
.selected-wrapper {
|
.selected-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -90,7 +90,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.quick-navigation {
|
.quick-navigation {
|
||||||
border-right: 1px solid $separator;
|
border-right: 1px solid variables.$separator;
|
||||||
min-width: 61px;
|
min-width: 61px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -105,7 +105,7 @@
|
|||||||
transition: background-color 0.25s;
|
transition: background-color 0.25s;
|
||||||
|
|
||||||
&:not(.disabled):hover {
|
&:not(.disabled):hover {
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat-icon {
|
mat-icon {
|
||||||
@ -124,21 +124,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pages {
|
.pages {
|
||||||
@include no-scroll-bar;
|
@include common-mixins.no-scroll-bar;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-separator {
|
.page-separator {
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -157,96 +157,12 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.annotation-wrapper {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
border-bottom: 1px solid $separator;
|
|
||||||
|
|
||||||
.active-bar-marker {
|
|
||||||
min-width: 4px;
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active-icon-marker-container {
|
|
||||||
min-width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
&:not(.lower-height) .active-bar-marker {
|
|
||||||
background-color: $primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.annotation {
|
|
||||||
padding: 10px 16px 8px 10px;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 14px;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
&.removed {
|
|
||||||
text-decoration: line-through;
|
|
||||||
color: $grey-7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.details {
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions-wrapper {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
margin-top: 8px;
|
|
||||||
min-height: 34px;
|
|
||||||
padding-left: 18px;
|
|
||||||
|
|
||||||
.comments-counter {
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
transition: background-color 0.2s;
|
|
||||||
line-height: 13px;
|
|
||||||
height: 24px;
|
|
||||||
border-radius: 12px;
|
|
||||||
|
|
||||||
mat-icon {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $grey-4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
redaction-type-annotation-icon {
|
|
||||||
margin-top: 6px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $grey-8;
|
|
||||||
|
|
||||||
::ng-deep .annotation-actions {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.has-scrollbar:hover .annotation-wrapper .annotation {
|
&.has-scrollbar:hover::ng-deep .annotation-wrapper .annotation {
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +1,10 @@
|
|||||||
import {
|
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, Output, TemplateRef, ViewChild } from '@angular/core';
|
||||||
ChangeDetectorRef,
|
|
||||||
Component,
|
|
||||||
ElementRef,
|
|
||||||
EventEmitter,
|
|
||||||
HostListener,
|
|
||||||
Input,
|
|
||||||
Output,
|
|
||||||
QueryList,
|
|
||||||
TemplateRef,
|
|
||||||
ViewChild,
|
|
||||||
ViewChildren
|
|
||||||
} from '@angular/core';
|
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||||
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
|
||||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||||
import { CircleButtonTypes, Debounce, FilterService, IconButtonTypes, IqserEventTarget, NestedFilter } from '@iqser/common-ui';
|
import { CircleButtonTypes, Debounce, FilterService, IconButtonTypes, IqserEventTarget, NestedFilter } from '@iqser/common-ui';
|
||||||
import { FileDataModel } from '@models/file/file-data.model';
|
import { FileDataModel } from '@models/file/file-data.model';
|
||||||
import { CommentsComponent } from '../comments/comments.component';
|
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { WebViewerInstance } from '@pdftron/webviewer';
|
import { WebViewerInstance } from '@pdftron/webviewer';
|
||||||
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
|
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
|
||||||
@ -56,7 +43,6 @@ export class FileWorkloadComponent {
|
|||||||
@Output() readonly actionPerformed = new EventEmitter<string>();
|
@Output() readonly actionPerformed = new EventEmitter<string>();
|
||||||
displayedPages: number[] = [];
|
displayedPages: number[] = [];
|
||||||
pagesPanelActive = true;
|
pagesPanelActive = true;
|
||||||
@ViewChildren(CommentsComponent) readonly annotationCommentsComponents: QueryList<CommentsComponent>;
|
|
||||||
@ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef;
|
@ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef;
|
||||||
@ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef;
|
@ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef;
|
||||||
|
|
||||||
@ -118,15 +104,6 @@ export class FileWorkloadComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isSelected(annotation: AnnotationWrapper) {
|
|
||||||
return this.selectedAnnotations?.find(a => a?.id === annotation.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleExpandComments(annotation: AnnotationWrapper, $event: MouseEvent) {
|
|
||||||
$event.stopPropagation();
|
|
||||||
this.annotationCommentsComponents.find(c => c.annotation === annotation).toggleExpandComments();
|
|
||||||
}
|
|
||||||
|
|
||||||
logAnnotation(annotation: AnnotationWrapper) {
|
logAnnotation(annotation: AnnotationWrapper) {
|
||||||
console.log(annotation);
|
console.log(annotation);
|
||||||
}
|
}
|
||||||
@ -156,25 +133,6 @@ export class FileWorkloadComponent {
|
|||||||
return this.displayedAnnotations;
|
return this.displayedAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
annotationClicked(annotation: AnnotationWrapper, $event: MouseEvent): void {
|
|
||||||
if (($event.target as IqserEventTarget).localName === 'input') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.pagesPanelActive = false;
|
|
||||||
this.logAnnotation(annotation);
|
|
||||||
if (this.isSelected(annotation)) {
|
|
||||||
this.deselectAnnotations.emit([annotation]);
|
|
||||||
} else {
|
|
||||||
if (($event.ctrlKey || $event.metaKey) && this.selectedAnnotations.length > 0) {
|
|
||||||
this.multiSelectActive = true;
|
|
||||||
}
|
|
||||||
this.selectAnnotations.emit({
|
|
||||||
annotations: [annotation],
|
|
||||||
multiSelect: this.multiSelectActive
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@HostListener('window:keyup', ['$event'])
|
@HostListener('window:keyup', ['$event'])
|
||||||
handleKeyEvent($event: KeyboardEvent): void {
|
handleKeyEvent($event: KeyboardEvent): void {
|
||||||
if (
|
if (
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
.needs-work {
|
.needs-work {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -7,13 +7,13 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.exclude-pages-input-container {
|
.exclude-pages-input-container {
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
padding: 15px 15px 16px 14px;
|
padding: 15px 15px 16px 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.all-caps-label-container {
|
.all-caps-label-container {
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ranges {
|
.ranges {
|
||||||
@ -22,7 +22,7 @@
|
|||||||
.range {
|
.range {
|
||||||
padding-left: 17px;
|
padding-left: 17px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -34,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-8;
|
background-color: variables.$grey-8;
|
||||||
|
|
||||||
iqser-circle-button {
|
iqser-circle-button {
|
||||||
display: initial;
|
display: initial;
|
||||||
@ -43,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.has-scrollbar:hover {
|
&.has-scrollbar:hover {
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
.range {
|
.range {
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.page-wrapper {
|
.page-wrapper {
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 12px 14px 12px 8px;
|
padding: 12px 14px 12px 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-left: 4px solid transparent;
|
border-left: 4px solid transparent;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border-left: 4px solid $primary;
|
border-left: 4px solid variables.$primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
mat-icon {
|
mat-icon {
|
||||||
@ -35,15 +35,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.read {
|
&.read {
|
||||||
color: $grey-5;
|
color: variables.$grey-5;
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dot {
|
.dot {
|
||||||
background: $primary;
|
background: variables.$primary;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, S
|
|||||||
import { ViewedPages, ViewedPagesControllerService } from '@redaction/red-ui-http';
|
import { ViewedPages, ViewedPagesControllerService } from '@redaction/red-ui-http';
|
||||||
import { AppStateService } from '@state/app-state.service';
|
import { AppStateService } from '@state/app-state.service';
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -25,7 +25,7 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly _viewedPagesControllerService: ViewedPagesControllerService,
|
private readonly _viewedPagesControllerService: ViewedPagesControllerService,
|
||||||
private readonly _appStateService: AppStateService,
|
private readonly _appStateService: AppStateService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _permissionService: PermissionsService
|
private readonly _permissionService: PermissionsService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -67,11 +67,11 @@ export class PageIndicatorComponent implements OnChanges, OnInit, OnDestroy {
|
|||||||
clearTimeout(this.pageReadTimeout);
|
clearTimeout(this.pageReadTimeout);
|
||||||
}
|
}
|
||||||
if (this.active && !this.read) {
|
if (this.active && !this.read) {
|
||||||
this.pageReadTimeout = setTimeout(() => {
|
this.pageReadTimeout = window.setTimeout(() => {
|
||||||
if (this.active && !this.read) {
|
if (this.active && !this.read) {
|
||||||
this._markPageRead();
|
this._markPageRead();
|
||||||
}
|
}
|
||||||
}, this._appConfigService.getConfig(AppConfigKey.AUTO_READ_TIME, 1.5) * 1000);
|
}, this._configService.values.AUTO_READ_TIME * 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -28,9 +28,9 @@
|
|||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%);
|
transform: translate(-50%);
|
||||||
background: $white;
|
background: variables.$white;
|
||||||
color: $grey-7;
|
color: variables.$grey-7;
|
||||||
border: 1px solid $grey-7;
|
border: 1px solid variables.$grey-7;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 6px 2px;
|
padding: 6px 2px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -56,7 +56,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
color: $grey-7;
|
color: variables.$grey-7;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
border: none;
|
border: none;
|
||||||
@ -67,7 +67,7 @@
|
|||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border-bottom: 1px solid $grey-7;
|
border-bottom: 1px solid variables.$grey-7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@
|
|||||||
padding-right: 4px;
|
padding-right: 4px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import {
|
|||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { ManualRedactionEntry } from '@redaction/red-ui-http';
|
import { ManualRedactionEntry } from '@redaction/red-ui-http';
|
||||||
import WebViewer, { Annotations, Tools, WebViewerInstance } from '@pdftron/webviewer';
|
import WebViewer, { Core, WebViewerInstance } from '@pdftron/webviewer';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
|
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
@ -23,7 +23,7 @@ import { AnnotationDrawService } from '../../services/annotation-draw.service';
|
|||||||
import { AnnotationActionsService } from '../../services/annotation-actions.service';
|
import { AnnotationActionsService } from '../../services/annotation-actions.service';
|
||||||
import { UserPreferenceService } from '@services/user-preference.service';
|
import { UserPreferenceService } from '@services/user-preference.service';
|
||||||
import { BASE_HREF } from '../../../../tokens';
|
import { BASE_HREF } from '../../../../tokens';
|
||||||
import { AppConfigKey, AppConfigService } from '../../../app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { LoadingService } from '@iqser/common-ui';
|
import { LoadingService } from '@iqser/common-ui';
|
||||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||||
import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||||
@ -33,6 +33,8 @@ import { ViewMode } from '@models/file/view-mode';
|
|||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import TextTool = Tools.TextTool;
|
import TextTool = Tools.TextTool;
|
||||||
|
import Tools = Core.Tools;
|
||||||
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-pdf-viewer',
|
selector: 'redaction-pdf-viewer',
|
||||||
@ -71,7 +73,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
private readonly _userPreferenceService: UserPreferenceService,
|
private readonly _userPreferenceService: UserPreferenceService,
|
||||||
private readonly _annotationDrawService: AnnotationDrawService,
|
private readonly _annotationDrawService: AnnotationDrawService,
|
||||||
private readonly _annotationActionsService: AnnotationActionsService,
|
private readonly _annotationActionsService: AnnotationActionsService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _loadingService: LoadingService
|
private readonly _loadingService: LoadingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -107,11 +109,11 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
setInitialViewerState() {
|
setInitialViewerState() {
|
||||||
// viewer init
|
// viewer init
|
||||||
this.instance.setFitMode('FitPage');
|
this.instance.UI.setFitMode('FitPage');
|
||||||
|
|
||||||
const instanceDisplayMode = this.instance.docViewer.getDisplayModeManager().getDisplayMode();
|
const instanceDisplayMode = this.instance.Core.documentViewer.getDisplayModeManager().getDisplayMode();
|
||||||
instanceDisplayMode.mode = this.viewMode === 'STANDARD' ? 'Single' : 'Facing';
|
instanceDisplayMode.mode = this.viewMode === 'STANDARD' ? 'Single' : 'Facing';
|
||||||
this.instance.docViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode);
|
this.instance.Core.documentViewer.getDisplayModeManager().setDisplayMode(instanceDisplayMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
async uploadFile(files: any) {
|
async uploadFile(files: any) {
|
||||||
@ -123,13 +125,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
if (fileToCompare) {
|
if (fileToCompare) {
|
||||||
fileReader.onload = async () => {
|
fileReader.onload = async () => {
|
||||||
const pdfData = fileReader.result;
|
const pdfData = fileReader.result;
|
||||||
|
const pdfNet = this.instance.Core.PDFNet;
|
||||||
|
|
||||||
const PDFNet = this.instance.PDFNet;
|
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
||||||
await PDFNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
|
||||||
|
|
||||||
const mergedDocument = await PDFNet.PDFDoc.create();
|
const mergedDocument = await pdfNet.PDFDoc.create();
|
||||||
const compareDocument = await PDFNet.PDFDoc.createFromBuffer(<any>pdfData);
|
const compareDocument = await pdfNet.PDFDoc.createFromBuffer(<any>pdfData);
|
||||||
const currentDocument = await PDFNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
|
const currentDocument = await pdfNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
|
||||||
|
|
||||||
const currentDocumentPageCount = await currentDocument.getPageCount();
|
const currentDocumentPageCount = await currentDocument.getPageCount();
|
||||||
const compareDocumentPageCount = await compareDocument.getPageCount();
|
const compareDocumentPageCount = await compareDocument.getPageCount();
|
||||||
@ -151,7 +153,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
() => {
|
() => {
|
||||||
this.utils.navigateToPage(1);
|
this.utils.navigateToPage(1);
|
||||||
},
|
},
|
||||||
PDFNet
|
this.instance.Core.PDFNet
|
||||||
);
|
);
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
};
|
};
|
||||||
@ -182,14 +184,14 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
async closeCompareMode() {
|
async closeCompareMode() {
|
||||||
this.viewMode = 'STANDARD';
|
this.viewMode = 'STANDARD';
|
||||||
const PDFNet = this.instance.PDFNet;
|
const pdfNet = this.instance.Core.PDFNet;
|
||||||
await PDFNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
||||||
const currentDocument = await PDFNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
|
const currentDocument = await pdfNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
|
||||||
this.instance.loadDocument(currentDocument, {
|
this.instance.UI.loadDocument(currentDocument, {
|
||||||
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
||||||
});
|
});
|
||||||
this.instance.disableElements(['closeCompareButton']);
|
this.instance.UI.disableElements(['closeCompareButton']);
|
||||||
this.instance.enableElements(['compareButton']);
|
this.instance.UI.enableElements(['compareButton']);
|
||||||
this.utils.navigateToPage(1);
|
this.utils.navigateToPage(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +218,8 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
this.utils.disableHotkeys();
|
this.utils.disableHotkeys();
|
||||||
this._configureTextPopup();
|
this._configureTextPopup();
|
||||||
|
|
||||||
this.instance.annotManager.on('annotationSelected', (annotations, action) => {
|
this.instance.Core.annotationManager.on('annotationSelected', (annotations, action) => {
|
||||||
this.annotationSelected.emit(this.instance.annotManager.getSelectedAnnotations().map(ann => ann.Id));
|
this.annotationSelected.emit(this.instance.Core.annotationManager.getSelectedAnnotations().map(ann => ann.Id));
|
||||||
if (action === 'deselected') {
|
if (action === 'deselected') {
|
||||||
this._toggleRectangleAnnotationAction(true);
|
this._toggleRectangleAnnotationAction(true);
|
||||||
} else {
|
} else {
|
||||||
@ -226,16 +228,16 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.annotManager.on('annotationChanged', annotations => {
|
this.instance.Core.annotationManager.on('annotationChanged', annotations => {
|
||||||
// when a rectangle is drawn,
|
// when a rectangle is drawn,
|
||||||
// it returns one annotation with tool name 'AnnotationCreateRectangle;
|
// it returns one annotation with tool name 'AnnotationCreateRectangle;
|
||||||
// this will auto select rectangle after drawing
|
// this will auto select rectangle after drawing
|
||||||
if (annotations.length === 1 && annotations[0].ToolName === 'AnnotationCreateRectangle') {
|
if (annotations.length === 1 && annotations[0].ToolName === 'AnnotationCreateRectangle') {
|
||||||
this.instance.annotManager.selectAnnotations(annotations);
|
this.instance.Core.annotationManager.selectAnnotations(annotations);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.docViewer.on('pageNumberUpdated', pageNumber => {
|
this.instance.Core.documentViewer.on('pageNumberUpdated', pageNumber => {
|
||||||
if (this.shouldDeselectAnnotationsOnPageChange) {
|
if (this.shouldDeselectAnnotationsOnPageChange) {
|
||||||
this.utils.deselectAllAnnotations();
|
this.utils.deselectAllAnnotations();
|
||||||
}
|
}
|
||||||
@ -250,9 +252,9 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.docViewer.on('documentLoaded', this._documentLoaded);
|
this.instance.Core.documentViewer.on('documentLoaded', this._documentLoaded);
|
||||||
|
|
||||||
this.instance.docViewer.on('keyUp', $event => {
|
this.instance.Core.documentViewer.on('keyUp', $event => {
|
||||||
// arrows and full-screen
|
// arrows and full-screen
|
||||||
if ($event.target?.tagName?.toLowerCase() !== 'input') {
|
if ($event.target?.tagName?.toLowerCase() !== 'input') {
|
||||||
if ($event.key.startsWith('Arrow') || $event.key === 'f') {
|
if ($event.key.startsWith('Arrow') || $event.key === 'f') {
|
||||||
@ -270,23 +272,23 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.docViewer.on('textSelected', (quads, selectedText) => {
|
this.instance.Core.documentViewer.on('textSelected', (quads, selectedText) => {
|
||||||
this._selectedText = selectedText;
|
this._selectedText = selectedText;
|
||||||
if (selectedText.length > 2 && this.canPerformActions) {
|
if (selectedText.length > 2 && this.canPerformActions) {
|
||||||
this.instance.enableElements(['add-dictionary', 'add-false-positive']);
|
this.instance.UI.enableElements(['add-dictionary', 'add-false-positive']);
|
||||||
} else {
|
} else {
|
||||||
this.instance.disableElements(['add-dictionary', 'add-false-positive']);
|
this.instance.UI.disableElements(['add-dictionary', 'add-false-positive']);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.iframeWindow.addEventListener('visibilityChanged', (event: any) => {
|
this.instance.UI.iframeWindow.addEventListener('visibilityChanged', (event: any) => {
|
||||||
if (event.detail.element === 'searchPanel') {
|
if (event.detail.element === 'searchPanel') {
|
||||||
const inputElement = this.instance.iframeWindow.document.getElementById('SearchPanel__input') as HTMLInputElement;
|
const inputElement = this.instance.UI.iframeWindow.document.getElementById('SearchPanel__input') as HTMLInputElement;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
inputElement.value = '';
|
inputElement.value = '';
|
||||||
}, 0);
|
}, 0);
|
||||||
if (!event.detail.isVisible) {
|
if (!event.detail.isVisible) {
|
||||||
this.instance.docViewer.clearSearchResults();
|
this.instance.Core.documentViewer.clearSearchResults();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -295,20 +297,20 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _setSelectionMode(): void {
|
private _setSelectionMode(): void {
|
||||||
const textTool = (<unknown>this.instance.Tools.TextTool) as TextTool;
|
const textTool = (<unknown>this.instance.Core.Tools.TextTool) as TextTool;
|
||||||
textTool.SELECTION_MODE = this._appConfigService.getConfig(AppConfigKey.SELECTION_MODE);
|
textTool.SELECTION_MODE = this._configService.values.SELECTION_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _toggleRectangleAnnotationAction(readonly: boolean) {
|
private _toggleRectangleAnnotationAction(readonly: boolean) {
|
||||||
if (!readonly) {
|
if (!readonly) {
|
||||||
this.instance.enableElements(['add-rectangle']);
|
this.instance.UI.enableElements(['add-rectangle']);
|
||||||
} else {
|
} else {
|
||||||
this.instance.disableElements(['add-rectangle']);
|
this.instance.UI.disableElements(['add-rectangle']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _disableElements() {
|
private _disableElements() {
|
||||||
this.instance.disableElements([
|
this.instance.UI.disableElements([
|
||||||
'pageNavOverlay',
|
'pageNavOverlay',
|
||||||
'menuButton',
|
'menuButton',
|
||||||
'selectToolButton',
|
'selectToolButton',
|
||||||
@ -331,7 +333,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
'annotationGroupButton'
|
'annotationGroupButton'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.instance.setHeaderItems(header => {
|
this.instance.UI.setHeaderItems(header => {
|
||||||
const originalHeaderItems = header.getItems();
|
const originalHeaderItems = header.getItems();
|
||||||
originalHeaderItems.splice(8, 0, {
|
originalHeaderItems.splice(8, 0, {
|
||||||
type: 'divider',
|
type: 'divider',
|
||||||
@ -372,9 +374,9 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.disableElements(['closeCompareButton']);
|
this.instance.UI.disableElements(['closeCompareButton']);
|
||||||
|
|
||||||
this.instance.docViewer.getTool('AnnotationCreateRectangle').setStyles(() => ({
|
this.instance.Core.documentViewer.getTool('AnnotationCreateRectangle').setStyles(() => ({
|
||||||
StrokeThickness: 2,
|
StrokeThickness: 2,
|
||||||
StrokeColor: this._annotationDrawService.getColor(this.instance, 'manual'),
|
StrokeColor: this._annotationDrawService.getColor(this.instance, 'manual'),
|
||||||
FillColor: this._annotationDrawService.getColor(this.instance, 'manual'),
|
FillColor: this._annotationDrawService.getColor(this.instance, 'manual'),
|
||||||
@ -382,13 +384,13 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _configureAnnotationSpecificActions(viewerAnnotations: Annotations.Annotation[]) {
|
private _configureAnnotationSpecificActions(viewerAnnotations: Annotation[]) {
|
||||||
if (!this.canPerformActions) {
|
if (!this.canPerformActions) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const annotationWrappers = viewerAnnotations.map(va => this.annotations.find(a => a.id === va.Id)).filter(va => !!va);
|
const annotationWrappers = viewerAnnotations.map(va => this.annotations.find(a => a.id === va.Id)).filter(va => !!va);
|
||||||
this.instance.annotationPopup.update([]);
|
this.instance.UI.annotationPopup.update([]);
|
||||||
|
|
||||||
if (annotationWrappers.length === 0) {
|
if (annotationWrappers.length === 0) {
|
||||||
this._configureRectangleAnnotationPopup();
|
this._configureRectangleAnnotationPopup();
|
||||||
@ -400,7 +402,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
if (allAnnotationsHaveImageAction) {
|
if (allAnnotationsHaveImageAction) {
|
||||||
const allAreVisible = viewerAnnotations.reduce((acc, next) => next.isVisible() && acc, true);
|
const allAreVisible = viewerAnnotations.reduce((acc, next) => next.isVisible() && acc, true);
|
||||||
|
|
||||||
this.instance.annotationPopup.add([
|
this.instance.UI.annotationPopup.add([
|
||||||
{
|
{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
img: allAreVisible
|
img: allAreVisible
|
||||||
@ -410,11 +412,11 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
onClick: () => {
|
onClick: () => {
|
||||||
this._ngZone.run(() => {
|
this._ngZone.run(() => {
|
||||||
if (allAreVisible) {
|
if (allAreVisible) {
|
||||||
this.instance.annotManager.hideAnnotations(viewerAnnotations);
|
this.instance.Core.annotationManager.hideAnnotations(viewerAnnotations);
|
||||||
} else {
|
} else {
|
||||||
this.instance.annotManager.showAnnotations(viewerAnnotations);
|
this.instance.Core.annotationManager.showAnnotations(viewerAnnotations);
|
||||||
}
|
}
|
||||||
this.instance.annotManager.deselectAllAnnotations();
|
this.instance.Core.annotationManager.deselectAllAnnotations();
|
||||||
this._annotationActionsService.updateHiddenAnnotation(this.annotations, viewerAnnotations, allAreVisible);
|
this._annotationActionsService.updateHiddenAnnotation(this.annotations, viewerAnnotations, allAreVisible);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -422,19 +424,19 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.instance.annotationPopup.add(
|
this.instance.UI.annotationPopup.add(
|
||||||
this._annotationActionsService.getViewerAvailableActions(annotationWrappers, this.annotationsChanged)
|
this._annotationActionsService.getViewerAvailableActions(annotationWrappers, this.annotationsChanged)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _configureRectangleAnnotationPopup() {
|
private _configureRectangleAnnotationPopup() {
|
||||||
this.instance.annotationPopup.add(<any>{
|
this.instance.UI.annotationPopup.add(<any>{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
dataElement: 'add-rectangle',
|
dataElement: 'add-rectangle',
|
||||||
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
|
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
|
||||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
|
title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const selectedAnnotations = this.instance.annotManager.getSelectedAnnotations();
|
const selectedAnnotations = this.instance.Core.annotationManager.getSelectedAnnotations();
|
||||||
const activeAnnotation = selectedAnnotations[0];
|
const activeAnnotation = selectedAnnotations[0];
|
||||||
const activePage = selectedAnnotations[0].getPageNumber();
|
const activePage = selectedAnnotations[0].getPageNumber();
|
||||||
const quad = this._annotationDrawService.annotationToQuads(activeAnnotation, this.instance);
|
const quad = this._annotationDrawService.annotationToQuads(activeAnnotation, this.instance);
|
||||||
@ -443,8 +445,8 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
const mre = this._getManualRedactionEntry(quadsObject, 'Rectangle');
|
const mre = this._getManualRedactionEntry(quadsObject, 'Rectangle');
|
||||||
// cleanup selection and button state
|
// cleanup selection and button state
|
||||||
this.utils.deselectAllAnnotations();
|
this.utils.deselectAllAnnotations();
|
||||||
this.instance.disableElements(['shapeToolGroupButton', 'rectangleToolDivider']);
|
this.instance.UI.disableElements(['shapeToolGroupButton', 'rectangleToolDivider']);
|
||||||
this.instance.enableElements(['shapeToolGroupButton', 'rectangleToolDivider']);
|
this.instance.UI.enableElements(['shapeToolGroupButton', 'rectangleToolDivider']);
|
||||||
// dispatch event
|
// dispatch event
|
||||||
this.manualAnnotationRequested.emit(
|
this.manualAnnotationRequested.emit(
|
||||||
new ManualRedactionEntryWrapper([quad], mre, 'REDACTION', 'RECTANGLE', activeAnnotation.Id)
|
new ManualRedactionEntryWrapper([quad], mre, 'REDACTION', 'RECTANGLE', activeAnnotation.Id)
|
||||||
@ -454,12 +456,12 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _configureTextPopup() {
|
private _configureTextPopup() {
|
||||||
this.instance.textPopup.add(<any>{
|
this.instance.UI.textPopup.add(<any>{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
img: this._convertPath('/assets/icons/general/pdftron-action-search.svg'),
|
img: this._convertPath('/assets/icons/general/pdftron-action-search.svg'),
|
||||||
title: this._translateService.instant('pdf-viewer.text-popup.actions.search'),
|
title: this._translateService.instant('pdf-viewer.text-popup.actions.search'),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const text = this.instance.docViewer.getSelectedText();
|
const text = this.instance.Core.documentViewer.getSelectedText();
|
||||||
const searchOptions = {
|
const searchOptions = {
|
||||||
caseSensitive: true, // match case
|
caseSensitive: true, // match case
|
||||||
wholeWord: true, // match whole words only
|
wholeWord: true, // match whole words only
|
||||||
@ -468,57 +470,57 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
searchUp: false, // search from the end of the document upwards
|
searchUp: false, // search from the end of the document upwards
|
||||||
ambientString: true // return ambient string as part of the result
|
ambientString: true // return ambient string as part of the result
|
||||||
};
|
};
|
||||||
this.instance.openElements(['searchPanel']);
|
this.instance.UI.openElements(['searchPanel']);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.instance.searchTextFull(text, searchOptions);
|
this.instance.UI.searchTextFull(text, searchOptions);
|
||||||
}, 250);
|
}, 250);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Adding directly to the false-positive dict is only available in dev-mode
|
// Adding directly to the false-positive dict is only available in dev-mode
|
||||||
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
||||||
this.instance.textPopup.add(<any>{
|
this.instance.UI.textPopup.add(<any>{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
dataElement: 'add-false-positive',
|
dataElement: 'add-false-positive',
|
||||||
img: this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg'),
|
img: this._convertPath('/assets/icons/general/pdftron-action-false-positive.svg'),
|
||||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('FALSE_POSITIVE')),
|
title: this._translateService.instant(this._manualAnnotationService.getTitle('FALSE_POSITIVE')),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
const selectedQuads = this.instance.Core.documentViewer.getSelectedTextQuads();
|
||||||
const text = this.instance.docViewer.getSelectedText();
|
const text = this.instance.Core.documentViewer.getSelectedText();
|
||||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||||
this.manualAnnotationRequested.emit(
|
this.manualAnnotationRequested.emit(
|
||||||
new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'FALSE_POSITIVE')
|
new ManualRedactionEntryWrapper(this.instance.Core.documentViewer.getSelectedTextQuads(), mre, 'FALSE_POSITIVE')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.instance.textPopup.add(<any>{
|
this.instance.UI.textPopup.add(<any>{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
dataElement: 'add-dictionary',
|
dataElement: 'add-dictionary',
|
||||||
img: this._convertPath('/assets/icons/general/pdftron-action-add-dict.svg'),
|
img: this._convertPath('/assets/icons/general/pdftron-action-add-dict.svg'),
|
||||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('DICTIONARY')),
|
title: this._translateService.instant(this._manualAnnotationService.getTitle('DICTIONARY')),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
const selectedQuads = this.instance.Core.documentViewer.getSelectedTextQuads();
|
||||||
const text = this.instance.docViewer.getSelectedText();
|
const text = this.instance.Core.documentViewer.getSelectedText();
|
||||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||||
this.manualAnnotationRequested.emit(
|
this.manualAnnotationRequested.emit(
|
||||||
new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'DICTIONARY')
|
new ManualRedactionEntryWrapper(this.instance.Core.documentViewer.getSelectedTextQuads(), mre, 'DICTIONARY')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.instance.textPopup.add(<any>{
|
this.instance.UI.textPopup.add(<any>{
|
||||||
type: 'actionButton',
|
type: 'actionButton',
|
||||||
dataElement: 'add-redaction',
|
dataElement: 'add-redaction',
|
||||||
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
|
img: this._convertPath('/assets/icons/general/pdftron-action-add-redaction.svg'),
|
||||||
title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
|
title: this._translateService.instant(this._manualAnnotationService.getTitle('REDACTION')),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const selectedQuads = this.instance.docViewer.getSelectedTextQuads();
|
const selectedQuads = this.instance.Core.documentViewer.getSelectedTextQuads();
|
||||||
const text = this.instance.docViewer.getSelectedText();
|
const text = this.instance.Core.documentViewer.getSelectedText();
|
||||||
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
const mre = this._getManualRedactionEntry(selectedQuads, text, true);
|
||||||
this.manualAnnotationRequested.emit(
|
this.manualAnnotationRequested.emit(
|
||||||
new ManualRedactionEntryWrapper(this.instance.docViewer.getSelectedTextQuads(), mre, 'REDACTION')
|
new ManualRedactionEntryWrapper(this.instance.Core.documentViewer.getSelectedTextQuads(), mre, 'REDACTION')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -526,10 +528,10 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleCustomActions() {
|
private _handleCustomActions() {
|
||||||
this.instance.setToolMode('AnnotationEdit');
|
this.instance.UI.setToolMode('AnnotationEdit');
|
||||||
if (this.canPerformActions) {
|
if (this.canPerformActions) {
|
||||||
this.instance.enableTools(['AnnotationCreateRectangle']);
|
this.instance.UI.enableTools(['AnnotationCreateRectangle']);
|
||||||
this.instance.enableElements([
|
this.instance.UI.enableElements([
|
||||||
'add-redaction',
|
'add-redaction',
|
||||||
'add-rectangle',
|
'add-rectangle',
|
||||||
'add-false-positive',
|
'add-false-positive',
|
||||||
@ -538,11 +540,11 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
'annotationPopup'
|
'annotationPopup'
|
||||||
]);
|
]);
|
||||||
if (this._selectedText.length > 2) {
|
if (this._selectedText.length > 2) {
|
||||||
this.instance.enableElements(['add-dictionary', 'add-false-positive']);
|
this.instance.UI.enableElements(['add-dictionary', 'add-false-positive']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.instance.disableTools(['AnnotationCreateRectangle']);
|
this.instance.UI.disableTools(['AnnotationCreateRectangle']);
|
||||||
this.instance.disableElements([
|
this.instance.UI.disableElements([
|
||||||
'add-redaction',
|
'add-redaction',
|
||||||
'add-dictionary',
|
'add-dictionary',
|
||||||
'add-false-positive',
|
'add-false-positive',
|
||||||
@ -568,7 +570,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
|||||||
|
|
||||||
private _loadDocument() {
|
private _loadDocument() {
|
||||||
if (this.fileData) {
|
if (this.fileData) {
|
||||||
this.instance.loadDocument(this.fileData, {
|
this.instance.UI.loadDocument(this.fileData, {
|
||||||
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
<mat-label>{{ 'assign-dossier-owner.dialog.single-user' | translate }}</mat-label>
|
<mat-label>{{ 'assign-dossier-owner.dialog.single-user' | translate }}</mat-label>
|
||||||
<mat-select formControlName="owner">
|
<mat-select formControlName="owner">
|
||||||
<mat-option *ngFor="let userId of ownersSelectOptions" [value]="userId">
|
<mat-option *ngFor="let userId of ownersSelectOptions" [value]="userId">
|
||||||
{{ userService.getNameForId(userId) }}
|
{{ userId | name }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
@use 'variables';
|
||||||
|
|
||||||
.search-container {
|
.search-container {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
@ -16,7 +17,7 @@ redaction-team-members {
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
@ -51,7 +52,7 @@ redaction-team-members {
|
|||||||
|
|
||||||
&.selected,
|
&.selected,
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
@ -27,8 +27,8 @@
|
|||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: $accent;
|
background-color: variables.$accent;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: -8px;
|
right: -8px;
|
||||||
bottom: -2px;
|
bottom: -2px;
|
||||||
@ -48,6 +48,6 @@
|
|||||||
|
|
||||||
.see-less {
|
.see-less {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
color: $primary;
|
color: variables.$primary;
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
.watermark {
|
.watermark {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
<mat-label>{{ 'assign-owner.dialog.label' | translate: { type: data.mode } }}</mat-label>
|
<mat-label>{{ 'assign-owner.dialog.label' | translate: { type: data.mode } }}</mat-label>
|
||||||
<mat-select formControlName="singleUser">
|
<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) }}
|
{{ userId | name }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -18,7 +18,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: $separator;
|
background-color: variables.$separator;
|
||||||
}
|
}
|
||||||
|
|
||||||
.datepicker-wrapper {
|
.datepicker-wrapper {
|
||||||
@ -60,7 +60,7 @@
|
|||||||
height: 50px;
|
height: 50px;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: center;
|
object-position: center;
|
||||||
border: 1px solid $grey-5;
|
border: 1px solid variables.$grey-5;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
@import '../../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.instructions {
|
.instructions {
|
||||||
color: $grey-7;
|
color: variables.$grey-7;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
text-align: end;
|
text-align: end;
|
||||||
}
|
}
|
||||||
@ -11,6 +11,6 @@
|
|||||||
height: calc(100% - 81px) !important;
|
height: calc(100% - 81px) !important;
|
||||||
|
|
||||||
.cdk-virtual-scroll-content-wrapper .table-item > div.cell.filename span {
|
.cdk-virtual-scroll-content-wrapper .table-item > div.cell.filename span {
|
||||||
@include line-clamp(1);
|
@include common-mixins.line-clamp(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import {
|
|||||||
import { FileManagementControllerService, FileStatus, StatusControllerService } from '@redaction/red-ui-http';
|
import { FileManagementControllerService, FileStatus, StatusControllerService } from '@redaction/red-ui-http';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { getLeftDateTime } from '@utils/functions';
|
import { getLeftDateTime } from '@utils/functions';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||||
@ -44,7 +44,7 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent<FileL
|
|||||||
tableColumnConfigs: TableColumnConfig<FileListItem>[];
|
tableColumnConfigs: TableColumnConfig<FileListItem>[];
|
||||||
readonly tableHeaderLabel = _('edit-dossier-dialog.deleted-documents.table-header.label');
|
readonly tableHeaderLabel = _('edit-dossier-dialog.deleted-documents.table-header.label');
|
||||||
readonly circleButtonTypes = CircleButtonTypes;
|
readonly circleButtonTypes = CircleButtonTypes;
|
||||||
readonly deleteRetentionHours = this._appConfigService.getConfig(AppConfigKey.DELETE_RETENTION_HOURS);
|
readonly deleteRetentionHours = this._configService.values.DELETE_RETENTION_HOURS;
|
||||||
@ViewChild('filenameTemplate', { static: true }) filenameTemplate: TemplateRef<never>;
|
@ViewChild('filenameTemplate', { static: true }) filenameTemplate: TemplateRef<never>;
|
||||||
@ViewChild('pagesTemplate', { static: true }) pagesTemplate: TemplateRef<never>;
|
@ViewChild('pagesTemplate', { static: true }) pagesTemplate: TemplateRef<never>;
|
||||||
@ViewChild('deletedDateTemplate', { static: true }) deletedDateTemplate: TemplateRef<never>;
|
@ViewChild('deletedDateTemplate', { static: true }) deletedDateTemplate: TemplateRef<never>;
|
||||||
@ -57,7 +57,7 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent<FileL
|
|||||||
private readonly _fileManagementController: FileManagementControllerService,
|
private readonly _fileManagementController: FileManagementControllerService,
|
||||||
private readonly _appStateService: AppStateService,
|
private readonly _appStateService: AppStateService,
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _dialogService: DossiersDialogService
|
private readonly _dialogService: DossiersDialogService
|
||||||
) {
|
) {
|
||||||
super(_injector);
|
super(_injector);
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@import '../../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
.download-includes {
|
.download-includes {
|
||||||
margin: 16px 0 10px;
|
margin: 16px 0 10px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.dialog-content {
|
.dialog-content {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
border-top: 1px solid $separator;
|
border-top: 1px solid variables.$separator;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: calc(90vh - 81px);
|
height: calc(90vh - 81px);
|
||||||
|
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.content {
|
.content {
|
||||||
padding: 24px 32px;
|
padding: 24px 32px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@include scroll-bar;
|
@include common-mixins.scroll-bar;
|
||||||
height: calc(100% - 81px);
|
height: calc(100% - 81px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
@import '../../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
.watermark {
|
.watermark {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,9 @@ import { DossiersService } from './services/dossiers.service';
|
|||||||
import { DossierDetailsStatsComponent } from './components/dossier-details-stats/dossier-details-stats.component';
|
import { DossierDetailsStatsComponent } from './components/dossier-details-stats/dossier-details-stats.component';
|
||||||
import { SearchScreenComponent } from './screens/search-screen/search-screen.component';
|
import { SearchScreenComponent } from './screens/search-screen/search-screen.component';
|
||||||
import { EditDossierDeletedDocumentsComponent } from './dialogs/edit-dossier-dialog/deleted-documents/edit-dossier-deleted-documents.component';
|
import { EditDossierDeletedDocumentsComponent } from './dialogs/edit-dossier-dialog/deleted-documents/edit-dossier-deleted-documents.component';
|
||||||
|
import { AnnotationsListComponent } from './components/file-workload/components/annotations-list/annotations-list.component';
|
||||||
|
import { AnnotationSourceComponent } from './components/file-workload/components/annotation-source/annotation-source.component';
|
||||||
|
import { OverlayModule } from '@angular/cdk/overlay';
|
||||||
|
|
||||||
const screens = [DossierListingScreenComponent, DossierOverviewScreenComponent, FilePreviewScreenComponent, SearchScreenComponent];
|
const screens = [DossierListingScreenComponent, DossierOverviewScreenComponent, FilePreviewScreenComponent, SearchScreenComponent];
|
||||||
|
|
||||||
@ -89,6 +92,8 @@ const components = [
|
|||||||
PageExclusionComponent,
|
PageExclusionComponent,
|
||||||
DossierDetailsStatsComponent,
|
DossierDetailsStatsComponent,
|
||||||
EditDossierDeletedDocumentsComponent,
|
EditDossierDeletedDocumentsComponent,
|
||||||
|
AnnotationsListComponent,
|
||||||
|
AnnotationSourceComponent,
|
||||||
|
|
||||||
...screens,
|
...screens,
|
||||||
...dialogs
|
...dialogs
|
||||||
@ -109,6 +114,6 @@ const services = [
|
|||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [...components],
|
declarations: [...components],
|
||||||
providers: [...services],
|
providers: [...services],
|
||||||
imports: [CommonModule, SharedModule, FileUploadDownloadModule, DossiersRoutingModule]
|
imports: [CommonModule, SharedModule, FileUploadDownloadModule, DossiersRoutingModule, OverlayModule]
|
||||||
})
|
})
|
||||||
export class DossiersModule {}
|
export class DossiersModule {}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
.file-upload-input {
|
.file-upload-input {
|
||||||
display: none;
|
display: none;
|
||||||
@ -9,7 +9,7 @@
|
|||||||
&.last-opened {
|
&.last-opened {
|
||||||
> .selection-column {
|
> .selection-column {
|
||||||
padding-left: 6px !important;
|
padding-left: 6px !important;
|
||||||
border-left: 4px solid $primary;
|
border-left: 4px solid variables.$primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
> div.cell {
|
> div.cell {
|
||||||
.error {
|
.error {
|
||||||
color: $primary;
|
color: variables.$primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-item-title {
|
.table-item-title {
|
||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
.primary-attribute {
|
.primary-attribute {
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
@include line-clamp(1);
|
@include common-mixins.line-clamp(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.extend-cols {
|
&.extend-cols {
|
||||||
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
@keyframes red-fading-background {
|
@keyframes red-fading-background {
|
||||||
0% {
|
0% {
|
||||||
background-color: rgba($primary, 0.1);
|
background-color: rgba(variables.$primary, 0.1);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
background-color: inherit;
|
background-color: inherit;
|
||||||
@ -67,7 +67,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.view-mode-selection {
|
.view-mode-selection {
|
||||||
border-right: 1px solid $separator;
|
border-right: 1px solid variables.$separator;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
margin-right: 16px !important;
|
margin-right: 16px !important;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -94,7 +94,7 @@
|
|||||||
|
|
||||||
.filename {
|
.filename {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
@include line-clamp(1);
|
@include common-mixins.line-clamp(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import { StatusSorter } from '@utils/sorters/status-sorter';
|
|||||||
import { convertFiles, handleFileDrop } from '@utils/file-drop-utils';
|
import { convertFiles, handleFileDrop } from '@utils/file-drop-utils';
|
||||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||||
import { AppConfigKey, AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
|
import { ActionConfig } from '@shared/components/page-header/models/action-config.model';
|
||||||
import {
|
import {
|
||||||
CircleButtonTypes,
|
CircleButtonTypes,
|
||||||
@ -52,7 +52,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
|||||||
import { annotationFilterChecker } from '@utils/filter-utils';
|
import { annotationFilterChecker } from '@utils/filter-utils';
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { RouterHistoryService } from '@services/router-history.service';
|
import { RouterHistoryService } from '@services/router-history.service';
|
||||||
import { DossierWrapper } from '../../../../state/model/dossier.wrapper';
|
import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { FileActionService } from '../../services/file-action.service';
|
import { FileActionService } from '../../services/file-action.service';
|
||||||
import StatusEnum = FileStatus.StatusEnum;
|
import StatusEnum = FileStatus.StatusEnum;
|
||||||
@ -106,7 +106,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
|||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _appStateService: AppStateService,
|
private readonly _appStateService: AppStateService,
|
||||||
readonly routerHistoryService: RouterHistoryService,
|
readonly routerHistoryService: RouterHistoryService,
|
||||||
private readonly _appConfigService: AppConfigService,
|
private readonly _configService: ConfigService,
|
||||||
private readonly _translateService: TranslateService,
|
private readonly _translateService: TranslateService,
|
||||||
private readonly _dialogService: DossiersDialogService,
|
private readonly _dialogService: DossiersDialogService,
|
||||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||||
@ -339,7 +339,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
|||||||
}
|
}
|
||||||
|
|
||||||
recentlyModifiedChecker = (file: FileStatusWrapper) =>
|
recentlyModifiedChecker = (file: FileStatusWrapper) =>
|
||||||
moment(file.lastUpdated).add(this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS), 'hours').isAfter(moment());
|
moment(file.lastUpdated).add(this._configService.values.RECENT_PERIOD_IN_HOURS, 'hours').isAfter(moment());
|
||||||
|
|
||||||
private _configureTableColumns() {
|
private _configureTableColumns() {
|
||||||
const dynamicColumns: TableColumnConfig<FileStatusWrapper>[] = [];
|
const dynamicColumns: TableColumnConfig<FileStatusWrapper>[] = [];
|
||||||
@ -555,7 +555,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
|||||||
private _createQuickFilters() {
|
private _createQuickFilters() {
|
||||||
let quickFilters = [];
|
let quickFilters = [];
|
||||||
if (this.entitiesService.all.filter(this.recentlyModifiedChecker).length > 0) {
|
if (this.entitiesService.all.filter(this.recentlyModifiedChecker).length > 0) {
|
||||||
const recentPeriod = this._appConfigService.getConfig(AppConfigKey.RECENT_PERIOD_IN_HOURS);
|
const recentPeriod = this._configService.values.RECENT_PERIOD_IN_HOURS;
|
||||||
quickFilters = [
|
quickFilters = [
|
||||||
{
|
{
|
||||||
key: 'recent',
|
key: 'recent',
|
||||||
|
|||||||
@ -88,6 +88,7 @@
|
|||||||
<div class="vertical-line"></div>
|
<div class="vertical-line"></div>
|
||||||
|
|
||||||
<redaction-file-actions
|
<redaction-file-actions
|
||||||
|
#fileActions
|
||||||
(actionPerformed)="fileActionPerformed($event)"
|
(actionPerformed)="fileActionPerformed($event)"
|
||||||
[activeDocumentInfo]="viewDocumentInfo"
|
[activeDocumentInfo]="viewDocumentInfo"
|
||||||
[activeExcludePages]="excludePages"
|
[activeExcludePages]="excludePages"
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.vertical-line {
|
.vertical-line {
|
||||||
width: 1px;
|
width: 1px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
background-color: $grey-4;
|
background-color: variables.$grey-4;
|
||||||
margin: 0 16px;
|
margin: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +32,7 @@
|
|||||||
::ng-deep .right-title {
|
::ng-deep .right-title {
|
||||||
height: 70px;
|
height: 70px;
|
||||||
display: flex;
|
display: flex;
|
||||||
border-bottom: 1px solid $separator;
|
border-bottom: 1px solid variables.$separator;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, HostListener, NgZone, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||||
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
||||||
import { AppStateService } from '@state/app-state.service';
|
import { AppStateService } from '@state/app-state.service';
|
||||||
import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
import { Core, WebViewerInstance } from '@pdftron/webviewer';
|
||||||
import { PdfViewerComponent } from '../../components/pdf-viewer/pdf-viewer.component';
|
import { PdfViewerComponent } from '../../components/pdf-viewer/pdf-viewer.component';
|
||||||
import {
|
import {
|
||||||
AutoUnsubscribe,
|
AutoUnsubscribe,
|
||||||
@ -43,6 +43,8 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { fileStatusTranslations } from '../../translations/file-status-translations';
|
import { fileStatusTranslations } from '../../translations/file-status-translations';
|
||||||
import { handleFilterDelta } from '@utils/filter-utils';
|
import { handleFilterDelta } from '@utils/filter-utils';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
|
import { FileActionsComponent } from '../../components/file-actions/file-actions.component';
|
||||||
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
|
const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f'];
|
||||||
|
|
||||||
@ -78,6 +80,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
static: true
|
static: true
|
||||||
})
|
})
|
||||||
private readonly _filterTemplate: TemplateRef<NestedFilter>;
|
private readonly _filterTemplate: TemplateRef<NestedFilter>;
|
||||||
|
@ViewChild('fileActions') fileActions: FileActionsComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly appStateService: AppStateService,
|
readonly appStateService: AppStateService,
|
||||||
@ -131,7 +134,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
get activeViewerPage(): number {
|
get activeViewerPage(): number {
|
||||||
const currentPage = this._instance?.docViewer?.getCurrentPage();
|
const currentPage = this._instance?.Core.documentViewer?.getCurrentPage();
|
||||||
if (!currentPage) {
|
if (!currentPage) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -257,14 +260,18 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
this.displayPDFViewer = true;
|
this.displayPDFViewer = true;
|
||||||
this._updateCanPerformActions();
|
this._updateCanPerformActions();
|
||||||
this._subscribeToFileUpdates();
|
this._subscribeToFileUpdates();
|
||||||
|
|
||||||
|
if (this.fileData?.fileStatus?.analysisRequired) {
|
||||||
|
this.fileActions.reanalyseFile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuildFilters(deletePreviousAnnotations = false): void {
|
rebuildFilters(deletePreviousAnnotations = false): void {
|
||||||
const startTime = new Date().getTime();
|
const startTime = new Date().getTime();
|
||||||
if (deletePreviousAnnotations) {
|
if (deletePreviousAnnotations) {
|
||||||
const annotationsToDelete = this._instance?.annotManager?.getAnnotationsList() || [];
|
const annotationsToDelete = this._instance?.Core.annotationManager?.getAnnotationsList() || [];
|
||||||
try {
|
try {
|
||||||
this._instance?.annotManager?.deleteAnnotations(annotationsToDelete, {
|
this._instance?.Core.annotationManager?.deleteAnnotations(annotationsToDelete, {
|
||||||
imported: true,
|
imported: true,
|
||||||
force: true
|
force: true
|
||||||
});
|
});
|
||||||
@ -344,8 +351,10 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
entryWrapper,
|
entryWrapper,
|
||||||
async (response: ManualAnnotationResponse) => {
|
async (response: ManualAnnotationResponse) => {
|
||||||
if (response?.annotationId) {
|
if (response?.annotationId) {
|
||||||
const annotation = this._instance.annotManager.getAnnotationById(response.manualRedactionEntryWrapper.rectId);
|
const annotation = this._instance.Core.annotationManager.getAnnotationById(
|
||||||
this._instance.annotManager.deleteAnnotation(annotation);
|
response.manualRedactionEntryWrapper.rectId
|
||||||
|
);
|
||||||
|
this._instance.Core.annotationManager.deleteAnnotation(annotation);
|
||||||
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
||||||
const distinctPages = entryWrapper.manualRedactionEntry.positions
|
const distinctPages = entryWrapper.manualRedactionEntry.positions
|
||||||
.map(p => p.page)
|
.map(p => p.page)
|
||||||
@ -550,11 +559,12 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
|
|
||||||
private async _doStampExcludedPages(excludedPages: number[]) {
|
private async _doStampExcludedPages(excludedPages: number[]) {
|
||||||
if (excludedPages && excludedPages.length > 0) {
|
if (excludedPages && excludedPages.length > 0) {
|
||||||
const document = await this._instance.docViewer.getDocument().getPDFDoc();
|
const pdfNet = this._instance.Core.PDFNet;
|
||||||
await clearStamps(document, this._instance.PDFNet, [...Array(this.fileData.fileStatus.numberOfPages).keys()]);
|
const document = await this._instance.Core.documentViewer.getDocument().getPDFDoc();
|
||||||
|
await clearStamps(document, pdfNet, [...Array(this.fileData.fileStatus.numberOfPages).keys()]);
|
||||||
await stampPDFPage(
|
await stampPDFPage(
|
||||||
document,
|
document,
|
||||||
this._instance.PDFNet,
|
pdfNet,
|
||||||
this._translateService.instant('file-preview.excluded-from-redaction'),
|
this._translateService.instant('file-preview.excluded-from-redaction'),
|
||||||
25,
|
25,
|
||||||
'courier',
|
'courier',
|
||||||
@ -568,8 +578,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
|
|
||||||
private async _stampExcludedPages() {
|
private async _stampExcludedPages() {
|
||||||
await this._doStampExcludedPages(this.fileData.fileStatus.excludedPages);
|
await this._doStampExcludedPages(this.fileData.fileStatus.excludedPages);
|
||||||
this._instance.docViewer.refreshAll();
|
this._instance.Core.documentViewer.refreshAll();
|
||||||
this._instance.docViewer.updateView([this.activeViewerPage], this.activeViewerPage);
|
this._instance.Core.documentViewer.updateView([this.activeViewerPage], this.activeViewerPage);
|
||||||
this._changeDetectorRef.detectChanges();
|
this._changeDetectorRef.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,6 +605,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
|
|
||||||
private async _loadFileData(performUpdate = false): Promise<void> {
|
private async _loadFileData(performUpdate = false): Promise<void> {
|
||||||
const fileData = await this._fileDownloadService.loadActiveFileData().toPromise();
|
const fileData = await this._fileDownloadService.loadActiveFileData().toPromise();
|
||||||
|
|
||||||
if (!fileData.fileStatus?.isPending && !fileData.fileStatus?.isError) {
|
if (!fileData.fileStatus?.isPending && !fileData.fileStatus?.isError) {
|
||||||
if (performUpdate) {
|
if (performUpdate) {
|
||||||
this.fileData.redactionLog = fileData.redactionLog;
|
this.fileData.redactionLog = fileData.redactionLog;
|
||||||
@ -678,9 +689,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _findAndDeleteAnnotation(id: string) {
|
private _findAndDeleteAnnotation(id: string) {
|
||||||
const viewerAnnotation = this._instance.annotManager.getAnnotationById(id);
|
const viewerAnnotation = this._instance.Core.annotationManager.getAnnotationById(id);
|
||||||
if (viewerAnnotation) {
|
if (viewerAnnotation) {
|
||||||
this._instance.annotManager.deleteAnnotation(viewerAnnotation, {
|
this._instance.Core.annotationManager.deleteAnnotation(viewerAnnotation, {
|
||||||
imported: true,
|
imported: true,
|
||||||
force: true
|
force: true
|
||||||
});
|
});
|
||||||
@ -701,16 +712,16 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _getAnnotations(predicate: (value) => unknown) {
|
private _getAnnotations(predicate: (value) => unknown) {
|
||||||
const annotations = this._instance.annotManager.getAnnotationsList();
|
const annotations = this._instance.Core.annotationManager.getAnnotationsList();
|
||||||
return predicate ? annotations.filter(predicate) : annotations;
|
return predicate ? annotations.filter(predicate) : annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _hide(annotations: Annotations.Annotation[]): void {
|
private _hide(annotations: Annotation[]): void {
|
||||||
this._instance.annotManager.hideAnnotations(annotations);
|
this._instance.Core.annotationManager.hideAnnotations(annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _show(annotations: Annotations.Annotation[]): void {
|
private _show(annotations: Annotation[]): void {
|
||||||
this._instance.annotManager.showAnnotations(annotations);
|
this._instance.Core.annotationManager.showAnnotations(annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setAnnotationsColor(annotations, customData: string) {
|
private _setAnnotationsColor(annotations, customData: string) {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<section *ngIf="searchResults$ | async as searchResult">
|
<section *ngIf="searchResults$ | async">
|
||||||
<redaction-page-header
|
<redaction-page-header
|
||||||
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
|
(closeAction)="routerHistoryService.navigateToLastDossiersScreen()"
|
||||||
[searchPlaceholder]="'search.placeholder' | translate"
|
[searchPlaceholder]="'search.placeholder' | translate"
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
@import '../../../../../assets/styles/variables';
|
|
||||||
|
|
||||||
:host ::ng-deep iqser-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .table-item > div.cell {
|
:host ::ng-deep iqser-table cdk-virtual-scroll-viewport .cdk-virtual-scroll-content-wrapper .table-item > div.cell {
|
||||||
.highlights {
|
.highlights {
|
||||||
@include line-clamp(1);
|
@include common-mixins.line-clamp(1);
|
||||||
|
|
||||||
em {
|
em {
|
||||||
background-color: #fffcc4;
|
background-color: #fffcc4;
|
||||||
|
|||||||
@ -16,8 +16,8 @@ import { RouterHistoryService } from '@services/router-history.service';
|
|||||||
interface ListItem extends Listable {
|
interface ListItem extends Listable {
|
||||||
readonly dossierId: string;
|
readonly dossierId: string;
|
||||||
readonly filename: string;
|
readonly filename: string;
|
||||||
readonly unmatched: string[] | null;
|
readonly unmatched: readonly string[] | null;
|
||||||
readonly highlights: { [key: string]: string[] };
|
readonly highlights: Record<string, readonly string[]>;
|
||||||
readonly routerLink: string;
|
readonly routerLink: string;
|
||||||
readonly status: string;
|
readonly status: string;
|
||||||
readonly dossierName: string;
|
readonly dossierName: string;
|
||||||
@ -25,8 +25,8 @@ interface ListItem extends Listable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface SearchInput {
|
interface SearchInput {
|
||||||
query: string;
|
readonly query: string;
|
||||||
dossierIds?: string[];
|
readonly dossierIds?: readonly string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -37,10 +37,12 @@ interface SearchInput {
|
|||||||
export class SearchScreenComponent extends ListingComponent<ListItem> implements OnDestroy, OnInit {
|
export class SearchScreenComponent extends ListingComponent<ListItem> implements OnDestroy, OnInit {
|
||||||
readonly fileStatusTranslations = fileStatusTranslations;
|
readonly fileStatusTranslations = fileStatusTranslations;
|
||||||
readonly searchPositions = SearchPositions;
|
readonly searchPositions = SearchPositions;
|
||||||
@ViewChild('filenameTemplate', { static: true }) filenameTemplate: TemplateRef<never>;
|
|
||||||
@ViewChild('statusTemplate', { static: true }) statusTemplate: TemplateRef<never>;
|
@ViewChild('filenameTemplate', { static: true }) readonly filenameTemplate: TemplateRef<unknown>;
|
||||||
@ViewChild('dossierTemplate', { static: true }) dossierTemplate: TemplateRef<never>;
|
@ViewChild('statusTemplate', { static: true }) readonly statusTemplate: TemplateRef<unknown>;
|
||||||
@ViewChild('pagesTemplate', { static: true }) pagesTemplate: TemplateRef<never>;
|
@ViewChild('dossierTemplate', { static: true }) readonly dossierTemplate: TemplateRef<unknown>;
|
||||||
|
@ViewChild('pagesTemplate', { static: true }) readonly pagesTemplate: TemplateRef<unknown>;
|
||||||
|
|
||||||
readonly tableHeaderLabel = _('search-screen.table-header');
|
readonly tableHeaderLabel = _('search-screen.table-header');
|
||||||
tableColumnConfigs: TableColumnConfig<ListItem>[];
|
tableColumnConfigs: TableColumnConfig<ListItem>[];
|
||||||
readonly search$ = new BehaviorSubject<SearchInput>(null);
|
readonly search$ = new BehaviorSubject<SearchInput>(null);
|
||||||
@ -68,6 +70,7 @@ export class SearchScreenComponent extends ListingComponent<ListItem> implements
|
|||||||
this.filterService.addFilterGroup({
|
this.filterService.addFilterGroup({
|
||||||
slug: 'dossiers',
|
slug: 'dossiers',
|
||||||
label: this._translateService.instant('search-screen.filters.by-dossier'),
|
label: this._translateService.instant('search-screen.filters.by-dossier'),
|
||||||
|
filterceptionPlaceholder: this._translateService.instant('search-screen.filters.search-placeholder'),
|
||||||
icon: 'red:folder',
|
icon: 'red:folder',
|
||||||
filters: this._appStateService.allDossiers.map(dossier => ({
|
filters: this._appStateService.allDossiers.map(dossier => ({
|
||||||
key: dossier.dossierId,
|
key: dossier.dossierId,
|
||||||
@ -118,7 +121,7 @@ export class SearchScreenComponent extends ListingComponent<ListItem> implements
|
|||||||
|
|
||||||
private _search(searchInput: SearchInput): Observable<SearchResult> {
|
private _search(searchInput: SearchInput): Observable<SearchResult> {
|
||||||
return this._searchControllerService.search({
|
return this._searchControllerService.search({
|
||||||
dossierIds: searchInput.dossierIds,
|
dossierIds: [...searchInput.dossierIds],
|
||||||
queryString: searchInput.query ?? '',
|
queryString: searchInput.query ?? '',
|
||||||
page: 1,
|
page: 1,
|
||||||
returnSections: false,
|
returnSections: false,
|
||||||
@ -161,7 +164,7 @@ export class SearchScreenComponent extends ListingComponent<ListItem> implements
|
|||||||
dossierId,
|
dossierId,
|
||||||
unmatched: unmatchedTerms || null,
|
unmatched: unmatchedTerms || null,
|
||||||
highlights,
|
highlights,
|
||||||
status,
|
status: fileWrapper.status,
|
||||||
numberOfPages: fileWrapper.numberOfPages,
|
numberOfPages: fileWrapper.numberOfPages,
|
||||||
dossierName: this._getDossierWrapper(dossierId).dossierName,
|
dossierName: this._getDossierWrapper(dossierId).dossierName,
|
||||||
filename: fileWrapper.filename,
|
filename: fileWrapper.filename,
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
|||||||
import { DossiersDialogService } from './dossiers-dialog.service';
|
import { DossiersDialogService } from './dossiers-dialog.service';
|
||||||
import { BASE_HREF } from '../../../tokens';
|
import { BASE_HREF } from '../../../tokens';
|
||||||
import { UserService } from '@services/user.service';
|
import { UserService } from '@services/user.service';
|
||||||
import { Annotations } from '@pdftron/webviewer';
|
import { Core } from '@pdftron/webviewer';
|
||||||
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AnnotationActionsService {
|
export class AnnotationActionsService {
|
||||||
@ -281,7 +282,7 @@ export class AnnotationActionsService {
|
|||||||
return availableActions;
|
return availableActions;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateHiddenAnnotation(annotations: AnnotationWrapper[], viewerAnnotations: Annotations.Annotation[], hidden: boolean) {
|
updateHiddenAnnotation(annotations: AnnotationWrapper[], viewerAnnotations: Annotation[], hidden: boolean) {
|
||||||
const annotationId = (viewerAnnotations[0] as any).Tw;
|
const annotationId = (viewerAnnotations[0] as any).Tw;
|
||||||
const annotationToBeUpdated = annotations.find((a: AnnotationWrapper) => a.annotationId === annotationId);
|
const annotationToBeUpdated = annotations.find((a: AnnotationWrapper) => a.annotationId === annotationId);
|
||||||
annotationToBeUpdated.hidden = hidden;
|
annotationToBeUpdated.hidden = hidden;
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
import { Core, 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 { hexToRgb } from '@utils/functions';
|
||||||
import { AppStateService } from '@state/app-state.service';
|
import { AppStateService } from '@state/app-state.service';
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { UserPreferenceService } from '@services/user-preference.service';
|
import { UserPreferenceService } from '@services/user-preference.service';
|
||||||
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AnnotationDrawService {
|
export class AnnotationDrawService {
|
||||||
@ -14,18 +15,14 @@ export class AnnotationDrawService {
|
|||||||
private readonly _userPreferenceService: UserPreferenceService
|
private readonly _userPreferenceService: UserPreferenceService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
drawAnnotations(
|
drawAnnotations(activeViewer: WebViewerInstance, annotationWrappers: AnnotationWrapper[], hideSkipped = false, compareMode = false) {
|
||||||
activeViewer: WebViewerInstance,
|
if (!activeViewer) {
|
||||||
annotationWrappers: AnnotationWrapper[],
|
return;
|
||||||
hideSkipped: boolean = false,
|
}
|
||||||
compareMode: boolean = false
|
const annotations = annotationWrappers.map(annotation =>
|
||||||
) {
|
this.computeAnnotation(activeViewer, annotation, hideSkipped, compareMode)
|
||||||
const annotations = [];
|
);
|
||||||
annotationWrappers.forEach(annotation => {
|
const annotationManager = activeViewer.Core.annotationManager;
|
||||||
annotations.push(this.computeAnnotation(activeViewer, annotation, hideSkipped, compareMode));
|
|
||||||
});
|
|
||||||
|
|
||||||
const annotationManager = activeViewer.annotManager;
|
|
||||||
annotationManager.addAnnotations(annotations, { imported: true });
|
annotationManager.addAnnotations(annotations, { imported: true });
|
||||||
annotationManager.drawAnnotationsFromList(annotations);
|
annotationManager.drawAnnotationsFromList(annotations);
|
||||||
|
|
||||||
@ -49,14 +46,14 @@ export class AnnotationDrawService {
|
|||||||
// })
|
// })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const annotationManager = activeViewer.annotManager;
|
const annotationManager = activeViewer.Core.annotationManager;
|
||||||
annotationManager.addAnnotations(sections, { imported: true });
|
annotationManager.addAnnotations(sections, { imported: true });
|
||||||
annotationManager.drawAnnotationsFromList(sections);
|
annotationManager.drawAnnotationsFromList(sections);
|
||||||
}
|
}
|
||||||
|
|
||||||
computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) {
|
computeSection(activeViewer: WebViewerInstance, pageNumber: number, sectionRectangle: SectionRectangle) {
|
||||||
const rectangleAnnot = new activeViewer.Annotations.RectangleAnnotation();
|
const rectangleAnnot = new activeViewer.Core.Annotations.RectangleAnnotation();
|
||||||
const pageHeight = activeViewer.docViewer.getPageHeight(pageNumber);
|
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
|
||||||
const rectangle = {
|
const rectangle = {
|
||||||
topLeft: sectionRectangle.topLeft,
|
topLeft: sectionRectangle.topLeft,
|
||||||
page: pageNumber,
|
page: pageNumber,
|
||||||
@ -75,14 +72,9 @@ export class AnnotationDrawService {
|
|||||||
return rectangleAnnot;
|
return rectangleAnnot;
|
||||||
}
|
}
|
||||||
|
|
||||||
computeAnnotation(
|
computeAnnotation(activeViewer: WebViewerInstance, annotationWrapper: AnnotationWrapper, hideSkipped = false, compareMode = false) {
|
||||||
activeViewer: WebViewerInstance,
|
|
||||||
annotationWrapper: AnnotationWrapper,
|
|
||||||
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();
|
const highlight = new activeViewer.Core.Annotations.TextHighlightAnnotation();
|
||||||
highlight.PageNumber = pageNumber;
|
highlight.PageNumber = pageNumber;
|
||||||
highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type);
|
highlight.StrokeColor = this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type);
|
||||||
highlight.setContents(annotationWrapper.content);
|
highlight.setContents(annotationWrapper.content);
|
||||||
@ -96,13 +88,16 @@ export class AnnotationDrawService {
|
|||||||
(hideSkipped && annotationWrapper.isSkipped) ||
|
(hideSkipped && annotationWrapper.isSkipped) ||
|
||||||
annotationWrapper.isOCR ||
|
annotationWrapper.isOCR ||
|
||||||
annotationWrapper.hidden;
|
annotationWrapper.hidden;
|
||||||
highlight.setCustomData('redacto-manager', true);
|
highlight.setCustomData('redacto-manager', 'true');
|
||||||
highlight.setCustomData('redaction', annotationWrapper.isRedacted);
|
highlight.setCustomData('redaction', String(annotationWrapper.isRedacted));
|
||||||
highlight.setCustomData('skipped', annotationWrapper.isSkipped);
|
highlight.setCustomData('skipped', String(annotationWrapper.isSkipped));
|
||||||
highlight.setCustomData('changeLog', annotationWrapper.isChangeLogEntry);
|
highlight.setCustomData('changeLog', String(annotationWrapper.isChangeLogEntry));
|
||||||
highlight.setCustomData('changeLogRemoved', annotationWrapper.isChangeLogRemoved);
|
highlight.setCustomData('changeLogRemoved', String(annotationWrapper.isChangeLogRemoved));
|
||||||
highlight.setCustomData('redactionColor', this.getColor(activeViewer, 'redaction', 'redaction'));
|
highlight.setCustomData('redactionColor', String(this.getColor(activeViewer, 'redaction', 'redaction')));
|
||||||
highlight.setCustomData('annotationColor', this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type));
|
highlight.setCustomData(
|
||||||
|
'annotationColor',
|
||||||
|
String(this.getColor(activeViewer, annotationWrapper.superType, annotationWrapper.type))
|
||||||
|
);
|
||||||
|
|
||||||
return highlight;
|
return highlight;
|
||||||
}
|
}
|
||||||
@ -123,10 +118,10 @@ export class AnnotationDrawService {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const rgbColor = hexToRgb(color);
|
const rgbColor = hexToRgb(color);
|
||||||
return new activeViewer.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
|
return new activeViewer.Core.Annotations.Color(rgbColor.r, rgbColor.g, rgbColor.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
annotationToQuads(annotation: Annotations.Annotation, activeViewer: WebViewerInstance) {
|
annotationToQuads(annotation: Annotation, activeViewer: WebViewerInstance) {
|
||||||
const x1 = annotation.getRect().x1;
|
const x1 = annotation.getRect().x1;
|
||||||
const y1 = annotation.getRect().y1 + annotation.getRect().getHeight();
|
const y1 = annotation.getRect().y1 + annotation.getRect().getHeight();
|
||||||
|
|
||||||
@ -139,11 +134,11 @@ export class AnnotationDrawService {
|
|||||||
const x4 = annotation.getRect().x1;
|
const x4 = annotation.getRect().x1;
|
||||||
const y4 = annotation.getRect().y1;
|
const y4 = annotation.getRect().y1;
|
||||||
|
|
||||||
return new activeViewer.CoreControls.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
return new activeViewer.Core.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);
|
const pageHeight = activeViewer.Core.documentViewer.getPageHeight(pageNumber);
|
||||||
return positions.map(p => this._rectangleToQuad(p, activeViewer, pageHeight));
|
return positions.map(p => this._rectangleToQuad(p, activeViewer, pageHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,6 +155,6 @@ export class AnnotationDrawService {
|
|||||||
const x4 = rectangle.topLeft.x;
|
const x4 = rectangle.topLeft.x;
|
||||||
const y4 = pageHeight - rectangle.topLeft.y;
|
const y4 = pageHeight - rectangle.topLeft.y;
|
||||||
|
|
||||||
return new activeViewer.CoreControls.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
return new activeViewer.Core.Math.Quad(x1, y1, x2, y2, x3, y3, x4, y4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { ManualAnnotationService } from './manual-annotation.service';
|
|||||||
import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
import { ManualAnnotationDialogComponent } from '../dialogs/manual-redaction-dialog/manual-annotation-dialog.component';
|
||||||
import { EditDossierDialogComponent } from '../dialogs/edit-dossier-dialog/edit-dossier-dialog.component';
|
import { EditDossierDialogComponent } from '../dialogs/edit-dossier-dialog/edit-dossier-dialog.component';
|
||||||
import { AssignReviewerApproverDialogComponent } from '../dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component';
|
import { AssignReviewerApproverDialogComponent } from '../dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component';
|
||||||
import { AppConfigService } from '@app-config/app-config.service';
|
import { ConfigService } from '@services/config.service';
|
||||||
import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
|
import { ChangeLegalBasisDialogComponent } from '../dialogs/change-legal-basis-dialog/change-legal-basis-dialog.component';
|
||||||
import { RecategorizeImageDialogComponent } from '../dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
|
import { RecategorizeImageDialogComponent } from '../dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
|
||||||
import { DialogService, largeDialogConfig } from '@shared/services/dialog.service';
|
import { DialogService, largeDialogConfig } from '@shared/services/dialog.service';
|
||||||
@ -78,7 +78,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
|
|||||||
protected readonly _dialog: MatDialog,
|
protected readonly _dialog: MatDialog,
|
||||||
private readonly _appStateService: AppStateService,
|
private readonly _appStateService: AppStateService,
|
||||||
private readonly _manualAnnotationService: ManualAnnotationService,
|
private readonly _manualAnnotationService: ManualAnnotationService,
|
||||||
private readonly _appConfigService: AppConfigService
|
private readonly _configService: ConfigService
|
||||||
) {
|
) {
|
||||||
super(_dialog);
|
super(_dialog);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { forkJoin, Observable, of } from 'rxjs';
|
import { forkJoin, Observable, of } from 'rxjs';
|
||||||
import { catchError, map } from 'rxjs/operators';
|
import { catchError, map, tap } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
FileManagementControllerService,
|
FileManagementControllerService,
|
||||||
ManualRedactionControllerService,
|
ManualRedactionControllerService,
|
||||||
@ -24,10 +24,14 @@ export class PdfViewerDataService {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
loadActiveFileRedactionLog() {
|
loadActiveFileRedactionLog() {
|
||||||
return this._redactionLogControllerService.getRedactionLog(
|
return this._redactionLogControllerService
|
||||||
this._appStateService.activeDossierId,
|
.getRedactionLog(this._appStateService.activeDossierId, this._appStateService.activeFileId)
|
||||||
this._appStateService.activeFileId
|
.pipe(
|
||||||
);
|
tap(
|
||||||
|
redactionLog => redactionLog.redactionLogEntry.sort((a, b) => a.positions[0].page - b.positions[0].page),
|
||||||
|
catchError(() => of({}))
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadActiveFileData(): Observable<FileDataModel> {
|
loadActiveFileData(): Observable<FileDataModel> {
|
||||||
@ -35,7 +39,7 @@ export class PdfViewerDataService {
|
|||||||
const fileId = this._appStateService.activeFileId;
|
const fileId = this._appStateService.activeFileId;
|
||||||
|
|
||||||
const file$ = this.downloadOriginalFile(this._appStateService.activeFile);
|
const file$ = this.downloadOriginalFile(this._appStateService.activeFile);
|
||||||
const reactionLog$ = this._redactionLogControllerService.getRedactionLog(dossierId, fileId).pipe(catchError(() => of({})));
|
const reactionLog$ = this.loadActiveFileRedactionLog();
|
||||||
const redactionChangeLog$ = this._redactionLogControllerService
|
const redactionChangeLog$ = this._redactionLogControllerService
|
||||||
.getRedactionChangeLog(dossierId, fileId)
|
.getRedactionChangeLog(dossierId, fileId)
|
||||||
.pipe(catchError(() => of({})));
|
.pipe(catchError(() => of({})));
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
import { stampPDFPage } from '../../../utils/page-stamper';
|
import { stampPDFPage } from '@utils/page-stamper';
|
||||||
|
|
||||||
const processPage = async (pageNumber, document1, document2, mergedDocument, PDFNet) => {
|
const processPage = async (pageNumber, document1, document2, mergedDocument, pdfNet) => {
|
||||||
const document1PageCount = await document1.getPageCount();
|
const document1PageCount = await document1.getPageCount();
|
||||||
if (document1PageCount >= pageNumber) {
|
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 {
|
} else {
|
||||||
const pageToCopy = await document2.getPage(pageNumber);
|
const pageToCopy = await document2.getPage(pageNumber);
|
||||||
const blankPage = await mergedDocument.pageCreate(await pageToCopy.getCropBox());
|
const blankPage = await mergedDocument.pageCreate(await pageToCopy.getCropBox());
|
||||||
await blankPage.setRotation(await pageToCopy.getRotation());
|
await blankPage.setRotation(await pageToCopy.getRotation());
|
||||||
await mergedDocument.pagePushBack(blankPage);
|
await mergedDocument.pagePushBack(blankPage);
|
||||||
await stampPDFPage(mergedDocument, PDFNet, '<< Compare Placeholder Page >>', 20, 'courier', 'DIAGONAL', 33, '#ffb83b', [
|
await stampPDFPage(mergedDocument, pdfNet, '<< Compare Placeholder Page >>', 20, 'courier', 'DIAGONAL', 33, '#ffb83b', [
|
||||||
await mergedDocument.getPageCount()
|
await mergedDocument.getPageCount()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -25,17 +25,17 @@ export const loadCompareDocumentWrapper = async (
|
|||||||
fileStatus,
|
fileStatus,
|
||||||
setCompareViewMode: () => void,
|
setCompareViewMode: () => void,
|
||||||
navigateToPage: () => void,
|
navigateToPage: () => void,
|
||||||
PDFNet
|
pdfNet: any
|
||||||
) => {
|
) => {
|
||||||
try {
|
try {
|
||||||
const maxPageCount = Math.max(currentDocumentPageCount, compareDocumentPageCount);
|
const maxPageCount = Math.max(currentDocumentPageCount, compareDocumentPageCount);
|
||||||
|
|
||||||
for (let idx = 1; idx <= maxPageCount; idx++) {
|
for (let idx = 1; idx <= maxPageCount; idx++) {
|
||||||
await processPage(idx, currentDocument, compareDocument, mergedDocument, PDFNet);
|
await processPage(idx, currentDocument, compareDocument, mergedDocument, pdfNet);
|
||||||
await processPage(idx, compareDocument, currentDocument, mergedDocument, PDFNet);
|
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], {
|
const mergedDocumentBuffer = new Blob([buffer], {
|
||||||
type: 'application/pdf'
|
type: 'application/pdf'
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
|
||||||
import { ViewMode } from '@models/file/view-mode';
|
import { ViewMode } from '@models/file/view-mode';
|
||||||
import { translateQuads } from '../../../utils/pdf-coordinates';
|
import { translateQuads } from '@utils/pdf-coordinates';
|
||||||
import { Rectangle } from '@redaction/red-ui-http';
|
import { Rectangle } from '@redaction/red-ui-http';
|
||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
|
import { Core, WebViewerInstance } from '@pdftron/webviewer';
|
||||||
|
import Annotation = Core.Annotations.Annotation;
|
||||||
|
|
||||||
const DISABLED_HOTKEYS = [
|
const DISABLED_HOTKEYS = [
|
||||||
'CTRL+SHIFT+EQUAL',
|
'CTRL+SHIFT+EQUAL',
|
||||||
@ -35,18 +36,19 @@ const DISABLED_HOTKEYS = [
|
|||||||
'H',
|
'H',
|
||||||
'K',
|
'K',
|
||||||
'U'
|
'U'
|
||||||
];
|
] as const;
|
||||||
|
|
||||||
export class PdfViewerUtils {
|
export class PdfViewerUtils {
|
||||||
instance: WebViewerInstance;
|
|
||||||
viewMode: ViewMode;
|
|
||||||
ready = false;
|
ready = false;
|
||||||
multiSelectActive: boolean;
|
|
||||||
|
|
||||||
constructor(instance: WebViewerInstance, viewMode: ViewMode, multiSelectActive: boolean) {
|
constructor(readonly instance: WebViewerInstance, public viewMode: ViewMode, public multiSelectActive: boolean) {}
|
||||||
this.instance = instance;
|
|
||||||
this.viewMode = viewMode;
|
private get _documentViewer() {
|
||||||
this.multiSelectActive = multiSelectActive;
|
return this.instance?.Core.documentViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _annotationManager() {
|
||||||
|
return this.instance?.Core.annotationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isCompareMode() {
|
get isCompareMode() {
|
||||||
@ -59,9 +61,7 @@ export class PdfViewerUtils {
|
|||||||
|
|
||||||
get currentPage() {
|
get currentPage() {
|
||||||
try {
|
try {
|
||||||
return this.isCompareMode
|
return this.isCompareMode ? Math.ceil(this._currentInternalPage / 2) : this._currentInternalPage;
|
||||||
? Math.ceil(this.instance?.docViewer?.getCurrentPage() / 2)
|
|
||||||
: this.instance?.docViewer?.getCurrentPage();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -73,18 +73,18 @@ export class PdfViewerUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this.isCompareMode ? Math.ceil(this.instance?.docViewer?.getPageCount() / 2) : this.instance?.docViewer?.getPageCount();
|
return this.isCompareMode ? Math.ceil(this._totalInternalPages / 2) : this._totalInternalPages;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _currentInternalPage() {
|
private get _currentInternalPage() {
|
||||||
return this.instance?.docViewer?.getCurrentPage();
|
return this.instance?.Core.documentViewer?.getCurrentPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _totalInternalPages() {
|
private get _totalInternalPages() {
|
||||||
return this.instance?.docViewer?.getPageCount();
|
return this.instance?.Core.documentViewer?.getPageCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
navigateToPage(pageNumber: string | number) {
|
navigateToPage(pageNumber: string | number) {
|
||||||
@ -106,17 +106,17 @@ export class PdfViewerUtils {
|
|||||||
|
|
||||||
disableHotkeys(): void {
|
disableHotkeys(): void {
|
||||||
for (const hotkey of DISABLED_HOTKEYS) {
|
for (const hotkey of DISABLED_HOTKEYS) {
|
||||||
this.instance.hotkeys.off(hotkey);
|
this.instance.UI.hotkeys.off(hotkey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
translateQuads(page: number, quads: any) {
|
translateQuads(page: number, quads: any) {
|
||||||
const rotation = this.instance.docViewer.getCompleteRotation(page);
|
const rotation = this._documentViewer.getCompleteRotation(page);
|
||||||
return translateQuads(page, rotation, quads);
|
return translateQuads(page, rotation, quads);
|
||||||
}
|
}
|
||||||
|
|
||||||
toPosition(page: number, selectedQuad: any): Rectangle {
|
toPosition(page: number, selectedQuad: any): Rectangle {
|
||||||
const pageHeight = this.instance.docViewer.getPageHeight(page);
|
const pageHeight = this._documentViewer.getPageHeight(page);
|
||||||
const height = selectedQuad.y2 - selectedQuad.y4;
|
const height = selectedQuad.y2 - selectedQuad.y4;
|
||||||
return {
|
return {
|
||||||
page: page,
|
page: page,
|
||||||
@ -130,7 +130,7 @@ export class PdfViewerUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deselectAllAnnotations() {
|
deselectAllAnnotations() {
|
||||||
this.instance.annotManager.deselectAllAnnotations();
|
this._annotationManager.deselectAllAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectAnnotations($event: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }) {
|
selectAnnotations($event: AnnotationWrapper[] | { annotations: AnnotationWrapper[]; multiSelect: boolean }) {
|
||||||
@ -149,24 +149,23 @@ export class PdfViewerUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const annotationsFromViewer = annotations.map(ann => this._getAnnotationById(ann.id));
|
const annotationsFromViewer = annotations.map(ann => this._getAnnotationById(ann.id));
|
||||||
this.instance.annotManager.selectAnnotations(annotationsFromViewer);
|
this._annotationManager.selectAnnotations(annotationsFromViewer);
|
||||||
// this.navigateToPage(annotations[0].pageNumber*this.paginationOffset);
|
// this.navigateToPage(annotations[0].pageNumber*this.paginationOffset);
|
||||||
this.instance.annotManager.jumpToAnnotation(annotationsFromViewer[0]);
|
this._annotationManager.jumpToAnnotation(annotationsFromViewer[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectAnnotations(annotations: AnnotationWrapper[]) {
|
deselectAnnotations(annotations: AnnotationWrapper[]) {
|
||||||
const ann = annotations.map(a => this._getAnnotationById(a.id));
|
const ann = annotations.map(a => this._getAnnotationById(a.id));
|
||||||
this.instance.annotManager.deselectAnnotations(ann);
|
this._annotationManager.deselectAnnotations(ann);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _navigateToPage(pageNumber) {
|
private _navigateToPage(pageNumber) {
|
||||||
const activePage = this.instance.docViewer.getCurrentPage();
|
if (this._currentInternalPage !== pageNumber) {
|
||||||
if (activePage !== pageNumber) {
|
this._documentViewer.displayPageLocation(pageNumber, 0, 0);
|
||||||
this.instance.docViewer.displayPageLocation(pageNumber, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getAnnotationById(id: string): Annotations.Annotation {
|
private _getAnnotationById(id: string): Annotation {
|
||||||
return this.instance.annotManager.getAnnotationById(id);
|
return this._annotationManager.getAnnotationById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,7 @@ export class IconsModule {
|
|||||||
constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) {
|
constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) {
|
||||||
const icons = [
|
const icons = [
|
||||||
'add',
|
'add',
|
||||||
|
'ai',
|
||||||
'analyse',
|
'analyse',
|
||||||
'approved',
|
'approved',
|
||||||
'arrow-right',
|
'arrow-right',
|
||||||
@ -62,6 +63,7 @@ export class IconsModule {
|
|||||||
'reason',
|
'reason',
|
||||||
'remove-from-dict',
|
'remove-from-dict',
|
||||||
'report',
|
'report',
|
||||||
|
'rule',
|
||||||
'secret',
|
'secret',
|
||||||
'status',
|
'status',
|
||||||
'status-collapse',
|
'status-collapse',
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
@ -11,7 +11,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--color);
|
background-color: var(--color);
|
||||||
}
|
}
|
||||||
@ -60,9 +60,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.skipped {
|
.skipped {
|
||||||
background-color: $grey-5;
|
background-color: variables.$grey-5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.none {
|
.none {
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
button {
|
button {
|
||||||
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
&[aria-expanded='true'] {
|
&[aria-expanded='true'] {
|
||||||
button {
|
button {
|
||||||
background: rgba($primary, 0.1);
|
background: rgba(variables.$primary, 0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -78,7 +78,7 @@ ngx-monaco-editor {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 12px;
|
right: 12px;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
|
|
||||||
.with-input {
|
.with-input {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -106,7 +106,7 @@ ngx-monaco-editor {
|
|||||||
padding: 0 100px;
|
padding: 0 100px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px solid $grey-5;
|
border: 1px solid variables.$grey-5;
|
||||||
|
|
||||||
> mat-icon {
|
> mat-icon {
|
||||||
height: 60px;
|
height: 60px;
|
||||||
@ -116,6 +116,6 @@ ngx-monaco-editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.heading-l {
|
.heading-l {
|
||||||
color: $grey-7;
|
color: variables.$grey-7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -15,5 +15,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.border {
|
.border {
|
||||||
border: 1px solid $grey-7;
|
border: 1px solid variables.$grey-7;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -22,7 +22,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
color: $primary;
|
color: variables.$primary;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 1px solid $grey-5;
|
border: 1px solid variables.$grey-5;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
&.ng-invalid {
|
&.ng-invalid {
|
||||||
border-color: rgba($primary, 0.3);
|
border-color: rgba(variables.$primary, 0.3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,23 +47,23 @@ mat-chip {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary {
|
.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary {
|
||||||
background-color: $grey-6;
|
background-color: variables.$grey-6;
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-chip.mat-standard-chip {
|
.mat-chip.mat-standard-chip {
|
||||||
background-color: $white;
|
background-color: variables.$white;
|
||||||
color: $accent;
|
color: variables.$accent;
|
||||||
margin: 0 0 2px 0;
|
margin: 0 0 2px 0;
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: $grey-8;
|
background-color: variables.$grey-8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-chip.mat-standard-chip::after {
|
.mat-chip.mat-standard-chip::after {
|
||||||
background: $grey-8;
|
background: variables.$grey-8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-standard-chip:focus::after {
|
.mat-standard-chip:focus::after {
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
@import '../../../../../assets/styles/variables';
|
@use 'variables';
|
||||||
@import 'libs/common-ui/src/assets/styles/mixins';
|
@use 'common-mixins';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
background-color: $grey-2;
|
background-color: variables.$grey-2;
|
||||||
border-right: 1px solid $separator;
|
border-right: 1px solid variables.$separator;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@include no-scroll-bar;
|
@include common-mixins.no-scroll-bar;
|
||||||
|
|
||||||
.all-caps-label {
|
.all-caps-label {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
@ -26,12 +26,12 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
||||||
&:not(.active):hover {
|
&:not(.active):hover {
|
||||||
background-color: rgba($primary, 0.2);
|
background-color: rgba(variables.$primary, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background-color: $primary;
|
background-color: variables.$primary;
|
||||||
color: $white;
|
color: variables.$white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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