mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
55693: Item mapper page + ItemSelectComponent
This commit is contained in:
@@ -13,6 +13,12 @@
|
||||
"head": "Recent Submissions"
|
||||
}
|
||||
}
|
||||
},
|
||||
"item-mapper": {
|
||||
"head": "Item Mapper - Map Items from Other Collections",
|
||||
"collection": "Collection: \"<b>{{name}}</b>\"",
|
||||
"description": "This is the item mapper tool that allows collection administrators to map items from other collections into this collection. You can search for items from other collections and map them, or browse the list of currently mapped items.",
|
||||
"return": "Return"
|
||||
}
|
||||
},
|
||||
"community": {
|
||||
@@ -43,6 +49,13 @@
|
||||
"simple": "Simple item page",
|
||||
"full": "Full item page"
|
||||
}
|
||||
},
|
||||
"select": {
|
||||
"table": {
|
||||
"collection": "Collection",
|
||||
"author": "Author",
|
||||
"title": "Title"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nav": {
|
||||
|
@@ -0,0 +1,45 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2>{{'collection.item-mapper.head' | translate}}</h2>
|
||||
<p [innerHTML]="'collection.item-mapper.collection' | translate:{ name: (collectionRD$ | async)?.payload?.name }"></p>
|
||||
<p>{{'collection.item-mapper.description' | translate}}</p>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6">
|
||||
<ds-search-form id="search-form"
|
||||
[query]="(searchOptions$ | async)?.query"
|
||||
[scope]="(searchOptions$ | async)?.scope"
|
||||
[currentUrl]="getCurrentUrl()">
|
||||
</ds-search-form>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="nav nav-tabs mb-2">
|
||||
<li class="nav-item">
|
||||
<span class="tab nav-link" id="tab-browse-content" (click)="activeTab = 0" [ngClass]="(activeTab == 0)?'active':''">Browse</span>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<span class="tab nav-link" id="tab-map-content" (click)="activeTab = 1" [ngClass]="(activeTab == 1)?'active':''">Map</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<!-- Browse Tab -->
|
||||
<div *ngIf="activeTab == 0" id="tab-browse">
|
||||
<ds-viewable-collection
|
||||
[config]="(searchOptions$ | async)?.pagination"
|
||||
[sortConfig]="(searchOptions$ | async)?.sort"
|
||||
[objects]="collectionItemsRD$ | async">
|
||||
</ds-viewable-collection>
|
||||
</div>
|
||||
|
||||
<!-- Map Tab -->
|
||||
<div *ngIf="activeTab == 1" id="tab-map">
|
||||
<ds-item-select [items$]="mappingItemsRD$"></ds-item-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button [routerLink]="['/collections/', (collectionRD$ | async)?.payload?.id]" class="btn btn-outline-secondary">{{'collection.item-mapper.return' | translate}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,5 @@
|
||||
@import '../../../styles/variables.scss';
|
||||
|
||||
.tab:hover {
|
||||
cursor: pointer;
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
||||
import { fadeIn, fadeInOut } from '../../shared/animations/fade';
|
||||
import { CollectionDataService } from '../../core/data/collection-data.service';
|
||||
import { ActivatedRoute, PRIMARY_OUTLET, Router, UrlSegmentGroup } from '@angular/router';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Collection } from '../../core/shared/collection.model';
|
||||
import { SearchConfigurationService } from '../../+search-page/search-service/search-configuration.service';
|
||||
import { PaginatedSearchOptions } from '../../+search-page/paginated-search-options.model';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { combineLatest, flatMap, map, tap } from 'rxjs/operators';
|
||||
import { getSucceededRemoteData, toDSpaceObjectListRD } from '../../core/shared/operators';
|
||||
import { SearchService } from '../../+search-page/search-service/search.service';
|
||||
import { DSpaceObject } from '../../core/shared/dspace-object.model';
|
||||
import { DSpaceObjectType } from '../../core/shared/dspace-object-type.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-collection-item-mapper',
|
||||
styleUrls: ['./collection-item-mapper.component.scss'],
|
||||
templateUrl: './collection-item-mapper.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
animations: [
|
||||
fadeIn,
|
||||
fadeInOut
|
||||
]
|
||||
})
|
||||
export class CollectionItemMapperComponent implements OnInit {
|
||||
|
||||
collectionRD$: Observable<RemoteData<Collection>>;
|
||||
searchOptions$: Observable<PaginatedSearchOptions>;
|
||||
collectionItemsRD$: Observable<RemoteData<PaginatedList<DSpaceObject>>>;
|
||||
mappingItemsRD$: Observable<RemoteData<PaginatedList<DSpaceObject>>>;
|
||||
|
||||
activeTab = 0;
|
||||
|
||||
constructor(private collectionDataService: CollectionDataService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private searchConfigService: SearchConfigurationService,
|
||||
private searchService: SearchService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.collectionRD$ = this.route.data.map((data) => data.collection);
|
||||
this.searchOptions$ = this.searchConfigService.paginatedSearchOptions;
|
||||
this.collectionItemsRD$ = this.collectionRD$.pipe(
|
||||
getSucceededRemoteData(),
|
||||
combineLatest(this.searchOptions$),
|
||||
flatMap(([collectionRD, options]) => {
|
||||
return this.searchService.search(Object.assign(options, {
|
||||
scope: collectionRD.payload.id
|
||||
}));
|
||||
}),
|
||||
toDSpaceObjectListRD()
|
||||
);
|
||||
this.mappingItemsRD$ = this.searchOptions$.pipe(
|
||||
flatMap((options: PaginatedSearchOptions) => this.searchService.search(options)),
|
||||
toDSpaceObjectListRD()
|
||||
);
|
||||
}
|
||||
|
||||
getCurrentUrl(): string {
|
||||
const urlTree = this.router.parseUrl(this.router.url);
|
||||
const g: UrlSegmentGroup = urlTree.root.children[PRIMARY_OUTLET];
|
||||
return '/' + g.toString();
|
||||
}
|
||||
|
||||
}
|
@@ -3,6 +3,7 @@ import { RouterModule } from '@angular/router';
|
||||
|
||||
import { CollectionPageComponent } from './collection-page.component';
|
||||
import { CollectionPageResolver } from './collection-page.resolver';
|
||||
import { CollectionItemMapperComponent } from './collection-item-mapper/collection-item-mapper.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -14,6 +15,14 @@ import { CollectionPageResolver } from './collection-page.resolver';
|
||||
resolve: {
|
||||
collection: CollectionPageResolver
|
||||
}
|
||||
},
|
||||
{
|
||||
path: ':id/mapper',
|
||||
component: CollectionItemMapperComponent,
|
||||
pathMatch: 'full',
|
||||
resolve: {
|
||||
collection: CollectionPageResolver
|
||||
}
|
||||
}
|
||||
])
|
||||
],
|
||||
|
@@ -6,6 +6,7 @@ import { SharedModule } from '../shared/shared.module';
|
||||
import { CollectionPageComponent } from './collection-page.component';
|
||||
import { CollectionPageRoutingModule } from './collection-page-routing.module';
|
||||
import { SearchPageModule } from '../+search-page/search-page.module';
|
||||
import { CollectionItemMapperComponent } from './collection-item-mapper/collection-item-mapper.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -16,6 +17,7 @@ import { SearchPageModule } from '../+search-page/search-page.module';
|
||||
],
|
||||
declarations: [
|
||||
CollectionPageComponent,
|
||||
CollectionItemMapperComponent
|
||||
]
|
||||
})
|
||||
export class CollectionPageModule {
|
||||
|
20
src/app/shared/item-select/item-select.component.html
Normal file
20
src/app/shared/item-select/item-select.component.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="table-responsive">
|
||||
<table id="item-select" class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th scope="col">{{'item.select.table.collection' | translate}}</th>
|
||||
<th scope="col">{{'item.select.table.author' | translate}}</th>
|
||||
<th scope="col">{{'item.select.table.title' | translate}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let item of (items$ | async)?.payload?.page ; let i = index">
|
||||
<td><input [(ngModel)]="checked[i]" type="checkbox"></td>
|
||||
<td><a [routerLink]="['/items', item.id]">{{(item.owningCollection | async)?.payload?.name}}</a></td>
|
||||
<td><a [routerLink]="['/items', item.id]">{{item.filterMetadata(['dc.contributor.author', 'dc.creator', 'dc.contributor.*'])[0].value}}</a></td>
|
||||
<td><a [routerLink]="['/items', item.id]">{{item.findMetadata("dc.title")}}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
28
src/app/shared/item-select/item-select.component.ts
Normal file
28
src/app/shared/item-select/item-select.component.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { ItemDataService } from '../../core/data/item-data.service';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-select',
|
||||
styleUrls: ['./item-select.component.scss'],
|
||||
templateUrl: './item-select.component.html'
|
||||
})
|
||||
|
||||
export class ItemSelectComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
items$: Observable<RemoteData<PaginatedList<Item>>>;
|
||||
|
||||
checked: boolean[] = [];
|
||||
|
||||
constructor(private itemDataService: ItemDataService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.items$ = this.itemDataService.findAll({});
|
||||
}
|
||||
|
||||
}
|
@@ -83,6 +83,7 @@ import { InputSuggestionsComponent } from './input-suggestions/input-suggestions
|
||||
import { CapitalizePipe } from './utils/capitalize.pipe';
|
||||
import { MomentModule } from 'angular2-moment';
|
||||
import { ObjectKeysPipe } from './utils/object-keys-pipe';
|
||||
import { ItemSelectComponent } from './item-select/item-select.component';
|
||||
|
||||
const MODULES = [
|
||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||
@@ -156,7 +157,8 @@ const COMPONENTS = [
|
||||
TruncatableComponent,
|
||||
TruncatablePartComponent,
|
||||
BrowseByComponent,
|
||||
InputSuggestionsComponent
|
||||
InputSuggestionsComponent,
|
||||
ItemSelectComponent
|
||||
];
|
||||
|
||||
const ENTRY_COMPONENTS = [
|
||||
|
Reference in New Issue
Block a user