mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merge branch 'feature/CST-9636' of bitbucket.org:4Science/dspace-angular into feature/CST-9636
This commit is contained in:
@@ -16,4 +16,5 @@ export enum Context {
|
||||
AdminWorkflowSearch = 'adminWorkflowSearch',
|
||||
SideBarSearchModal = 'sideBarSearchModal',
|
||||
SideBarSearchModalCurrent = 'sideBarSearchModalCurrent',
|
||||
Bitstream = 'bitstream',
|
||||
}
|
||||
|
@@ -43,6 +43,10 @@ import {
|
||||
AccessControlArrayFormModule
|
||||
} from '../../shared/access-control-array-form/access-control-array-form.component';
|
||||
import { UiSwitchModule } from 'ngx-ui-switch';
|
||||
import {
|
||||
ItemAccessControlSelectBitstreamsModalComponent
|
||||
} from './item-access-control/item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component';
|
||||
import { ResultsBackButtonModule } from '../../shared/results-back-button/results-back-button.module';
|
||||
|
||||
|
||||
/**
|
||||
@@ -62,6 +66,7 @@ import { UiSwitchModule } from 'ngx-ui-switch';
|
||||
DsoSharedModule,
|
||||
AccessControlArrayFormModule,
|
||||
UiSwitchModule,
|
||||
ResultsBackButtonModule,
|
||||
],
|
||||
declarations: [
|
||||
EditItemPageComponent,
|
||||
@@ -89,7 +94,8 @@ import { UiSwitchModule } from 'ngx-ui-switch';
|
||||
ItemAuthorizationsComponent,
|
||||
IdentifierDataComponent,
|
||||
ItemRegisterDoiComponent,
|
||||
ItemAccessControlComponent
|
||||
ItemAccessControlComponent,
|
||||
ItemAccessControlSelectBitstreamsModalComponent
|
||||
],
|
||||
providers: [
|
||||
BundleDataService,
|
||||
|
@@ -0,0 +1,33 @@
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Hi there!</h4>
|
||||
<button type="button" class="close" aria-label="Close"
|
||||
(click)="activeModal.dismiss('Cross click')">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ng-container *ngIf="data$ | async as data">
|
||||
<ds-viewable-collection
|
||||
*ngIf="data.payload.page.length > 0"
|
||||
[config]="paginationConfig"
|
||||
[context]="context"
|
||||
[objects]="data"
|
||||
[selectable]="true"
|
||||
[selectionConfig]="{ repeatable: true, listId: LIST_ID }"
|
||||
[showPaginator]="true"
|
||||
(pageChange)="loadForPage($event)">
|
||||
</ds-viewable-collection>
|
||||
|
||||
<div *ngIf="data && data.payload.page.length === 0"
|
||||
class="alert alert-info w-100" role="alert">
|
||||
{{'browse.empty' | translate}}
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-dark"
|
||||
(click)="activeModal.close('Close click')">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ItemAccessControlSelectBitstreamsModalComponent } from './item-access-control-select-bitstreams-modal.component';
|
||||
|
||||
describe('ItemAccessControlSelectBitstreamsModalComponent', () => {
|
||||
let component: ItemAccessControlSelectBitstreamsModalComponent;
|
||||
let fixture: ComponentFixture<ItemAccessControlSelectBitstreamsModalComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ItemAccessControlSelectBitstreamsModalComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ItemAccessControlSelectBitstreamsModalComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@@ -0,0 +1,62 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { PaginationService } from '../../../../core/pagination/pagination.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BitstreamDataService } from '../../../../core/data/bitstream-data.service';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { Item } from '../../../../core/shared/item.model';
|
||||
import { getFirstCompletedRemoteData } from '../../../../core/shared/operators';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list.model';
|
||||
import { Bitstream } from '../../../../core/shared/bitstream.model';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model';
|
||||
import { hasValue } from '../../../../shared/empty.util';
|
||||
import { Context } from '../../../../core/shared/context.model';
|
||||
|
||||
export const ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID = 'item-access-control-select-bitstreams'
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-access-control-select-bitstreams-modal',
|
||||
templateUrl: './item-access-control-select-bitstreams-modal.component.html',
|
||||
styleUrls: [ './item-access-control-select-bitstreams-modal.component.scss' ]
|
||||
})
|
||||
export class ItemAccessControlSelectBitstreamsModalComponent implements OnInit {
|
||||
|
||||
LIST_ID = ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID;
|
||||
|
||||
@Input() item!: Item;
|
||||
@Input() selectedBitstreams: string[] = [];
|
||||
|
||||
data$ = new BehaviorSubject<RemoteData<PaginatedList<Bitstream>> | null>(null);
|
||||
paginationConfig: PaginationComponentOptions;
|
||||
pageSize = 5;
|
||||
|
||||
context: Context = Context.Bitstream;
|
||||
|
||||
constructor(
|
||||
private bitstreamService: BitstreamDataService,
|
||||
protected paginationService: PaginationService,
|
||||
protected translateService: TranslateService,
|
||||
public activeModal: NgbActiveModal
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.loadForPage(1);
|
||||
|
||||
this.paginationConfig = new PaginationComponentOptions();
|
||||
this.paginationConfig.id = 'iacsbm';
|
||||
this.paginationConfig.currentPage = 1;
|
||||
if (hasValue(this.pageSize)) {
|
||||
this.paginationConfig.pageSize = this.pageSize;
|
||||
}
|
||||
}
|
||||
|
||||
loadForPage(page: number) {
|
||||
this.bitstreamService.findAllByItemAndBundleName(this.item, 'ORIGINAL', { currentPage: page}, false)
|
||||
.pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
)
|
||||
.subscribe(this.data$);
|
||||
}
|
||||
|
||||
}
|
@@ -87,6 +87,14 @@
|
||||
<label class="form-check-label" for="processSelected">
|
||||
{{ state.bitstream.selectedBitstreams.length }}
|
||||
{{'access-control-bitstreams-selected' | translate}}
|
||||
|
||||
<button
|
||||
*ngIf="itemRD$ | async as itemRD"
|
||||
[disabled]="!state.bitstream.toggleStatus && state.bitstream.changesLimit !== 'selected'"
|
||||
(click)="openSelectBitstreamsModal(itemRD.payload)" class="btn btn-outline-dark" type="button">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,22 +1,42 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import {
|
||||
AccessControlArrayFormComponent
|
||||
} from '../../../shared/access-control-array-form/access-control-array-form.component';
|
||||
import { shareReplay } from 'rxjs';
|
||||
import { concatMap, Observable, shareReplay } from 'rxjs';
|
||||
import { ItemAccessControlService } from './item-access-control.service';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import {
|
||||
ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID,
|
||||
ItemAccessControlSelectBitstreamsModalComponent
|
||||
} from './item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
import { getFirstSucceededRemoteData } from '../../../core/shared/operators';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { SelectableListService } from '../../../shared/object-list/selectable-list/selectable-list.service';
|
||||
import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-access-control',
|
||||
templateUrl: './item-access-control.component.html',
|
||||
styleUrls: ['./item-access-control.component.scss'],
|
||||
providers: [ItemAccessControlService]
|
||||
styleUrls: [ './item-access-control.component.scss' ],
|
||||
providers: [ ItemAccessControlService ]
|
||||
})
|
||||
export class ItemAccessControlComponent implements OnInit {
|
||||
export class ItemAccessControlComponent implements OnInit, OnDestroy {
|
||||
|
||||
itemRD$: Observable<RemoteData<Item>>;
|
||||
|
||||
@ViewChild('bitstreamAccessCmp', { static: true }) bitstreamAccessCmp: AccessControlArrayFormComponent;
|
||||
@ViewChild('itemAccessCmp', { static: true }) itemAccessCmp: AccessControlArrayFormComponent;
|
||||
|
||||
constructor(private itemAccessControlService: ItemAccessControlService) {}
|
||||
constructor(
|
||||
private itemAccessControlService: ItemAccessControlService,
|
||||
private selectableListService: SelectableListService,
|
||||
protected modalService: NgbModal,
|
||||
private route: ActivatedRoute,
|
||||
private cdr: ChangeDetectorRef
|
||||
) {}
|
||||
|
||||
state = initialState;
|
||||
|
||||
@@ -25,7 +45,9 @@ export class ItemAccessControlComponent implements OnInit {
|
||||
);
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
this.itemRD$ = this.route.parent.parent.data.pipe(
|
||||
map((data) => data.dso)
|
||||
).pipe(getFirstSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||
}
|
||||
|
||||
reset() {
|
||||
@@ -52,6 +74,24 @@ export class ItemAccessControlComponent implements OnInit {
|
||||
active ? this.itemAccessCmp.enable() : this.itemAccessCmp.disable();
|
||||
}
|
||||
}
|
||||
|
||||
openSelectBitstreamsModal(item: Item) {
|
||||
const ref = this.modalService.open(ItemAccessControlSelectBitstreamsModalComponent);
|
||||
ref.componentInstance.selectedBitstreams = this.state.bitstream.selectedBitstreams;
|
||||
ref.componentInstance.item = item;
|
||||
|
||||
ref.closed.pipe(
|
||||
concatMap(() => this.selectableListService.getSelectableList(ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID)),
|
||||
take(1)
|
||||
).subscribe((list) => {
|
||||
this.state.bitstream.selectedBitstreams = list.selection;
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.selectableListService.deselectAll(ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID);
|
||||
}
|
||||
}
|
||||
|
||||
const initialState = {
|
||||
@@ -63,6 +103,6 @@ const initialState = {
|
||||
toggleStatus: false,
|
||||
accessMode: '',
|
||||
changesLimit: '', // 'all' | 'selected'
|
||||
selectedBitstreams: []
|
||||
selectedBitstreams: [] as ListableObject[],
|
||||
},
|
||||
};
|
||||
|
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { BitstreamListItemComponent } from './bitstream-list-item.component';
|
||||
|
||||
describe('BitstreamListItemComponent', () => {
|
||||
let component: BitstreamListItemComponent;
|
||||
let fixture: ComponentFixture<BitstreamListItemComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ BitstreamListItemComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BitstreamListItemComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@@ -0,0 +1,17 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { listableObjectComponent } from '../../object-collection/shared/listable-object/listable-object.decorator';
|
||||
import { ViewMode } from '../../../core/shared/view-mode.model';
|
||||
import {
|
||||
AbstractListableElementComponent
|
||||
} from '../../object-collection/shared/object-collection-element/abstract-listable-element.component';
|
||||
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||
import { Context } from '../../../core/shared/context.model';
|
||||
|
||||
|
||||
@listableObjectComponent(Bitstream, ViewMode.ListElement, Context.Bitstream)
|
||||
@Component({
|
||||
selector: 'ds-bitstream-list-item',
|
||||
template: ` {{object.name}} `,
|
||||
styleUrls: ['./bitstream-list-item.component.scss']
|
||||
})
|
||||
export class BitstreamListItemComponent extends AbstractListableElementComponent<Bitstream>{}
|
@@ -48,7 +48,7 @@ export class ThemedObjectListComponent extends ThemedComponent<ObjectListCompone
|
||||
|
||||
@Input() selectionConfig: { repeatable: boolean, listId: string };
|
||||
|
||||
/**
|
||||
w /**
|
||||
* The link type of the listable elements
|
||||
*/
|
||||
@Input() linkType: CollectionElementLinkType;
|
||||
|
@@ -271,6 +271,7 @@ import { GroupSearchBoxComponent } from './eperson-group-list/group-search-box/g
|
||||
import {
|
||||
ThemedItemPageTitleFieldComponent
|
||||
} from '../item-page/simple/field-components/specific-field/title/themed-item-page-field.component';
|
||||
import { BitstreamListItemComponent } from './object-list/bitstream-list-item/bitstream-list-item.component';
|
||||
|
||||
const MODULES = [
|
||||
CommonModule,
|
||||
@@ -395,6 +396,7 @@ const ENTRY_COMPONENTS = [
|
||||
SearchResultGridElementComponent,
|
||||
ItemListElementComponent,
|
||||
ItemGridElementComponent,
|
||||
BitstreamListItemComponent,
|
||||
ItemSearchResultListElementComponent,
|
||||
ItemSearchResultGridElementComponent,
|
||||
BrowseEntryListElementComponent,
|
||||
|
Reference in New Issue
Block a user