diff --git a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html index 2c7929dc1..1872fac50 100644 --- a/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html +++ b/apps/red-ui/src/app/components/downloads-list-screen/downloads-list-screen.component.html @@ -66,9 +66,7 @@ > - - - +
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts index efc1fb506..2e4580cfb 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component.ts @@ -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, @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); } } diff --git a/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.html b/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.html index 2af43a9c1..4c3b0ac62 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.html @@ -1,6 +1,6 @@
- {{ 'confirm-delete-file-attribute.title' | translate: { name: fileAttribute.label } }} + {{ 'confirm-delete-file-attribute.title.' + type | translate: { name: fileAttribute?.label } }}
@@ -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 }}
-
+
diff --git a/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.ts b/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.ts index 8e86022bc..ddcf589ce 100644 --- a/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/dialogs/confirm-delete-file-attribute-dialog/confirm-delete-file-attribute-dialog.component.ts @@ -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, - @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(); } diff --git a/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.html index 9bfee854f..1e0b16e56 100644 --- a/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.html @@ -37,6 +37,17 @@ {{ 'file-attributes-listing.table-header.title' | translate: { length: displayedAttributes.length } }} + + + + +
@@ -71,6 +82,8 @@ + +
@@ -86,8 +99,8 @@
-
- {{ attribute.label }} +
+ {{ attribute.label }}
+
+ {{ attribute.csvColumnHeader }} +
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; } } } diff --git a/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts index e94ea6dc5..eb5368be3 100644 --- a/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/file-attributes-listing/file-attributes-listing-screen.component.ts @@ -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(); }); } diff --git a/apps/red-ui/src/app/modules/admin/services/admin-dialog-service.service.ts b/apps/red-ui/src/app/modules/admin/services/admin-dialog-service.service.ts index db245ee60..9d10aead4 100644 --- a/apps/red-ui/src/app/modules/admin/services/admin-dialog-service.service.ts +++ b/apps/red-ui/src/app/modules/admin/services/admin-dialog-service.service.ts @@ -166,7 +166,7 @@ export class AdminDialogService { ): MatDialogRef { const ref = this._dialog.open(ConfirmDeleteFileAttributeDialogComponent, { ...dialogConfig, - data: { fileAttribute, ruleSetId }, + data: fileAttribute, autoFocus: true }); diff --git a/apps/red-ui/src/assets/i18n/en.json b/apps/red-ui/src/assets/i18n/en.json index 9af7236e2..15c1308a7 100644 --- a/apps/red-ui/src/assets/i18n/en.json +++ b/apps/red-ui/src/assets/i18n/en.json @@ -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": {