mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +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',
|
AdminWorkflowSearch = 'adminWorkflowSearch',
|
||||||
SideBarSearchModal = 'sideBarSearchModal',
|
SideBarSearchModal = 'sideBarSearchModal',
|
||||||
SideBarSearchModalCurrent = 'sideBarSearchModalCurrent',
|
SideBarSearchModalCurrent = 'sideBarSearchModalCurrent',
|
||||||
|
Bitstream = 'bitstream',
|
||||||
}
|
}
|
||||||
|
@@ -43,6 +43,10 @@ import {
|
|||||||
AccessControlArrayFormModule
|
AccessControlArrayFormModule
|
||||||
} from '../../shared/access-control-array-form/access-control-array-form.component';
|
} from '../../shared/access-control-array-form/access-control-array-form.component';
|
||||||
import { UiSwitchModule } from 'ngx-ui-switch';
|
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,
|
DsoSharedModule,
|
||||||
AccessControlArrayFormModule,
|
AccessControlArrayFormModule,
|
||||||
UiSwitchModule,
|
UiSwitchModule,
|
||||||
|
ResultsBackButtonModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
EditItemPageComponent,
|
EditItemPageComponent,
|
||||||
@@ -89,7 +94,8 @@ import { UiSwitchModule } from 'ngx-ui-switch';
|
|||||||
ItemAuthorizationsComponent,
|
ItemAuthorizationsComponent,
|
||||||
IdentifierDataComponent,
|
IdentifierDataComponent,
|
||||||
ItemRegisterDoiComponent,
|
ItemRegisterDoiComponent,
|
||||||
ItemAccessControlComponent
|
ItemAccessControlComponent,
|
||||||
|
ItemAccessControlSelectBitstreamsModalComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
BundleDataService,
|
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">
|
<label class="form-check-label" for="processSelected">
|
||||||
{{ state.bitstream.selectedBitstreams.length }}
|
{{ state.bitstream.selectedBitstreams.length }}
|
||||||
{{'access-control-bitstreams-selected' | translate}}
|
{{'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>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,22 +1,42 @@
|
|||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
AccessControlArrayFormComponent
|
AccessControlArrayFormComponent
|
||||||
} from '../../../shared/access-control-array-form/access-control-array-form.component';
|
} 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 { 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({
|
@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]
|
providers: [ ItemAccessControlService ]
|
||||||
})
|
})
|
||||||
export class ItemAccessControlComponent implements OnInit {
|
export class ItemAccessControlComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
itemRD$: Observable<RemoteData<Item>>;
|
||||||
|
|
||||||
@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(private itemAccessControlService: ItemAccessControlService) {}
|
constructor(
|
||||||
|
private itemAccessControlService: ItemAccessControlService,
|
||||||
|
private selectableListService: SelectableListService,
|
||||||
|
protected modalService: NgbModal,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private cdr: ChangeDetectorRef
|
||||||
|
) {}
|
||||||
|
|
||||||
state = initialState;
|
state = initialState;
|
||||||
|
|
||||||
@@ -25,7 +45,9 @@ export class ItemAccessControlComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.itemRD$ = this.route.parent.parent.data.pipe(
|
||||||
|
map((data) => data.dso)
|
||||||
|
).pipe(getFirstSucceededRemoteData()) as Observable<RemoteData<Item>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
@@ -52,6 +74,24 @@ export class ItemAccessControlComponent implements OnInit {
|
|||||||
active ? this.itemAccessCmp.enable() : this.itemAccessCmp.disable();
|
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 = {
|
const initialState = {
|
||||||
@@ -63,6 +103,6 @@ const initialState = {
|
|||||||
toggleStatus: false,
|
toggleStatus: false,
|
||||||
accessMode: '',
|
accessMode: '',
|
||||||
changesLimit: '', // 'all' | 'selected'
|
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 };
|
@Input() selectionConfig: { repeatable: boolean, listId: string };
|
||||||
|
|
||||||
/**
|
w /**
|
||||||
* The link type of the listable elements
|
* The link type of the listable elements
|
||||||
*/
|
*/
|
||||||
@Input() linkType: CollectionElementLinkType;
|
@Input() linkType: CollectionElementLinkType;
|
||||||
|
@@ -271,6 +271,7 @@ import { GroupSearchBoxComponent } from './eperson-group-list/group-search-box/g
|
|||||||
import {
|
import {
|
||||||
ThemedItemPageTitleFieldComponent
|
ThemedItemPageTitleFieldComponent
|
||||||
} from '../item-page/simple/field-components/specific-field/title/themed-item-page-field.component';
|
} 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 = [
|
const MODULES = [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@@ -395,6 +396,7 @@ const ENTRY_COMPONENTS = [
|
|||||||
SearchResultGridElementComponent,
|
SearchResultGridElementComponent,
|
||||||
ItemListElementComponent,
|
ItemListElementComponent,
|
||||||
ItemGridElementComponent,
|
ItemGridElementComponent,
|
||||||
|
BitstreamListItemComponent,
|
||||||
ItemSearchResultListElementComponent,
|
ItemSearchResultListElementComponent,
|
||||||
ItemSearchResultGridElementComponent,
|
ItemSearchResultGridElementComponent,
|
||||||
BrowseEntryListElementComponent,
|
BrowseEntryListElementComponent,
|
||||||
|
Reference in New Issue
Block a user