Pull request #252: Some branch
Merge in RED/ui from some-branch to master * commit '26f5de1d30ef28a49d31a8635660884dfd47a467': chore(release) fixed legal basis issues with backend not exactly matching LB reason chore(release) duplicated keys in search quick fix chore(release) chore(release) manual redaction fixes working entire platform search add library for common ui
This commit is contained in:
commit
10976ab876
28
angular.json
28
angular.json
@ -1,5 +1,4 @@
|
||||
{
|
||||
"$schema": "node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"cli": {
|
||||
"defaultCollection": "@nrwl/angular",
|
||||
@ -9,12 +8,15 @@
|
||||
"defaultProject": "red-ui",
|
||||
"schematics": {
|
||||
"@nrwl/angular:application": {
|
||||
"linter": "eslint",
|
||||
"unitTestRunner": "jest",
|
||||
"e2eTestRunner": "cypress"
|
||||
},
|
||||
"@nrwl/angular:library": {
|
||||
"linter": "eslint",
|
||||
"unitTestRunner": "jest"
|
||||
}
|
||||
},
|
||||
"@nrwl/angular:component": {}
|
||||
},
|
||||
"projects": {
|
||||
"red-ui": {
|
||||
@ -186,6 +188,28 @@
|
||||
"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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,2 @@
|
||||
<router-outlet></router-outlet>
|
||||
<redaction-full-page-loading-indicator
|
||||
[displayed]="loadingService.isLoading | async"
|
||||
></redaction-full-page-loading-indicator>
|
||||
<redaction-full-page-loading-indicator [displayed]="loadingService.isLoading$ | async"></redaction-full-page-loading-indicator>
|
||||
|
||||
@ -32,6 +32,7 @@ import { GlobalErrorHandler } from '@utils/global-error-handler.service';
|
||||
import { REDMissingTranslationHandler } from '@utils/missing-translations-handler';
|
||||
import { configurationInitializer } from '@app-config/configuration.initializer';
|
||||
import { AppConfigService } from '@app-config/app-config.service';
|
||||
import { SpotlightSearchComponent } from '@components/spotlight-search/spotlight-search.component';
|
||||
|
||||
export function httpLoaderFactory(httpClient: HttpClient) {
|
||||
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
|
||||
@ -49,7 +50,15 @@ function cleanupBaseUrl(baseUrl: string) {
|
||||
|
||||
const screens = [BaseScreenComponent, DownloadsListScreenComponent, UserProfileScreenComponent];
|
||||
|
||||
const components = [AppComponent, LogoComponent, AuthErrorComponent, ToastComponent, NotificationsComponent, ...screens];
|
||||
const components = [
|
||||
AppComponent,
|
||||
LogoComponent,
|
||||
AuthErrorComponent,
|
||||
ToastComponent,
|
||||
NotificationsComponent,
|
||||
SpotlightSearchComponent,
|
||||
...screens
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [...components],
|
||||
|
||||
@ -6,11 +6,7 @@
|
||||
<mat-icon svgIcon="red:menu"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuNav="matMenu">
|
||||
<button
|
||||
mat-menu-item
|
||||
routerLink="/main/dossiers"
|
||||
translate="top-bar.navigation-items.dossiers"
|
||||
></button>
|
||||
<button mat-menu-item routerLink="/main/dossiers" translate="top-bar.navigation-items.dossiers"></button>
|
||||
<button
|
||||
*ngIf="appStateService.activeDossier"
|
||||
[routerLink]="'/main/dossiers/' + appStateService.activeDossierId"
|
||||
@ -20,22 +16,14 @@
|
||||
</button>
|
||||
<button
|
||||
*ngIf="appStateService.activeFile"
|
||||
[routerLink]="
|
||||
'/main/dossiers/' +
|
||||
appStateService.activeDossierId +
|
||||
'/file/' +
|
||||
appStateService.activeFile.fileId
|
||||
"
|
||||
[routerLink]="'/main/dossiers/' + appStateService.activeDossierId + '/file/' + appStateService.activeFile.fileId"
|
||||
mat-menu-item
|
||||
>
|
||||
{{ appStateService.activeFile.filename }}
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="permissionsService.isUser()"
|
||||
class="menu flex-2 visible-lg breadcrumbs-container"
|
||||
>
|
||||
<div *ngIf="permissionsService.isUser()" class="menu flex-2 visible-lg breadcrumbs-container">
|
||||
<a
|
||||
*ngIf="dossiersView"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
@ -49,15 +37,8 @@
|
||||
{{ 'top-bar.navigation-items.back' | translate }}
|
||||
</a>
|
||||
<ng-container *ngIf="dossiersView">
|
||||
<mat-icon
|
||||
*ngIf="!appStateService.activeDossier"
|
||||
class="primary"
|
||||
svgIcon="red:arrow-down"
|
||||
></mat-icon>
|
||||
<mat-icon
|
||||
*ngIf="appStateService.activeDossier"
|
||||
svgIcon="red:arrow-right"
|
||||
></mat-icon>
|
||||
<mat-icon *ngIf="!appStateService.activeDossier" class="primary" svgIcon="red:arrow-down"></mat-icon>
|
||||
<mat-icon *ngIf="appStateService.activeDossier" svgIcon="red:arrow-right"></mat-icon>
|
||||
<a
|
||||
*ngIf="appStateService.activeDossier"
|
||||
[routerLinkActiveOptions]="{ exact: true }"
|
||||
@ -70,12 +51,7 @@
|
||||
<mat-icon *ngIf="appStateService.activeFile" svgIcon="red:arrow-right"></mat-icon>
|
||||
<a
|
||||
*ngIf="appStateService.activeFile"
|
||||
[routerLink]="
|
||||
'/main/dossiers/' +
|
||||
appStateService.activeDossierId +
|
||||
'/file/' +
|
||||
appStateService.activeFile.fileId
|
||||
"
|
||||
[routerLink]="'/main/dossiers/' + appStateService.activeDossierId + '/file/' + appStateService.activeFile.fileId"
|
||||
class="breadcrumb"
|
||||
routerLinkActive="active"
|
||||
>
|
||||
@ -90,26 +66,21 @@
|
||||
<div class="app-name">{{ titleService.getTitle() }}</div>
|
||||
</div>
|
||||
<div class="menu right flex-2">
|
||||
<redaction-notifications
|
||||
*ngIf="userPreferenceService.areDevFeaturesEnabled"
|
||||
class="mr-8"
|
||||
></redaction-notifications>
|
||||
<redaction-circle-button
|
||||
*ngIf="!isSearchScreen"
|
||||
[icon]="'red:search'"
|
||||
(action)="openSpotlightSearch()"
|
||||
[tooltip]="'search.header-label' | translate"
|
||||
tooltipPosition="below"
|
||||
></redaction-circle-button>
|
||||
|
||||
<redaction-user-button
|
||||
[matMenuTriggerFor]="userMenu"
|
||||
[showDot]="showPendingDownloadsDot"
|
||||
[user]="user"
|
||||
></redaction-user-button>
|
||||
<redaction-notifications *ngIf="userPreferenceService.areDevFeaturesEnabled" class="mr-8"></redaction-notifications>
|
||||
|
||||
<redaction-user-button [matMenuTriggerFor]="userMenu" [showDot]="showPendingDownloadsDot" [user]="user"></redaction-user-button>
|
||||
|
||||
<mat-menu #userMenu="matMenu" xPosition="before">
|
||||
<ng-container *ngFor="let item of userMenuItems; trackBy: trackByName">
|
||||
<button
|
||||
(click)="(item.action)"
|
||||
*ngIf="item.show"
|
||||
[routerLink]="item.routerLink"
|
||||
mat-menu-item
|
||||
translate
|
||||
>
|
||||
<button (click)="(item.action)" *ngIf="item.show" [routerLink]="item.routerLink" mat-menu-item translate>
|
||||
{{ item.name }}
|
||||
</button>
|
||||
</ng-container>
|
||||
@ -124,10 +95,5 @@
|
||||
<div class="divider"></div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="userPreferenceService.areDevFeaturesEnabled"
|
||||
class="dev-mode"
|
||||
translate="dev-mode"
|
||||
></div>
|
||||
|
||||
<div *ngIf="userPreferenceService.areDevFeaturesEnabled" class="dev-mode" translate="dev-mode"></div>
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
@ -7,6 +7,10 @@ import { Router } from '@angular/router';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { FileDownloadService } from '@upload-download/services/file-download.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { SpotlightSearchComponent } from '@components/spotlight-search/spotlight-search.component';
|
||||
import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-search-action';
|
||||
import { SpotlightSearchDialogData } from '@components/spotlight-search/spotlight-search-dialog-data';
|
||||
|
||||
interface MenuItem {
|
||||
name: string;
|
||||
@ -44,6 +48,8 @@ export class BaseScreenComponent {
|
||||
}
|
||||
];
|
||||
|
||||
showSearch = false;
|
||||
|
||||
constructor(
|
||||
readonly appStateService: AppStateService,
|
||||
readonly permissionsService: PermissionsService,
|
||||
@ -52,10 +58,11 @@ export class BaseScreenComponent {
|
||||
readonly fileDownloadService: FileDownloadService,
|
||||
private readonly _router: Router,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _translateService: TranslateService
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _dialog: MatDialog
|
||||
) {
|
||||
_router.events.subscribe(() => {
|
||||
this._dossiersView = _router.url.indexOf('/main/dossiers') === 0;
|
||||
this._dossiersView = _router.url.includes('/main/dossiers') && !this.isSearchScreen;
|
||||
});
|
||||
}
|
||||
|
||||
@ -65,6 +72,10 @@ export class BaseScreenComponent {
|
||||
return this._dossiersView;
|
||||
}
|
||||
|
||||
get isSearchScreen() {
|
||||
return this._router.url.includes('/search');
|
||||
}
|
||||
|
||||
get user() {
|
||||
return this._userService.user;
|
||||
}
|
||||
@ -77,6 +88,44 @@ export class BaseScreenComponent {
|
||||
return this._translateService.langs;
|
||||
}
|
||||
|
||||
openSpotlightSearch() {
|
||||
const spotlightSearchActions: SpotlightSearchAction[] = [
|
||||
{
|
||||
text: this._translateService.instant('search.this-dossier'),
|
||||
icon: 'red:enter',
|
||||
hide: !this.appStateService.activeDossier,
|
||||
action: query => this._searchThisDossier(query)
|
||||
},
|
||||
{
|
||||
text: this._translateService.instant('search.entire-platform'),
|
||||
icon: 'red:enter',
|
||||
action: query => this._searchEntirePlatform(query)
|
||||
}
|
||||
];
|
||||
|
||||
this._dialog.open(SpotlightSearchComponent, {
|
||||
data: {
|
||||
actionsConfig: spotlightSearchActions,
|
||||
placeholder: this._translateService.instant('search.placeholder')
|
||||
} as SpotlightSearchDialogData
|
||||
});
|
||||
}
|
||||
|
||||
private _searchThisDossier(query: string) {
|
||||
this._router
|
||||
.navigate(['main/dossiers/search'], {
|
||||
queryParams: {
|
||||
query: query,
|
||||
dossierId: this.appStateService.activeDossier.dossierId
|
||||
}
|
||||
})
|
||||
.then();
|
||||
}
|
||||
|
||||
private _searchEntirePlatform(query: string) {
|
||||
this._router.navigate(['main/dossiers/search'], { queryParams: { query: query } }).then();
|
||||
}
|
||||
|
||||
logout() {
|
||||
this._userService.logout();
|
||||
}
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
export interface SpotlightSearchAction {
|
||||
text: string;
|
||||
action: (query: string) => void;
|
||||
icon?: string;
|
||||
hide?: boolean;
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
import { SpotlightSearchAction } from './spotlight-search-action';
|
||||
|
||||
export interface SpotlightSearchDialogData {
|
||||
actionsConfig: SpotlightSearchAction[];
|
||||
placeholder: string;
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
<div class="spotlight-wrapper">
|
||||
<form [formGroup]="formGroup">
|
||||
<div class="search d-flex">
|
||||
<input
|
||||
tabindex="-1"
|
||||
id="query"
|
||||
type="text"
|
||||
formControlName="query"
|
||||
autocomplete="off"
|
||||
class="spotlight-row"
|
||||
[placeholder]="data.placeholder"
|
||||
/>
|
||||
|
||||
<mat-icon class="mr-34" *ngIf="(showActions$ | async) === false" [svgIcon]="'red:search'"></mat-icon>
|
||||
|
||||
<redaction-circle-button
|
||||
*ngIf="showActions$ | async"
|
||||
class="mr-24"
|
||||
(action)="close()"
|
||||
icon="red:close"
|
||||
></redaction-circle-button>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<ng-container *ngIf="showActions$ | async">
|
||||
<ng-container *ngFor="let item of data.actionsConfig">
|
||||
<button
|
||||
*ngIf="!item.hide"
|
||||
#actions
|
||||
(keydown.space)="$event.preventDefault()"
|
||||
(keyup.space)="$event.preventDefault()"
|
||||
tabindex="0"
|
||||
class="spotlight-row focus pointer"
|
||||
(click)="item.action(formGroup.get('query').value); close()"
|
||||
>
|
||||
<mat-icon class="mr-16" [svgIcon]="item.icon"></mat-icon>
|
||||
<span>{{ item.text }}</span>
|
||||
</button>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</form>
|
||||
</div>
|
||||
@ -0,0 +1,51 @@
|
||||
@import 'apps/red-ui/src/assets/styles/red-variables';
|
||||
|
||||
.spotlight-wrapper {
|
||||
overflow: hidden;
|
||||
width: 750px;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 15%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.spotlight-row {
|
||||
display: block;
|
||||
width: 750px;
|
||||
height: 60px;
|
||||
margin: auto;
|
||||
text-align: left;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
outline: none;
|
||||
color: $grey-1;
|
||||
padding: 0 24px;
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.focus:focus {
|
||||
background-color: $grey-2;
|
||||
}
|
||||
|
||||
.search {
|
||||
background-color: $white;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
background-color: rgba(226, 228, 233, 0.9);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 668px !important;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, HostListener, Inject, QueryList, ViewChildren } from '@angular/core';
|
||||
import { FormBuilder } from '@angular/forms';
|
||||
import { debounceTime, map, startWith, tap } from 'rxjs/operators';
|
||||
import { debounce } from '@utils/debounce';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { SpotlightSearchDialogData } from '@components/spotlight-search/spotlight-search-dialog-data';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-spotlight-search',
|
||||
templateUrl: './spotlight-search.component.html',
|
||||
styleUrls: ['./spotlight-search.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SpotlightSearchComponent {
|
||||
@ViewChildren('actions')
|
||||
private readonly _actions: QueryList<ElementRef>;
|
||||
private _currentActionIdx = 0;
|
||||
|
||||
formGroup = this._formBuilder.group({ query: [''] });
|
||||
query$ = this.formGroup.get('query').valueChanges.pipe(startWith(''));
|
||||
showActions$ = this.query$.pipe(
|
||||
debounceTime(300),
|
||||
tap(value => this._restoreFocusOnAction(value === '')),
|
||||
map(value => value !== '')
|
||||
);
|
||||
|
||||
constructor(
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
private readonly _dialogRef: MatDialogRef<SpotlightSearchComponent>,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
readonly data: SpotlightSearchDialogData
|
||||
) {}
|
||||
|
||||
close() {
|
||||
this._dialogRef.close();
|
||||
}
|
||||
|
||||
@HostListener('document:keyup', ['$event'])
|
||||
handleKeyDown(event: KeyboardEvent) {
|
||||
if (event.code === 'ArrowDown' && this._actions) {
|
||||
this._currentActionIdx++;
|
||||
return this._restoreFocusOnAction(this._currentActionIdx === this._actions.length);
|
||||
}
|
||||
|
||||
if (event.code === 'ArrowUp' && this._actions) {
|
||||
if (this._currentActionIdx === 0) this._currentActionIdx = this._actions.length - 1;
|
||||
else this._currentActionIdx--;
|
||||
return this._restoreFocusOnAction();
|
||||
}
|
||||
|
||||
if (['Tab'].includes(event.code)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._actions.find((_, index) => index === this._currentActionIdx)?.nativeElement === document.activeElement) {
|
||||
let query = this.formGroup.get('query').value as string;
|
||||
if (event.code === 'Backspace') query = query.substring(0, query.length - 1);
|
||||
else if (event.key.length === 1) query = query + event.key;
|
||||
this.formGroup.patchValue({ query: query });
|
||||
}
|
||||
document.getElementById('query').focus();
|
||||
}
|
||||
|
||||
@debounce(50)
|
||||
private _restoreFocusOnAction(resetToFirst = false) {
|
||||
if (resetToFirst) this._currentActionIdx = 0;
|
||||
this._actions.find((_, index) => index === this._currentActionIdx)?.nativeElement.focus();
|
||||
}
|
||||
}
|
||||
@ -359,7 +359,7 @@ export class AnnotationWrapper {
|
||||
|
||||
private static _getShortContent(entry: RedactionLogEntryWrapper) {
|
||||
if (entry.legalBasis) {
|
||||
const lb = entry.legalBasisMapping?.find(lbm => lbm.reason === entry.legalBasis);
|
||||
const lb = entry.legalBasisMapping?.find(lbm => lbm.reason.toLowerCase().includes(entry.legalBasis.toLowerCase()));
|
||||
if (lb) return lb.name;
|
||||
}
|
||||
|
||||
|
||||
@ -21,42 +21,39 @@ export class RedRoleGuard implements CanActivate {
|
||||
this._loadingService.stop();
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
} else {
|
||||
// we have at least 1 RED Role -> if it's not user he must be admin
|
||||
return;
|
||||
}
|
||||
// we have at least 1 RED Role -> if it's not user he must be admin
|
||||
|
||||
if (
|
||||
this._userService.user.isUserAdmin &&
|
||||
!this._userService.user.isAdmin &&
|
||||
!(
|
||||
state.url.startsWith('/main/admin/users') ||
|
||||
state.url.startsWith('/main/my-profile')
|
||||
)
|
||||
) {
|
||||
this._router.navigate(['/main/admin/users']);
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
return;
|
||||
}
|
||||
if (
|
||||
this._userService.user.isUserAdmin &&
|
||||
!this._userService.user.isAdmin &&
|
||||
!(state.url.startsWith('/main/admin/users') || state.url.startsWith('/main/my-profile'))
|
||||
) {
|
||||
this._router.navigate(['/main/admin/users']);
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._userService.isUser() && state.url.startsWith('/main/dossiers')) {
|
||||
this._router.navigate(['/main/admin']);
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
return;
|
||||
}
|
||||
if (route.data.requiredRoles) {
|
||||
if (this._userService.hasAnyRole(route.data.requiredRoles)) {
|
||||
obs.next(true);
|
||||
obs.complete();
|
||||
} else {
|
||||
this._router.navigate(['/main/dossiers']);
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
}
|
||||
} else {
|
||||
if (!this._userService.isUser() && state.url.startsWith('/main/dossiers')) {
|
||||
this._router.navigate(['/main/admin']);
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
return;
|
||||
}
|
||||
if (route.data.requiredRoles) {
|
||||
if (this._userService.hasAnyRole(route.data.requiredRoles)) {
|
||||
obs.next(true);
|
||||
obs.complete();
|
||||
} else {
|
||||
this._router.navigate(['/main/dossiers']);
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
}
|
||||
} else {
|
||||
obs.next(true);
|
||||
obs.complete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -27,10 +27,6 @@ mat-slide-toggle {
|
||||
line-height: 33px;
|
||||
}
|
||||
|
||||
.mr-24 {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
mat-slide-toggle {
|
||||
margin-left: 8px;
|
||||
margin-right: 5px;
|
||||
|
||||
@ -12,10 +12,7 @@ import { DossierWrapper } from '@state/model/dossier.wrapper';
|
||||
export class NeedsWorkBadgeComponent {
|
||||
@Input() needsWorkInput: FileStatusWrapper | DossierWrapper;
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _permissionsService: PermissionsService
|
||||
) {}
|
||||
constructor(private readonly _appStateService: AppStateService, private readonly _permissionsService: PermissionsService) {}
|
||||
|
||||
get suggestionColor() {
|
||||
return this._getDictionaryColor('suggestion');
|
||||
@ -50,10 +47,7 @@ export class NeedsWorkBadgeComponent {
|
||||
}
|
||||
|
||||
get hasAnnotationComments(): boolean {
|
||||
return (
|
||||
this.needsWorkInput instanceof FileStatusWrapper &&
|
||||
(<any>this.needsWorkInput).hasAnnotationComments
|
||||
);
|
||||
return this.needsWorkInput instanceof FileStatusWrapper && (<any>this.needsWorkInput).hasAnnotationComments;
|
||||
}
|
||||
|
||||
reanalysisRequired() {
|
||||
@ -65,11 +59,6 @@ export class NeedsWorkBadgeComponent {
|
||||
}
|
||||
|
||||
private _getDictionaryColor(type: string) {
|
||||
let dossierTemplateId = null;
|
||||
if (this.needsWorkInput instanceof DossierWrapper) {
|
||||
dossierTemplateId = this.needsWorkInput.dossierTemplateId;
|
||||
}
|
||||
|
||||
return this._appStateService.getDictionaryColor(type, dossierTemplateId);
|
||||
return this._appStateService.getDictionaryColor(type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,7 @@
|
||||
<button
|
||||
(click)="scroll(buttonType.TOP)"
|
||||
[hidden]="!showScroll(buttonType.TOP)"
|
||||
class="scroll-button top pointer"
|
||||
>
|
||||
<button (click)="scroll(buttonType.top)" [hidden]="!showScroll(buttonType.top)" class="scroll-button top pointer">
|
||||
<mat-icon svgIcon="red:arrow-down-o"></mat-icon>
|
||||
</button>
|
||||
|
||||
<button
|
||||
(click)="scroll(buttonType.BOTTOM)"
|
||||
[hidden]="!showScroll(buttonType.BOTTOM)"
|
||||
class="scroll-button bottom pointer"
|
||||
>
|
||||
<button (click)="scroll(buttonType.bottom)" [hidden]="!showScroll(buttonType.bottom)" class="scroll-button bottom pointer">
|
||||
<mat-icon svgIcon="red:arrow-down-o"></mat-icon>
|
||||
</button>
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
import { Component, HostListener, Input } from '@angular/core';
|
||||
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
||||
|
||||
enum ButtonType {
|
||||
TOP = 'top',
|
||||
BOTTOM = 'bottom'
|
||||
}
|
||||
const ButtonTypes = {
|
||||
top: 'top',
|
||||
bottom: 'bottom'
|
||||
} as const;
|
||||
|
||||
type ButtonType = keyof typeof ButtonTypes;
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-scroll-button',
|
||||
@ -12,7 +14,7 @@ enum ButtonType {
|
||||
styleUrls: ['./scroll-button.component.scss']
|
||||
})
|
||||
export class ScrollButtonComponent {
|
||||
buttonType = ButtonType;
|
||||
buttonType = ButtonTypes;
|
||||
|
||||
@Input()
|
||||
scrollViewport: CdkVirtualScrollViewport;
|
||||
@ -20,9 +22,7 @@ export class ScrollButtonComponent {
|
||||
itemSize: number;
|
||||
|
||||
scroll(type: ButtonType): void {
|
||||
const viewportSize =
|
||||
(this.scrollViewport?.getViewportSize() - this.itemSize) *
|
||||
(type === ButtonType.TOP ? -1 : 1);
|
||||
const viewportSize = (this.scrollViewport?.getViewportSize() - this.itemSize) * (type === ButtonTypes.top ? -1 : 1);
|
||||
const scrollOffset = this.scrollViewport?.measureScrollOffset('top');
|
||||
this.scrollViewport?.scrollToOffset(scrollOffset + viewportSize, 'smooth');
|
||||
}
|
||||
@ -37,10 +37,10 @@ export class ScrollButtonComponent {
|
||||
|
||||
@HostListener('document:keyup', ['$event'])
|
||||
spaceAndPageDownScroll(event: KeyboardEvent): void {
|
||||
if (['Space', 'PageDown'].includes(event.code)) {
|
||||
this.scroll(ButtonType.BOTTOM);
|
||||
} else if (['PageUp'].includes(event.code)) {
|
||||
this.scroll(ButtonType.TOP);
|
||||
if (['Space', 'PageDown'].includes(event.code) && (event.target as any).tagName === 'BODY') {
|
||||
this.scroll(ButtonTypes.bottom);
|
||||
} else if (['PageUp'].includes(event.code) && (event.target as any).tagName === 'BODY') {
|
||||
this.scroll(ButtonTypes.top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { DossierListingScreenComponent } from './screens/dossier-listing-screen/dossier-listing-screen.component';
|
||||
import { CompositeRouteGuard } from '@guards/composite-route.guard';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
import { RedRoleGuard } from '../auth/red-role.guard';
|
||||
import { AppStateGuard } from '@state/app-state.guard';
|
||||
import { DossierOverviewScreenComponent } from './screens/dossier-overview-screen/dossier-overview-screen.component';
|
||||
import { SearchScreenComponent } from './screens/search-screen/search-screen.component';
|
||||
import { FilePreviewScreenComponent } from './screens/file-preview-screen/file-preview-screen.component';
|
||||
import { DossierOverviewScreenComponent } from './screens/dossier-overview-screen/dossier-overview-screen.component';
|
||||
|
||||
const routes = [
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DossierListingScreenComponent,
|
||||
path: 'search',
|
||||
component: SearchScreenComponent,
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||
reuse: true
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -35,6 +35,16 @@ const routes = [
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||
reuse: true
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
pathMatch: 'full',
|
||||
component: DossierListingScreenComponent,
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard],
|
||||
reuse: true
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -49,8 +49,9 @@ import { RecategorizeImageDialogComponent } from './dialogs/recategorize-image-d
|
||||
import { EditDossierAttributesComponent } from './dialogs/edit-dossier-dialog/attributes/edit-dossier-attributes.component';
|
||||
import { DossiersService } from './services/dossiers.service';
|
||||
import { DossierDetailsStatsComponent } from './components/dossier-details-stats/dossier-details-stats.component';
|
||||
import { SearchScreenComponent } from './screens/search-screen/search-screen.component';
|
||||
|
||||
const screens = [DossierListingScreenComponent, DossierOverviewScreenComponent, FilePreviewScreenComponent];
|
||||
const screens = [DossierListingScreenComponent, DossierOverviewScreenComponent, FilePreviewScreenComponent, SearchScreenComponent];
|
||||
|
||||
const dialogs = [
|
||||
AddDossierDialogComponent,
|
||||
|
||||
@ -583,7 +583,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribeComponent impleme
|
||||
/* Get the documentElement (<html>) to display the page in fullscreen */
|
||||
|
||||
private _cleanupAndRedrawManualAnnotations() {
|
||||
this._fileDownloadService.loadActiveFileRedactionLogPreview().subscribe(redactionLogPreview => {
|
||||
this._fileDownloadService.loadActiveFileRedactionLog().subscribe(redactionLogPreview => {
|
||||
this.fileData.redactionLog = redactionLogPreview;
|
||||
this._annotationDrawService.drawAnnotations(
|
||||
this._instance,
|
||||
@ -599,7 +599,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribeComponent impleme
|
||||
const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id);
|
||||
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
||||
|
||||
this._fileDownloadService.loadActiveFileRedactionLogPreview().subscribe(redactionLogPreview => {
|
||||
this._fileDownloadService.loadActiveFileRedactionLog().subscribe(redactionLogPreview => {
|
||||
this.fileData.redactionLog = redactionLogPreview;
|
||||
this.rebuildFilters();
|
||||
if (this.viewMode === 'STANDARD') {
|
||||
|
||||
@ -0,0 +1,98 @@
|
||||
<section *ngIf="searchResults$ | async as searchResult">
|
||||
<redaction-page-header
|
||||
[showCloseButton]="true"
|
||||
[searchPlaceholder]="'search.placeholder' | translate"
|
||||
[searchWidth]="600"
|
||||
></redaction-page-header>
|
||||
|
||||
<div class="overlay-shadow"></div>
|
||||
|
||||
<div class="red-content-inner">
|
||||
<div class="content-container">
|
||||
<redaction-table-header
|
||||
[tableHeaderLabel]="'search-screen.table-header'"
|
||||
[tableColConfigs]="tableColConfigs"
|
||||
></redaction-table-header>
|
||||
|
||||
<redaction-empty-state
|
||||
*ngIf="searchResult.length === 0"
|
||||
[icon]="'red:search'"
|
||||
[text]="'search-screen.no-data' | translate"
|
||||
></redaction-empty-state>
|
||||
|
||||
<cdk-virtual-scroll-viewport [itemSize]="itemSize" redactionHasScrollbar>
|
||||
<div
|
||||
*cdkVirtualFor="let item of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey"
|
||||
[class.pointer]="true"
|
||||
[routerLink]="item.routerLink"
|
||||
class="table-item"
|
||||
>
|
||||
<div class="filename">
|
||||
<div [matTooltip]="item.fileName" class="table-item-title heading" matTooltipPosition="above">
|
||||
<span
|
||||
*ngIf="item.highlights.filename; else defaultFilename"
|
||||
class="highlights"
|
||||
[innerHTML]="item.highlights.filename[0]"
|
||||
></span>
|
||||
<ng-template #defaultFilename>{{ item.fileName }}</ng-template>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="item.highlights['sections.text'] as highlights">
|
||||
<div class="small-label" *ngIf="highlights.length > 0">
|
||||
<span class="highlights" [innerHTML]="highlights[0]"></span>
|
||||
</div>
|
||||
<div class="small-label" *ngIf="highlights.length > 1">
|
||||
<span class="highlights" [innerHTML]="highlights[1]"></span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div class="small-label" *ngIf="item.unmatched as unmatched">
|
||||
<span>
|
||||
{{ 'search-screen.missing' | translate }}:<span *ngFor="let term of unmatched"
|
||||
> <s>{{ term }}</s></span
|
||||
>. {{ 'search-screen.must-contain' | translate }}:
|
||||
<span
|
||||
*ngFor="let term of unmatched"
|
||||
(click)="$event.stopPropagation(); updateNavigation({ query: search$.getValue(), mustContain: term })"
|
||||
> <u>{{ term }}</u></span
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<redaction-status-bar
|
||||
[small]="true"
|
||||
[config]="[
|
||||
{
|
||||
color: item.status,
|
||||
label: item.status | translate,
|
||||
length: 1
|
||||
}
|
||||
]"
|
||||
></redaction-status-bar>
|
||||
</div>
|
||||
|
||||
<div class="small-label">
|
||||
{{ item.dossierName }}
|
||||
</div>
|
||||
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ item.pages }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="scrollbar-placeholder"></div>
|
||||
</div>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
|
||||
<redaction-scroll-button
|
||||
*ngIf="(screenStateService.noData$ | async) === false"
|
||||
[itemSize]="itemSize"
|
||||
[scrollViewport]="scrollViewport"
|
||||
></redaction-scroll-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@ -0,0 +1,38 @@
|
||||
@import 'apps/red-ui/src/assets/styles/red-mixins';
|
||||
@import 'apps/red-ui/src/assets/styles/red-variables';
|
||||
|
||||
.content-container {
|
||||
position: relative;
|
||||
|
||||
cdk-virtual-scroll-viewport {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 1fr auto 11px;
|
||||
|
||||
.table-item {
|
||||
> div {
|
||||
height: 85px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.status-container {
|
||||
width: 160px;
|
||||
padding-right: 13px;
|
||||
}
|
||||
|
||||
.highlights em {
|
||||
background-color: #fffcc4;
|
||||
}
|
||||
|
||||
.highlights {
|
||||
@include line-clamp(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.has-scrollbar:hover {
|
||||
::ng-deep.cdk-virtual-scroll-content-wrapper {
|
||||
grid-template-columns: 2fr 1fr 1fr auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,155 @@
|
||||
import { Component, Injector, OnDestroy } from '@angular/core';
|
||||
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
|
||||
import { SearchControllerService, SearchResult } from '@redaction/red-ui-http';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { debounceTime, map, switchMap, tap } from 'rxjs/operators';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { MatchedDocument } from '@redaction/red-ui-http';
|
||||
import { TableColConfig } from '../../../shared/components/table-col-name/table-col-name.component';
|
||||
import { FilterService } from '../../../shared/services/filter.service';
|
||||
import { SearchService } from '../../../shared/services/search.service';
|
||||
import { ScreenStateService } from '../../../shared/services/screen-state.service';
|
||||
import { SortingService } from '../../../../services/sorting.service';
|
||||
import { AppStateService } from '../../../../state/app-state.service';
|
||||
import { FileStatusWrapper } from '../../../../models/file/file-status.wrapper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { LoadingService } from '../../../../services/loading.service';
|
||||
|
||||
interface ListItem {
|
||||
fileName: string;
|
||||
matchedDocument: MatchedDocument;
|
||||
unmatched: string[] | null;
|
||||
highlights: { [key: string]: string[] };
|
||||
routerLink: string;
|
||||
status: string;
|
||||
dossierName: string;
|
||||
pages: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './search-screen.component.html',
|
||||
styleUrls: ['./search-screen.component.scss'],
|
||||
providers: [FilterService, SearchService, ScreenStateService, SortingService]
|
||||
})
|
||||
export class SearchScreenComponent extends BaseListingComponent<ListItem> implements OnDestroy {
|
||||
protected readonly _primaryKey = 'fileName';
|
||||
readonly itemSize = 85;
|
||||
|
||||
readonly search$ = new BehaviorSubject<string>(null);
|
||||
readonly searchResults$: Observable<ListItem[]> = this.search$.asObservable().pipe(
|
||||
switchMap(query => this._search(query)),
|
||||
map(searchResult => this._toMatchedDocuments(searchResult)),
|
||||
map(documents => this._toListItems(documents)),
|
||||
tap(result => this.screenStateService.setEntities(result)),
|
||||
tap(() => this._loadingService.stop())
|
||||
);
|
||||
|
||||
private _dossierId: string;
|
||||
|
||||
readonly tableColConfigs: TableColConfig[] = [
|
||||
{
|
||||
label: this._translateService.instant('search-screen.cols.document')
|
||||
},
|
||||
{
|
||||
label: this._translateService.instant('search-screen.cols.status')
|
||||
},
|
||||
{
|
||||
label: this._translateService.instant('search-screen.cols.dossier')
|
||||
},
|
||||
{
|
||||
label: this._translateService.instant('search-screen.cols.pages')
|
||||
}
|
||||
];
|
||||
|
||||
constructor(
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _searchControllerService: SearchControllerService,
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _router: Router
|
||||
) {
|
||||
super(_injector);
|
||||
|
||||
this.addSubscription = _activatedRoute.queryParamMap
|
||||
.pipe(
|
||||
tap(() => this._loadingService.start()),
|
||||
map(value => ({ query: value.get('query'), dossierId: value.get('dossierId') })),
|
||||
tap(mappedValue => this._updateValues(mappedValue))
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
this.addSubscription = this.searchService.searchForm
|
||||
.get('query')
|
||||
.valueChanges.pipe(debounceTime(300))
|
||||
.subscribe(value => this.updateNavigation({ query: value }));
|
||||
}
|
||||
|
||||
setInitialConfig() {
|
||||
return;
|
||||
}
|
||||
|
||||
updateNavigation({ query, mustContain }: { readonly query: string; readonly mustContain?: string }) {
|
||||
const newQuery = query?.replace(mustContain, `"${mustContain}"`);
|
||||
const queryParams = newQuery && newQuery !== '' ? { query: newQuery } : {};
|
||||
const queryParamsHandling = this._dossierId ? 'merge' : '';
|
||||
this._router
|
||||
.navigate([], {
|
||||
queryParams,
|
||||
queryParamsHandling
|
||||
})
|
||||
.then();
|
||||
}
|
||||
|
||||
private _search(query: string): Observable<SearchResult> {
|
||||
return this._searchControllerService.search({
|
||||
dossierId: this._dossierId,
|
||||
queryString: query ?? '',
|
||||
from: 0,
|
||||
returnSections: true,
|
||||
size: 100
|
||||
});
|
||||
}
|
||||
|
||||
private _updateValues({ query, dossierId }: { readonly query: string; readonly dossierId: string }) {
|
||||
this._dossierId = dossierId;
|
||||
this.searchService.searchValue = query;
|
||||
this.search$.next(query);
|
||||
}
|
||||
|
||||
private _getFileWrapper(dossierId: string, fileId: string): FileStatusWrapper {
|
||||
return this._appStateService.getFileById(dossierId, fileId);
|
||||
}
|
||||
|
||||
private _getDossierWrapper(dossierId: string) {
|
||||
return this._appStateService.getDossierById(dossierId);
|
||||
}
|
||||
|
||||
private _toMatchedDocuments({ matchedDocuments }: SearchResult) {
|
||||
return matchedDocuments.filter(doc => doc.score > 0 && doc.matchedTerms.length > 0);
|
||||
}
|
||||
|
||||
private _toListItems(matchedDocuments: MatchedDocument[]) {
|
||||
return matchedDocuments
|
||||
.map<ListItem>(document => {
|
||||
const fileStatus = this._getFileWrapper(document.dossierId, document.fileId);
|
||||
if (!fileStatus) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { dossierId, dossierName } = this._getDossierWrapper(document.dossierId);
|
||||
return {
|
||||
matchedDocument: document,
|
||||
unmatched: document.unmatchedTerms.length ? document.unmatchedTerms : null,
|
||||
highlights: document.highlights,
|
||||
status: fileStatus.status,
|
||||
pages: fileStatus.numberOfPages,
|
||||
dossierName: dossierName,
|
||||
fileName: fileStatus.filename,
|
||||
routerLink: `/main/dossiers/${dossierId}/file/${fileStatus.fileId}`
|
||||
} as ListItem;
|
||||
})
|
||||
.filter(value => value);
|
||||
}
|
||||
}
|
||||
@ -23,8 +23,8 @@ export class PdfViewerDataService {
|
||||
private readonly _viewedPagesControllerService: ViewedPagesControllerService
|
||||
) {}
|
||||
|
||||
loadActiveFileRedactionLogPreview() {
|
||||
return this._redactionLogControllerService.getRedactionLogPreview(
|
||||
loadActiveFileRedactionLog() {
|
||||
return this._redactionLogControllerService.getRedactionLog(
|
||||
this._appStateService.activeDossierId,
|
||||
this._appStateService.activeFileId
|
||||
);
|
||||
@ -37,9 +37,7 @@ export class PdfViewerDataService {
|
||||
this._man.getManualRedaction(dossierId, fileId).subscribe();
|
||||
|
||||
const file$ = this.downloadOriginalFile(this._appStateService.activeFile);
|
||||
const reactionLog$ = this._redactionLogControllerService
|
||||
.getRedactionLogPreview(dossierId, fileId)
|
||||
.pipe(catchError(() => of({})));
|
||||
const reactionLog$ = this._redactionLogControllerService.getRedactionLog(dossierId, fileId).pipe(catchError(() => of({})));
|
||||
const redactionChangeLog$ = this._redactionLogControllerService
|
||||
.getRedactionChangeLog(dossierId, fileId)
|
||||
.pipe(catchError(() => of({})));
|
||||
@ -53,10 +51,7 @@ export class PdfViewerDataService {
|
||||
getViewedPagesForActiveFile() {
|
||||
if (this._permissionsService.canMarkPagesAsViewed()) {
|
||||
return this._viewedPagesControllerService
|
||||
.getViewedPages(
|
||||
this._appStateService.activeDossierId,
|
||||
this._appStateService.activeFileId
|
||||
)
|
||||
.getViewedPages(this._appStateService.activeDossierId, this._appStateService.activeFileId)
|
||||
.pipe(catchError(() => of({ pages: [] })));
|
||||
}
|
||||
return of({ pages: [] });
|
||||
|
||||
@ -9,10 +9,7 @@ import { DomSanitizer } from '@angular/platform-browser';
|
||||
exports: [MatIconModule]
|
||||
})
|
||||
export class IconsModule {
|
||||
constructor(
|
||||
private readonly _iconRegistry: MatIconRegistry,
|
||||
private readonly _sanitizer: DomSanitizer
|
||||
) {
|
||||
constructor(private readonly _iconRegistry: MatIconRegistry, private readonly _sanitizer: DomSanitizer) {
|
||||
const icons = [
|
||||
'add',
|
||||
'analyse',
|
||||
@ -38,6 +35,7 @@ export class IconsModule {
|
||||
'download',
|
||||
'edit',
|
||||
'entries',
|
||||
'enter',
|
||||
'error',
|
||||
'exclude-pages',
|
||||
'exit-fullscreen',
|
||||
|
||||
@ -17,7 +17,7 @@ export abstract class BaseListingComponent<T> extends AutoUnsubscribeComponent i
|
||||
readonly permissionsService: PermissionsService;
|
||||
readonly filterService: FilterService;
|
||||
readonly sortingService: SortingService;
|
||||
readonly searchService: SearchService<T>;
|
||||
readonly searchService: SearchService;
|
||||
readonly screenStateService: ScreenStateService<T>;
|
||||
|
||||
readonly sortedDisplayedEntities$: Observable<T[]>;
|
||||
|
||||
@ -11,11 +11,7 @@
|
||||
<span *ngIf="hint" [translate]="hint" class="hint"></span>
|
||||
|
||||
<!-- Search-->
|
||||
<mat-icon
|
||||
*ngIf="type === 'search' && !hasContent"
|
||||
class="icon-right"
|
||||
svgIcon="red:search"
|
||||
></mat-icon>
|
||||
<mat-icon *ngIf="type === 'search' && !hasContent" class="icon-right" svgIcon="red:search"></mat-icon>
|
||||
|
||||
<redaction-circle-button
|
||||
(action)="clearContent()"
|
||||
@ -23,8 +19,7 @@
|
||||
[disabled]="form.invalid"
|
||||
[size]="25"
|
||||
icon="red:close"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
|
||||
<!-- Submit-->
|
||||
<redaction-circle-button
|
||||
@ -34,7 +29,6 @@
|
||||
[icon]="icon"
|
||||
[isSubmit]="true"
|
||||
[size]="25"
|
||||
>
|
||||
</redaction-circle-button>
|
||||
></redaction-circle-button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -29,7 +29,7 @@ export class InputWithActionComponent {
|
||||
}
|
||||
|
||||
clearContent() {
|
||||
this.form.patchValue({ query: '' });
|
||||
this.form.patchValue({ query: '' }, { emitEvent: true });
|
||||
}
|
||||
|
||||
executeAction($event?: MouseEvent) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<div class="page-header">
|
||||
<div *ngIf="pageLabel" class="breadcrumb">{{ pageLabel }}</div>
|
||||
|
||||
<div class="filters" *ngIf="filters$ | async as filters">
|
||||
<div class="filters" [style.max-width]="computedWidth" [style.width]="computedWidth" *ngIf="filters$ | async as filters">
|
||||
<div translate="filters.filter-by" *ngIf="filters.length"></div>
|
||||
|
||||
<ng-container *ngFor="let config of filters; trackBy: trackByLabel">
|
||||
@ -16,6 +16,7 @@
|
||||
</ng-container>
|
||||
|
||||
<redaction-input-with-action
|
||||
[width]="searchWidth"
|
||||
*ngIf="searchPlaceholder"
|
||||
[form]="searchService.searchForm"
|
||||
[placeholder]="searchPlaceholder"
|
||||
|
||||
@ -11,17 +11,18 @@ import { combineLatest, Observable, of } from 'rxjs';
|
||||
templateUrl: './page-header.component.html',
|
||||
styleUrls: ['./page-header.component.scss']
|
||||
})
|
||||
export class PageHeaderComponent<T> {
|
||||
export class PageHeaderComponent {
|
||||
@Input() pageLabel: string;
|
||||
@Input() showCloseButton: boolean;
|
||||
@Input() actionConfigs: ActionConfig[];
|
||||
@Input() buttonConfigs: ButtonConfig[];
|
||||
@Input() searchPlaceholder: string;
|
||||
@Input() searchWidth: number | 'full';
|
||||
|
||||
readonly filters$ = this.filterService?.filterGroups$.pipe(map(all => all.filter(f => f.icon)));
|
||||
readonly showResetFilters$ = this._showResetFilters$;
|
||||
|
||||
constructor(@Optional() readonly filterService: FilterService, @Optional() readonly searchService: SearchService<T>) {}
|
||||
constructor(@Optional() readonly filterService: FilterService, @Optional() readonly searchService: SearchService) {}
|
||||
|
||||
get _showResetFilters$(): Observable<boolean> {
|
||||
if (!this.filterService) return of(false);
|
||||
@ -36,6 +37,10 @@ export class PageHeaderComponent<T> {
|
||||
);
|
||||
}
|
||||
|
||||
get computedWidth() {
|
||||
return this.searchWidth === 'full' ? '100%' : `${this.searchWidth}px`;
|
||||
}
|
||||
|
||||
resetFilters(): void {
|
||||
this.filterService.reset();
|
||||
this.searchService.reset();
|
||||
|
||||
@ -25,8 +25,8 @@ export class SyncWidthDirective implements AfterViewInit, OnDestroy {
|
||||
@debounce(10)
|
||||
matchWidth() {
|
||||
const headerItems = this._elementRef.nativeElement.children;
|
||||
// const tableRows = document.getElementsByClassName(this.redactionSyncWidth);
|
||||
const tableRows = this._elementRef.nativeElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
|
||||
const tableRows = document.getElementsByClassName(this.redactionSyncWidth);
|
||||
// const tableRows = this._elementRef.nativeElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
|
||||
|
||||
if (!tableRows || !tableRows.length) {
|
||||
return;
|
||||
|
||||
@ -26,7 +26,7 @@ export class ScreenStateService<T> {
|
||||
readonly areSomeEntitiesSelected$ = this._areSomeEntitiesSelected$;
|
||||
readonly notAllEntitiesSelected$ = this._notAllEntitiesSelected$;
|
||||
|
||||
constructor(private readonly _filterService: FilterService, private readonly _searchService: SearchService<T>) {
|
||||
constructor(private readonly _filterService: FilterService, private readonly _searchService: SearchService) {
|
||||
// setInterval(() => {
|
||||
// console.log('All entities subs: ', this._allEntities$.observers);
|
||||
// console.log('Displayed entities subs: ', this._displayedEntities$.observers);
|
||||
|
||||
@ -3,7 +3,7 @@ import { FormBuilder } from '@angular/forms';
|
||||
import { startWith } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class SearchService<T> {
|
||||
export class SearchService {
|
||||
private _searchKey: string;
|
||||
|
||||
readonly searchForm = this._formBuilder.group({
|
||||
@ -14,7 +14,7 @@ export class SearchService<T> {
|
||||
|
||||
constructor(private readonly _formBuilder: FormBuilder) {}
|
||||
|
||||
searchIn(entities: T[]) {
|
||||
searchIn<T>(entities: T[]) {
|
||||
if (!this._searchKey) return entities;
|
||||
|
||||
const searchValue = this.searchValue.toLowerCase();
|
||||
@ -29,11 +29,15 @@ export class SearchService<T> {
|
||||
return this.searchForm.get('query').value;
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.searchForm.reset({ query: '' });
|
||||
set searchValue(value: string) {
|
||||
this.searchForm.patchValue({ query: value });
|
||||
}
|
||||
|
||||
private _searchField(entity: T): string {
|
||||
return entity[this._searchKey].toLowerCase();
|
||||
reset(): void {
|
||||
this.searchForm.reset({ query: '' }, { emitEvent: true });
|
||||
}
|
||||
|
||||
private _searchField<T>(entity: T): string {
|
||||
return entity[this._searchKey].toString().toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ export class LoadingService {
|
||||
private readonly _loadingEvent = new BehaviorSubject(false);
|
||||
private _loadingStarted: number;
|
||||
|
||||
get isLoading(): Observable<boolean> {
|
||||
get isLoading$(): Observable<boolean> {
|
||||
return this._loadingEvent.asObservable();
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ export class RouterHistoryService {
|
||||
|
||||
constructor(private readonly _router: Router) {
|
||||
this._router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe((event: NavigationEnd) => {
|
||||
if (event.url.startsWith('/main/dossiers')) {
|
||||
if (event.url.startsWith('/main/dossiers') && !event.url.includes('/search')) {
|
||||
this._lastDossiersScreen = event.url;
|
||||
}
|
||||
});
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
ReanalysisControllerService,
|
||||
StatusControllerService
|
||||
} from '@redaction/red-ui-http';
|
||||
import { Toaster } from '../services/toaster.service';
|
||||
import { Toaster } from '@services/toaster.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Event, NavigationEnd, ResolveStart, Router } from '@angular/router';
|
||||
import { UserService } from '@services/user.service';
|
||||
@ -156,7 +156,12 @@ export class AppStateService {
|
||||
}
|
||||
|
||||
private static _isDossierOverviewRoute(event: Event) {
|
||||
return event instanceof ResolveStart && event.url.includes('/main/dossiers/') && !event.url.includes('/file/');
|
||||
return (
|
||||
event instanceof ResolveStart &&
|
||||
event.url.includes('/main/dossiers/') &&
|
||||
!event.url.includes('/file/') &&
|
||||
!event.url.includes('/search')
|
||||
);
|
||||
}
|
||||
|
||||
private static _isRandomRoute(event: Event) {
|
||||
@ -174,7 +179,7 @@ export class AppStateService {
|
||||
dossierTemplateId = this.dossierTemplates[0]?.dossierTemplateId;
|
||||
}
|
||||
if (!dossierTemplateId) {
|
||||
return undefined;
|
||||
return '#cccccc';
|
||||
}
|
||||
const color = this._dictionaryData[dossierTemplateId][type]?.hexColor;
|
||||
return color ?? this._dictionaryData[dossierTemplateId]['default'].hexColor;
|
||||
@ -205,7 +210,7 @@ export class AppStateService {
|
||||
}
|
||||
|
||||
getFileById(dossierId: string, fileId: string) {
|
||||
return this.getDossierById(dossierId).files.find(file => file.fileId === fileId);
|
||||
return this.getDossierById(dossierId)?.files.find(file => file.fileId === fileId);
|
||||
}
|
||||
|
||||
async loadAllDossiers(emitEvents: boolean = true) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"OAUTH_URL": "https://red-staging.iqser.cloud/auth/realms/redaction",
|
||||
"API_URL": "https://red-staging.iqser.cloud/redaction-gateway-v1",
|
||||
"OAUTH_URL": "https://dev-06.iqser.cloud/auth/realms/redaction",
|
||||
"API_URL": "https://dev-06.iqser.cloud/redaction-gateway-v1",
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"BACKEND_APP_VERSION": "4.4.40",
|
||||
"FRONTEND_APP_VERSION": "1.1",
|
||||
|
||||
@ -1435,5 +1435,24 @@
|
||||
"hours": "hours",
|
||||
"day": "day",
|
||||
"days": "days"
|
||||
},
|
||||
"search": {
|
||||
"header-label": "Search entire platform",
|
||||
"placeholder": "Search for documents or document content",
|
||||
"this-dossier": "in this dossier",
|
||||
"entire-platform": "entire platform",
|
||||
"close": "Close"
|
||||
},
|
||||
"search-screen": {
|
||||
"table-header": "{{length}} search results",
|
||||
"cols": {
|
||||
"document": "Document",
|
||||
"status": "Status",
|
||||
"dossier": "Dossier",
|
||||
"pages": "Pages"
|
||||
},
|
||||
"no-data": "Please enter a keyword in the search input to look for documents or document content.",
|
||||
"missing": "Missing",
|
||||
"must-contain": "Must contain"
|
||||
}
|
||||
}
|
||||
|
||||
15
apps/red-ui/src/assets/icons/general/enter.svg
Normal file
15
apps/red-ui/src/assets/icons/general/enter.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<title>B99F3D5E-879A-47E3-A8C7-84877EE418F3</title>
|
||||
<g id="04.Search-all-in-Document" transform="translate(-319.000000, -144.000000)">
|
||||
<g id="Group-30" transform="translate(295.000000, 121.000000)">
|
||||
<g id="collapse" transform="translate(24.000000, 23.000000)" fill="currentColor"
|
||||
fill-rule="nonzero">
|
||||
<path
|
||||
d="M2.38,0 L2.38,7.98 L10.5,7.98 L8.75,6.16 L9.73,5.18 L13.16,8.68 L9.73,12.18 L8.75,11.2 L10.5,9.38 L1.96,9.38 L1.959,9.379 L0.98,9.38 L0.98,0 L2.38,0 Z"
|
||||
id="Combined-Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 781 B |
@ -256,6 +256,10 @@ section.settings {
|
||||
margin-left: 14px;
|
||||
}
|
||||
|
||||
.mr-24 {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.pb-24 {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
@ -358,6 +362,10 @@ section.settings {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.mr-34 {
|
||||
margin-right: 34px;
|
||||
}
|
||||
|
||||
.fit-content {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
module.exports = {
|
||||
projects: ['<rootDir>/apps/red-ui', '<rootDir>/libs/red-ui-http', '<rootDir>/libs/red-cache']
|
||||
projects: ['<rootDir>/apps/red-ui', '<rootDir>/libs/red-ui-http', '<rootDir>/libs/red-cache', '<rootDir>/libs/common-ui']
|
||||
};
|
||||
|
||||
33
libs/common-ui/.eslintrc.json
Normal file
33
libs/common-ui/.eslintrc.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts"],
|
||||
"extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
|
||||
"rules": {
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "attribute",
|
||||
"prefix": "redaction",
|
||||
"style": "camelCase"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{
|
||||
"type": "element",
|
||||
"prefix": "redaction",
|
||||
"style": "kebab-case"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.html"],
|
||||
"extends": ["plugin:@nrwl/nx/angular-template"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
7
libs/common-ui/README.md
Normal file
7
libs/common-ui/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
# common-ui
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test common-ui` to execute the unit tests.
|
||||
20
libs/common-ui/jest.config.js
Normal file
20
libs/common-ui/jest.config.js
Normal file
@ -0,0 +1,20 @@
|
||||
module.exports = {
|
||||
displayName: 'common-ui',
|
||||
preset: '../../jest.preset.js',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
stringifyContentPathRegex: '\\.(html|svg)$',
|
||||
astTransformers: {
|
||||
before: ['jest-preset-angular/build/InlineFilesTransformer', 'jest-preset-angular/build/StripStylesTransformer']
|
||||
}
|
||||
}
|
||||
},
|
||||
coverageDirectory: '../../coverage/libs/common-ui',
|
||||
snapshotSerializers: [
|
||||
'jest-preset-angular/build/serializers/no-ng-attributes',
|
||||
'jest-preset-angular/build/serializers/ng-snapshot',
|
||||
'jest-preset-angular/build/serializers/html-comment'
|
||||
]
|
||||
};
|
||||
1
libs/common-ui/src/index.ts
Normal file
1
libs/common-ui/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './lib/common-ui.module';
|
||||
7
libs/common-ui/src/lib/common-ui.module.ts
Normal file
7
libs/common-ui/src/lib/common-ui.module.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule]
|
||||
})
|
||||
export class CommonUiModule {}
|
||||
1
libs/common-ui/src/test-setup.ts
Normal file
1
libs/common-ui/src/test-setup.ts
Normal file
@ -0,0 +1 @@
|
||||
import 'jest-preset-angular/setup-jest';
|
||||
24
libs/common-ui/tsconfig.json
Normal file
24
libs/common-ui/tsconfig.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
}
|
||||
14
libs/common-ui/tsconfig.lib.json
Normal file
14
libs/common-ui/tsconfig.lib.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": ["dom", "es2018"]
|
||||
},
|
||||
"exclude": ["src/test-setup.ts", "**/*.spec.ts"],
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
10
libs/common-ui/tsconfig.spec.json
Normal file
10
libs/common-ui/tsconfig.spec.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"files": ["src/test-setup.ts"],
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
||||
@ -78,15 +78,11 @@ export class RedactionLogControllerService {
|
||||
reportProgress: boolean = false
|
||||
): Observable<any> {
|
||||
if (dossierId === null || dossierId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter dossierId was null or undefined when calling getRedactionLog.'
|
||||
);
|
||||
throw new Error('Required parameter dossierId was null or undefined when calling getRedactionLog.');
|
||||
}
|
||||
|
||||
if (fileId === null || fileId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter fileId was null or undefined when calling getRedactionLog.'
|
||||
);
|
||||
throw new Error('Required parameter fileId was null or undefined when calling getRedactionLog.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
@ -94,25 +90,20 @@ export class RedactionLogControllerService {
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken =
|
||||
typeof this.configuration.accessToken === 'function'
|
||||
? this.configuration.accessToken()
|
||||
: this.configuration.accessToken;
|
||||
typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = ['application/json'];
|
||||
const httpHeaderAcceptSelected: string | undefined =
|
||||
this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<RedactionChangeLog>(
|
||||
'get',
|
||||
`${this.basePath}/redactionChnageLog/${encodeURIComponent(
|
||||
String(dossierId)
|
||||
)}/${encodeURIComponent(String(fileId))}`,
|
||||
`${this.basePath}/redactionChnageLog/${encodeURIComponent(String(dossierId))}/${encodeURIComponent(String(fileId))}`,
|
||||
{
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
@ -130,12 +121,7 @@ export class RedactionLogControllerService {
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public getRedactionLog(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe?: 'body',
|
||||
reportProgress?: boolean
|
||||
): Observable<RedactionLog>;
|
||||
public getRedactionLog(dossierId: string, fileId: string, observe?: 'body', reportProgress?: boolean): Observable<RedactionLog>;
|
||||
|
||||
public getRedactionLog(
|
||||
dossierId: string,
|
||||
@ -151,22 +137,13 @@ export class RedactionLogControllerService {
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<RedactionLog>>;
|
||||
|
||||
public getRedactionLog(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe: any = 'body',
|
||||
reportProgress: boolean = false
|
||||
): Observable<any> {
|
||||
public getRedactionLog(dossierId: string, fileId: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
|
||||
if (dossierId === null || dossierId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter dossierId was null or undefined when calling getRedactionLog1.'
|
||||
);
|
||||
throw new Error('Required parameter dossierId was null or undefined when calling getRedactionLog1.');
|
||||
}
|
||||
|
||||
if (fileId === null || fileId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter fileId was null or undefined when calling getRedactionLog1.'
|
||||
);
|
||||
throw new Error('Required parameter fileId was null or undefined when calling getRedactionLog1.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
@ -174,101 +151,20 @@ export class RedactionLogControllerService {
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken =
|
||||
typeof this.configuration.accessToken === 'function'
|
||||
? this.configuration.accessToken()
|
||||
: this.configuration.accessToken;
|
||||
typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = ['application/json'];
|
||||
const httpHeaderAcceptSelected: string | undefined =
|
||||
this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<RedactionLog>(
|
||||
'get',
|
||||
`${this.basePath}/redactionLog/${encodeURIComponent(
|
||||
String(dossierId)
|
||||
)}/${encodeURIComponent(String(fileId))}`,
|
||||
{
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
reportProgress: reportProgress
|
||||
}
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Gets the redaction log preview
|
||||
* None
|
||||
* @param dossierId dossierId
|
||||
* @param fileId fileId
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public getRedactionLogPreview(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe?: 'body',
|
||||
reportProgress?: boolean
|
||||
): Observable<RedactionLog>;
|
||||
public getRedactionLogPreview(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe?: 'response',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpResponse<RedactionLog>>;
|
||||
public getRedactionLogPreview(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe?: 'events',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<RedactionLog>>;
|
||||
public getRedactionLogPreview(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe: any = 'body',
|
||||
reportProgress: boolean = false
|
||||
): Observable<any> {
|
||||
if (dossierId === null || dossierId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter dossierId was null or undefined when calling getRedactionLogPreview.'
|
||||
);
|
||||
}
|
||||
|
||||
if (fileId === null || fileId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter fileId was null or undefined when calling getRedactionLogPreview.'
|
||||
);
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken =
|
||||
typeof this.configuration.accessToken === 'function'
|
||||
? this.configuration.accessToken()
|
||||
: this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = ['application/json'];
|
||||
const httpHeaderAcceptSelected: string | undefined =
|
||||
this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<RedactionLog>(
|
||||
'get',
|
||||
`${this.basePath}/sectionGrid/${encodeURIComponent(
|
||||
String(dossierId)
|
||||
)}/${encodeURIComponent(String(fileId))}/preview`,
|
||||
`${this.basePath}/redactionLog/${encodeURIComponent(String(dossierId))}/${encodeURIComponent(String(fileId))}`,
|
||||
{
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
@ -286,12 +182,7 @@ export class RedactionLogControllerService {
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public getSectionGrid(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe?: 'body',
|
||||
reportProgress?: boolean
|
||||
): Observable<SectionGrid>;
|
||||
public getSectionGrid(dossierId: string, fileId: string, observe?: 'body', reportProgress?: boolean): Observable<SectionGrid>;
|
||||
|
||||
public getSectionGrid(
|
||||
dossierId: string,
|
||||
@ -307,22 +198,13 @@ export class RedactionLogControllerService {
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<SectionGrid>>;
|
||||
|
||||
public getSectionGrid(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe: any = 'body',
|
||||
reportProgress: boolean = false
|
||||
): Observable<any> {
|
||||
public getSectionGrid(dossierId: string, fileId: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
|
||||
if (dossierId === null || dossierId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter dossierId was null or undefined when calling getSectionGrid.'
|
||||
);
|
||||
throw new Error('Required parameter dossierId was null or undefined when calling getSectionGrid.');
|
||||
}
|
||||
|
||||
if (fileId === null || fileId === undefined) {
|
||||
throw new Error(
|
||||
'Required parameter fileId was null or undefined when calling getSectionGrid.'
|
||||
);
|
||||
throw new Error('Required parameter fileId was null or undefined when calling getSectionGrid.');
|
||||
}
|
||||
|
||||
let headers = this.defaultHeaders;
|
||||
@ -330,25 +212,20 @@ export class RedactionLogControllerService {
|
||||
// authentication (RED-OAUTH) required
|
||||
if (this.configuration.accessToken) {
|
||||
const accessToken =
|
||||
typeof this.configuration.accessToken === 'function'
|
||||
? this.configuration.accessToken()
|
||||
: this.configuration.accessToken;
|
||||
typeof this.configuration.accessToken === 'function' ? this.configuration.accessToken() : this.configuration.accessToken;
|
||||
headers = headers.set('Authorization', 'Bearer ' + accessToken);
|
||||
}
|
||||
|
||||
// to determine the Accept header
|
||||
const httpHeaderAccepts: string[] = ['application/json'];
|
||||
const httpHeaderAcceptSelected: string | undefined =
|
||||
this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||
if (httpHeaderAcceptSelected !== undefined) {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<SectionGrid>(
|
||||
'get',
|
||||
`${this.basePath}/sectionGrid/${encodeURIComponent(
|
||||
String(dossierId)
|
||||
)}/${encodeURIComponent(String(fileId))}`,
|
||||
`${this.basePath}/sectionGrid/${encodeURIComponent(String(dossierId))}/${encodeURIComponent(String(fileId))}`,
|
||||
{
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
|
||||
@ -78,3 +78,4 @@ export * from './legalBasisChangeRequest';
|
||||
export * from './manualLegalBasisChange';
|
||||
export * from './searchRequest';
|
||||
export * from './searchResult';
|
||||
export * from './matchedDocument';
|
||||
|
||||
3
nx.json
3
nx.json
@ -30,6 +30,9 @@
|
||||
},
|
||||
"red-cache": {
|
||||
"tags": []
|
||||
},
|
||||
"common-ui": {
|
||||
"tags": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "redaction",
|
||||
"version": "2.134.0",
|
||||
"version": "2.138.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
Binary file not shown.
@ -29,7 +29,8 @@
|
||||
"@environments/*": ["apps/red-ui/src/environments/*"],
|
||||
"@shared/*": ["apps/red-ui/src/app/modules/shared/*"],
|
||||
"@app-config/*": ["apps/red-ui/src/app/modules/app-config/*"],
|
||||
"@upload-download/*": ["apps/red-ui/src/app/modules/upload-download/*"]
|
||||
"@upload-download/*": ["apps/red-ui/src/app/modules/upload-download/*"],
|
||||
"@devplant/common-ui": ["libs/common-ui/src/index.ts"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "tmp"],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user