diff --git a/src/app/access-control/bulk-access/bulk-access.component.html b/src/app/access-control/bulk-access/bulk-access.component.html index aa6c82e133..382caf85f4 100644 --- a/src/app/access-control/bulk-access/bulk-access.component.html +++ b/src/app/access-control/bulk-access/bulk-access.component.html @@ -7,7 +7,7 @@
diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts index 4e2fd55967..f08534e8f9 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts @@ -1,5 +1,5 @@ import {Component, Input, OnInit, ViewChild} from '@angular/core'; -import {NgForm} from '@angular/forms'; +import {NgForm, NgModelGroup} from '@angular/forms'; import {AccessesConditionOption} from '../../../core/config/models/config-accesses-conditions-options.model'; import {dateToISOFormat} from '../../date.util'; @@ -17,14 +17,13 @@ export class AccessControlArrayFormComponent implements OnInit { @ViewChild('ngForm', {static: true}) ngForm!: NgForm; form: { accessControls: AccessControlItem[] } = { - accessControls: [] + accessControls: [emptyAccessControlItem()] // Start with one empty access control item }; - ngOnInit(): void { - this.addAccessControlItem(); + formDisabled = true; - // Disable the form by default - setTimeout(() => this.disable(), 0); + ngOnInit(): void { + this.disable(); // Disable the form by default } get allControlsAreEmpty() { @@ -32,29 +31,31 @@ export class AccessControlArrayFormComponent implements OnInit { .every(x => x.itemName === null || x.itemName === ''); } + get showWarning() { + return this.mode === 'replace' && this.allControlsAreEmpty && !this.formDisabled; + } + /** * Add a new access control item to the form. * Start and end date are disabled by default. * @param itemName The name of the item to add */ addAccessControlItem(itemName: string = null) { - this.form.accessControls.push({ - itemName, - startDate: null, - hasStartDate: false, - maxStartDate: null, - endDate: null, - hasEndDate: false, - maxEndDate: null, - }); + this.form.accessControls = [ + ...this.form.accessControls, + {...emptyAccessControlItem(), itemName} + ]; } /** * Remove an access control item from the form. + * @param ngModelGroup * @param index */ - removeAccessControlItem(index: number) { - this.form.accessControls.splice(index, 1); + removeAccessControlItem(ngModelGroup: NgModelGroup, id: number) { + this.ngForm.removeFormGroup(ngModelGroup); + + this.form.accessControls = this.form.accessControls.filter(item => item.id !== id); } /** @@ -77,19 +78,30 @@ export class AccessControlArrayFormComponent implements OnInit { */ reset() { this.form.accessControls = []; + + // Add an empty access control item by default + this.addAccessControlItem(); + + this.disable(); } /** * Disable the form. * This will be used to disable the form from the parent component. */ - disable = () => this.ngForm.control.disable(); + disable = () => { + this.ngForm.form.disable(); + this.formDisabled = true; + }; /** * Enable the form. * This will be used to enable the form from the parent component. */ - enable = () => this.ngForm.control.enable(); + enable = () => { + this.ngForm.form.enable(); + this.formDisabled = false; + }; accessControlChanged(control: AccessControlItem, selectedItem: string) { const item = this.dropdownOptions @@ -105,9 +117,16 @@ export class AccessControlArrayFormComponent implements OnInit { control.maxEndDate = item?.maxEndDate || null; } + trackById(index: number, item: AccessControlItem) { + return item.id; + } + } + export interface AccessControlItem { + id: number; // will be used only locally + itemName: string | null; hasStartDate?: boolean; @@ -118,3 +137,16 @@ export interface AccessControlItem { endDate: string | null; maxEndDate?: string | null; } + +const emptyAccessControlItem = (): AccessControlItem => ({ + id: randomID(), + itemName: null, + startDate: null, + hasStartDate: false, + maxStartDate: null, + endDate: null, + hasEndDate: false, + maxEndDate: null, +}); + +const randomID = () => Math.floor(Math.random() * 1000000); diff --git a/src/app/shared/access-control-form-container/access-control-form-container.component.html b/src/app/shared/access-control-form-container/access-control-form-container.component.html index afee07139f..a5173d10d7 100644 --- a/src/app/shared/access-control-form-container/access-control-form-container.component.html +++ b/src/app/shared/access-control-form-container/access-control-form-container.component.html @@ -153,12 +153,12 @@
-
diff --git a/src/app/shared/access-control-form-container/bulk-access-control.service.ts b/src/app/shared/access-control-form-container/bulk-access-control.service.ts index 51eba4275d..6fb6b62532 100644 --- a/src/app/shared/access-control-form-container/bulk-access-control.service.ts +++ b/src/app/shared/access-control-form-container/bulk-access-control.service.ts @@ -21,6 +21,9 @@ export interface BulkAccessPayload { itemAccess: any; } +/** + * This service is used to create a payload file and execute the bulk access control script + */ @Injectable({ providedIn: 'root' }) export class BulkAccessControlService { constructor( @@ -28,10 +31,13 @@ export class BulkAccessControlService { private router: Router, private scriptService: ScriptDataService, private translationService: TranslateService - ) { - - } + ) {} + /** + * Create a payload file from the given payload and return the file and the url to the file + * The created file will be used as input for the bulk access control script + * @param payload The payload to create the file from + */ createPayloadFile(payload: BulkAccessPayload) { const content = convertToBulkAccessControlFileModel(payload); @@ -48,6 +54,11 @@ export class BulkAccessControlService { return { url, file }; } + /** + * Execute the bulk access control script with the given uuids and file + * @param uuids + * @param file + */ executeScript(uuids: string[], file: File): Observable { console.log('execute', { uuids, file }); @@ -80,6 +91,10 @@ export class BulkAccessControlService { } } +/** + * Convert the given payload to a BulkAccessControlFileModel + * @param payload + */ export const convertToBulkAccessControlFileModel = (payload: { state: AccessControlFormState, bitstreamAccess: AccessCondition[], itemAccess: AccessCondition[] }): BulkAccessControlFileModel => { let finalPayload: BulkAccessControlFileModel = {}; diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 223c2fce27..a454131175 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -225,7 +225,9 @@ "admin.registries.schema.title": "Metadata Schema Registry", + "admin.access-control.bulk-access.breadcrumbs": "Bulk Access Management", + "administrativeBulkAccess.search.results.head": "Search Results", "admin.access-control.bulk-access": "Bulk Access Management", @@ -5399,14 +5401,14 @@ "access-control-option-label": "Access condition type", - "access-control-option-note": "Select an access condition to apply on the bitstream once the item is deposited", + "access-control-option-note": "Choose an access condition to apply to selected objects.", "access-control-option-start-date": "Grant access from", - "access-control-option-start-date-note": "Select the date from which the relate access condition is applied", + "access-control-option-start-date-note": "Select the date from which the related access condition is applied", "access-control-option-end-date": "Grant access until", - "access-control-option-end-date-note": "Select the date until which the relate access condition is applied", + "access-control-option-end-date-note": "Select the date until which the related access condition is applied", }