mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-15 14:03:06 +00:00
CST-9639: Fixed error on control remove, fixed cancel button behavior, fixed bad state of access control tab on load, fixed translations, added jsdocs
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end">
|
||||||
<button class="btn btn-outline-primary mr-3" (click)="reset()">
|
<button class="btn btn-outline-primary mr-3" (click)="reset()">
|
||||||
{{ 'access-control-reset' | translate }}
|
{{ 'access-control-cancel' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary" [disabled]="!canExport()" (click)="submit()">
|
<button class="btn btn-primary" [disabled]="!canExport()" (click)="submit()">
|
||||||
{{ 'access-control-execute' | translate }}
|
{{ 'access-control-execute' | translate }}
|
||||||
|
@@ -1,22 +1,22 @@
|
|||||||
<form #ngForm="ngForm">
|
<form #ngForm="ngForm">
|
||||||
<div *ngIf="mode === 'replace' && allControlsAreEmpty && ngForm.enabled"
|
<div *ngIf="showWarning" class="alert alert-warning">
|
||||||
class="alert alert-warning">
|
|
||||||
{{'access-control-no-access-conditions-warning-message' | translate}}
|
{{'access-control-no-access-conditions-warning-message' | translate}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-container *ngFor="let control of form.accessControls; let i = index">
|
<ng-container *ngFor="let control of form.accessControls; trackBy: trackById">
|
||||||
<div ngModelGroup="access-control-item-{{i}}" class="access-control-item mt-3">
|
<div #ngModelGroup="ngModelGroup" ngModelGroup="access-control-item-{{control.id}}" class="access-control-item mt-3">
|
||||||
|
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column">
|
||||||
<div>
|
<div>
|
||||||
<label for="accesscontroloption-{{i}}">
|
<label for="accesscontroloption-{{control.id}}">
|
||||||
{{'access-control-option-label' | translate}}
|
{{'access-control-option-label' | translate}}
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="accesscontroloption-{{i}}"
|
id="accesscontroloption-{{control.id}}"
|
||||||
|
[disabled]="ngForm.disabled"
|
||||||
[(ngModel)]="control.itemName"
|
[(ngModel)]="control.itemName"
|
||||||
(ngModelChange)="accessControlChanged(control, $event)"
|
(ngModelChange)="accessControlChanged(control, $event)"
|
||||||
name="itemName-{{i}}"
|
name="itemName-{{control.id}}"
|
||||||
class="form-control">
|
class="form-control">
|
||||||
<option value=""></option>
|
<option value=""></option>
|
||||||
<option *ngFor="let option of dropdownOptions" [value]="option.name">
|
<option *ngFor="let option of dropdownOptions" [value]="option.name">
|
||||||
@@ -29,16 +29,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="control.hasStartDate" class="mt-3">
|
<div *ngIf="control.hasStartDate" class="mt-3">
|
||||||
<label for="accesscontrolstartdate-{{i}}">
|
<label for="accesscontrolstartdate-{{control.id}}">
|
||||||
{{'access-control-option-start-date' | translate}}
|
{{'access-control-option-start-date' | translate}}
|
||||||
</label>
|
</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input
|
<input
|
||||||
id="accesscontrolstartdate-{{i}}"
|
id="accesscontrolstartdate-{{control.id}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="yyyy-mm-dd"
|
placeholder="yyyy-mm-dd"
|
||||||
[(ngModel)]="control.startDate"
|
[(ngModel)]="control.startDate"
|
||||||
name="startDate-{{i}}"
|
name="startDate-{{control.id}}"
|
||||||
[minDate]="control.maxStartDate | toDate"
|
[minDate]="control.maxStartDate | toDate"
|
||||||
ngbDatepicker
|
ngbDatepicker
|
||||||
#d="ngbDatepicker"
|
#d="ngbDatepicker"
|
||||||
@@ -57,16 +57,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="control.hasEndDate" class="mt-3">
|
<div *ngIf="control.hasEndDate" class="mt-3">
|
||||||
<label for="accesscontrolenddate-{{i}}">
|
<label for="accesscontrolenddate-{{control.id}}">
|
||||||
{{'access-control-option-end-date' | translate}}
|
{{'access-control-option-end-date' | translate}}
|
||||||
</label>
|
</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input
|
<input
|
||||||
id="accesscontrolenddate-{{i}}"
|
id="accesscontrolenddate-{{control.id}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="yyyy-mm-dd"
|
placeholder="yyyy-mm-dd"
|
||||||
[(ngModel)]="control.endDate"
|
[(ngModel)]="control.endDate"
|
||||||
name="endDate-{{i}}"
|
name="endDate-{{control.id}}"
|
||||||
[maxDate]="control.maxEndDate | toDate"
|
[maxDate]="control.maxEndDate | toDate"
|
||||||
ngbDatepicker
|
ngbDatepicker
|
||||||
#d1="ngbDatepicker"
|
#d1="ngbDatepicker"
|
||||||
@@ -90,8 +90,8 @@
|
|||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
|
|
||||||
<button type="button" class="btn btn-outline-danger"
|
<button type="button" class="btn btn-outline-danger"
|
||||||
[disabled]="ngForm.disabled"
|
[disabled]="ngForm.disabled || form.accessControls.length === 1"
|
||||||
(click)="removeAccessControlItem(i)">
|
(click)="removeAccessControlItem(ngModelGroup, control.id)">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import {Component, Input, OnInit, ViewChild} from '@angular/core';
|
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 {AccessesConditionOption} from '../../../core/config/models/config-accesses-conditions-options.model';
|
||||||
import {dateToISOFormat} from '../../date.util';
|
import {dateToISOFormat} from '../../date.util';
|
||||||
|
|
||||||
@@ -17,14 +17,13 @@ export class AccessControlArrayFormComponent implements OnInit {
|
|||||||
@ViewChild('ngForm', {static: true}) ngForm!: NgForm;
|
@ViewChild('ngForm', {static: true}) ngForm!: NgForm;
|
||||||
|
|
||||||
form: { accessControls: AccessControlItem[] } = {
|
form: { accessControls: AccessControlItem[] } = {
|
||||||
accessControls: []
|
accessControls: [emptyAccessControlItem()] // Start with one empty access control item
|
||||||
};
|
};
|
||||||
|
|
||||||
ngOnInit(): void {
|
formDisabled = true;
|
||||||
this.addAccessControlItem();
|
|
||||||
|
|
||||||
// Disable the form by default
|
ngOnInit(): void {
|
||||||
setTimeout(() => this.disable(), 0);
|
this.disable(); // Disable the form by default
|
||||||
}
|
}
|
||||||
|
|
||||||
get allControlsAreEmpty() {
|
get allControlsAreEmpty() {
|
||||||
@@ -32,29 +31,31 @@ export class AccessControlArrayFormComponent implements OnInit {
|
|||||||
.every(x => x.itemName === null || x.itemName === '');
|
.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.
|
* Add a new access control item to the form.
|
||||||
* Start and end date are disabled by default.
|
* Start and end date are disabled by default.
|
||||||
* @param itemName The name of the item to add
|
* @param itemName The name of the item to add
|
||||||
*/
|
*/
|
||||||
addAccessControlItem(itemName: string = null) {
|
addAccessControlItem(itemName: string = null) {
|
||||||
this.form.accessControls.push({
|
this.form.accessControls = [
|
||||||
itemName,
|
...this.form.accessControls,
|
||||||
startDate: null,
|
{...emptyAccessControlItem(), itemName}
|
||||||
hasStartDate: false,
|
];
|
||||||
maxStartDate: null,
|
|
||||||
endDate: null,
|
|
||||||
hasEndDate: false,
|
|
||||||
maxEndDate: null,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an access control item from the form.
|
* Remove an access control item from the form.
|
||||||
|
* @param ngModelGroup
|
||||||
* @param index
|
* @param index
|
||||||
*/
|
*/
|
||||||
removeAccessControlItem(index: number) {
|
removeAccessControlItem(ngModelGroup: NgModelGroup, id: number) {
|
||||||
this.form.accessControls.splice(index, 1);
|
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() {
|
reset() {
|
||||||
this.form.accessControls = [];
|
this.form.accessControls = [];
|
||||||
|
|
||||||
|
// Add an empty access control item by default
|
||||||
|
this.addAccessControlItem();
|
||||||
|
|
||||||
|
this.disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable the form.
|
* Disable the form.
|
||||||
* This will be used to disable the form from the parent component.
|
* 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.
|
* Enable the form.
|
||||||
* This will be used to enable the form from the parent component.
|
* 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) {
|
accessControlChanged(control: AccessControlItem, selectedItem: string) {
|
||||||
const item = this.dropdownOptions
|
const item = this.dropdownOptions
|
||||||
@@ -105,9 +117,16 @@ export class AccessControlArrayFormComponent implements OnInit {
|
|||||||
control.maxEndDate = item?.maxEndDate || null;
|
control.maxEndDate = item?.maxEndDate || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackById(index: number, item: AccessControlItem) {
|
||||||
|
return item.id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface AccessControlItem {
|
export interface AccessControlItem {
|
||||||
|
id: number; // will be used only locally
|
||||||
|
|
||||||
itemName: string | null;
|
itemName: string | null;
|
||||||
|
|
||||||
hasStartDate?: boolean;
|
hasStartDate?: boolean;
|
||||||
@@ -118,3 +137,16 @@ export interface AccessControlItem {
|
|||||||
endDate: string | null;
|
endDate: string | null;
|
||||||
maxEndDate?: 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);
|
||||||
|
@@ -153,12 +153,12 @@
|
|||||||
<hr *ngIf="showSubmit">
|
<hr *ngIf="showSubmit">
|
||||||
|
|
||||||
<div *ngIf="showSubmit" class="d-flex justify-content-end">
|
<div *ngIf="showSubmit" class="d-flex justify-content-end">
|
||||||
<button class="btn btn-outline-primary mr-3" (click)="reset()">
|
<button class="btn btn-outline-primary mr-3" (click)="reset()" type="button">
|
||||||
{{ 'access-control-cancel' | translate }}
|
{{ 'access-control-cancel' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary"
|
<button class="btn btn-primary"
|
||||||
[disabled]="!state.item.toggleStatus && !state.bitstream.toggleStatus"
|
[disabled]="!state.item.toggleStatus && !state.bitstream.toggleStatus"
|
||||||
(click)="submit()">
|
(click)="submit()" type="submit">
|
||||||
{{ 'access-control-execute' | translate }}
|
{{ 'access-control-execute' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -21,6 +21,9 @@ export interface BulkAccessPayload {
|
|||||||
itemAccess: any;
|
itemAccess: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service is used to create a payload file and execute the bulk access control script
|
||||||
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class BulkAccessControlService {
|
export class BulkAccessControlService {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -28,10 +31,13 @@ export class BulkAccessControlService {
|
|||||||
private router: Router,
|
private router: Router,
|
||||||
private scriptService: ScriptDataService,
|
private scriptService: ScriptDataService,
|
||||||
private translationService: TranslateService
|
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) {
|
createPayloadFile(payload: BulkAccessPayload) {
|
||||||
const content = convertToBulkAccessControlFileModel(payload);
|
const content = convertToBulkAccessControlFileModel(payload);
|
||||||
|
|
||||||
@@ -48,6 +54,11 @@ export class BulkAccessControlService {
|
|||||||
return { url, file };
|
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<boolean> {
|
executeScript(uuids: string[], file: File): Observable<boolean> {
|
||||||
console.log('execute', { uuids, file });
|
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 => {
|
export const convertToBulkAccessControlFileModel = (payload: { state: AccessControlFormState, bitstreamAccess: AccessCondition[], itemAccess: AccessCondition[] }): BulkAccessControlFileModel => {
|
||||||
let finalPayload: BulkAccessControlFileModel = {};
|
let finalPayload: BulkAccessControlFileModel = {};
|
||||||
|
|
||||||
|
@@ -225,7 +225,9 @@
|
|||||||
|
|
||||||
"admin.registries.schema.title": "Metadata Schema Registry",
|
"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",
|
"admin.access-control.bulk-access": "Bulk Access Management",
|
||||||
|
|
||||||
@@ -5399,14 +5401,14 @@
|
|||||||
|
|
||||||
"access-control-option-label": "Access condition type",
|
"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": "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": "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",
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user