Bulk delete file attrs

This commit is contained in:
Adina Țeudan 2021-04-13 17:04:02 +03:00
parent 7400553024
commit f78671d304
9 changed files with 83 additions and 34 deletions

View File

@ -66,9 +66,7 @@
>
</redaction-circle-button>
<ng-container *ngIf="download.inProgress">
<mat-spinner diameter="15"></mat-spinner>
</ng-container>
<mat-spinner *ngIf="download.inProgress" diameter="15"></mat-spinner>
</div>
</div>
<div class="scrollbar-placeholder"></div>

View File

@ -1,7 +1,7 @@
import { Component, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '../../../../state/app-state.service';
import { FileAttributeConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
import { FileAttributeConfig } from '@redaction/red-ui-http';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@Component({
@ -17,7 +17,6 @@ export class AddEditFileAttributeDialogComponent {
constructor(
private readonly _appStateService: AppStateService,
private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesControllerService,
public dialogRef: MatDialogRef<AddEditFileAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { fileAttribute: FileAttributeConfig; ruleSetId: string }
) {
@ -54,7 +53,6 @@ export class AddEditFileAttributeDialogComponent {
editable: !this.fileAttributeForm.get('readonly').value,
...this.fileAttributeForm.getRawValue()
};
await this._fileAttributesService.setFileAttributesConfiguration(fileAttribute, this.ruleSetId).toPromise();
this.dialogRef.close(fileAttribute);
}
}

View File

@ -1,6 +1,6 @@
<section class="dialog">
<div class="dialog-header heading-l">
{{ 'confirm-delete-file-attribute.title' | translate: { name: fileAttribute.label } }}
{{ 'confirm-delete-file-attribute.title.' + type | translate: { name: fileAttribute?.label } }}
</div>
<div class="inline-dialog-toast toast-error" *ngIf="showToast">
@ -19,15 +19,15 @@
color="primary"
[class.error]="!checkbox.value && showToast"
>
{{ 'confirm-delete-file-attribute.checkbox-' + (idx + 1) | translate }}
{{ 'confirm-delete-file-attribute.' + checkbox.label | translate }}
</mat-checkbox>
</div>
<div class="dialog-actions">
<button color="primary" mat-flat-button (click)="deleteFileAttribute()">
{{ 'confirm-delete-file-attribute.delete' | translate }}
{{ 'confirm-delete-file-attribute.delete.' + type | translate }}
</button>
<div class="all-caps-label cancel" (click)="cancel()" translate="confirm-delete-file-attribute.cancel"></div>
<div class="all-caps-label cancel" (click)="cancel()" [translate]="'confirm-delete-file-attribute.cancel.' + type"></div>
</div>
<redaction-circle-button icon="red:close" mat-dialog-close class="dialog-close"></redaction-circle-button>
</section>

View File

@ -1,6 +1,6 @@
import { Component, Inject } from '@angular/core';
import { AppStateService } from '../../../../state/app-state.service';
import { FileAttributeConfig, FileAttributesControllerService } from '@redaction/red-ui-http';
import { FileAttributeConfig } from '@redaction/red-ui-http';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@Component({
@ -10,33 +10,36 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
})
export class ConfirmDeleteFileAttributeDialogComponent {
public fileAttribute: FileAttributeConfig;
public ruleSetId: string;
public checkboxes = [{ value: false }, { value: false }];
public checkboxes = [
{ value: false, label: 'impacted-documents.' + this.type },
{ value: false, label: 'lost-details' }
];
public showToast = false;
constructor(
private readonly _appStateService: AppStateService,
private readonly _fileAttributesService: FileAttributesControllerService,
public dialogRef: MatDialogRef<ConfirmDeleteFileAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { fileAttribute: FileAttributeConfig; ruleSetId: string }
@Inject(MAT_DIALOG_DATA) public data: FileAttributeConfig
) {
this.fileAttribute = data.fileAttribute;
this.ruleSetId = data.ruleSetId;
this.fileAttribute = data;
}
public get valid() {
return this.checkboxes[0].value && this.checkboxes[1].value;
}
async deleteFileAttribute() {
public deleteFileAttribute() {
if (this.valid) {
await this._fileAttributesService.deleteFileAttributesConfiguration(this.ruleSetId, this.fileAttribute.id).toPromise();
this.dialogRef.close(true);
} else {
this.showToast = true;
}
}
public get type(): 'bulk' | 'single' {
return !this.fileAttribute ? 'bulk' : 'single';
}
public cancel() {
this.dialogRef.close();
}

View File

@ -37,6 +37,17 @@
{{ 'file-attributes-listing.table-header.title' | translate: { length: displayedAttributes.length } }}
</span>
<redaction-circle-button
*ngIf="areSomeAttributesSelected"
tooltip="file-attributes-listing.bulk-actions.delete"
type="dark-bg"
icon="red:trash"
(click)="openConfirmDeleteAttributeDialog($event)"
>
</redaction-circle-button>
<mat-spinner *ngIf="loading" diameter="15"></mat-spinner>
<div class="attributes-actions-container">
<redaction-search-input [form]="searchForm" [placeholder]="'file-attributes-listing.search'"></redaction-search-input>
<input #fileInput (change)="importCSV($event.target['files'])" class="csv-input" type="file" accept=".csv" />
@ -71,6 +82,8 @@
<redaction-table-col-name label="file-attributes-listing.table-col-names.read-only" class="flex-center"></redaction-table-col-name>
<redaction-table-col-name label="file-attributes-listing.table-col-names.csv-column"></redaction-table-col-name>
<div></div>
<div class="scrollbar-placeholder"></div>
@ -86,8 +99,8 @@
<mat-icon class="selection-icon active" *ngIf="isAttributeSelected(attribute)" svgIcon="red:radio-selected"></mat-icon>
</div>
<div>
{{ attribute.label }}
<div class="label">
<span>{{ attribute.label }}</span>
</div>
<div class="center read-only">
<mat-icon
@ -97,6 +110,9 @@
matTooltipPosition="above"
></mat-icon>
</div>
<div>
{{ attribute.csvColumnHeader }}
</div>
<div class="actions-container">
<div class="action-buttons">
<redaction-circle-button

View File

@ -1,3 +1,5 @@
@import '../../../../../assets/styles/red-mixins';
.page-header .actions {
display: flex;
justify-content: flex-end;
@ -30,7 +32,7 @@ redaction-table-col-name::ng-deep {
cdk-virtual-scroll-viewport {
::ng-deep.cdk-virtual-scroll-content-wrapper {
grid-template-columns: auto 1fr 1fr 3fr 11px;
grid-template-columns: auto 2fr 1fr 2fr 3fr 11px;
.table-item {
> div:not(.scrollbar-placeholder) {
@ -42,6 +44,10 @@ redaction-table-col-name::ng-deep {
align-items: center;
}
&.label span {
@include line-clamp(1);
}
&.read-only mat-icon {
width: 14px;
height: 34px;
@ -52,7 +58,7 @@ redaction-table-col-name::ng-deep {
&.has-scrollbar:hover {
::ng-deep.cdk-virtual-scroll-content-wrapper {
grid-template-columns: auto 1fr 1fr 3fr;
grid-template-columns: auto 2fr 1fr 2fr 3fr;
}
}
}

View File

@ -19,6 +19,7 @@ export class FileAttributesListingScreenComponent implements OnInit {
public displayedAttributes: FileAttributeConfig[] = [];
public selectedFileAttributeIds: string[] = [];
public viewReady = false;
public loading = false;
@ViewChild('fileInput') private _fileInput: ElementRef;
@ -45,14 +46,17 @@ export class FileAttributesListingScreenComponent implements OnInit {
}
private async _loadData() {
this.viewReady = false;
try {
const response = await this._fileAttributesService.getFileAttributesConfiguration(this._appStateService.activeRuleSetId).toPromise();
this.attributes = 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;
}
}
@ -74,7 +78,9 @@ export class FileAttributesListingScreenComponent implements OnInit {
public openAddEditAttributeDialog($event: MouseEvent, fileAttribute?: FileAttributeConfig) {
$event.stopPropagation();
this._dialogService.openAddEditFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async () => {
this._dialogService.openAddEditFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async (newValue: FileAttributeConfig) => {
this.loading = true;
await this._fileAttributesService.setFileAttributesConfiguration(newValue, this._appStateService.activeRuleSetId).toPromise();
await this._loadData();
});
}
@ -82,6 +88,12 @@ export class FileAttributesListingScreenComponent implements OnInit {
public openConfirmDeleteAttributeDialog($event: MouseEvent, fileAttribute?: FileAttributeConfig) {
$event.stopPropagation();
this._dialogService.openConfirmDeleteFileAttributeDialog(fileAttribute, this._appStateService.activeRuleSetId, async () => {
this.loading = true;
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._loadData();
});
}

View File

@ -166,7 +166,7 @@ export class AdminDialogService {
): MatDialogRef<ConfirmDeleteFileAttributeDialogComponent> {
const ref = this._dialog.open(ConfirmDeleteFileAttributeDialogComponent, {
...dialogConfig,
data: { fileAttribute, ruleSetId },
data: fileAttribute,
autoFocus: true
});

View File

@ -763,28 +763,44 @@
"table-header": {
"title": "{{length}} file attributes"
},
"bulk-actions": {
"delete": "Delete Selected Attributes"
},
"table-col-names": {
"name": "Name",
"created-by": "Created by",
"read-only": "Read-Only"
"read-only": "Read-Only",
"csv-column": "CSV Column"
},
"no-data": {
"title": "There are no file attributes yet."
},
"read-only": "Read-only",
"action": {
"edit": "Edit attribute",
"delete": "Delete attribute"
"edit": "Edit Attribute",
"delete": "Delete Attribute"
},
"upload-csv": "Upload File Attributes Configuration"
},
"confirm-delete-file-attribute": {
"title": "Delete {{name}}",
"title": {
"single": "Delete {{name}}",
"bulk": "Delete File Attributes"
},
"warning": "Warning: this cannot be undone!",
"delete": "Delete Attribute",
"cancel": "Keep Attribute",
"checkbox-1": "All documents it is used on will be impacted",
"checkbox-2": "All inputted details on the documents will be lost",
"delete": {
"single": "Delete Attribute",
"bulk": "Delete Attributes"
},
"cancel": {
"single": "Keep Attribute",
"bulk": "Keep Attributes"
},
"impacted-documents": {
"single": "All documents it is used on will be impacted",
"bulk": "All documents they are used on will be impacted"
},
"lost-details": "All inputted details on the documents will be lost",
"toast-error": "Please confirm that you understand the ramifications of your action!"
},
"confirm-delete-users": {