CSV import search by column name
This commit is contained in:
parent
f78671d304
commit
05bde93f49
@ -25,13 +25,13 @@ import { ConfirmDeleteFileAttributeDialogComponent } from './dialogs/confirm-del
|
||||
import { EditColorDialogComponent } from './dialogs/edit-color-dialog/edit-color-dialog.component';
|
||||
import { ComboChartComponent, ComboSeriesVerticalComponent } from './components/combo-chart';
|
||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||
import { AdminDialogService } from './services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from './services/admin-dialog.service';
|
||||
import { SmtpConfigScreenComponent } from './screens/smtp-config/smtp-config-screen.component';
|
||||
import { SmtpAuthDialogComponent } from './dialogs/smtp-auth-dialog/smtp-auth-dialog.component';
|
||||
import { AddEditUserDialogComponent } from './dialogs/add-edit-user-dialog/add-edit-user-dialog.component';
|
||||
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 './screens/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
|
||||
import { FileAttributesCsvImportDialogComponent } from './dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
|
||||
|
||||
const dialogs = [
|
||||
AddEditRuleSetDialogComponent,
|
||||
|
||||
@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { PermissionsService } from '../../../../services/permissions.service';
|
||||
import { AppStateService } from '../../../../state/app-state.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-rule-set-actions',
|
||||
|
||||
@ -53,19 +53,37 @@
|
||||
}}</span>
|
||||
<span class="all-caps-label">{{ 'file-attributes-csv-import.selected' | translate: { value: activeFields.length } }}</span>
|
||||
</div>
|
||||
<div class="quick-activation">
|
||||
<span class="all-caps-label primary pointer" (click)="activateAll()" translate="file-attributes-csv-import.quick-activation.all"></span>
|
||||
<span
|
||||
class="all-caps-label primary pointer"
|
||||
(click)="deactivateAll()"
|
||||
translate="file-attributes-csv-import.quick-activation.none"
|
||||
></span>
|
||||
<div class="actions">
|
||||
<redaction-circle-button
|
||||
icon="red:search"
|
||||
(click)="isSearchOpen = !isSearchOpen"
|
||||
[attr.aria-expanded]="isSearchOpen"
|
||||
></redaction-circle-button>
|
||||
<div class="quick-activation">
|
||||
<span
|
||||
class="all-caps-label primary pointer"
|
||||
(click)="activateAll()"
|
||||
translate="file-attributes-csv-import.quick-activation.all"
|
||||
></span>
|
||||
<span
|
||||
class="all-caps-label primary pointer"
|
||||
(click)="deactivateAll()"
|
||||
translate="file-attributes-csv-import.quick-activation.none"
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="csv-header-pill-content">
|
||||
<div class="search-input-container" *ngIf="isSearchOpen">
|
||||
<redaction-search-input
|
||||
[form]="searchForm"
|
||||
placeholder="file-attributes-csv-import.search.placeholder"
|
||||
width="full"
|
||||
></redaction-search-input>
|
||||
</div>
|
||||
<div class="csv-header-pill-content" [class.search-open]="isSearchOpen">
|
||||
<div
|
||||
class="csv-header-pill"
|
||||
*ngFor="let field of relevantFields"
|
||||
*ngFor="let field of filteredFields"
|
||||
(mouseenter)="hoveredColumn = field.csvColumn"
|
||||
(mouseleave)="hoveredColumn = undefined"
|
||||
(click)="toggleFieldActive(field)"
|
||||
@ -47,7 +47,8 @@
|
||||
|
||||
.csv-part {
|
||||
display: flex;
|
||||
max-height: calc(90vh - 251px);
|
||||
min-height: calc(90vh - 240px);
|
||||
max-height: calc(90vh - 240px);
|
||||
|
||||
.csv-part-header {
|
||||
height: 50px;
|
||||
@ -60,16 +61,31 @@
|
||||
justify-content: space-between;
|
||||
padding: 0 16px;
|
||||
|
||||
> :not(.quick-activation) > *:not(:last-child)::after {
|
||||
> div:first-child > *:not(:last-child)::after {
|
||||
content: '-';
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.quick-activation > :not(:last-child) {
|
||||
margin-right: 10px;
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.quick-activation {
|
||||
margin-left: 12px;
|
||||
|
||||
> :not(:last-child) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-input-container {
|
||||
background-color: $white;
|
||||
border-bottom: 1px solid $separator;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.csv-part-content {
|
||||
overflow: auto;
|
||||
@include no-scroll-bar;
|
||||
@ -110,6 +126,10 @@
|
||||
height: calc(100% - 58px);
|
||||
@include no-scroll-bar;
|
||||
|
||||
&.search-open {
|
||||
height: calc(100% - 58px - 51px);
|
||||
}
|
||||
|
||||
.csv-header-pill {
|
||||
min-height: 32px;
|
||||
margin: 6px auto;
|
||||
@ -5,6 +5,7 @@ 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';
|
||||
|
||||
enum FieldType {
|
||||
Text = 'Text',
|
||||
@ -35,6 +36,9 @@ export class FileAttributesCsvImportDialogComponent implements OnInit {
|
||||
public activeFields: Field[] = [];
|
||||
public selectedFields: string[] = [];
|
||||
public baseConfigForm: FormGroup;
|
||||
public isSearchOpen = false;
|
||||
public searchForm: FormGroup;
|
||||
public filteredFields: Field[];
|
||||
|
||||
@ViewChild(CdkVirtualScrollViewport, { static: false }) cdkVirtualScrollViewport: CdkVirtualScrollViewport;
|
||||
|
||||
@ -48,6 +52,10 @@ export class FileAttributesCsvImportDialogComponent implements OnInit {
|
||||
this.csvFile = data.csv;
|
||||
this.ruleSetId = data.ruleSetId;
|
||||
|
||||
this.searchForm = this._formBuilder.group({
|
||||
query: ['']
|
||||
});
|
||||
|
||||
this.baseConfigForm = this._formBuilder.group({
|
||||
filenameMappingColumnHeaderName: [undefined, Validators.required],
|
||||
delimiter: [undefined, Validators.required],
|
||||
@ -55,10 +63,8 @@ export class FileAttributesCsvImportDialogComponent implements OnInit {
|
||||
});
|
||||
|
||||
this._readFile();
|
||||
}
|
||||
|
||||
get relevantFields() {
|
||||
return this.parseResult?.fields.filter((f) => this.getEntries(f.csvColumn) > 0);
|
||||
this.searchForm.valueChanges.subscribe((value) => this._executeSearch(value));
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -70,6 +76,11 @@ export class FileAttributesCsvImportDialogComponent implements OnInit {
|
||||
}, 500);
|
||||
}
|
||||
|
||||
@debounce(200)
|
||||
private _executeSearch(value: { query: string }) {
|
||||
this.filteredFields = this.parseResult.fields.filter((f) => f.csvColumn.toLowerCase().includes(value.query.toLowerCase()));
|
||||
}
|
||||
|
||||
private _readFile() {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', async (event) => {
|
||||
@ -82,7 +93,7 @@ export class FileAttributesCsvImportDialogComponent implements OnInit {
|
||||
this.baseConfigForm.patchValue({ delimiter: this.parseResult.meta.delimiter });
|
||||
}
|
||||
this.parseResult.fields = this.parseResult.meta.fields.map((field) => this._buildAttribute(field));
|
||||
console.log(this.parseResult);
|
||||
this.filteredFields = [...this.parseResult.fields];
|
||||
});
|
||||
reader.readAsText(this.csvFile, this.baseConfigForm.get('encoding').value);
|
||||
}
|
||||
@ -4,7 +4,7 @@ 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.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-default-colors-screen',
|
||||
|
||||
@ -9,7 +9,7 @@ import { PermissionsService } from '../../../../services/permissions.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounce } from '../../../../utils/debounce';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AdminDialogService } from '../../services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dictionary-listing-screen',
|
||||
|
||||
@ -11,7 +11,7 @@ import { Observable } from 'rxjs';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { ComponentHasChanges } from '../../../../guards/can-deactivate.guard';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { AdminDialogService } from '../../services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
declare var ace;
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import { AppStateService } from '../../../../state/app-state.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { debounce } from '../../../../utils/debounce';
|
||||
import { SortingOption, SortingService } from '../../../../services/sorting.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-attributes-listing-screen',
|
||||
|
||||
@ -6,7 +6,7 @@ import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounce } from '../../../../utils/debounce';
|
||||
import { RuleSetModel } from '@redaction/red-ui-http';
|
||||
import { UserPreferenceService } from '../../../../services/user-preference.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-rule-sets-listing-screen',
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PermissionsService } from '../../../../services/permissions.service';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { AdminDialogService } from '../../services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { SmtpConfigurationControllerService, SMTPConfigurationModel } from '@redaction/red-ui-http';
|
||||
import { NotificationService, NotificationType } from '../../../../services/notification.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
@ -4,7 +4,7 @@ import { UserService } from '../../../../services/user.service';
|
||||
import { RuleSetModel, User, UserControllerService } from '@redaction/red-ui-http';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounce } from '../../../../utils/debounce';
|
||||
import { AdminDialogService } from '../../services/admin-dialog-service.service';
|
||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DoughnutChartConfig } from '../../../shared/components/simple-doughnut-chart/simple-doughnut-chart.component';
|
||||
import { TranslateChartService } from '../../../../services/translate-chart.service';
|
||||
|
||||
@ -24,7 +24,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { SmtpAuthDialogComponent } from '../dialogs/smtp-auth-dialog/smtp-auth-dialog.component';
|
||||
import { AddEditUserDialogComponent } from '../dialogs/add-edit-user-dialog/add-edit-user-dialog.component';
|
||||
import { ConfirmDeleteUsersDialogComponent } from '../dialogs/confirm-delete-users-dialog/confirm-delete-users-dialog.component';
|
||||
import { FileAttributesCsvImportDialogComponent } from '../screens/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
|
||||
import { FileAttributesCsvImportDialogComponent } from '../dialogs/file-attributes-csv-import-dialog/file-attributes-csv-import-dialog.component';
|
||||
|
||||
const largeDialogConfig = {
|
||||
width: '90vw',
|
||||
@ -1,5 +1,5 @@
|
||||
<form [formGroup]="form">
|
||||
<div class="red-input-group" [style.width]="width + 'px'" [style.max-width]="width + 'px'">
|
||||
<div class="red-input-group" [style.width]="computedWidth" [style.max-width]="computedWidth">
|
||||
<input [placeholder]="placeholder | translate" class="with-icon mt-0" formControlName="query" name="query" type="text" />
|
||||
<mat-icon *ngIf="!hasContent" class="icon-right" svgIcon="red:search"></mat-icon>
|
||||
<mat-icon *ngIf="hasContent" class="icon-right pointer" svgIcon="red:close" (click)="clearContent()"></mat-icon>
|
||||
|
||||
@ -9,7 +9,7 @@ import { FormGroup } from '@angular/forms';
|
||||
export class SearchInputComponent implements OnInit {
|
||||
@Input() form: FormGroup;
|
||||
@Input() placeholder: string;
|
||||
@Input() width = 250;
|
||||
@Input() width: number | 'full' = 250;
|
||||
|
||||
constructor() {}
|
||||
|
||||
@ -22,4 +22,8 @@ export class SearchInputComponent implements OnInit {
|
||||
public clearContent() {
|
||||
this.form.patchValue({ query: '' });
|
||||
}
|
||||
|
||||
public get computedWidth() {
|
||||
return this.width === 'full' ? '100%' : `${this.width}px`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1160,6 +1160,9 @@
|
||||
"selected": "{{value}} selected",
|
||||
"csv-column": "CSV Column",
|
||||
"no-hovered-column": "Preview CSV column by hovering the entry.",
|
||||
"search": {
|
||||
"placeholder": "Search by column name..."
|
||||
},
|
||||
"table-header": {
|
||||
"title": "{{length}} file attributes",
|
||||
"actions": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user