diff --git a/apps/red-ui/src/app/modules/admin/admin.module.ts b/apps/red-ui/src/app/modules/admin/admin.module.ts
index 2c12acb71..3f31c7f61 100644
--- a/apps/red-ui/src/app/modules/admin/admin.module.ts
+++ b/apps/red-ui/src/app/modules/admin/admin.module.ts
@@ -32,6 +32,7 @@ import { AddEditUserDialogComponent } from './dialogs/add-edit-user-dialog/add-e
import { UsersStatsComponent } from './components/users-stats/users-stats.component';
import { ConfirmDeleteUsersDialogComponent } from './dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component';
import { FileAttributesCsvImportDialogComponent } from './dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
+import { ActiveFieldsListingComponent } from './dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component';
const dialogs = [
AddEditRuleSetDialogComponent,
@@ -41,7 +42,8 @@ const dialogs = [
EditColorDialogComponent,
SmtpAuthDialogComponent,
AddEditUserDialogComponent,
- ConfirmDeleteUsersDialogComponent
+ ConfirmDeleteUsersDialogComponent,
+ FileAttributesCsvImportDialogComponent
];
const screens = [
@@ -66,12 +68,14 @@ const components = [
ComboChartComponent,
ComboSeriesVerticalComponent,
UsersStatsComponent,
+ ActiveFieldsListingComponent,
+
...dialogs,
...screens
];
@NgModule({
- declarations: [...components, FileAttributesCsvImportDialogComponent],
+ declarations: [...components],
providers: [AdminDialogService],
imports: [CommonModule, SharedModule, AdminRoutingModule, AceEditorModule, NgxChartsModule, ColorPickerModule]
})
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.html b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.html
new file mode 100644
index 000000000..a33c01a53
--- /dev/null
+++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.html
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ field.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ 'file-attributes-csv-import.types.' + type | translate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.scss b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.scss
new file mode 100644
index 000000000..42b2d5706
--- /dev/null
+++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.scss
@@ -0,0 +1,84 @@
+@import '../../../../../../assets/styles/red-variables';
+
+redaction-table-col-name::ng-deep {
+ > div {
+ padding: 0 13px 0 10px !important;
+
+ &.name {
+ padding-left: 22px !important;
+ }
+ }
+}
+
+.header-item {
+ padding: 0 24px 0 10px;
+ box-shadow: none;
+ border-top: 1px solid $separator;
+
+ .all-caps-label {
+ margin-right: 10px;
+ }
+
+ redaction-circle-button {
+ margin-right: 2px;
+ }
+
+ .separator {
+ margin-left: 14px;
+ background-color: $separator;
+ width: 1px;
+ height: 30px;
+ margin-right: 16px;
+ }
+}
+
+cdk-virtual-scroll-viewport {
+ height: calc(100% - 80px);
+
+ ::ng-deep.cdk-virtual-scroll-content-wrapper {
+ grid-template-columns: 30px minmax(0, 25vw) 150px auto auto auto 11px;
+
+ .table-item {
+ > div {
+ height: 50px;
+
+ &:not(.scrollbar-placeholder) {
+ padding-left: 10px;
+
+ &.center {
+ align-items: center;
+ }
+ }
+
+ &.name {
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-start;
+
+ &:not(.editing) {
+ padding-left: 22px;
+ }
+
+ .edit-name-button {
+ display: none;
+ }
+
+ redaction-circle-button:first-of-type {
+ margin-left: 7px;
+ margin-right: 2px;
+ }
+ }
+ }
+
+ &:hover .name .edit-name-button {
+ display: block;
+ }
+ }
+ }
+
+ &.has-scrollbar:hover {
+ ::ng-deep.cdk-virtual-scroll-content-wrapper {
+ grid-template-columns: 30px minmax(0, 25vw) 150px auto auto auto;
+ }
+ }
+}
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.ts
new file mode 100644
index 000000000..84c01afd9
--- /dev/null
+++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/active-fields-listing/active-fields-listing.component.ts
@@ -0,0 +1,40 @@
+import { Component, EventEmitter, Injector, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
+import { BaseListingComponent } from '../../../../shared/base/base-listing.component';
+import { Field } from '../file-attributes-csv-import-dialog.component';
+
+@Component({
+ selector: 'redaction-active-fields-listing',
+ templateUrl: './active-fields-listing.component.html',
+ styleUrls: ['./active-fields-listing.component.scss']
+})
+export class ActiveFieldsListingComponent extends BaseListingComponent implements OnChanges {
+ @Input() public allEntities: Field[];
+ @Output() public allEntitiesChange = new EventEmitter();
+ @Output() public setHoveredColumn = new EventEmitter();
+ @Output() public toggleFieldActive = new EventEmitter();
+
+ protected readonly _selectionKey = 'csvColumn';
+
+ constructor(protected readonly _injector: Injector) {
+ super(_injector);
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.allEntities) {
+ this.displayedEntities = this.allEntities;
+ this._updateSelection();
+ }
+ }
+
+ public deactivateSelection() {
+ this.allEntities = [...this.allEntities.filter((field) => !this.isEntitySelected(field))];
+ this.allEntitiesChange.emit(this.allEntities);
+ this.selectedEntitiesIds = [];
+ }
+
+ public setAttributeForSelection(attribute: string, value: any) {
+ for (const csvColumn of this.selectedEntitiesIds) {
+ this.allEntities.find((f) => f.csvColumn === csvColumn)[attribute] = value;
+ }
+ }
+}
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.html b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.html
index 443b5c7c3..2131fdde6 100644
--- a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.html
+++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.html
@@ -90,7 +90,7 @@
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.scss b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.scss
index fdf45c402..88d6fc0d2 100644
--- a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.scss
+++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.scss
@@ -114,6 +114,7 @@
> .left {
width: 375px;
+ min-width: 375px;
background: $grey-2;
.csv-header-pill-content {
@@ -198,88 +199,5 @@
> .content-container {
width: 100%;
-
- redaction-table-col-name::ng-deep {
- > div {
- padding: 0 13px 0 10px !important;
-
- &.name {
- padding-left: 22px !important;
- }
- }
- }
-
- .header-item {
- padding: 0 24px 0 10px;
- box-shadow: none;
- border-top: 1px solid $separator;
-
- .all-caps-label {
- margin-right: 10px;
- }
-
- redaction-circle-button {
- margin-right: 2px;
- }
-
- .separator {
- margin-left: 14px;
- background-color: $separator;
- width: 1px;
- height: 30px;
- margin-right: 16px;
- }
- }
-
- cdk-virtual-scroll-viewport {
- height: calc(100% - 80px);
-
- ::ng-deep.cdk-virtual-scroll-content-wrapper {
- grid-template-columns: 30px minmax(0, 25vw) 150px auto auto auto 11px;
-
- .table-item {
- > div {
- height: 50px;
-
- &:not(.scrollbar-placeholder) {
- padding-left: 10px;
-
- &.center {
- align-items: center;
- }
- }
-
- &.name {
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
-
- &:not(.editing) {
- padding-left: 22px;
- }
-
- .edit-name-button {
- display: none;
- }
-
- redaction-circle-button:first-of-type {
- margin-left: 7px;
- margin-right: 2px;
- }
- }
- }
-
- &:hover .name .edit-name-button {
- display: block;
- }
- }
- }
-
- &.has-scrollbar:hover {
- ::ng-deep.cdk-virtual-scroll-content-wrapper {
- grid-template-columns: 30px minmax(0, 25vw) 150px auto auto auto;
- }
- }
- }
}
}
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts
index 45a7afd1c..64fa985b3 100644
--- a/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts
+++ b/apps/red-ui/src/app/modules/admin/dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component.ts
@@ -1,13 +1,13 @@
-import { Component, Inject, ViewChild } from '@angular/core';
-import { AbstractControl, FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms';
+import { Component, Inject, Injector, ViewChild } from '@angular/core';
+import { AbstractControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
import { AppStateService } from '../../../../state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import * as Papa from 'papaparse';
import { FileAttributesControllerService } from '@redaction/red-ui-http';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
-import { debounce } from '../../../../utils/debounce';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
+import { BaseListingComponent } from '../../../shared/base/base-listing.component';
enum FieldType {
Text = 'Text',
@@ -15,7 +15,7 @@ enum FieldType {
Date = 'Date'
}
-interface Field {
+export interface Field {
csvColumn: string;
name: string;
type: FieldType;
@@ -30,17 +30,16 @@ interface Field {
templateUrl: './file-attributes-csv-import-dialog.component.html',
styleUrls: ['./file-attributes-csv-import-dialog.component.scss']
})
-export class FileAttributesCsvImportDialogComponent {
+export class FileAttributesCsvImportDialogComponent extends BaseListingComponent {
+ protected readonly _searchKey = 'csvColumn';
+
public csvFile: File;
public ruleSetId: string;
public parseResult: { data: any[]; errors: any[]; meta: any; fields: Field[] };
public hoveredColumn: string;
public activeFields: Field[] = [];
- public selectedFields: string[] = [];
public baseConfigForm: FormGroup;
public isSearchOpen = false;
- public searchForm: FormGroup;
- public filteredFields: Field[];
public previewExpanded = true;
public filteredKeyOptions: Observable;
public keepPreview = false;
@@ -50,18 +49,15 @@ export class FileAttributesCsvImportDialogComponent {
constructor(
private readonly _appStateService: AppStateService,
- private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesControllerService: FileAttributesControllerService,
public dialogRef: MatDialogRef,
+ protected readonly _injector: Injector,
@Inject(MAT_DIALOG_DATA) public data: { csv: File; ruleSetId: string }
) {
+ super(_injector);
this.csvFile = data.csv;
this.ruleSetId = data.ruleSetId;
- this.searchForm = this._formBuilder.group({
- query: ['']
- });
-
this.baseConfigForm = this._formBuilder.group({
filenameMappingColumnHeaderName: ['', [Validators.required, this._autocompleteStringValidator()]],
delimiter: [undefined, Validators.required],
@@ -69,13 +65,6 @@ export class FileAttributesCsvImportDialogComponent {
});
this._readFile();
-
- this.searchForm.valueChanges.subscribe((value) => this._executeSearch(value));
- }
-
- @debounce(200)
- private _executeSearch(value: { query: string }) {
- this.filteredFields = this.parseResult.fields.filter((f) => f.csvColumn.toLowerCase().includes(value.query.toLowerCase()));
}
private _autocompleteStringValidator(): ValidatorFn {
@@ -98,12 +87,14 @@ export class FileAttributesCsvImportDialogComponent {
if (!this.baseConfigForm.get('delimiter').value) {
this.baseConfigForm.patchValue({ delimiter: this.parseResult.meta.delimiter });
}
- this.parseResult.fields = this.parseResult.meta.fields.map((field) => this._buildAttribute(field));
- this.filteredFields = [...this.parseResult.fields];
+ this.allEntities = this.parseResult.meta.fields.map((field) => this._buildAttribute(field));
+ this.displayedEntities = [...this.allEntities];
this.filteredKeyOptions = this.baseConfigForm.get('filenameMappingColumnHeaderName').valueChanges.pipe(
startWith(''),
- map((value: string) => this.parseResult.meta.fields.filter((field) => field.toLowerCase().indexOf(value.toLowerCase()) !== -1))
+ map((value: string) =>
+ this.allEntities.filter((field) => field.csvColumn.toLowerCase().indexOf(value.toLowerCase()) !== -1).map((field) => field.csvColumn)
+ )
);
});
reader.readAsText(this.csvFile, this.baseConfigForm.get('encoding').value);
@@ -137,9 +128,6 @@ export class FileAttributesCsvImportDialogComponent {
} else {
this.activeFields.splice(this.activeFields.indexOf(field), 1);
this.activeFields = [...this.activeFields];
- if (this.isFieldSelected(field.csvColumn)) {
- this.toggleFieldSelected(field.csvColumn);
- }
}
}
@@ -157,52 +145,11 @@ export class FileAttributesCsvImportDialogComponent {
}
public activateAll() {
- this.activeFields = [...this.parseResult.fields];
+ this.activeFields = [...this.allEntities];
}
public deactivateAll() {
this.activeFields = [];
- this.selectedFields = [];
- }
-
- public toggleFieldSelected(field: string) {
- const idx = this.selectedFields.indexOf(field);
- if (idx === -1) {
- this.selectedFields.push(field);
- } else {
- this.selectedFields.splice(idx, 1);
- }
- }
-
- public toggleSelectAll() {
- if (this.areSomeFieldsSelected) {
- this.selectedFields = [];
- } else {
- this.selectedFields = this.activeFields.map((field) => field.csvColumn);
- }
- }
-
- public get areAllFieldsSelected() {
- return this.activeFields.length !== 0 && this.selectedFields.length === this.activeFields.length;
- }
-
- public get areSomeFieldsSelected() {
- return this.selectedFields.length > 0;
- }
-
- public isFieldSelected(field: string) {
- return this.selectedFields.indexOf(field) !== -1;
- }
-
- public deactivateSelection() {
- this.activeFields = [...this.activeFields.filter((field) => !this.isFieldSelected(field.csvColumn))];
- this.selectedFields = [];
- }
-
- public setAttributeForSelection(attribute: string, value: any) {
- for (const csvColumn of this.selectedFields) {
- this.activeFields.find((f) => f.csvColumn === csvColumn)[attribute] = value;
- }
}
public async save() {
diff --git a/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.html
index 95b6c0fa5..a91352feb 100644
--- a/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.html
+++ b/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.html
@@ -15,7 +15,7 @@
@@ -36,7 +36,7 @@
-
+
diff --git a/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts
index e4f1f461e..b34fa75cf 100644
--- a/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts
+++ b/apps/red-ui/src/app/modules/admin/screens/default-colors/default-colors-screen.component.ts
@@ -1,41 +1,35 @@
-import { Component } from '@angular/core';
+import { Component, Injector } from '@angular/core';
import { AppStateService } from '../../../../state/app-state.service';
import { Colors, DictionaryControllerService } from '@redaction/red-ui-http';
import { ActivatedRoute } from '@angular/router';
-import { SortingOption, SortingService } from '../../../../services/sorting.service';
import { PermissionsService } from '../../../../services/permissions.service';
import { AdminDialogService } from '../../services/admin-dialog.service';
+import { BaseListingComponent } from '../../../shared/base/base-listing.component';
@Component({
selector: 'redaction-default-colors-screen',
templateUrl: './default-colors-screen.component.html',
styleUrls: ['./default-colors-screen.component.scss']
})
-export class DefaultColorsScreenComponent {
+export class DefaultColorsScreenComponent extends BaseListingComponent<{ key: string; value: string }> {
+ protected readonly _sortKey = 'default-colors';
+
public viewReady = false;
private _colorsObj: Colors;
- public colors: { key: string; value: string }[] = [];
constructor(
private readonly _appStateService: AppStateService,
private readonly _activatedRoute: ActivatedRoute,
private readonly _dictionaryControllerService: DictionaryControllerService,
- private readonly _sortingService: SortingService,
private readonly _dialogService: AdminDialogService,
- public readonly permissionsService: PermissionsService
+ public readonly permissionsService: PermissionsService,
+ protected readonly _injector: Injector
) {
+ super(_injector);
this._appStateService.activateRuleSet(_activatedRoute.snapshot.params.ruleSetId);
this._loadColors();
}
- public get sortingOption(): SortingOption {
- return this._sortingService.getSortingOption('default-colors');
- }
-
- public toggleSort($event) {
- this._sortingService.toggleSort('default-colors', $event);
- }
-
public async loadRuleSetsData(): Promise
{
await this._appStateService.loadAllRuleSets();
}
@@ -46,7 +40,7 @@ export class DefaultColorsScreenComponent {
.toPromise()
.then((data) => {
this._colorsObj = data;
- this.colors = Object.keys(data).map((key) => ({
+ this.allEntities = Object.keys(data).map((key) => ({
key,
value: data[key]
}));
diff --git a/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html
index f99b01c39..ab3fd4b2e 100644
--- a/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html
+++ b/apps/red-ui/src/app/modules/admin/screens/dictionary-listing/dictionary-listing-screen.component.html
@@ -17,13 +17,13 @@
-
+
- {{ 'dictionary-listing.table-header.title' | translate: { length: displayedDictionaries.length } }}
+ {{ 'dictionary-listing.table-header.title' | translate: { length: displayedEntities.length } }}
@@ -48,7 +48,7 @@
-