Refactored file attributes listing

This commit is contained in:
Adina Țeudan 2021-04-19 22:37:22 +03:00
parent 6783c04c97
commit 271e8b6501
3 changed files with 28 additions and 89 deletions

View File

@ -15,18 +15,13 @@
<div class="select-all-container">
<div
(click)="toggleSelectAll()"
[class.active]="areAllAttributesSelected"
[class.active]="areAllEntitiesSelected"
class="select-oval always-visible"
*ngIf="!areAllAttributesSelected && !areSomeAttributesSelected"
*ngIf="!areAllEntitiesSelected && !areSomeEntitiesSelected"
></div>
<mat-icon *ngIf="areAllEntitiesSelected" (click)="toggleSelectAll()" class="selection-icon active" svgIcon="red:radio-selected"></mat-icon>
<mat-icon
*ngIf="areAllAttributesSelected"
(click)="toggleSelectAll()"
class="selection-icon active"
svgIcon="red:radio-selected"
></mat-icon>
<mat-icon
*ngIf="areSomeAttributesSelected && !areAllAttributesSelected"
*ngIf="areSomeEntitiesSelected && !areAllEntitiesSelected"
(click)="toggleSelectAll()"
class="selection-icon"
svgIcon="red:radio-indeterminate"
@ -34,11 +29,11 @@
</div>
<span class="all-caps-label">
{{ 'file-attributes-listing.table-header.title' | translate: { length: displayedAttributes.length } }}
{{ 'file-attributes-listing.table-header.title' | translate: { length: displayedEntities.length } }}
</span>
<redaction-circle-button
*ngIf="areSomeAttributesSelected"
*ngIf="areSomeEntitiesSelected"
tooltip="file-attributes-listing.bulk-actions.delete"
type="dark-bg"
icon="red:trash"
@ -69,7 +64,7 @@
</div>
</div>
<div [class.no-data]="!attributes.length" class="table-header" redactionSyncWidth="table-item">
<div [class.no-data]="!allEntities.length" class="table-header" redactionSyncWidth="table-item">
<div class="select-oval-placeholder"></div>
<redaction-table-col-name
@ -77,7 +72,7 @@
(toggleSort)="toggleSort($event)"
[activeSortingOption]="sortingOption"
[withSort]="true"
column="name"
column="label"
></redaction-table-col-name>
<redaction-table-col-name label="file-attributes-listing.table-col-names.read-only" class="flex-center"></redaction-table-col-name>
@ -89,20 +84,20 @@
<div class="scrollbar-placeholder"></div>
</div>
<redaction-empty-state *ngIf="!attributes.length" screen="file-attributes-listing" icon="red:attribute"></redaction-empty-state>
<redaction-empty-state *ngIf="!allEntities.length" screen="file-attributes-listing" icon="red:attribute"></redaction-empty-state>
<redaction-empty-state
*ngIf="attributes.length && !displayedAttributes.length"
*ngIf="allEntities.length && !displayedEntities.length"
screen="file-attributes-listing"
type="no-match"
></redaction-empty-state>
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
<!-- Table lines -->
<div class="table-item" *cdkVirtualFor="let attribute of displayedAttributes | sortBy: sortingOption.order:sortingOption.column">
<div class="pr-0" (click)="toggleAttributeSelected($event, attribute)">
<div *ngIf="!isAttributeSelected(attribute)" class="select-oval"></div>
<mat-icon class="selection-icon active" *ngIf="isAttributeSelected(attribute)" svgIcon="red:radio-selected"></mat-icon>
<div class="table-item" *cdkVirtualFor="let attribute of displayedEntities | sortBy: sortingOption.order:sortingOption.column">
<div class="pr-0" (click)="toggleEntitySelected($event, attribute)">
<div *ngIf="!isEntitySelected(attribute)" class="select-oval"></div>
<mat-icon class="selection-icon active" *ngIf="isEntitySelected(attribute)" svgIcon="red:radio-selected"></mat-icon>
</div>
<div class="label">

View File

