dictionary admin

This commit is contained in:
Timo 2020-12-02 10:14:52 +02:00
parent 7227d6a07e
commit f5f5e27f1f
41 changed files with 2539 additions and 1940 deletions

View File

@ -46,7 +46,7 @@ import { LogoComponent } from './logo/logo.component';
import { CompositeRouteGuard } from './utils/composite-route.guard';
import { AppStateGuard } from './state/app-state.guard';
import { SimpleDoughnutChartComponent } from './components/simple-doughnut-chart/simple-doughnut-chart.component';
import { MAT_CHECKBOX_DEFAULT_OPTIONS, MatCheckboxModule } from '@angular/material/checkbox';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { AnnotationIconComponent } from './components/annotation-icon/annotation-icon.component';
import { AuthGuard } from './auth/auth.guard';
@ -83,11 +83,11 @@ import { UserButtonComponent } from './components/buttons/user-button/user-butto
import { CircleButtonComponent } from './components/buttons/circle-button/circle-button.component';
import { ChevronButtonComponent } from './components/buttons/chevron-button/chevron-button.component';
import { DictionaryListingScreenComponent } from './screens/admin/dictionary-listing-screen/dictionary-listing-screen.component';
import { CustomTooltipModule } from './common/red-tooltip/custom-tooltip.module';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { VirtualScrollComponent } from './utils/virtual-scroll/virtual-scroll.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { SyncWidthDirective } from './utils/sync-width.directive';
import { AddEditDictionaryDialogComponent } from './screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component';
import { DictionaryOverviewScreenComponent } from './screens/admin/dictionary-overview-screen/dictionary-overview-screen.component';
import { ColorPickerModule } from 'ngx-color-picker';
import { AceEditorModule } from 'ng2-ace-editor';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, '/assets/i18n/', '.json');
@ -140,8 +140,9 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
CircleButtonComponent,
ChevronButtonComponent,
DictionaryListingScreenComponent,
VirtualScrollComponent,
SyncWidthDirective
SyncWidthDirective,
AddEditDictionaryDialogComponent,
DictionaryOverviewScreenComponent
],
imports: [
BrowserModule,
@ -154,7 +155,6 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
ApiModule,
MatDialogModule,
MatNativeDateModule,
CustomTooltipModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
@ -212,6 +212,14 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
data: {
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
}
},
{
path: 'dictionary-overview/:type',
component: DictionaryOverviewScreenComponent,
canActivate: [CompositeRouteGuard],
data: {
routeGuards: [AuthGuard, RedRoleGuard, AppStateGuard]
}
}
]
}
@ -241,16 +249,10 @@ export function HttpLoaderFactory(httpClient: HttpClient) {
MatListModule,
MatDatepickerModule,
MatInputModule,
DragDropModule
ColorPickerModule,
AceEditorModule
],
providers: [
{
provide: MAT_CHECKBOX_DEFAULT_OPTIONS,
useValue: {
clickAction: 'noop',
color: 'primary'
}
},
{
provide: HTTP_INTERCEPTORS,
multi: true,

View File

@ -3,11 +3,21 @@ import { AppStateService } from '../../state/app-state.service';
import { FilterModel } from './model/filter.model';
import { handleCheckedValue } from './utils/filter-utils';
import { MatMenuTrigger } from '@angular/material/menu';
import { MAT_CHECKBOX_DEFAULT_OPTIONS } from '@angular/material/checkbox';
@Component({
selector: 'redaction-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.scss']
styleUrls: ['./filter.component.scss'],
providers: [
{
provide: MAT_CHECKBOX_DEFAULT_OPTIONS,
useValue: {
clickAction: 'noop',
color: 'primary'
}
}
]
})
export class FilterComponent {
@Output() filtersChanged = new EventEmitter<FilterModel[]>();

View File

@ -1,115 +0,0 @@
import { ComponentRef, Directive, ElementRef, HostListener, Input, OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core';
import { Overlay, OverlayPositionBuilder, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { TooltipContentComponent } from './tooltip-content/tooltip-content.component';
import { NavigationStart, Router } from '@angular/router';
import { OverlayPosition, Placement } from './overlay-position';
@Directive({
selector: '[redactionTooltip]',
exportAs: 'redactionTooltip'
})
export class CustomTooltipDirective implements OnInit, OnChanges, OnDestroy {
@Input() redactionTooltip: string;
@Input() placement: Placement = 'top';
private overlayRef: OverlayRef;
private tooltipRef: ComponentRef<TooltipContentComponent>;
private _enable = true;
protected test: string;
constructor(
protected overlayPositionBuilder: OverlayPositionBuilder,
protected router: Router,
protected elementRef: ElementRef,
protected overlay: Overlay
) {}
ngOnInit(): void {
this.router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
this.destroyOverlay();
}
});
}
ngOnChanges(changes: SimpleChanges): void {
if (this.tooltipRef && this.redactionTooltip) {
this.tooltipRef.instance.tooltip = this.redactionTooltip;
}
}
ngOnDestroy(): void {
this.destroyOverlay();
}
@HostListener('mouseover', ['$event'])
show($event) {
if (this._enable) {
$event.stopPropagation();
$event.preventDefault();
this.open();
}
}
open(model?: string) {
if (!this.overlayRef) {
this.createOverlay();
}
if (model) {
this.redactionTooltip = model;
}
if (this.redactionTooltip) {
this.overlayRef.detach();
const tooltipPortal = new ComponentPortal(TooltipContentComponent);
this.tooltipRef = this.overlayRef.attach(tooltipPortal);
this.tooltipRef.instance.tooltip = this.redactionTooltip;
}
}
close() {
this.destroyOverlay();
}
@HostListener('mouseout')
hideFromMouseOut() {
this.detachOverlay();
}
@HostListener('mousedown')
hideFromClick() {
this._enable = false;
this.destroyOverlay();
}
@HostListener('mouseup')
_enableTooltip() {
this._enable = true;
}
private createOverlay() {
const positionStrategy = this.overlayPositionBuilder
.flexibleConnectedTo(this.elementRef)
.withPositions(OverlayPosition.getConnectedPosition(this.placement));
this.overlayRef = this.overlay.create({
positionStrategy,
scrollStrategy: this.overlay.scrollStrategies.close()
});
}
private destroyOverlay() {
if (this.overlayRef) {
this.overlayRef.dispose();
this.overlayRef = null;
}
}
private detachOverlay() {
if (this.overlayRef && this.overlayRef.hasAttached()) {
this.overlayRef.detach();
}
}
}

View File

@ -1,13 +0,0 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { OverlayModule } from '@angular/cdk/overlay';
import { TooltipContentComponent } from './tooltip-content/tooltip-content.component';
import { CustomTooltipDirective } from './custom-tooltip.directive';
@NgModule({
imports: [CommonModule, OverlayModule],
declarations: [CustomTooltipDirective, TooltipContentComponent],
exports: [CustomTooltipDirective],
entryComponents: [TooltipContentComponent]
})
export class CustomTooltipModule {}

View File

@ -1,138 +0,0 @@
import { ConnectedPosition } from '@angular/cdk/overlay';
import { isArray } from 'rxjs/internal-compatibility';
export declare type Placement =
| 'auto'
| 'top'
| 'bottom'
| 'left'
| 'right'
| 'top-left'
| 'top-right'
| 'bottom-left'
| 'bottom-right'
| 'left-top'
| 'left-bottom'
| 'right-top'
| 'right-bottom';
export declare type PlacementArray = Placement | Array<Placement>;
export class OverlayPosition {
private static readonly _offsetYVal = 7;
public static TOP_LEFT: ConnectedPosition = {
originX: 'end',
originY: 'top',
overlayX: 'end',
overlayY: 'bottom',
offsetY: -OverlayPosition._offsetYVal
};
public static TOP_RIGHT: ConnectedPosition = {
originX: 'start',
originY: 'top',
overlayX: 'start',
overlayY: 'bottom',
offsetY: -OverlayPosition._offsetYVal
};
public static BOTTOM_LEFT: ConnectedPosition = {
originX: 'end',
originY: 'bottom',
overlayX: 'end',
overlayY: 'top',
offsetY: OverlayPosition._offsetYVal
};
public static BOTTOM_RIGHT: ConnectedPosition = {
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top',
offsetY: OverlayPosition._offsetYVal
};
public static LEFT_TOP: ConnectedPosition = {
originX: 'start',
originY: 'top',
overlayX: 'end',
overlayY: 'top',
offsetX: -OverlayPosition._offsetYVal
};
public static LEFT_BOTTOM: ConnectedPosition = {
originX: 'start',
originY: 'bottom',
overlayX: 'end',
overlayY: 'bottom',
offsetX: -OverlayPosition._offsetYVal
};
public static RIGHT_TOP: ConnectedPosition = {
originX: 'end',
originY: 'top',
overlayX: 'start',
overlayY: 'top',
offsetX: OverlayPosition._offsetYVal
};
public static RIGHT_BOTTOM: ConnectedPosition = {
originX: 'end',
originY: 'bottom',
overlayX: 'start',
overlayY: 'bottom',
offsetX: OverlayPosition._offsetYVal
};
public static getConnectedPosition(position: PlacementArray): ConnectedPosition[] {
if (isArray(position)) {
return Array.from(position).map((pos) => this.getPosition(pos as Placement));
} else if (position === 'auto') {
return this.getAutoPosition();
} else {
return [this.getPosition(position as Placement)];
}
}
private static getPosition(position: Placement) {
switch (position) {
case 'top':
return OverlayPosition.TOP_RIGHT;
case 'bottom':
return OverlayPosition.BOTTOM_RIGHT;
case 'left':
return OverlayPosition.LEFT_TOP;
case 'right':
return OverlayPosition.RIGHT_TOP;
case 'top-left':
return OverlayPosition.TOP_LEFT;
case 'top-right':
return OverlayPosition.TOP_RIGHT;
case 'bottom-left':
return OverlayPosition.BOTTOM_LEFT;
case 'bottom-right':
return OverlayPosition.BOTTOM_RIGHT;
case 'left-top':
return OverlayPosition.LEFT_TOP;
case 'left-bottom':
return OverlayPosition.LEFT_BOTTOM;
case 'right-top':
return OverlayPosition.RIGHT_TOP;
case 'right-bottom':
return OverlayPosition.RIGHT_BOTTOM;
}
}
private static getAutoPosition(): ConnectedPosition[] {
return [
OverlayPosition.TOP_LEFT,
OverlayPosition.TOP_RIGHT,
OverlayPosition.BOTTOM_LEFT,
OverlayPosition.BOTTOM_RIGHT,
OverlayPosition.LEFT_TOP,
OverlayPosition.LEFT_BOTTOM,
OverlayPosition.RIGHT_TOP,
OverlayPosition.RIGHT_BOTTOM
];
}
}

View File

@ -1,3 +0,0 @@
<div class="tooltip-wrapper">
{{ tooltip }}
</div>

View File

@ -1,14 +0,0 @@
@import '../../../../assets/styles/red-variables';
.tooltip-wrapper {
background-color: $accent;
border-radius: 3px;
padding: 10px;
font-family: Inter, sans-serif;
font-size: 11px;
line-height: 14px;
color: white;
position: relative;
overflow: visible !important;
text-align: center;
}

View File

@ -1,14 +0,0 @@
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'redaction-tooltip-content',
templateUrl: './tooltip-content.component.html',
styleUrls: ['./tooltip-content.component.scss']
})
export class TooltipContentComponent implements OnInit {
@Input() tooltip: string;
constructor() {}
ngOnInit() {}
}

