mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
[CST-9636] Added unit tests and the logic to create file object from payload
This commit is contained in:
@@ -1,3 +1,92 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
Access control page!!!
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<p>
|
||||||
|
This form allows you to perform changes to the access condition of all the items owned by collection under this community.
|
||||||
|
Changes can be performed on the access condition for the metadata (item) or for the content (bitstream).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12 col-md-6 border-right">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<h4 class="mb-0 mr-4">Item's Metadata</h4>
|
||||||
|
<ui-switch [(ngModel)]="state.item.toggleStatus"></ui-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12 col-md-3">Mode</div>
|
||||||
|
<div class="col-12 col-md-8">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="itemMode" id="itemReplace" value="replace" [(ngModel)]="state.item.accessMode">
|
||||||
|
<label class="form-check-label" for="itemReplace">Replace access conditions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="itemMode" id="itemAdd" value="add" [(ngModel)]="state.item.accessMode">
|
||||||
|
<label class="form-check-label" for="itemAdd">Add to existing ones</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
<h5>Access conditions</h5>
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
You have not specified any access conditions, the new items access conditions will be inherited from the owning collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ds-access-control-array-form
|
||||||
|
#itemAccessCmp
|
||||||
|
[dropdownOptions]="(dropdownData$ | async)?.itemAccessConditionOptions || []">
|
||||||
|
</ds-access-control-array-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<h4 class="mb-0 mr-4">Bitstreams</h4>
|
||||||
|
<ui-switch [(ngModel)]="state.bitstream.toggleStatus"></ui-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12 col-md-3">Mode</div>
|
||||||
|
<div class="col-12 col-md-8">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="bitstreamMode" id="bitstreamReplace" value="replace" [(ngModel)]="state.bitstream.accessMode">
|
||||||
|
<label class="form-check-label" for="bitstreamReplace">Replace access conditions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="bitstreamMode" id="bitstreamAdd" value="add" [(ngModel)]="state.bitstream.accessMode">
|
||||||
|
<label class="form-check-label" for="bitstreamAdd">Add to existing ones</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
<h5>Access conditions</h5>
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
You have not specified any access conditions, the new items access conditions will be inherited from the owning collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ds-access-control-array-form
|
||||||
|
#bitstreamAccessCmp
|
||||||
|
[dropdownOptions]="(dropdownData$ | async)?.bitstreamAccessConditionOptions || []">
|
||||||
|
</ds-access-control-array-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<button class="btn btn-lg btn-outline-primary mr-3" (click)="reset()">Reset</button>
|
||||||
|
<button class="btn btn-lg btn-primary" (click)="submit()">Execute</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,37 +1,56 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { shareReplay } from 'rxjs';
|
||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import {
|
||||||
import { ActivatedRoute } from '@angular/router';
|
AccessControlArrayFormComponent
|
||||||
import { first, map } from 'rxjs/operators';
|
} from '../../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
|
import { CollectionAccessControlService } from './collection-access-control.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-collection-access-control',
|
selector: 'ds-collection-access-control',
|
||||||
templateUrl: './collection-access-control.component.html',
|
templateUrl: './collection-access-control.component.html',
|
||||||
styleUrls: ['./collection-access-control.component.scss']
|
styleUrls: ['./collection-access-control.component.scss'],
|
||||||
|
providers: [CollectionAccessControlService]
|
||||||
})
|
})
|
||||||
export class CollectionAccessControlComponent<TDomain extends DSpaceObject> implements OnInit {
|
export class CollectionAccessControlComponent implements OnInit {
|
||||||
|
|
||||||
/**
|
@ViewChild('bitstreamAccessCmp', { static: true }) bitstreamAccessCmp: AccessControlArrayFormComponent;
|
||||||
* The initial DSO object
|
@ViewChild('itemAccessCmp', { static: true }) itemAccessCmp: AccessControlArrayFormComponent;
|
||||||
*/
|
|
||||||
public dsoRD$: Observable<RemoteData<TDomain>>;
|
constructor(private collectionAccessControlService: CollectionAccessControlService) {}
|
||||||
|
|
||||||
|
state = initialState;
|
||||||
|
|
||||||
|
dropdownData$ = this.collectionAccessControlService.dropdownData$.pipe(
|
||||||
|
shareReplay(1)
|
||||||
|
);
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize instance variables
|
|
||||||
*
|
|
||||||
* @param {ActivatedRoute} route
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
private route: ActivatedRoute
|
|
||||||
) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
reset() {
|
||||||
* Initialize the component, setting up the collection
|
this.bitstreamAccessCmp.reset();
|
||||||
*/
|
this.itemAccessCmp.reset();
|
||||||
ngOnInit(): void {
|
this.state = initialState;
|
||||||
this.dsoRD$ = this.route.parent.parent.data.pipe(first(), map((data) => data.dso));
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
const bitstreamAccess = this.bitstreamAccessCmp.getValue();
|
||||||
|
const itemAccess = this.itemAccessCmp.getValue();
|
||||||
|
|
||||||
|
console.log('bitstreamAccess', bitstreamAccess);
|
||||||
|
console.log('itemAccess', itemAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
item: {
|
||||||
|
toggleStatus: false,
|
||||||
|
accessMode: '',
|
||||||
|
},
|
||||||
|
bitstream: {
|
||||||
|
toggleStatus: false,
|
||||||
|
accessMode: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
@@ -0,0 +1,54 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { AccessControlItem } from '../../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
import { Observable, of } from 'rxjs';
|
||||||
|
|
||||||
|
export interface AccessControlDropdownDataResponse {
|
||||||
|
id: string;
|
||||||
|
itemAccessConditionOptions: AccessControlItem[];
|
||||||
|
bitstreamAccessConditionOptions: AccessControlItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CollectionAccessControlService {
|
||||||
|
dropdownData$: Observable<AccessControlDropdownDataResponse> = of(accessControlDropdownData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessControlDropdownData: AccessControlDropdownDataResponse = {
|
||||||
|
'id': 'default',
|
||||||
|
'itemAccessConditionOptions': [
|
||||||
|
{
|
||||||
|
'name': 'openaccess'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'administrator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'embargo',
|
||||||
|
'hasStartDate': true,
|
||||||
|
'maxStartDate': '2018-06-24T00:40:54.970+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'lease',
|
||||||
|
'hasEndDate': true,
|
||||||
|
'maxEndDate': '2017-12-24T00:40:54.970+0000'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'bitstreamAccessConditionOptions': [
|
||||||
|
{
|
||||||
|
'name': 'openaccess'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'administrator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'embargo',
|
||||||
|
'hasStartDate': true,
|
||||||
|
'maxStartDate': '2018-06-24T00:40:54.970+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'lease',
|
||||||
|
'hasEndDate': true,
|
||||||
|
'maxEndDate': '2017-12-24T00:40:54.970+0000'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
@@ -14,6 +14,10 @@ import { ResourcePoliciesModule } from '../../shared/resource-policies/resource-
|
|||||||
import { FormModule } from '../../shared/form/form.module';
|
import { FormModule } from '../../shared/form/form.module';
|
||||||
import { ComcolModule } from '../../shared/comcol/comcol.module';
|
import { ComcolModule } from '../../shared/comcol/comcol.module';
|
||||||
import { CollectionAccessControlComponent } from './collection-access-control/collection-access-control.component';
|
import { CollectionAccessControlComponent } from './collection-access-control/collection-access-control.component';
|
||||||
|
import {
|
||||||
|
AccessControlArrayFormModule
|
||||||
|
} from '../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
import { UiSwitchModule } from 'ngx-ui-switch';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module that contains all components related to the Edit Collection page administrator functionality
|
* Module that contains all components related to the Edit Collection page administrator functionality
|
||||||
@@ -27,6 +31,8 @@ import { CollectionAccessControlComponent } from './collection-access-control/co
|
|||||||
ResourcePoliciesModule,
|
ResourcePoliciesModule,
|
||||||
FormModule,
|
FormModule,
|
||||||
ComcolModule,
|
ComcolModule,
|
||||||
|
AccessControlArrayFormModule,
|
||||||
|
UiSwitchModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
EditCollectionPageComponent,
|
EditCollectionPageComponent,
|
||||||
|
@@ -1 +1,92 @@
|
|||||||
<p>community-access-control works!</p>
|
<div class="container">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<p>
|
||||||
|
This form allows you to perform changes to the access condition of all the items owned by collection under this community.
|
||||||
|
Changes can be performed on the access condition for the metadata (item) or for the content (bitstream).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12 col-md-6 border-right">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<h4 class="mb-0 mr-4">Item's Metadata</h4>
|
||||||
|
<ui-switch [(ngModel)]="state.item.toggleStatus"></ui-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12 col-md-3">Mode</div>
|
||||||
|
<div class="col-12 col-md-8">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="itemMode" id="itemReplace" value="replace" [(ngModel)]="state.item.accessMode">
|
||||||
|
<label class="form-check-label" for="itemReplace">Replace access conditions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="itemMode" id="itemAdd" value="add" [(ngModel)]="state.item.accessMode">
|
||||||
|
<label class="form-check-label" for="itemAdd">Add to existing ones</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
<h5>Access conditions</h5>
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
You have not specified any access conditions, the new items access conditions will be inherited from the owning collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ds-access-control-array-form
|
||||||
|
#itemAccessCmp
|
||||||
|
[dropdownOptions]="(dropdownData$ | async)?.itemAccessConditionOptions || []">
|
||||||
|
</ds-access-control-array-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<h4 class="mb-0 mr-4">Bitstreams</h4>
|
||||||
|
<ui-switch [(ngModel)]="state.bitstream.toggleStatus"></ui-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12 col-md-3">Mode</div>
|
||||||
|
<div class="col-12 col-md-8">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="bitstreamMode" id="bitstreamReplace" value="replace" [(ngModel)]="state.bitstream.accessMode">
|
||||||
|
<label class="form-check-label" for="bitstreamReplace">Replace access conditions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="bitstreamMode" id="bitstreamAdd" value="add" [(ngModel)]="state.bitstream.accessMode">
|
||||||
|
<label class="form-check-label" for="bitstreamAdd">Add to existing ones</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
<h5>Access conditions</h5>
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
You have not specified any access conditions, the new items access conditions will be inherited from the owning collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ds-access-control-array-form
|
||||||
|
#bitstreamAccessCmp
|
||||||
|
[dropdownOptions]="(dropdownData$ | async)?.bitstreamAccessConditionOptions || []">
|
||||||
|
</ds-access-control-array-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<button class="btn btn-lg btn-outline-primary mr-3" (click)="reset()">Reset</button>
|
||||||
|
<button class="btn btn-lg btn-primary" (click)="submit()">Execute</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@@ -1,15 +1,56 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import { CommunityAccessControlService } from './community-access-control.service';
|
||||||
|
import { shareReplay } from 'rxjs';
|
||||||
|
import {
|
||||||
|
AccessControlArrayFormComponent
|
||||||
|
} from '../../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-community-access-control',
|
selector: 'ds-community-access-control',
|
||||||
templateUrl: './community-access-control.component.html',
|
templateUrl: './community-access-control.component.html',
|
||||||
styleUrls: ['./community-access-control.component.scss']
|
styleUrls: ['./community-access-control.component.scss'],
|
||||||
|
providers: [CommunityAccessControlService]
|
||||||
})
|
})
|
||||||
export class CommunityAccessControlComponent implements OnInit {
|
export class CommunityAccessControlComponent implements OnInit {
|
||||||
|
|
||||||
constructor() { }
|
@ViewChild('bitstreamAccessCmp', { static: true }) bitstreamAccessCmp: AccessControlArrayFormComponent;
|
||||||
|
@ViewChild('itemAccessCmp', { static: true }) itemAccessCmp: AccessControlArrayFormComponent;
|
||||||
|
|
||||||
|
constructor(private communityAccessControlService: CommunityAccessControlService) {}
|
||||||
|
|
||||||
|
state = initialState;
|
||||||
|
|
||||||
|
dropdownData$ = this.communityAccessControlService.dropdownData$.pipe(
|
||||||
|
shareReplay(1)
|
||||||
|
);
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.bitstreamAccessCmp.reset();
|
||||||
|
this.itemAccessCmp.reset();
|
||||||
|
this.state = initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
const bitstreamAccess = this.bitstreamAccessCmp.getValue();
|
||||||
|
const itemAccess = this.itemAccessCmp.getValue();
|
||||||
|
|
||||||
|
console.log('bitstreamAccess', bitstreamAccess);
|
||||||
|
console.log('itemAccess', itemAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
item: {
|
||||||
|
toggleStatus: false,
|
||||||
|
accessMode: '',
|
||||||
|
},
|
||||||
|
bitstream: {
|
||||||
|
toggleStatus: false,
|
||||||
|
accessMode: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
@@ -0,0 +1,54 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { AccessControlItem } from '../../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
import { Observable, of } from 'rxjs';
|
||||||
|
|
||||||
|
export interface AccessControlDropdownDataResponse {
|
||||||
|
id: string;
|
||||||
|
itemAccessConditionOptions: AccessControlItem[];
|
||||||
|
bitstreamAccessConditionOptions: AccessControlItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CommunityAccessControlService {
|
||||||
|
dropdownData$: Observable<AccessControlDropdownDataResponse> = of(accessControlDropdownData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessControlDropdownData: AccessControlDropdownDataResponse = {
|
||||||
|
'id': 'default',
|
||||||
|
'itemAccessConditionOptions': [
|
||||||
|
{
|
||||||
|
'name': 'openaccess'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'administrator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'embargo',
|
||||||
|
'hasStartDate': true,
|
||||||
|
'maxStartDate': '2018-06-24T00:40:54.970+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'lease',
|
||||||
|
'hasEndDate': true,
|
||||||
|
'maxEndDate': '2017-12-24T00:40:54.970+0000'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'bitstreamAccessConditionOptions': [
|
||||||
|
{
|
||||||
|
'name': 'openaccess'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'administrator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'embargo',
|
||||||
|
'hasStartDate': true,
|
||||||
|
'maxStartDate': '2018-06-24T00:40:54.970+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'lease',
|
||||||
|
'hasEndDate': true,
|
||||||
|
'maxEndDate': '2017-12-24T00:40:54.970+0000'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
@@ -11,6 +11,10 @@ import { CommunityFormModule } from '../community-form/community-form.module';
|
|||||||
import { ResourcePoliciesModule } from '../../shared/resource-policies/resource-policies.module';
|
import { ResourcePoliciesModule } from '../../shared/resource-policies/resource-policies.module';
|
||||||
import { ComcolModule } from '../../shared/comcol/comcol.module';
|
import { ComcolModule } from '../../shared/comcol/comcol.module';
|
||||||
import { CommunityAccessControlComponent } from './community-access-control/community-access-control.component';
|
import { CommunityAccessControlComponent } from './community-access-control/community-access-control.component';
|
||||||
|
import { UiSwitchModule } from 'ngx-ui-switch';
|
||||||
|
import {
|
||||||
|
AccessControlArrayFormModule
|
||||||
|
} from '../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module that contains all components related to the Edit Community page administrator functionality
|
* Module that contains all components related to the Edit Community page administrator functionality
|
||||||
@@ -23,6 +27,8 @@ import { CommunityAccessControlComponent } from './community-access-control/comm
|
|||||||
CommunityFormModule,
|
CommunityFormModule,
|
||||||
ComcolModule,
|
ComcolModule,
|
||||||
ResourcePoliciesModule,
|
ResourcePoliciesModule,
|
||||||
|
UiSwitchModule,
|
||||||
|
AccessControlArrayFormModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
EditCommunityPageComponent,
|
EditCommunityPageComponent,
|
||||||
|
@@ -39,6 +39,10 @@ import { IdentifierDataComponent } from '../../shared/object-list/identifier-dat
|
|||||||
import { ItemRegisterDoiComponent } from './item-register-doi/item-register-doi.component';
|
import { ItemRegisterDoiComponent } from './item-register-doi/item-register-doi.component';
|
||||||
import { DsoSharedModule } from '../../dso-shared/dso-shared.module';
|
import { DsoSharedModule } from '../../dso-shared/dso-shared.module';
|
||||||
import { ItemAccessControlComponent } from './item-access-control/item-access-control.component';
|
import { ItemAccessControlComponent } from './item-access-control/item-access-control.component';
|
||||||
|
import {
|
||||||
|
AccessControlArrayFormModule
|
||||||
|
} from '../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
import { UiSwitchModule } from 'ngx-ui-switch';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,6 +60,8 @@ import { ItemAccessControlComponent } from './item-access-control/item-access-co
|
|||||||
NgbModule,
|
NgbModule,
|
||||||
ItemVersionsModule,
|
ItemVersionsModule,
|
||||||
DsoSharedModule,
|
DsoSharedModule,
|
||||||
|
AccessControlArrayFormModule,
|
||||||
|
UiSwitchModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
EditItemPageComponent,
|
EditItemPageComponent,
|
||||||
|
@@ -1 +1,110 @@
|
|||||||
<p>item-access-control works!</p>
|
<div class="container">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<p>
|
||||||
|
This form allows you to perform changes to the access condition of all the items owned by collection under this community.
|
||||||
|
Changes can be performed on the access condition for the metadata (item) or for the content (bitstream).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="row mt-5">
|
||||||
|
<div class="col-12 col-md-6 border-right">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<h4 class="mb-0 mr-4">Item's Metadata</h4>
|
||||||
|
<ui-switch [(ngModel)]="state.item.toggleStatus"></ui-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12 col-md-3">Mode</div>
|
||||||
|
<div class="col-12 col-md-8">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="itemMode" id="itemReplace" value="replace" [(ngModel)]="state.item.accessMode">
|
||||||
|
<label class="form-check-label" for="itemReplace">Replace access conditions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="itemMode" id="itemAdd" value="add" [(ngModel)]="state.item.accessMode">
|
||||||
|
<label class="form-check-label" for="itemAdd">Add to existing ones</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
<h5>Access conditions</h5>
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
You have not specified any access conditions, the new items access conditions will be inherited from the owning collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ds-access-control-array-form
|
||||||
|
#itemAccessCmp
|
||||||
|
[dropdownOptions]="(dropdownData$ | async)?.itemAccessConditionOptions || []">
|
||||||
|
</ds-access-control-array-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<h4 class="mb-0 mr-4">Bitstreams</h4>
|
||||||
|
<ui-switch [(ngModel)]="state.bitstream.toggleStatus"></ui-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12">Limit the changes to specific bitstreams</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="changesLimit" id="processAll" value="all" [(ngModel)]="state.bitstream.changesLimit">
|
||||||
|
<label class="form-check-label" for="processAll">process all the bitstreams in the item</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="changesLimit" id="processSelected" value="selected" [(ngModel)]="state.bitstream.changesLimit">
|
||||||
|
<label class="form-check-label" for="processSelected">
|
||||||
|
{{ state.bitstream.selectedBitstreams.length }} bitstreams selected
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-12 col-md-3">Mode</div>
|
||||||
|
<div class="col-12 col-md-8">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="bitstreamMode" id="bitstreamReplace" value="replace" [(ngModel)]="state.bitstream.accessMode">
|
||||||
|
<label class="form-check-label" for="bitstreamReplace">Replace access conditions</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio"
|
||||||
|
name="bitstreamMode" id="bitstreamAdd" value="add" [(ngModel)]="state.bitstream.accessMode">
|
||||||
|
<label class="form-check-label" for="bitstreamAdd">Add to existing ones</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3">
|
||||||
|
<h5>Access conditions</h5>
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
You have not specified any access conditions, the new items access conditions will be inherited from the owning collection.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ds-access-control-array-form
|
||||||
|
#bitstreamAccessCmp
|
||||||
|
[dropdownOptions]="(dropdownData$ | async)?.bitstreamAccessConditionOptions || []">
|
||||||
|
</ds-access-control-array-form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<button class="btn btn-lg btn-outline-primary mr-3" (click)="reset()">Reset</button>
|
||||||
|
<button class="btn btn-lg btn-primary" (click)="submit()">Execute</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@@ -1,15 +1,64 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
|
import {
|
||||||
|
AccessControlArrayFormComponent
|
||||||
|
} from '../../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
import {
|
||||||
|
CollectionAccessControlService
|
||||||
|
} from '../../../collection-page/edit-collection-page/collection-access-control/collection-access-control.service';
|
||||||
|
import { shareReplay } from 'rxjs';
|
||||||
|
import { ItemAccessControlService } from './item-access-control.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-item-access-control',
|
selector: 'ds-item-access-control',
|
||||||
templateUrl: './item-access-control.component.html',
|
templateUrl: './item-access-control.component.html',
|
||||||
styleUrls: ['./item-access-control.component.scss']
|
styleUrls: ['./item-access-control.component.scss'],
|
||||||
|
providers: [ItemAccessControlService]
|
||||||
})
|
})
|
||||||
export class ItemAccessControlComponent implements OnInit {
|
export class ItemAccessControlComponent implements OnInit {
|
||||||
|
|
||||||
constructor() { }
|
@ViewChild('bitstreamAccessCmp', { static: true }) bitstreamAccessCmp: AccessControlArrayFormComponent;
|
||||||
|
@ViewChild('itemAccessCmp', { static: true }) itemAccessCmp: AccessControlArrayFormComponent;
|
||||||
|
|
||||||
|
constructor(private itemAccessControlService: ItemAccessControlService) {}
|
||||||
|
|
||||||
|
state = initialState;
|
||||||
|
|
||||||
|
dropdownData$ = this.itemAccessControlService.dropdownData$.pipe(
|
||||||
|
shareReplay(1)
|
||||||
|
);
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.bitstreamAccessCmp.reset();
|
||||||
|
this.itemAccessCmp.reset();
|
||||||
|
this.state = initialState;
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
const bitstreamAccess = this.bitstreamAccessCmp.getValue();
|
||||||
|
const itemAccess = this.itemAccessCmp.getValue();
|
||||||
|
|
||||||
|
this.itemAccessControlService.execute({
|
||||||
|
bitstreamAccess,
|
||||||
|
itemAccess,
|
||||||
|
state: this.state
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
item: {
|
||||||
|
toggleStatus: false,
|
||||||
|
accessMode: '',
|
||||||
|
},
|
||||||
|
bitstream: {
|
||||||
|
toggleStatus: false,
|
||||||
|
accessMode: '',
|
||||||
|
changesLimit: '', // 'all' | 'selected'
|
||||||
|
selectedBitstreams: []
|
||||||
|
},
|
||||||
|
};
|
||||||
|
@@ -0,0 +1,71 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { AccessControlItem } from '../../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
|
import { Observable, of } from 'rxjs';
|
||||||
|
|
||||||
|
export interface AccessControlDropdownDataResponse {
|
||||||
|
id: string;
|
||||||
|
itemAccessConditionOptions: AccessControlItem[];
|
||||||
|
bitstreamAccessConditionOptions: AccessControlItem[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ItemAccessControlService {
|
||||||
|
dropdownData$: Observable<AccessControlDropdownDataResponse> = of(accessControlDropdownData);
|
||||||
|
|
||||||
|
|
||||||
|
execute(payload: any) {
|
||||||
|
console.log('execute', payload);
|
||||||
|
|
||||||
|
const blob = new Blob([JSON.stringify(payload, null, 2)], {
|
||||||
|
type: 'application/json',
|
||||||
|
});
|
||||||
|
|
||||||
|
const file = new File([blob], 'data.json', {
|
||||||
|
type: 'application/json',
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = URL.createObjectURL(file);
|
||||||
|
window.open(url, '_blank');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const accessControlDropdownData: AccessControlDropdownDataResponse = {
|
||||||
|
'id': 'default',
|
||||||
|
'itemAccessConditionOptions': [
|
||||||
|
{
|
||||||
|
'name': 'openaccess'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'administrator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'embargo',
|
||||||
|
'hasStartDate': true,
|
||||||
|
'maxStartDate': '2018-06-24T00:40:54.970+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'lease',
|
||||||
|
'hasEndDate': true,
|
||||||
|
'maxEndDate': '2017-12-24T00:40:54.970+0000'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'bitstreamAccessConditionOptions': [
|
||||||
|
{
|
||||||
|
'name': 'openaccess'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'administrator'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'embargo',
|
||||||
|
'hasStartDate': true,
|
||||||
|
'maxStartDate': '2018-06-24T00:40:54.970+0000'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'lease',
|
||||||
|
'hasEndDate': true,
|
||||||
|
'maxEndDate': '2017-12-24T00:40:54.970+0000'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
@@ -0,0 +1,68 @@
|
|||||||
|
<form [formGroup]="form">
|
||||||
|
<ng-container *ngFor="let control of accessControl.controls; let i = index">
|
||||||
|
<div [formGroup]="$any(control)"
|
||||||
|
class="mt-3" data-testId="access-control-item"
|
||||||
|
style="display: grid; grid-template-columns: 1fr 1fr 1fr 50px; grid-gap: 5px">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<select id="accesscontroloption" formControlName="itemName" class="form-control">
|
||||||
|
<option value=""></option>
|
||||||
|
<option *ngFor="let option of dropdownOptions" [value]="option.name">
|
||||||
|
{{ option.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
placeholder="yyyy-mm-dd"
|
||||||
|
name="dp"
|
||||||
|
formControlName="startDate"
|
||||||
|
[minDate]="control | maxStartDate: dropdownOptions"
|
||||||
|
ngbDatepicker
|
||||||
|
#d="ngbDatepicker"
|
||||||
|
/>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary fas fa-calendar" (click)="d.toggle()"
|
||||||
|
type="button"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
placeholder="yyyy-mm-dd"
|
||||||
|
name="dp"
|
||||||
|
formControlName="endDate"
|
||||||
|
[maxDate]="control | maxEndDate: dropdownOptions"
|
||||||
|
ngbDatepicker
|
||||||
|
#d1="ngbDatepicker"
|
||||||
|
/>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary fas fa-calendar" (click)="d1.toggle()"
|
||||||
|
type="button">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button type="button" (click)="removeAccessControlItem(i)" class="btn btn-outline-danger">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<button type="button" id="add-btn" class="btn btn-outline-primary mt-3"
|
||||||
|
(click)="addAccessControlItem()">
|
||||||
|
<i class="fas fa-plus"></i>
|
||||||
|
Add more
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</form>
|
@@ -0,0 +1,101 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AccessControlArrayFormComponent, AccessControlItemValue } from './access-control-array-form.component';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { SharedBrowseByModule } from '../browse-by/shared-browse-by.module';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { ControlMaxStartDatePipe } from './control-max-start-date.pipe';
|
||||||
|
import { ControlMaxEndDatePipe } from './control-max-end-date.pipe';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
fdescribe('AccessControlArrayFormComponent', () => {
|
||||||
|
let component: AccessControlArrayFormComponent;
|
||||||
|
let fixture: ComponentFixture<AccessControlArrayFormComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ CommonModule, ReactiveFormsModule, SharedBrowseByModule, TranslateModule, NgbDatepickerModule ],
|
||||||
|
declarations: [ AccessControlArrayFormComponent, ControlMaxStartDatePipe, ControlMaxEndDatePipe ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AccessControlArrayFormComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
component.dropdownOptions = [{name: 'Option1'}, {name: 'Option2'}];
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have only one empty control access item in the form', () => {
|
||||||
|
const accessControlItems = fixture.debugElement.queryAll(By.css('[data-testId="access-control-item"]'));
|
||||||
|
expect(accessControlItems.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add access control item', () => {
|
||||||
|
component.addAccessControlItem();
|
||||||
|
expect(component.accessControl.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove access control item', () => {
|
||||||
|
component.removeAccessControlItem(0);
|
||||||
|
expect(component.accessControl.length).toEqual(0);
|
||||||
|
|
||||||
|
component.addAccessControlItem();
|
||||||
|
component.removeAccessControlItem(0);
|
||||||
|
expect(component.accessControl.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set access control item value', () => {
|
||||||
|
const item: AccessControlItemValue = { itemName: 'item1', startDate: '2022-01-01', endDate: '2022-02-01' };
|
||||||
|
component.addAccessControlItem(item.itemName);
|
||||||
|
component.accessControl.controls[0].patchValue(item);
|
||||||
|
expect(component.form.value.accessControl[0]).toEqual(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should reset form value', () => {
|
||||||
|
const item: AccessControlItemValue = { itemName: 'item1', startDate: '2022-01-01', endDate: '2022-02-01' };
|
||||||
|
component.addAccessControlItem(item.itemName);
|
||||||
|
component.accessControl.controls[1].patchValue(item);
|
||||||
|
component.reset();
|
||||||
|
expect(component.form.value.accessControl[1].value).toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should display a select dropdown with options', () => {
|
||||||
|
const selectElement: DebugElement = fixture.debugElement.query(By.css('select#accesscontroloption'));
|
||||||
|
expect(selectElement).toBeTruthy();
|
||||||
|
|
||||||
|
const options = selectElement.nativeElement.querySelectorAll('option');
|
||||||
|
expect(options.length).toEqual(3); // 2 options + default empty option
|
||||||
|
|
||||||
|
expect(options[0].value).toEqual('');
|
||||||
|
expect(options[1].value).toEqual('Option1');
|
||||||
|
expect(options[2].value).toEqual('Option2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add new access control items when clicking "Add more" button', () => {
|
||||||
|
const addButton: DebugElement = fixture.debugElement.query(By.css('button#add-btn'));
|
||||||
|
addButton.nativeElement.click();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const accessControlItems = fixture.debugElement.queryAll(By.css('[data-testId="access-control-item"]'));
|
||||||
|
expect(accessControlItems.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove access control items when clicking remove button', () => {
|
||||||
|
const removeButton: DebugElement = fixture.debugElement.query(By.css('button.btn-outline-danger'));
|
||||||
|
removeButton.nativeElement.click();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const accessControlItems = fixture.debugElement.queryAll(By.css('[data-testId="access-control-item"]'));
|
||||||
|
expect(accessControlItems.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,88 @@
|
|||||||
|
import { Component, Input, NgModule, OnInit } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormArray, FormBuilder, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { SharedBrowseByModule } from '../browse-by/shared-browse-by.module';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { NgbDatepickerModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { ControlMaxStartDatePipe } from './control-max-start-date.pipe';
|
||||||
|
import { ControlMaxEndDatePipe } from './control-max-end-date.pipe';
|
||||||
|
|
||||||
|
// type of the dropdown item that comes from backend
|
||||||
|
export interface AccessControlItem {
|
||||||
|
name: string
|
||||||
|
hasStartDate?: boolean
|
||||||
|
maxStartDate?: string
|
||||||
|
hasEndDate?: boolean
|
||||||
|
maxEndDate?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// will be used on the form value
|
||||||
|
export interface AccessControlItemValue {
|
||||||
|
itemName: string | null; // item name
|
||||||
|
startDate?: string;
|
||||||
|
endDate?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccessControlArrayFormValue {
|
||||||
|
accessControl: AccessControlItemValue[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-access-control-array-form',
|
||||||
|
templateUrl: './access-control-array-form.component.html',
|
||||||
|
styleUrls: [ './access-control-array-form.component.scss' ]
|
||||||
|
})
|
||||||
|
export class AccessControlArrayFormComponent implements OnInit {
|
||||||
|
@Input() dropdownOptions: AccessControlItem[] = [];
|
||||||
|
@Input() accessControlItems: AccessControlItemValue[] = [];
|
||||||
|
|
||||||
|
form = this.fb.group({
|
||||||
|
accessControl: this.fb.array([])
|
||||||
|
});
|
||||||
|
|
||||||
|
constructor(private fb: FormBuilder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if (this.accessControlItems.length === 0) {
|
||||||
|
this.addAccessControlItem();
|
||||||
|
} else {
|
||||||
|
for (const item of this.accessControlItems) {
|
||||||
|
this.addAccessControlItem(item.itemName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get accessControl() {
|
||||||
|
return this.form.get('accessControl') as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
addAccessControlItem(itemName: string = null) {
|
||||||
|
this.accessControl.push(this.fb.group({
|
||||||
|
itemName,
|
||||||
|
startDate: null,
|
||||||
|
endDate: null
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAccessControlItem(index: number) {
|
||||||
|
this.accessControl.removeAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
getValue() {
|
||||||
|
return this.form.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.accessControl.reset([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [ CommonModule, ReactiveFormsModule, SharedBrowseByModule, TranslateModule, NgbDatepickerModule ],
|
||||||
|
declarations: [ AccessControlArrayFormComponent, ControlMaxStartDatePipe, ControlMaxEndDatePipe ],
|
||||||
|
exports: [ AccessControlArrayFormComponent ],
|
||||||
|
})
|
||||||
|
export class AccessControlArrayFormModule {
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { AbstractControl } from '@angular/forms';
|
||||||
|
import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap/datepicker/ngb-date-struct';
|
||||||
|
import { AccessControlItem } from './access-control-array-form.component';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
// eslint-disable-next-line @angular-eslint/pipe-prefix
|
||||||
|
name: 'maxEndDate',
|
||||||
|
pure: false
|
||||||
|
})
|
||||||
|
export class ControlMaxEndDatePipe implements PipeTransform {
|
||||||
|
transform(control: AbstractControl, dropdownOptions: AccessControlItem[]): NgbDateStruct | null {
|
||||||
|
const { itemName } = control.value;
|
||||||
|
const item = dropdownOptions.find((x) => x.name === itemName);
|
||||||
|
if (!item?.hasEndDate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const date = new Date(item.maxEndDate);
|
||||||
|
return {
|
||||||
|
year: date.getFullYear(),
|
||||||
|
month: date.getMonth() + 1,
|
||||||
|
day: date.getDate()
|
||||||
|
} as NgbDateStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,26 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { AbstractControl } from '@angular/forms';
|
||||||
|
import { NgbDateStruct } from '@ng-bootstrap/ng-bootstrap/datepicker/ngb-date-struct';
|
||||||
|
import { AccessControlItem } from './access-control-array-form.component';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
// eslint-disable-next-line @angular-eslint/pipe-prefix
|
||||||
|
name: 'maxStartDate',
|
||||||
|
pure: false
|
||||||
|
})
|
||||||
|
export class ControlMaxStartDatePipe implements PipeTransform {
|
||||||
|
transform(control: AbstractControl, dropdownOptions: AccessControlItem[]): NgbDateStruct | null {
|
||||||
|
const { itemName } = control.value;
|
||||||
|
const item = dropdownOptions.find((x) => x.name === itemName);
|
||||||
|
if (!item?.hasStartDate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const date = new Date(item.maxStartDate);
|
||||||
|
return {
|
||||||
|
year: date.getFullYear(),
|
||||||
|
month: date.getMonth() + 1,
|
||||||
|
day: date.getDate()
|
||||||
|
} as NgbDateStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user