[CST-9636] Make access control form container reusable

This commit is contained in:
Enea Jahollari
2023-05-10 15:11:44 +02:00
parent 52d72766ca
commit 723e1e1278
5 changed files with 110 additions and 28 deletions

View File

@@ -16,7 +16,56 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio
@Component({ @Component({
selector: 'ds-bulk-access-browse', selector: 'ds-bulk-access-browse',
templateUrl: './bulk-access-browse.component.html', template: `
<ngb-accordion #acc="ngbAccordion" [activeIds]="'browse'">
<ngb-panel [id]="'browse'">
<ng-template ngbPanelHeader>
<div class="w-100 d-flex justify-content-between collapse-toggle" ngbPanelToggle (click)="acc.toggle('browse')"
data-test="browse">
<button type="button" class="btn btn-link p-0" (click)="$event.preventDefault()"
[attr.aria-expanded]="!acc.isExpanded('browse')"
aria-controls="collapsePanels">
{{ 'admin.access-control.bulk-access-browse.header' | translate }}
</button>
<div class="text-right d-flex">
<div class="ml-3 d-inline-block">
<span *ngIf="acc.isExpanded('browse')" class="fas fa-chevron-up fa-fw"></span>
<span *ngIf="!acc.isExpanded('browse')" class="fas fa-chevron-down fa-fw"></span>
</div>
</div>
</div>
</ng-template>
<ng-template ngbPanelContent>
<ul ngbNav #nav="ngbNav" [(activeId)]="activateId" class="nav-pills">
<li [ngbNavItem]="'search'">
<a ngbNavLink>{{'admin.access-control.bulk-access-browse.search.header' | translate}}</a>
<ng-template ngbNavContent>
<div class="mx-n3">
<ds-themed-search [configuration]="'default'"
[selectable]="true"
[selectionConfig]="{ repeatable: true, listId: listId }"
[showThumbnails]="false"></ds-themed-search>
</div>
</ng-template>
</li>
<li [ngbNavItem]="'selected'">
<a
ngbNavLink>{{'admin.access-control.bulk-access-browse.selected.header' | translate: {number: ((objectsSelected$ | async)?.payload?.totalElements) ? (objectsSelected$ | async)?.payload?.totalElements : '0'} }}</a>
<ng-template ngbNavContent>
<ds-viewable-collection [config]="paginationOptions"
[hideGear]="true"
[objects]="objectsSelected$ | async"
[selectable]="true"
[selectionConfig]="{ repeatable: true, listId: listId }"
[showThumbnails]="false"></ds-viewable-collection>
</ng-template>
</li>
</ul>
<div [ngbNavOutlet]="nav" class="mt-5"></div>
</ng-template>
</ngb-panel>
</ngb-accordion>
`,
styleUrls: ['./bulk-access-browse.component.scss'], styleUrls: ['./bulk-access-browse.component.scss'],
providers: [ providers: [
{ {
@@ -44,8 +93,7 @@ export class BulkAccessBrowseComponent implements OnInit {
paginationOptions: PaginationComponentOptions; paginationOptions: PaginationComponentOptions;
private subs: Subscription[] = []; private subs: Subscription[] = [];
constructor(private selectableListService: SelectableListService) { constructor(private selectableListService: SelectableListService) {}
}
ngOnInit(): void { ngOnInit(): void {
this.paginationOptions = Object.assign(new PaginationComponentOptions(), { this.paginationOptions = Object.assign(new PaginationComponentOptions(), {

View File

@@ -1,13 +1,10 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ItemAccessControlService } from './item-access-control.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { getFirstSucceededRemoteData } from '../../../core/shared/operators'; import { getFirstSucceededRemoteData } from '../../../core/shared/operators';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { Item } from '../../../core/shared/item.model'; import { Item } from '../../../core/shared/item.model';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { SelectableListService } from '../../../shared/object-list/selectable-list/selectable-list.service';
@Component({ @Component({
selector: 'ds-item-access-control', selector: 'ds-item-access-control',

View File

@@ -3,10 +3,6 @@
<div class="card-body"> <div class="card-body">
<ng-content select="[title]"></ng-content> <ng-content select="[title]"></ng-content>
<!-- <p>-->
<!-- {{ 'item-access-control-title' | translate }}-->
<!-- </p>-->
<div class="row mt-5"> <div class="row mt-5">
<div class="col-12 col-md-6 border-right"> <div class="col-12 col-md-6 border-right">
<div class="d-flex align-items-center"> <div class="d-flex align-items-center">
@@ -95,7 +91,8 @@
<button <button
*ngIf="itemRD" *ngIf="itemRD"
[disabled]="!state.bitstream.toggleStatus && state.bitstream.changesLimit !== 'selected'" [disabled]="!state.bitstream.toggleStatus && state.bitstream.changesLimit !== 'selected'"
(click)="openSelectBitstreamsModal(itemRD.payload)" class="btn btn-outline-dark" type="button"> (click)="openSelectBitstreamsModal(itemRD.payload)"
class="btn btn-outline-dark" type="button">
<i class="fa fa-search"></i> <i class="fa fa-search"></i>
</button> </button>
@@ -148,9 +145,9 @@
</div> </div>
</div> </div>
<hr> <hr *ngIf="!hideSubmit">
<div class="d-flex justify-content-end"> <div *ngIf="!hideSubmit" class="d-flex justify-content-end">
<button class="btn btn-lg btn-outline-primary mr-3" (click)="reset()"> <button class="btn btn-lg btn-outline-primary mr-3" (click)="reset()">
{{ 'access-control-reset' | translate }} {{ 'access-control-reset' | translate }}
</button> </button>

View File

@@ -6,9 +6,7 @@ import {
AccessControlArrayFormComponent, AccessControlArrayFormComponent,
AccessControlArrayFormModule AccessControlArrayFormModule
} from '../access-control-array-form/access-control-array-form.component'; } from '../access-control-array-form/access-control-array-form.component';
import { import { BulkAccessControlService } from './bulk-access-control.service';
ItemAccessControlService
} from '../../item-page/edit-item-page/item-access-control/item-access-control.service';
import { SelectableListService } from '../object-list/selectable-list/selectable-list.service'; import { SelectableListService } from '../object-list/selectable-list/selectable-list.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
@@ -26,18 +24,21 @@ import {
@Component({ @Component({
selector: 'ds-access-control-form-container', selector: 'ds-access-control-form-container',
templateUrl: './access-control-form-container.component.html', templateUrl: './access-control-form-container.component.html',
styleUrls: ['./access-control-form-container.component.scss'] styleUrls: [ './access-control-form-container.component.scss' ],
exportAs: 'dsAccessControlForm'
}) })
export class AccessControlFormContainerComponent<T extends DSpaceObject> { export class AccessControlFormContainerComponent<T extends DSpaceObject> {
@Input() showLimitToSpecificBitstreams = false; @Input() showLimitToSpecificBitstreams = false;
@Input() itemRD: RemoteData<T>; @Input() itemRD: RemoteData<T>;
@Input() hideSubmit = false;
@ViewChild('bitstreamAccessCmp', { static: true }) bitstreamAccessCmp: AccessControlArrayFormComponent; @ViewChild('bitstreamAccessCmp', { static: true }) bitstreamAccessCmp: AccessControlArrayFormComponent;
@ViewChild('itemAccessCmp', { static: true }) itemAccessCmp: AccessControlArrayFormComponent; @ViewChild('itemAccessCmp', { static: true }) itemAccessCmp: AccessControlArrayFormComponent;
constructor( constructor(
private itemAccessControlService: ItemAccessControlService, private bulkAccessControlService: BulkAccessControlService,
private selectableListService: SelectableListService, private selectableListService: SelectableListService,
protected modalService: NgbModal, protected modalService: NgbModal,
private cdr: ChangeDetectorRef private cdr: ChangeDetectorRef
@@ -45,10 +46,18 @@ export class AccessControlFormContainerComponent<T extends DSpaceObject> {
state = initialState; state = initialState;
dropdownData$ = this.itemAccessControlService.dropdownData$.pipe( dropdownData$ = this.bulkAccessControlService.dropdownData$.pipe(
shareReplay(1) shareReplay(1)
); );
getFormValue() {
return {
bitstream: this.bitstreamAccessCmp.getValue(),
item: this.itemAccessCmp.getValue(),
state: this.state
};
}
reset() { reset() {
this.bitstreamAccessCmp.reset(); this.bitstreamAccessCmp.reset();
this.itemAccessCmp.reset(); this.itemAccessCmp.reset();
@@ -59,11 +68,18 @@ export class AccessControlFormContainerComponent<T extends DSpaceObject> {
const bitstreamAccess = this.bitstreamAccessCmp.getValue(); const bitstreamAccess = this.bitstreamAccessCmp.getValue();
const itemAccess = this.itemAccessCmp.getValue(); const itemAccess = this.itemAccessCmp.getValue();
this.itemAccessControlService.execute({ const { file } = this.bulkAccessControlService.createPayloadFile({
bitstreamAccess, bitstreamAccess,
itemAccess, itemAccess,
state: this.state state: this.state
}); });
this.bulkAccessControlService.executeScript(
[ this.itemRD.payload.uuid ],
file
).pipe(take(1)).subscribe((res) => {
console.log('success', res);
});
} }
handleStatusChange(type: 'item' | 'bitstream', active: boolean) { handleStatusChange(type: 'item' | 'bitstream', active: boolean) {
@@ -110,9 +126,18 @@ const initialState = {
@NgModule({ @NgModule({
imports: [ CommonModule, AccessControlArrayFormModule, SharedModule, TranslateModule, UiSwitchModule ], imports: [
exports: [AccessControlFormContainerComponent], CommonModule,
declarations: [ AccessControlFormContainerComponent, ItemAccessControlSelectBitstreamsModalComponent ], AccessControlArrayFormModule,
SharedModule,
TranslateModule,
UiSwitchModule
],
declarations: [
AccessControlFormContainerComponent,
ItemAccessControlSelectBitstreamsModalComponent
],
exports: [ AccessControlFormContainerComponent ],
}) })
export class AccessControlFormContainerModule {} export class AccessControlFormContainerModule {}

View File

@@ -1,6 +1,8 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { AccessControlItem } from '../../../core/shared/bulk-access-condition-options.model'; import { AccessControlItem } from '../../core/shared/bulk-access-condition-options.model';
import { ScriptDataService } from '../../core/data/processes/script-data.service';
import { ProcessParameter } from '../../process-page/processes/process-parameter.model';
export interface AccessControlDropdownDataResponse { export interface AccessControlDropdownDataResponse {
id: string; id: string;
@@ -9,11 +11,12 @@ export interface AccessControlDropdownDataResponse {
} }
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ItemAccessControlService { export class BulkAccessControlService {
constructor(private scriptService: ScriptDataService) {}
dropdownData$: Observable<AccessControlDropdownDataResponse> = of(accessControlDropdownData); dropdownData$: Observable<AccessControlDropdownDataResponse> = of(accessControlDropdownData);
createPayloadFile(payload: any) {
execute(payload: any) {
console.log('execute', payload); console.log('execute', payload);
const blob = new Blob([JSON.stringify(payload, null, 2)], { const blob = new Blob([JSON.stringify(payload, null, 2)], {
@@ -25,7 +28,19 @@ export class ItemAccessControlService {
}); });
const url = URL.createObjectURL(file); const url = URL.createObjectURL(file);
window.open(url, '_blank'); window.open(url, '_blank'); // remove this later
return { url, file };
}
executeScript(uuids: string[], file: File) {
console.log('execute', { uuids, file });
const params: ProcessParameter[] = [
{ name: 'uuid', value: uuids.join(',') },
];
return this.scriptService.invoke('bulk-access-control', params, [file]);
} }
} }