View File

@ -203,4 +203,11 @@ export class PermissionsService {
}
return project.files.reduce((acc, file) => acc && this.canDeleteFile(file, project), true);
}
isAdmin(user?: UserWrapper) {
if (!user) {
user = this._userService.user;
}
return user.isAdmin || true;
}
}

View File

@ -1,4 +1,4 @@
<button mat-button [class.overlay]="showDot" [class.primary]="primary" (click)="action.emit($event)">
<button mat-button [class.overlay]="showDot" [class.primary]="primary" (click)="action.emit($event)" [class.link-button]="linkButton">
<mat-icon [svgIcon]="icon" *ngIf="icon"></mat-icon>
<span [translate]="text"></span>
</button>

View File

@ -1,3 +1,5 @@
@import '../../../../assets/styles/red-variables';
button {
padding: 0 14px 0 10px;
@ -5,3 +7,13 @@ button {
width: 14px;
}
}
.link-button {
text-transform: uppercase;
opacity: 0.7;
color: $accent;
font-size: 11px;
letter-spacing: 0;
line-height: 14px;
font-weight: 600 !important;
}

View File

@ -10,6 +10,7 @@ export class IconButtonComponent implements OnInit {
@Input() text: string;
@Input() showDot = false;
@Input() primary = false;
@Input() linkButton = false;
@Output() action = new EventEmitter<any>();
constructor() {}

View File

@ -1,7 +1,14 @@
import { Injectable } from '@angular/core';
import { FileDetailsDialogComponent } from './file-details-dialog/file-details-dialog.component';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { FileStatus, FileManagementControllerService, ManualRedactionControllerService, Project } from '@redaction/red-ui-http';
import {
FileStatus,
FileManagementControllerService,
ManualRedactionControllerService,
Project,
TypeValue,
DictionaryControllerService
} from '@redaction/red-ui-http';
import { ConfirmationDialogComponent, ConfirmationDialogInput } from '../common/confirmation-dialog/confirmation-dialog.component';
import { NotificationService, NotificationType } from '../notification/notification.service';
import { TranslateService } from '@ngx-translate/core';
@ -13,6 +20,7 @@ import { AnnotationWrapper } from '../screens/file/model/annotation.wrapper';
import { ManualAnnotationDialogComponent } from './manual-redaction-dialog/manual-annotation-dialog.component';
import { ManualAnnotationService } from '../screens/file/service/manual-annotation.service';
import { ProjectWrapper } from '../state/model/project.wrapper';
import { AddEditDictionaryDialogComponent } from '../screens/admin/dictionary-listing-screen/add-edit-dictionary-dialog/add-edit-dictionary-dialog.component';
const dialogConfig = {
width: '600px',
@ -28,6 +36,7 @@ export class DialogService {
private readonly _dialog: MatDialog,
private readonly _translateService: TranslateService,
private readonly _appStateService: AppStateService,
private readonly _dictionaryControllerService: DictionaryControllerService,
private readonly _fileManagementControllerService: FileManagementControllerService,
private readonly _notificationService: NotificationService,
private readonly _manualAnnotationService: ManualAnnotationService,
@ -140,6 +149,18 @@ export class DialogService {
return ref;
}
public openDeleteDictionaryDialog($event: MouseEvent, dictionary: TypeValue, cb?: Function): MatDialogRef<ConfirmationDialogComponent> {
$event.stopPropagation();
const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig);
ref.afterClosed().subscribe(async (result) => {
if (result) {
await this._dictionaryControllerService.deleteType(dictionary.type).toPromise();
if (cb) cb();
}
});
return ref;
}
public openDeleteProjectDialog($event: MouseEvent, project: ProjectWrapper, cb?: Function): MatDialogRef<ConfirmationDialogComponent> {
$event.stopPropagation();
const ref = this._dialog.open(ConfirmationDialogComponent, dialogConfig);
@ -216,6 +237,22 @@ export class DialogService {
return ref;
}
public openAddEditDictionaryDialog(dictionary: TypeValue, cb?: Function): MatDialogRef<AddEditDictionaryDialogComponent> {
const ref = this._dialog.open(AddEditDictionaryDialogComponent, {
...dialogConfig,
data: dictionary,
autoFocus: true
});
ref.afterClosed().subscribe((result) => {
if (result && cb) {
cb(result);
}
});
return ref;
}
openRemoveAnnotationModal($event: MouseEvent, annotation: AnnotationWrapper, callback: () => void) {
$event.stopPropagation();

View File

@ -22,6 +22,7 @@ export class IconsModule {
'check',
'close',
'collapse',
'color-picker',
'comment',
'comment-fill',
'document',

View File

@ -0,0 +1,49 @@
<section class="dialog">
<form (submit)="saveDictionary()" [formGroup]="dictionaryForm">
<div [translate]="dictionary ? 'add-edit-dictionary.title.edit' : 'add-edit-dictionary.title.new'" class="dialog-header heading-l"></div>
<div class="dialog-content">
<div class="red-input-group required w-300">
<label translate="add-edit-dictionary.form.type"></label>
<input formControlName="type" name="type" type="text" placeholder="{{ 'add-edit-dictionary.form.type-placeholder' | translate }}" />
</div>
<div class="red-input-group required w-150">
<label translate="add-edit-dictionary.form.rank"></label>
<input formControlName="rank" name="rank" type="number" placeholder="{{ 'add-edit-dictionary.form.rank-placeholder' | translate }}" />
</div>
<div class="red-input-group required w-150">
<label translate="add-edit-dictionary.form.color"></label>
<input formControlName="hexColor" name="hexColor" type="text" placeholder="{{ 'add-edit-dictionary.form.color-placeholder' | translate }}" />
<div
class="input-icon"
[colorPicker]="dictionaryForm.get('hexColor').value"
[cpOutputFormat]="'hex'"
(colorPickerChange)="dictionaryForm.get('hexColor').setValue($event)"
>
<mat-icon svgIcon="red:color-picker"></mat-icon>
</div>
</div>
<div class="red-input-group slider-row">
<mat-button-toggle-group name="hint" formControlName="hint" appearance="legacy">
<mat-button-toggle [value]="false"> {{ 'add-edit-dictionary.form.redaction' | translate }}</mat-button-toggle>
<mat-button-toggle [value]="true"> {{ 'add-edit-dictionary.form.hint' | translate }}</mat-button-toggle>
</mat-button-toggle-group>
</div>
<div class="red-input-group">
<mat-checkbox formControlName="caseSensitive" color="primary">
{{ 'add-edit-dictionary.form.case-sensitive' | translate }}
</mat-checkbox>
</div>
</div>
<div class="dialog-actions">
<button [disabled]="dictionaryForm.invalid" color="primary" mat-flat-button translate="add-edit-dictionary.save" type="submit"></button>
</div>
</form>
<button (click)="dialogRef.close()" class="dialog-close" mat-icon-button>
<mat-icon svgIcon="red:close"></mat-icon>
</button>
</section>

View File

@ -0,0 +1,26 @@
@import '../../../../../assets/styles/red-variables';
.w-300 {
max-width: 300px;
}
.w-150 {
max-width: 150px;
}
.slider-row {
display: flex;
flex-direction: row;
align-items: center;
> mat-slide-toggle {
margin-left: 4px;
margin-right: 4px;
}
}
.mat-button-toggle-checked {
background: $primary;
transition: background-color 0.25s ease;
color: $white;
}

View File

@ -0,0 +1,85 @@
import { Component, Inject, OnInit } from '@angular/core';
import { AppStateService } from '../../../../state/app-state.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http';
import { Observable } from 'rxjs';
import { NotificationService, NotificationType } from '../../../../notification/notification.service';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'redaction-add-edit-dictionary-dialog',
templateUrl: './add-edit-dictionary-dialog.component.html',
styleUrls: ['./add-edit-dictionary-dialog.component.scss']
})
export class AddEditDictionaryDialogComponent implements OnInit {
dictionaryForm: FormGroup;
constructor(
private readonly _dictionaryControllerService: DictionaryControllerService,
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
private readonly _notificationService: NotificationService,
private readonly _translateService: TranslateService,
public dialogRef: MatDialogRef<AddEditDictionaryDialogComponent>,
@Inject(MAT_DIALOG_DATA) public dictionary: TypeValue
) {}
ngOnInit(): void {
this.dictionaryForm = this._formBuilder.group({
type: [this.dictionary?.type, Validators.required],
rank: [this.dictionary?.rank, Validators.required],
hexColor: [this.dictionary?.hexColor, Validators.required],
hint: [!!this.dictionary?.hint],
caseSensitive: [this.dictionary ? !this.dictionary.caseInsensitive : false]
});
// edit mode, cannot change type value
if (!!this.dictionary) {
this.dictionaryForm.get('type').disable();
}
}
async saveDictionary() {
const typeValue: TypeValue = this._formToObject();
let observable: Observable<any>;
if (this.dictionary) {
// edit mode
observable = this._dictionaryControllerService.updateType(typeValue, typeValue.type);
} else {
// create mode
observable = this._dictionaryControllerService.addType(typeValue);
}
//
observable.subscribe(
() => {
this.dialogRef.close({ dictionary: typeValue });
},
(error) => {
if (error.status === 409) {
this._notifyError('add-edit-dictionary.error.dictionary-already-exists');
} else if (error.status === 400) {
this._notifyError('add-edit-dictionary.error.invalid-color-or-rank');
} else {
this._notifyError('add-edit-dictionary.error.generic');
}
}
);
}
private _notifyError(message: string) {
this._notificationService.showToastNotification(this._translateService.instant(message), null, NotificationType.ERROR);
}
private _formToObject(): TypeValue {
return {
caseInsensitive: !this.dictionaryForm.get('caseSensitive').value,
hexColor: this.dictionaryForm.get('hexColor').value,
hint: this.dictionaryForm.get('hint').value,
type: this.dictionaryForm.get('type').value,
rank: this.dictionaryForm.get('rank').value
};
}
}

View File

@ -1,6 +1,27 @@
<section>
<div class="page-header">
<div class="section" translate="dictionaries"></div>
<div class="menu flex-2 visible-lg breadcrumbs-container">
<a class="breadcrumb" routerLink="/ui/admin-dictionaries" translate="dictionaries"></a>
<div>&nbsp;</div>
</div>
<div class="actions">
<redaction-icon-button
*ngIf="permissionsService.isAdmin()"
icon="red:plus"
(action)="openAddEditDictionaryDialog()"
text="dictionary-listing.add-new"
[primary]="true"
></redaction-icon-button>
<redaction-circle-button
class="ml-6"
[routerLink]="['/ui/projects/']"
tooltip="common.close"
tooltipPosition="before"
icon="red:close"
></redaction-circle-button>
</div>
</div>
<div class="red-content-inner">
@ -38,12 +59,17 @@
[withSort]="true"
></redaction-table-col-name>
<redaction-table-col-name label="dictionary-listing.table-col-names.hint-redaction" class="flex-center"></redaction-table-col-name>
<div></div>
<div class="scrollbar-placeholder"></div>
<div class="placeholder-bottom-border scrollbar-placeholder"></div>
<div class="placeholder-bottom-border scrollbar-placeholder"></div>
</div>
<div class="grid-container">
<div class="table-item" *ngFor="let dict of dictionaries | sortBy: sortingOption.order:sortingOption.column">
<!-- Table lines -->
<div
class="table-item"
*ngFor="let dict of dictionaries | sortBy: sortingOption.order:sortingOption.column"
[routerLink]="['/ui/dictionary-overview/' + dict.type]"
>
<div class="pr-0" (click)="toggleDictSelected($event, dict)">
<div *ngIf="!isDictSelected(dict)" class="select-oval"></div>
<mat-icon class="selection-icon active" *ngIf="isDictSelected(dict)" svgIcon="red:radio-selected"></mat-icon>
@ -64,9 +90,30 @@
</div>
</div>
<div class="analyzed">
<redaction-annotation-icon [dictType]="dict"></redaction-annotation-icon>
<redaction-annotation-icon [dictType]="dict" [type]="dict.hint ? 'circle' : 'square'"></redaction-annotation-icon>
</div>
<div class="actions-container">
<div class="action-buttons">
<redaction-circle-button
(action)="openDeleteDictionaryDialog($event, dict)"
*ngIf="permissionsService.isAdmin()"
tooltip="dictionary-listing.action.delete"
type="dark-bg"
icon="red:trash"
>
</redaction-circle-button>
<redaction-circle-button
(action)="openEditDictionaryDialog($event, dict)"
*ngIf="permissionsService.isAdmin()"
tooltip="dictionary-listing.action.edit"
type="dark-bg"
icon="red:edit"
>
</redaction-circle-button>
</div>
</div>
<div></div>
<div class="scrollbar-placeholder"></div>
</div>
</div>

View File

@ -59,3 +59,11 @@ redaction-table-col-name::ng-deep {
justify-content: center;
padding: 50px 0;
}
.actions {
display: flex;
.ml-6 {
margin-left: 6px;
}
}

View File

@ -6,6 +6,7 @@ import { DialogService } from '../../../dialogs/dialog.service';
import { AppStateService } from '../../../state/app-state.service';
import { tap } from 'rxjs/operators';
import { forkJoin } from 'rxjs';
import { PermissionsService } from '../../../common/service/permissions.service';
@Component({
selector: 'redaction-dictionary-listing-screen',
@ -21,10 +22,16 @@ export class DictionaryListingScreenComponent implements OnInit {
private readonly _dialogService: DialogService,
private readonly _sortingService: SortingService,
private readonly _dictionaryControllerService: DictionaryControllerService,
private readonly _appStateService: AppStateService
private readonly _appStateService: AppStateService,
public readonly permissionsService: PermissionsService
) {}
ngOnInit(): void {
this._loadDictionaryData();
this._calculateData();
}
private _loadDictionaryData() {
this._appStateService.reset();
const appStateDictionaryData = this._appStateService.dictionaryData;
this.dictionaries = Object.keys(appStateDictionaryData)
@ -42,7 +49,6 @@ export class DictionaryListingScreenComponent implements OnInit {
forkJoin(dataObs).subscribe(() => {
this._calculateData();
});
this._calculateData();
}
private _calculateData() {
@ -95,4 +101,25 @@ export class DictionaryListingScreenComponent implements OnInit {
public isDictSelected(dict: TypeValue) {
return this.selectedDictKeys.indexOf(dict.type) !== -1;
}
openAddEditDictionaryDialog(dict?: TypeValue) {
this._dialogService.openAddEditDictionaryDialog(dict, async (newDictionary) => {
if (newDictionary) {
await this._appStateService.loadDictionaryData();
this._loadDictionaryData();
}
});
}
openEditDictionaryDialog($event: any, dict: TypeValue) {
$event.stopPropagation();
this.openAddEditDictionaryDialog(dict);
}
openDeleteDictionaryDialog($event: any, dict: TypeValue) {
this._dialogService.openDeleteDictionaryDialog($event, dict, async () => {
await this._appStateService.loadDictionaryData();
this._loadDictionaryData();
});
}
}

View File

@ -0,0 +1,74 @@
<section>
<div class="page-header">
<div class="menu flex-2 visible-lg breadcrumbs-container">
<a class="breadcrumb" routerLink="/ui/admin-dictionaries" translate="dictionaries"></a>
<mat-icon svgIcon="red:arrow-right"></mat-icon>
<a class="breadcrumb" [routerLink]="'/ui/dictionary-overview/' + dictionary.type">
{{ dictionary.type }}
</a>
</div>
<div class="actions">
<redaction-circle-button
(action)="openDeleteDictionaryDialog($event)"
*ngIf="permissionsService.isAdmin()"
tooltip="dictionary-listing.action.delete"
type="dark-bg"
icon="red:trash"
>
</redaction-circle-button>
<redaction-circle-button
(action)="openEditDictionaryDialog($event)"
*ngIf="permissionsService.isAdmin()"
tooltip="dictionary-listing.action.edit"
type="dark-bg"
icon="red:edit"
>
</redaction-circle-button>
<redaction-circle-button
class="ml-6"
[routerLink]="['/ui/admin-dictionaries/']"
tooltip="common.close"
tooltipPosition="before"
icon="red:close"
></redaction-circle-button>
</div>
</div>
<div class="flex red-content-inner">
<div class="left-container">
<div class="editor-container">
<ace-editor
#editorComponent
[mode]="'text'"
[theme]="'light'"
[options]="aceOptions"
(textChanged)="textChanged($event)"
[autoUpdateContent]="true"
[text]="dictionaryEntriesAsText"
>
</ace-editor>
</div>
<div class="changes-box" *ngIf="hasChanges">
<redaction-icon-button
*ngIf="permissionsService.isAdmin()"
icon="red:check"
(action)="saveEntries()"
text="dictionary-overview.save-changes"
[primary]="true"
></redaction-icon-button>
<redaction-icon-button
*ngIf="permissionsService.isAdmin()"
(action)="revert()"
text="dictionary-overview.revert-changes"
[linkButton]="true"
></redaction-icon-button>
</div>
</div>
<div class="right-fixed-container"></div>
</div>
</section>

View File

@ -0,0 +1,43 @@
@import '../../../../assets/styles/red-variables';
@import '../../../../assets/styles/red-mixins';
.editor-container {
height: 100%;
width: 100%;
ace-editor {
width: 100%;
height: 100%;
}
}
.left-container {
width: calc(100vw - 383px);
height: calc(100vh - 141px);
padding: 15px;
}
.right-fixed-container {
overflow-y: scroll;
@include no-scroll-bar();
display: flex;
width: calc(353px);
height: calc(100vh - 110px - 2 * 50px);
justify-content: center;
padding: 50px 0;
}
.changes-box {
position: absolute;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
bottom: 40px;
right: 40px;
border-radius: 8px;
padding: 16px;
background-color: #ffffff;
box-shadow: 0 2px 6px 0 rgba(40, 50, 65, 0.3);
z-index: 5000;
}

View File

@ -0,0 +1,126 @@
import { Component, ViewChild } from '@angular/core';
import { DictionaryControllerService, TypeValue } from '@redaction/red-ui-http';
import { DialogService } from '../../../dialogs/dialog.service';
import { AppStateService } from '../../../state/app-state.service';
import { PermissionsService } from '../../../common/service/permissions.service';
import { ActivatedRoute, Router } from '@angular/router';
import { AceEditorComponent } from 'ng2-ace-editor';
import * as aceModule from 'ace-builds/src-noconflict/ace';
import { reference } from '../../../utils/functions';
declare var ace;
const Range = ace.acequire('ace/range').Range;
@Component({
selector: 'redaction-dictionary-overview-screen',
templateUrl: './dictionary-overview-screen.component.html',
styleUrls: ['./dictionary-overview-screen.component.scss']
})
export class DictionaryOverviewScreenComponent {
@ViewChild('editorComponent')
editorComponent: AceEditorComponent;
dictionary: TypeValue;
activeMarkers: any[] = [];
initialDictionaryEntries: string[] = [];
currentDictionaryEntries: string[] = [];
changedLines: number[] = [];
dictionaryEntriesAsText: string;
aceOptions = { showPrintMargin: false };
constructor(
public readonly permissionsService: PermissionsService,
private readonly _dictionaryControllerService: DictionaryControllerService,
private readonly _dialogService: DialogService,
private readonly _router: Router,
private readonly _activatedRoute: ActivatedRoute,
private readonly _appStateService: AppStateService
) {
this._activatedRoute.params.subscribe((params) => {
this.dictionary = this._appStateService.dictionaryData[params.type];
if (!this.dictionary) {
this._router.navigate(['/ui/admin-dictionaries']);
} else {
this._initialize();
}
});
reference(aceModule);
}
private _initialize() {
this._dictionaryControllerService.getDictionaryForType(this.dictionary.type).subscribe((data) => {
this.initialDictionaryEntries = data.entries;
this.revert();
});
}
openEditDictionaryDialog($event: any) {
$event.stopPropagation();
this._dialogService.openAddEditDictionaryDialog(this.dictionary, async (newDictionary) => {
if (newDictionary) {
await this._appStateService.loadDictionaryData();
this.dictionary = this._appStateService.dictionaryData[this.dictionary.type];
}
});
}
openDeleteDictionaryDialog($event: any) {
this._dialogService.openDeleteDictionaryDialog($event, this.dictionary, async () => {
await this._appStateService.loadDictionaryData();
this._router.navigate(['/ui/admin-dictionaries']);
});
}
textChanged($event: any) {
this.currentDictionaryEntries = $event.split('\n');
this.changedLines = [];
this.activeMarkers.forEach((am) => {
this.editorComponent.getEditor().getSession().removeMarker(am);
});
this.activeMarkers = [];
for (let i = 0; i < this.currentDictionaryEntries.length; i++) {
const currentEntry = this.currentDictionaryEntries[i];
if (this.initialDictionaryEntries.indexOf(currentEntry) < 0) {
this.changedLines.push(i);
}
}
for (let i of this.changedLines) {
this.activeMarkers.push(this.editorComponent.getEditor().getSession().addMarker(new Range(i, 0, i, 1), 'changed-row-marker', 'fullLine'));
}
}
get hasChanges() {
return this.changedLines.length > 0 || this.currentDictionaryEntries.length !== this.initialDictionaryEntries.length;
}
async saveEntries() {
const entriesToAdd = [];
const entriesToDelete = [];
this.currentDictionaryEntries.forEach((currentEntry) => {
if (this.initialDictionaryEntries.indexOf(currentEntry) < 0) {
entriesToAdd.push(currentEntry);
}
});
this.initialDictionaryEntries.forEach((initialEntry) => {
if (this.currentDictionaryEntries.indexOf(initialEntry) < 0) {
entriesToDelete.push(initialEntry);
}
});
if (entriesToAdd.length > 0) {
await this._dictionaryControllerService.addEntry(entriesToAdd, this.dictionary.type).toPromise();
}
if (entriesToDelete.length > 0) {
await this._dictionaryControllerService.deleteEntries(entriesToDelete, this.dictionary.type).toPromise();
}
this._initialize();
}
revert() {
this.dictionaryEntriesAsText = this.initialDictionaryEntries.join('\n');
this.editorComponent.getEditor().setValue(this.dictionaryEntriesAsText);
this.editorComponent.getEditor().clearSelection();
}
}

View File

@ -1,28 +1,6 @@
@import '../../../assets/styles/red-variables';
@import '../../../assets/styles/red-mixins';
.breadcrumbs-container {
display: flex;
gap: 6px;
.breadcrumb {
text-decoration: none;
color: $grey-1;
font-weight: 600;
width: fit-content;
white-space: nowrap;
&:last-child {
color: $primary;
@include line-clamp(1);
}
}
mat-icon {
width: 16px;
}
}
.dev-mode {
margin: 0 10px;
padding: 2px 5px;

View File

@ -361,113 +361,117 @@ export class AppStateService {
async loadDictionaryDataIfNecessary() {
if (!this._dictionaryData) {
this._dictionaryData = {};
const typeObs = this._dictionaryControllerService.getAllTypes().pipe(
tap((typesResponse) => {
for (const type of typesResponse.types) {
this._dictionaryData[type.type] = type;
}
})
);
const colorsObs = this._dictionaryControllerService.getColors().pipe(
tap((colors) => {
// declined
this._dictionaryData['declined-suggestion'] = {
hexColor: colors.notRedacted,
type: 'declined-suggestion',
virtual: true
};
// manual
this._dictionaryData['manual'] = {
hexColor: colors.defaultColor,
type: 'manual',
virtual: true
};
// dictionary actions
this._dictionaryData['add-dictionary'] = {
hexColor: '#dd4d50',
type: 'add-dictionary',
virtual: true
};
this._dictionaryData['remove-dictionary'] = {
hexColor: '#dd4d50',
type: 'remove-dictionary',
virtual: true
};
// generic suggestions
this._dictionaryData['suggestion'] = {
hexColor: colors.requestAdd,
type: 'suggestion',
virtual: true
};
// add suggestions
this._dictionaryData['suggestion-add'] = {
hexColor: colors.requestAdd,
type: 'suggestion-add',
virtual: true
};
this._dictionaryData['suggestion-add-dictionary'] = {
hexColor: '#5B97DB',
type: 'suggestion-add',
virtual: true
};
// suggestion remove
this._dictionaryData['suggestion-remove'] = {
hexColor: colors.requestRemove,
type: 'suggestion-add',
virtual: true
};
this._dictionaryData['suggestion-remove-dictionary'] = {
hexColor: '#5B97DB',
type: 'suggestion-add',
virtual: true
};
this._dictionaryData['manual'] = {
hexColor: colors.defaultColor,
type: 'manual',
virtual: true
};
this._dictionaryData['ignore'] = {
hexColor: colors.notRedacted,
type: 'ignore',
virtual: true
};
this._dictionaryData['default'] = {
hexColor: colors.defaultColor,
type: 'default',
virtual: true
};
this._dictionaryData['add'] = {
hexColor: colors.requestAdd,
type: 'add',
virtual: true
};
this._dictionaryData['analysis'] = {
hexColor: '#dd4d50',
type: 'analysis',
virtual: true
};
})
);
await forkJoin([typeObs, colorsObs]).toPromise();
this._dictionaryData['hint'] = { hexColor: '#9398a0', type: 'hint', virtual: true };
this._dictionaryData['redaction'] = {
hexColor: '#283241',
type: 'redaction',
virtual: true
};
for (const key of Object.keys(this._dictionaryData)) {
this._dictionaryData[key].label = humanize(key, false);
}
await this.loadDictionaryData();
} else {
return this._dictionaryData;
}
}
async loadDictionaryData() {
this._dictionaryData = {};
const typeObs = this._dictionaryControllerService.getAllTypes().pipe(
tap((typesResponse) => {
for (const type of typesResponse.types) {
this._dictionaryData[type.type] = type;
}
})
);
const colorsObs = this._dictionaryControllerService.getColors().pipe(
tap((colors) => {
// declined
this._dictionaryData['declined-suggestion'] = {
hexColor: colors.notRedacted,
type: 'declined-suggestion',
virtual: true
};
// manual
this._dictionaryData['manual'] = {
hexColor: colors.defaultColor,
type: 'manual',
virtual: true
};
// dictionary actions
this._dictionaryData['add-dictionary'] = {
hexColor: '#dd4d50',
type: 'add-dictionary',
virtual: true
};
this._dictionaryData['remove-dictionary'] = {
hexColor: '#dd4d50',
type: 'remove-dictionary',
virtual: true
};
// generic suggestions
this._dictionaryData['suggestion'] = {
hexColor: colors.requestAdd,
type: 'suggestion',
virtual: true
};
// add suggestions
this._dictionaryData['suggestion-add'] = {
hexColor: colors.requestAdd,
type: 'suggestion-add',
virtual: true
};
this._dictionaryData['suggestion-add-dictionary'] = {
hexColor: '#5B97DB',
type: 'suggestion-add',
virtual: true
};
// suggestion remove
this._dictionaryData['suggestion-remove'] = {
hexColor: colors.requestRemove,
type: 'suggestion-add',
virtual: true
};
this._dictionaryData['suggestion-remove-dictionary'] = {
hexColor: '#5B97DB',
type: 'suggestion-add',
virtual: true
};
this._dictionaryData['manual'] = {
hexColor: colors.defaultColor,
type: 'manual',
virtual: true
};
this._dictionaryData['ignore'] = {
hexColor: colors.notRedacted,
type: 'ignore',
virtual: true
};
this._dictionaryData['default'] = {
hexColor: colors.defaultColor,
type: 'default',
virtual: true
};
this._dictionaryData['add'] = {
hexColor: colors.requestAdd,
type: 'add',
virtual: true
};
this._dictionaryData['analysis'] = {
hexColor: '#dd4d50',
type: 'analysis',
virtual: true
};
})
);
await forkJoin([typeObs, colorsObs]).toPromise();
this._dictionaryData['hint'] = { hexColor: '#9398a0', type: 'hint', virtual: true };
this._dictionaryData['redaction'] = {
hexColor: '#283241',
type: 'redaction',
virtual: true
};
for (const key of Object.keys(this._dictionaryData)) {
this._dictionaryData[key].label = humanize(key, false);
}
}
getDictionaryTypeValue(key: string) {
const data = this._dictionaryData[key];
return data ? data : this._dictionaryData['default'];

View File

@ -38,3 +38,7 @@ export function hexToRgb(hex) {
export function keypress(key: string) {
document.dispatchEvent(new KeyboardEvent('keypress', { key: key }));
}
export function reference(x: any) {
return x;
}

View File

@ -1,13 +0,0 @@
<div class="virtual-scroll" #scrollElement (click)="scrollClicked($event)">
<div
class="scroller"
[style.height]="height + 'px'"
cdkDragBoundary=".virtual-scroll"
cdkDrag
#scroller
(cdkDragMoved)="moved($event)"
(cdkDragReleased)="released($event)"
(cdkDragStarted)="started($event)"
(click)="$event.stopPropagation()"
></div>
</div>

View File

@ -1,25 +0,0 @@
@import '../../../assets/styles/red-variables';
.virtual-scroll {
// TODO fix this - pass information as input or such
position: fixed;
width: 10px;
right: 480px;
bottom: 0;
z-index: 100;
top: 191px;
overflow: auto;
background: $grey-6;
.scroller {
position: absolute;
height: 50px;
width: 10px;
background: $grey-5;
transition: transform 0.1s ease 0s, background 0.25s ease;
&:hover {
background: $grey-7;
}
}
}

View File

@ -1,66 +0,0 @@
import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
import { CdkDragMove, CdkDragRelease, CdkDragStart } from '@angular/cdk/drag-drop';
@Component({
selector: 'redaction-virtual-scroll',
templateUrl: './virtual-scroll.component.html',
styleUrls: ['./virtual-scroll.component.scss']
})
export class VirtualScrollComponent implements AfterViewInit {
@Input() targetQuerySelector = '.red-content';
@ViewChild('scrollElement')
scrollElement: ElementRef;
@ViewChild('scroller')
scroller: ElementRef;
content: HTMLElement;
factor: number;
height: number;
listener = () => {
console.log('adjust', this.content.scrollTop);
const top = Math.min(this.content.scrollTop * this.factor, this.scrollElement.nativeElement.clientHeight - this.height);
this.scroller.nativeElement.style.transform = 'translate3d(0px,' + top + 'px, 0px)';
};
constructor() {}
ngAfterViewInit(): void {
this.content = document.querySelector(this.targetQuerySelector);
this.factor = this.content.clientHeight / this.scrollElement.nativeElement.clientHeight;
const scrollFactor = this.content.scrollHeight / this.content.clientHeight;
this.height = this.scrollElement.nativeElement.clientHeight / scrollFactor;
this.content.addEventListener('scroll', this.listener);
}
scrollClicked($event: MouseEvent) {
console.log('clicked');
// half the scroll bar size - center pos ->
const top = Math.min(Math.max(0, $event.offsetY - this.height / 2), this.scrollElement.nativeElement.clientHeight - this.height);
this.scroller.nativeElement.style.transform = 'translate3d(0px,' + top + 'px, 0px)';
this.content.removeEventListener('scroll', this.listener);
this.content.scrollTop = top * this.factor;
console.log(this.content.scrollTop, top, this.factor);
this.content.addEventListener('scroll', this.listener);
}
released($event: CdkDragRelease) {
this.content.addEventListener('scroll', this.listener);
}
started($event: CdkDragStart) {
this.content.removeEventListener('scroll', this.listener);
}
moved($event: CdkDragMove<any>) {
console.log('moveded', this._getTop());
}
private _getTop() {
const translateY = this.scroller.nativeElement.style.transform
.split('translate3d')
.filter((t) => t.trim().length > 0)
.map((t) => t.split(',')[1].trim().replace('px', ''))
.map((t) => parseInt(t, 10))
.reduce((acc, el) => acc + el, 0);
this.content.scrollTop = translateY * this.factor;
}
}

View File

@ -1,5 +1,5 @@
{
"OAUTH_URL": "https://redkc-staging.iqser.cloud/auth/realms/redaction",
"OAUTH_CLIENT_ID": "redaction",
"API_URL": "https://redapi-staging.iqser.cloud"
"API_URL": "https://timo-redaction-dev.iqser.cloud"
}

View File

@ -475,7 +475,39 @@
"question": "Do you wish to proceed?"
}
},
"add-edit-dictionary": {
"title": {
"edit": "Edit Dictionary",
"new": "Create Dictionary"
},
"form": {
"type": "Type",
"type-placeholder": "Enter Type Name",
"rank": "Rank",
"rank-placeholder": "1000",
"color": "Hex Color",
"color-placeholder": "#",
"redaction": "Redaction",
"hint": "Hint",
"case-sensitive": "Case Sensitive"
},
"error": {
"dictionary-already-exists": "Dictionary with this name already exists!",
"invalid-color-or-rank": "Invalid color or rank! Rank is already used by another dictionary or the color is not a valid hexColor!",
"generic": "Failed to save dictionary!"
},
"save": "Save Dictionary"
},
"dictionary-overview": {
"save-changes": "Save Changes",
"revert-changes": "Revert"
},
"dictionary-listing": {
"action": {
"delete": "Delete Dictionary",
"edit": "Edit Dictionary"
},
"add-new": "New Dictionary",
"stats": {
"charts": {
"types": "Types",

View File

@ -0,0 +1,14 @@
<svg id="Capa_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 464.736 464.736" style="enable-background:new 0 0 464.736 464.736;" xml:space="preserve">
<g>
<path d="M446.598,18.143c-24.183-24.184-63.393-24.191-87.592-0.008l-16.717,16.717c-8.98-8.979-23.525-8.979-32.504,0
c-8.981,8.972-8.981,23.533,0,32.505l5.416,5.419L134.613,253.377h-0.016l-62.685,62.691c-4.982,4.982-7.919,11.646-8.235,18.684
l-0.15,3.344c0,0.016,0,0.03,0,0.046l-2.529,56.704c-0.104,2.633,0.883,5.185,2.739,7.048c1.751,1.759,4.145,2.738,6.63,2.738
c0.135,0,0.269,0,0.42-0.008l30.064-1.331h0.016l18.318-0.815l8.318-0.366c9.203-0.412,17.944-4.259,24.469-10.776l240.898-240.891
l4.506,4.505c4.49,4.488,10.372,6.733,16.252,6.733c5.881,0,11.764-2.245,16.253-6.733c8.98-8.973,8.98-23.534,0-32.505
l16.716-16.718C470.782,81.544,470.782,42.334,446.598,18.143z M272.639,227.33l-84.6,15.96l137.998-138.004l34.332,34.316
L272.639,227.33z" fill="currentColor"/>
<path d="M64.5,423.872c-35.617,0-64.5,9.145-64.5,20.435c0,11.284,28.883,20.428,64.5,20.428s64.486-9.143,64.486-20.428
C128.986,433.016,100.117,423.872,64.5,423.872z" fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,25 @@
@import 'red-variables';
@import 'red-mixins';
.breadcrumbs-container {
display: flex;
align-items: center;
gap: 6px;
.breadcrumb {
text-decoration: none;
color: $grey-1;
font-weight: 600;
width: fit-content;
white-space: nowrap;
&:last-child {
color: $primary;
@include line-clamp(1);
}
}
mat-icon {
width: 16px;
}
}

View File

@ -8,15 +8,17 @@
.dialog-close {
position: absolute;
top: -15px;
top: 0;
right: -10px;
mat-icon {
width: 12px;
width: 14px;
height: 14px;
}
}
.dialog-header {
padding-top: 12px;
padding-bottom: 12px;
}
@ -31,5 +33,6 @@
> * {
margin-right: 16px;
}
padding-bottom: 40px;
}
}

View File

@ -0,0 +1,8 @@
@import 'red-variables';
@import 'red-mixins';
.changed-row-marker {
position: absolute;
background: rgba($primary, 0.2);
z-index: 20;
}

View File

@ -7,6 +7,33 @@
margin-top: 13px;
position: relative;
.input-icon {
position: absolute;
right: 1px;
bottom: 1px;
background: $grey-5;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
width: 32px;
border: 1px solid $grey-5;
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
cursor: pointer;
transition: background-color 0.25s ease;
&:hover {
background: $grey-6;
}
mat-icon {
width: 14px;
height: 14px;
color: $grey-1;
}
}
.mat-form-field-underline {
display: none;
}

View File

@ -20,3 +20,5 @@
@import 'red-toasts';
@import 'red-tooltips';
@import 'red-grid';
@import 'red-breadcrumbs';
@import 'red-editor';

View File

@ -31,11 +31,7 @@ export class DictionaryControllerService {
public defaultHeaders = new HttpHeaders();
public configuration = new Configuration();
constructor(
protected httpClient: HttpClient,
@Optional() @Inject(BASE_PATH) basePath: string,
@Optional() configuration: Configuration
) {
constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
if (basePath) {
this.basePath = basePath;
}
@ -67,30 +63,10 @@ export class DictionaryControllerService {
* @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 addEntry(
body: Array<string>,
type: string,
observe?: 'body',
reportProgress?: boolean
): Observable<any>;
public addEntry(
body: Array<string>,
type: string,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public addEntry(
body: Array<string>,
type: string,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public addEntry(
body: Array<string>,
type: string,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public addEntry(body: Array<string>, type: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public addEntry(body: Array<string>, type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public addEntry(body: Array<string>, type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public addEntry(body: Array<string>, type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (body === null || body === undefined) {
throw new Error('Required parameter body was null or undefined when calling addEntry.');
}
@ -103,42 +79,31 @@ export class DictionaryControllerService {
// authentication (RED-OAUTH) required
if (this.configuration.accessToken) {
const accessToken =
typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: 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[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = ['application/json'];
const httpContentTypeSelected:
| string
| undefined = this.configuration.selectHeaderContentType(consumes);
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected !== undefined) {
headers = headers.set('Content-Type', httpContentTypeSelected);
}
return this.httpClient.request<any>(
'post',
`${this.basePath}/dictionary/${encodeURIComponent(String(type))}`,
{
body: body,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
return this.httpClient.request<any>('post', `${this.basePath}/dictionary/${encodeURIComponent(String(type))}`, {
body: body,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
/**
@ -149,21 +114,9 @@ export class DictionaryControllerService {
* @param reportProgress flag to report request and response progress.
*/
public addType(body: TypeValue, observe?: 'body', reportProgress?: boolean): Observable<any>;
public addType(
body: TypeValue,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public addType(
body: TypeValue,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public addType(
body: TypeValue,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public addType(body: TypeValue, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public addType(body: TypeValue, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public addType(body: TypeValue, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (body === null || body === undefined) {
throw new Error('Required parameter body was null or undefined when calling addType.');
}
@ -172,27 +125,20 @@ export class DictionaryControllerService {
// authentication (RED-OAUTH) required
if (this.configuration.accessToken) {
const accessToken =
typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: 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[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = ['application/json'];
const httpContentTypeSelected:
| string
| undefined = this.configuration.selectHeaderContentType(consumes);
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected !== undefined) {
headers = headers.set('Content-Type', httpContentTypeSelected);
}
@ -214,82 +160,47 @@ export class DictionaryControllerService {
* @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 deleteEntry(
body: Array<string>,
type: string,
observe?: 'body',
reportProgress?: boolean
): Observable<any>;
public deleteEntry(
body: Array<string>,
type: string,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public deleteEntry(
body: Array<string>,
type: string,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public deleteEntry(
body: Array<string>,
type: string,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public deleteEntry(body: Array<string>, type: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public deleteEntry(body: Array<string>, type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public deleteEntry(body: Array<string>, type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public deleteEntry(body: Array<string>, type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (body === null || body === undefined) {
throw new Error(
'Required parameter body was null or undefined when calling deleteEntry.'
);
throw new Error('Required parameter body was null or undefined when calling deleteEntry.');
}
if (type === null || type === undefined) {
throw new Error(
'Required parameter type was null or undefined when calling deleteEntry.'
);
throw new Error('Required parameter type was null or undefined when calling deleteEntry.');
}
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;
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[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = ['*/*'];
const httpContentTypeSelected:
| string
| undefined = this.configuration.selectHeaderContentType(consumes);
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected !== undefined) {
headers = headers.set('Content-Type', httpContentTypeSelected);
}
return this.httpClient.request<any>(
'delete',
`${this.basePath}/dictionary/${encodeURIComponent(String(type))}`,
{
body: body,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
return this.httpClient.request<any>('delete', `${this.basePath}/dictionary/${encodeURIComponent(String(type))}`, {
body: body,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
/**
@ -300,43 +211,24 @@ export class DictionaryControllerService {
* @param reportProgress flag to report request and response progress.
*/
public deleteType(type: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public deleteType(
type: string,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public deleteType(
type: string,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public deleteType(
type: string,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public deleteType(type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public deleteType(type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public deleteType(type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (type === null || type === undefined) {
throw new Error(
'Required parameter type was null or undefined when calling deleteType.'
);
throw new Error('Required parameter type was null or undefined when calling deleteType.');
}
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;
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[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
@ -344,16 +236,63 @@ export class DictionaryControllerService {
// to determine the Content-Type header
const consumes: string[] = [];
return this.httpClient.request<any>(
'delete',
`${this.basePath}/dictionary/type/${encodeURIComponent(String(type))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
return this.httpClient.request<any>('delete', `${this.basePath}/dictionary/type/${encodeURIComponent(String(type))}`, {
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
/**
* Delete dictionary entries with entry type.
* None
* @param body entries
* @param type type
* @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 deleteEntries(body: Array<string>, type: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public deleteEntries(body: Array<string>, type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public deleteEntries(body: Array<string>, type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public deleteEntries(body: Array<string>, type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (body === null || body === undefined) {
throw new Error('Required parameter body was null or undefined when calling deleteEntries.');
}
if (type === null || type === undefined) {
throw new Error('Required parameter type was null or undefined when calling deleteEntries.');
}
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
let httpHeaderAccepts: string[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = ['application/json'];
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected != undefined) {
headers = headers.set('Content-Type', httpContentTypeSelected);
}
return this.httpClient.request<any>('post', `${this.basePath}/dictionary/delete/${encodeURIComponent(String(type))}`, {
body: body,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
/**
@ -363,48 +302,25 @@ export class DictionaryControllerService {
* @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 downloadDictionaryFile(
type: string,
observe?: 'body',
reportProgress?: boolean
): Observable<any>;
public downloadDictionaryFile(
type: string,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public downloadDictionaryFile(
type: string,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public downloadDictionaryFile(
type: string,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public downloadDictionaryFile(type: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public downloadDictionaryFile(type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public downloadDictionaryFile(type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public downloadDictionaryFile(type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (type === null || type === undefined) {
throw new Error(
'Required parameter type was null or undefined when calling downloadDictionaryFile.'
);
throw new Error('Required parameter type was null or undefined when calling downloadDictionaryFile.');
}
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;
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[] = ['*/*'];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
@ -412,16 +328,12 @@ export class DictionaryControllerService {
// to determine the Content-Type header
const consumes: string[] = [];
return this.httpClient.request<any>(
'get',
`${this.basePath}/dictionary/download/${encodeURIComponent(String(type))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
return this.httpClient.request<any>('get', `${this.basePath}/dictionary/download/${encodeURIComponent(String(type))}`, {
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
/**
@ -431,31 +343,20 @@ export class DictionaryControllerService {
* @param reportProgress flag to report request and response progress.
*/
public getAllTypes(observe?: 'body', reportProgress?: boolean): Observable<TypeResponse>;
public getAllTypes(
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<TypeResponse>>;
public getAllTypes(
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<TypeResponse>>;
public getAllTypes(observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<TypeResponse>>;
public getAllTypes(observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<TypeResponse>>;
public getAllTypes(observe: any = 'body', reportProgress: boolean = false): Observable<any> {
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;
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
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
@ -478,28 +379,20 @@ export class DictionaryControllerService {
* @param reportProgress flag to report request and response progress.
*/
public getColors(observe?: 'body', reportProgress?: boolean): Observable<Colors>;
public getColors(
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<Colors>>;
public getColors(observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<Colors>>;
public getColors(observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Colors>>;
public getColors(observe: any = 'body', reportProgress: boolean = false): Observable<any> {
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;
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
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
@ -522,48 +415,25 @@ export class DictionaryControllerService {
* @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 getDictionaryForType(
type: string,
observe?: 'body',
reportProgress?: boolean
): Observable<Dictionary>;
public getDictionaryForType(
type: string,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<Dictionary>>;
public getDictionaryForType(
type: string,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<Dictionary>>;
public getDictionaryForType(
type: string,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public getDictionaryForType(type: string, observe?: 'body', reportProgress?: boolean): Observable<Dictionary>;
public getDictionaryForType(type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<Dictionary>>;
public getDictionaryForType(type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Dictionary>>;
public getDictionaryForType(type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (type === null || type === undefined) {
throw new Error(
'Required parameter type was null or undefined when calling getDictionaryForType.'
);
throw new Error('Required parameter type was null or undefined when calling getDictionaryForType.');
}
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;
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
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
@ -571,16 +441,12 @@ export class DictionaryControllerService {
// to determine the Content-Type header
const consumes: string[] = [];
return this.httpClient.request<Dictionary>(
'get',
`${this.basePath}/dictionary/${encodeURIComponent(String(type))}`,
{
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
return this.httpClient.request<Dictionary>('get', `${this.basePath}/dictionary/${encodeURIComponent(String(type))}`, {
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
/**
@ -591,52 +457,31 @@ export class DictionaryControllerService {
* @param reportProgress flag to report request and response progress.
*/
public setColors(body: Colors, observe?: 'body', reportProgress?: boolean): Observable<any>;
public setColors(
body: Colors,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public setColors(
body: Colors,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public setColors(
body: Colors,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public setColors(body: Colors, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public setColors(body: Colors, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public setColors(body: Colors, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (body === null || body === undefined) {
throw new Error(
'Required parameter body was null or undefined when calling setColors.'
);
throw new Error('Required parameter body was null or undefined when calling setColors.');
}
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;
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[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = ['application/json'];
const httpContentTypeSelected:
| string
| undefined = this.configuration.selectHeaderContentType(consumes);
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected !== undefined) {
headers = headers.set('Content-Type', httpContentTypeSelected);
}
@ -658,82 +503,47 @@ export class DictionaryControllerService {
* @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 updateType(
body: UpdateTypeValue,
type: string,
observe?: 'body',
reportProgress?: boolean
): Observable<any>;
public updateType(
body: UpdateTypeValue,
type: string,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public updateType(
body: UpdateTypeValue,
type: string,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public updateType(
body: UpdateTypeValue,
type: string,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public updateType(body: UpdateTypeValue, type: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public updateType(body: UpdateTypeValue, type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public updateType(body: UpdateTypeValue, type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public updateType(body: UpdateTypeValue, type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (body === null || body === undefined) {
throw new Error(
'Required parameter body was null or undefined when calling updateType.'
);
throw new Error('Required parameter body was null or undefined when calling updateType.');
}
if (type === null || type === undefined) {
throw new Error(
'Required parameter type was null or undefined when calling updateType.'
);
throw new Error('Required parameter type was null or undefined when calling updateType.');
}
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;
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[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
// to determine the Content-Type header
const consumes: string[] = ['application/json'];
const httpContentTypeSelected:
| string
| undefined = this.configuration.selectHeaderContentType(consumes);
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
if (httpContentTypeSelected !== undefined) {
headers = headers.set('Content-Type', httpContentTypeSelected);
}
return this.httpClient.request<any>(
'post',
`${this.basePath}/dictionary/type/${encodeURIComponent(String(type))}`,
{
body: body,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
return this.httpClient.request<any>('post', `${this.basePath}/dictionary/type/${encodeURIComponent(String(type))}`, {
body: body,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
/**
@ -744,58 +554,29 @@ export class DictionaryControllerService {
* @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 uploadDictionaryFileForm(
file: Blob,
type: string,
observe?: 'body',
reportProgress?: boolean
): Observable<any>;
public uploadDictionaryFileForm(
file: Blob,
type: string,
observe?: 'response',
reportProgress?: boolean
): Observable<HttpResponse<any>>;
public uploadDictionaryFileForm(
file: Blob,
type: string,
observe?: 'events',
reportProgress?: boolean
): Observable<HttpEvent<any>>;
public uploadDictionaryFileForm(
file: Blob,
type: string,
observe: any = 'body',
reportProgress: boolean = false
): Observable<any> {
public uploadDictionaryFileForm(file: Blob, type: string, observe?: 'body', reportProgress?: boolean): Observable<any>;
public uploadDictionaryFileForm(file: Blob, type: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<any>>;
public uploadDictionaryFileForm(file: Blob, type: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<any>>;
public uploadDictionaryFileForm(file: Blob, type: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
if (file === null || file === undefined) {
throw new Error(
'Required parameter file was null or undefined when calling uploadDictionaryFile.'
);
throw new Error('Required parameter file was null or undefined when calling uploadDictionaryFile.');
}
if (type === null || type === undefined) {
throw new Error(
'Required parameter type was null or undefined when calling uploadDictionaryFile.'
);
throw new Error('Required parameter type was null or undefined when calling uploadDictionaryFile.');
}
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;
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[] = [];
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(
httpHeaderAccepts
);
const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected !== undefined) {
headers = headers.set('Accept', httpHeaderAcceptSelected);
}
@ -821,16 +602,12 @@ export class DictionaryControllerService {
formParams = (formParams.append('file', <any>file) as any) || formParams;
}
return this.httpClient.request<any>(
'post',
`${this.basePath}/dictionary/upload/${encodeURIComponent(String(type))}`,
{
body: convertFormParamsToString ? formParams.toString() : formParams,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
);
return this.httpClient.request<any>('post', `${this.basePath}/dictionary/upload/${encodeURIComponent(String(type))}`, {
body: convertFormParamsToString ? formParams.toString() : formParams,
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
});
}
}

View File

@ -31,6 +31,11 @@ export interface TypeValue {
* The nonnull entry type.
*/
type?: string;
/**
* Rank of this dictionary
*/
rank?: number;
isDefaultFilter?: boolean;
virtual?: boolean;
label?: string;

View File

@ -1,104 +1,106 @@
{
"name": "redaction",
"version": "0.0.197",
"private": true,
"license": "MIT",
"scripts": {
"affected": "nx affected",
"affected:apps": "nx affected:apps",
"affected:build": "nx affected:build",
"affected:dep-graph": "nx affected:dep-graph",
"affected:e2e": "nx affected:e2e",
"affected:libs": "nx affected:libs",
"affected:lint": "nx affected:lint",
"affected:test": "nx affected:test",
"build": "nx build",
"build-lint-all": "ng lint --project=red-ui-http --fix && ng build --project=red-ui-http && ng lint --project=red-ui --fix && ng build --project=red-ui --prod",
"dep-graph": "nx dep-graph",
"e2e": "nx e2e",
"format": "nx format:write",
"format:check": "nx format:check",
"format:write": "nx format:write",
"help": "nx help",
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points",
"lint": "nx workspace-lint && nx lint",
"nx": "nx",
"start": "nx serve",
"test": "nx test",
"update": "nx migrate latest",
"workspace-schematic": "nx workspace-schematic"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && ng lint --project=red-ui-http && ng lint --project=red-ui --fix"
"name": "redaction",
"version": "0.0.197",
"private": true,
"license": "MIT",
"scripts": {
"affected": "nx affected",
"affected:apps": "nx affected:apps",
"affected:build": "nx affected:build",
"affected:dep-graph": "nx affected:dep-graph",
"affected:e2e": "nx affected:e2e",
"affected:libs": "nx affected:libs",
"affected:lint": "nx affected:lint",
"affected:test": "nx affected:test",
"build": "nx build",
"build-lint-all": "ng lint --project=red-ui-http --fix && ng build --project=red-ui-http && ng lint --project=red-ui --fix && ng build --project=red-ui --prod",
"dep-graph": "nx dep-graph",
"e2e": "nx e2e",
"format": "nx format:write",
"format:check": "nx format:check",
"format:write": "nx format:write",
"help": "nx help",
"postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points",
"lint": "nx workspace-lint && nx lint",
"nx": "nx",
"start": "nx serve",
"test": "nx test",
"update": "nx migrate latest",
"workspace-schematic": "nx workspace-schematic"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && ng lint --project=red-ui-http && ng lint --project=red-ui --fix"
}
},
"dependencies": {
"@angular/animations": "~11.0.1",
"@angular/cdk": "~11.0.1",
"@angular/common": "~11.0.1",
"@angular/compiler": "~11.0.1",
"@angular/core": "~11.0.1",
"@angular/forms": "~11.0.1",
"@angular/material": "~11.0.1",
"@angular/platform-browser": "~11.0.1",
"@angular/platform-browser-dynamic": "~11.0.1",
"@angular/router": "~11.0.1",
"@angular/service-worker": "~11.0.1",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@nrwl/angular": "^10.2.0",
"@pdftron/webviewer": "^7.0.1",
"file-saver": "^2.0.2",
"jwt-decode": "^3.0.0",
"keycloak-angular": "^8.0.1",
"keycloak-js": "10.0.2",
"lint-staged": "^10.5.0",
"ng2-ace-editor": "^0.3.9",
"ng2-file-upload": "^1.4.0",
"ngp-sort-pipe": "^0.0.4",
"ngx-color-picker": "^10.1.0",
"ngx-dropzone": "^2.2.2",
"ngx-toastr": "^13.0.0",
"rxjs": "~6.6.0",
"scroll-into-view-if-needed": "^2.2.26",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1100.2",
"@angular-devkit/build-ng-packagr": "~0.1002.0",
"@angular/cli": "~11.0.2",
"@angular/compiler": "~11.0.1",
"@angular/compiler-cli": "~11.0.1",
"@angular/language-service": "~11.0.2",
"@nrwl/cypress": "10.2.0",
"@nrwl/jest": "10.2.0",
"@nrwl/workspace": "10.2.0",
"@types/cypress": "^1.1.3",
"@types/jasmine": "~3.6.0",
"@types/jest": "26.0.8",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"cypress": "^5.6.0",
"cypress-file-upload": "^4.1.1",
"cypress-keycloak": "^1.5.0",
"cypress-keycloak-commands": "^1.2.0",
"cypress-localstorage-commands": "^1.2.4",
"dotenv": "6.2.0",
"eslint": "6.8.0",
"google-translate-api-browser": "^1.1.71",
"husky": "^4.3.0",
"jest": "26.2.2",
"jest-preset-angular": "8.2.1",
"lodash": "^4.17.20",
"moment": "^2.29.1",
"ng-packagr": "^10.1.2",
"prettier": "2.0.4",
"pretty-quick": "^3.1.0",
"superagent": "^6.1.0",
"superagent-promise": "^1.1.0",
"ts-jest": "26.1.4",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.0.2"
}
},
"dependencies": {
"@angular/animations": "~11.0.1",
"@angular/cdk": "~11.0.1",
"@angular/common": "~11.0.1",
"@angular/compiler": "~11.0.1",
"@angular/core": "~11.0.1",
"@angular/forms": "~11.0.1",
"@angular/material": "~11.0.1",
"@angular/platform-browser": "~11.0.1",
"@angular/platform-browser-dynamic": "~11.0.1",
"@angular/router": "~11.0.1",
"@angular/service-worker": "~11.0.1",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"@nrwl/angular": "^10.2.0",
"@pdftron/webviewer": "^7.0.1",
"file-saver": "^2.0.2",
"jwt-decode": "^3.0.0",
"keycloak-angular": "^8.0.1",
"keycloak-js": "10.0.2",
"lint-staged": "^10.5.0",
"ng2-file-upload": "^1.4.0",
"ngp-sort-pipe": "^0.0.4",
"ngx-dropzone": "^2.2.2",
"ngx-toastr": "^13.0.0",
"rxjs": "~6.6.0",
"scroll-into-view-if-needed": "^2.2.26",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1100.2",
"@angular-devkit/build-ng-packagr": "~0.1002.0",
"@angular/cli": "~11.0.2",
"@angular/compiler": "~11.0.1",
"@angular/compiler-cli": "~11.0.1",
"@angular/language-service": "~11.0.2",
"@nrwl/cypress": "10.2.0",
"@nrwl/jest": "10.2.0",
"@nrwl/workspace": "10.2.0",
"@types/cypress": "^1.1.3",
"@types/jasmine": "~3.6.0",
"@types/jest": "26.0.8",
"@types/node": "^12.11.1",
"codelyzer": "^6.0.0",
"cypress": "^5.6.0",
"cypress-file-upload": "^4.1.1",
"cypress-keycloak": "^1.5.0",
"cypress-keycloak-commands": "^1.2.0",
"cypress-localstorage-commands": "^1.2.4",
"dotenv": "6.2.0",
"eslint": "6.8.0",
"google-translate-api-browser": "^1.1.71",
"husky": "^4.3.0",
"jest": "26.2.2",
"jest-preset-angular": "8.2.1",
"lodash": "^4.17.20",
"moment": "^2.29.1",
"ng-packagr": "^10.1.2",
"prettier": "2.0.4",
"pretty-quick": "^3.1.0",
"superagent": "^6.1.0",
"superagent-promise": "^1.1.0",
"ts-jest": "26.1.4",
"ts-node": "~8.3.0",
"tslint": "~6.1.0",
"typescript": "~4.0.2"
}
}

2344
yarn.lock

File diff suppressed because it is too large Load Diff