@ -1,23 +1,22 @@
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { Component, ElementRef, Injector, OnInit, ViewChild } from '@angular/core';
import { PermissionsService } from '../../../../services/permissions.service';
import { FormBuilder, FormGroup } from '@angular/forms';
import { FileAttributeConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
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';
import { BaseListingComponent } from '../../../shared/base/base-listing.component';
@Component({
selector: 'redaction-file-attributes-listing-screen',
templateUrl: './file-attributes-listing-screen.component.html',
styleUrls: ['./file-attributes-listing-screen.component.scss']
})
export class FileAttributesListingScreenComponent implements OnInit {
public searchForm: FormGroup;
public attributes: FileAttributeConfig[] = [];
public displayedAttributes: FileAttributeConfig[] = [];
public selectedFileAttributeIds: string[] = [];
export class FileAttributesListingScreenComponent extends BaseListingComponent<FileAttributeConfig> implements OnInit {
protected readonly _searchKey = 'label';
protected readonly _selectionKey = 'id';
protected readonly _sortKey = 'file-attributes-listing';
public allEntities: FileAttributeConfig[] = [];
public viewReady = false;
public loading = false;
@ -25,20 +24,14 @@ export class FileAttributesListingScreenComponent implements OnInit {
constructor(
public readonly permissionsService: PermissionsService,
public readonly _sortingService: SortingService,
private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesControllerService,
private readonly _appStateService: AppStateService,
private readonly _activatedRoute: ActivatedRoute,
private readonly _dialogService: AdminDialogService
private readonly _dialogService: AdminDialogService,
protected readonly _injector: Injector
) {
super(_injector);
this._appStateService.activateRuleSet(_activatedRoute.snapshot.params.ruleSetId);
this.searchForm = this._formBuilder.group({
query: ['']
});
this.searchForm.valueChanges.subscribe((value) => this._executeSearch(value));
}
async ngOnInit() {
@ -48,34 +41,15 @@ export class FileAttributesListingScreenComponent implements OnInit {
private async _loadData() {
try {
const response = await this._fileAttributesService.getFileAttributesConfiguration(this._appStateService.activeRuleSetId).toPromise();
this.attributes = response?.fileAttributeConfigs || [];
this.allEntities = response?.fileAttributeConfigs || [];
} catch (e) {
} finally {
// Remove potentially deleted items
this.selectedFileAttributeIds = this.selectedFileAttributeIds.filter((id) => !!this.attributes.find((attr) => attr.id === id));
this._executeSearch();
this.viewReady = true;
this.loading = false;
}
}
public get sortingOption(): SortingOption {
return this._sortingService.getSortingOption('file-attributes-listing');
}
public toggleSort($event) {
this._sortingService.toggleSort('file-attributes-listing', $event);
}
@debounce(200)
private _executeSearch(value?: { query: string }) {
if (!value) {
value = { query: this.searchForm.get('query').value };
}
this.displayedAttributes = this.attributes.filter((attribute) => attribute.label.toLowerCase().includes(value.query.toLowerCase()));
}
public openAddEditAttributeDialog($event: MouseEvent, fileAttribute?: FileAttributeConfig) {
$event.stopPropagation();
this._dialogService.openAddEditFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async (newValue: FileAttributeConfig) => {
@ -92,42 +66,12 @@ export class FileAttributesListingScreenComponent implements OnInit {
if (!!fileAttribute) {
await this._fileAttributesService.deleteFileAttribute(this._appStateService.activeRuleSetId, fileAttribute.id).toPromise();
} else {
await this._fileAttributesService.deleteFileAttributes(this.selectedFileAttributeIds, this._appStateService.activeRuleSetId).toPromise();
await this._fileAttributesService.deleteFileAttributes(this.selectedEntitiesIds, this._appStateService.activeRuleSetId).toPromise();
}
await this._loadData();
});
}
public toggleAttributeSelected($event: MouseEvent, attribute: FileAttributeConfig) {
$event.stopPropagation();
const idx = this.selectedFileAttributeIds.indexOf(attribute.id);
if (idx === -1) {
this.selectedFileAttributeIds.push(attribute.id);
} else {
this.selectedFileAttributeIds.splice(idx, 1);
}
}
public toggleSelectAll() {
if (this.areSomeAttributesSelected) {
this.selectedFileAttributeIds = [];
} else {
this.selectedFileAttributeIds = this.displayedAttributes.map((a) => a.id);
}
}
public get areAllAttributesSelected() {
return this.displayedAttributes.length !== 0 && this.selectedFileAttributeIds.length === this.displayedAttributes.length;
}
public get areSomeAttributesSelected() {
return this.selectedFileAttributeIds.length > 0;
}
public isAttributeSelected(attribute: FileAttributeConfig) {
return this.selectedFileAttributeIds.indexOf(attribute.id) !== -1;
}
public importCSV(files: FileList | File[]) {
const csvFile = files[0];
this._fileInput.nativeElement.value = null;

View File

@ -17,7 +17,7 @@ export class SortingService {
'dictionary-listing': { column: 'label', order: 'asc' },
'rule-sets-listing': { column: 'name', order: 'asc' },
'default-colors': { column: 'key', order: 'asc' },
'file-attributes-listing': { column: 'name', order: 'asc' }
'file-attributes-listing': { column: 'label', order: 'asc' }
};
constructor() {}