mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
68729: ItemVersionsComponent + changes to Version(History) model and services
This commit is contained in:
@@ -981,6 +981,22 @@
|
||||
|
||||
|
||||
|
||||
"item.version.history.head": "Version History",
|
||||
|
||||
"item.version.history.selected": "Selected version",
|
||||
|
||||
"item.version.history.table.version": "Version",
|
||||
|
||||
"item.version.history.table.item": "Item",
|
||||
|
||||
"item.version.history.table.editor": "Editor",
|
||||
|
||||
"item.version.history.table.date": "Date",
|
||||
|
||||
"item.version.history.table.summary": "Summary",
|
||||
|
||||
|
||||
|
||||
"journal.listelement.badge": "Journal",
|
||||
|
||||
"journal.page.description": "Description",
|
||||
|
@@ -29,6 +29,7 @@ import { MetadataFieldWrapperComponent } from './field-components/metadata-field
|
||||
import { TabbedRelatedEntitiesSearchComponent } from './simple/related-entities/tabbed-related-entities-search/tabbed-related-entities-search.component';
|
||||
import { StatisticsModule } from '../statistics/statistics.module';
|
||||
import { AbstractIncrementalListComponent } from './simple/abstract-incremental-list/abstract-incremental-list.component';
|
||||
import { ItemVersionsComponent } from './item-versions/item-versions.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -59,7 +60,8 @@ import { AbstractIncrementalListComponent } from './simple/abstract-incremental-
|
||||
MetadataRepresentationListComponent,
|
||||
RelatedEntitiesSearchComponent,
|
||||
TabbedRelatedEntitiesSearchComponent,
|
||||
AbstractIncrementalListComponent
|
||||
AbstractIncrementalListComponent,
|
||||
ItemVersionsComponent
|
||||
],
|
||||
exports: [
|
||||
ItemComponent,
|
||||
|
@@ -0,0 +1,44 @@
|
||||
<div *ngVar="(versionsRD$ | async)?.payload as versions">
|
||||
<div *ngVar="(versionRD$ | async)?.payload as itemVersion">
|
||||
<div *ngIf="versions?.page?.length > 0">
|
||||
<h2>{{"item.version.history.head" | translate}}</h2>
|
||||
<ds-pagination [hideGear]="true"
|
||||
[hidePagerWhenSinglePage]="true"
|
||||
[paginationOptions]="options"
|
||||
[pageInfoState]="versions"
|
||||
[collectionSize]="versions?.totalElements"
|
||||
(pageChange)="switchPage($event)">
|
||||
<table class="table table-striped my-2">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{"item.version.history.table.version" | translate}}</th>
|
||||
<th scope="col">{{"item.version.history.table.item" | translate}}</th>
|
||||
<th scope="col" *ngIf="(hasEpersons$ | async)">{{"item.version.history.table.editor" | translate}}</th>
|
||||
<th scope="col">{{"item.version.history.table.date" | translate}}</th>
|
||||
<th scope="col">{{"item.version.history.table.summary" | translate}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let version of versions?.page">
|
||||
<td>{{version?.version}}</td>
|
||||
<td>
|
||||
<span *ngVar="(version?.item | async)?.payload as item">
|
||||
<a *ngIf="item" [routerLink]="['/items', item?.id]">{{item?.handle}}</a>
|
||||
<span *ngIf="version?.id === itemVersion?.id">*</span>
|
||||
</span>
|
||||
</td>
|
||||
<td *ngIf="(hasEpersons$ | async)">
|
||||
<span *ngVar="(version?.eperson | async)?.payload as eperson">
|
||||
<a *ngIf="eperson" [href]="'mailto:' + eperson?.email">{{eperson?.name}}</a>
|
||||
</span>
|
||||
</td>
|
||||
<td>{{version?.created}}</td>
|
||||
<td>{{version?.summary}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div>* {{"item.version.history.selected" | translate}}</div>
|
||||
</ds-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
108
src/app/+item-page/item-versions/item-versions.component.ts
Normal file
108
src/app/+item-page/item-versions/item-versions.component.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
import { Version } from '../../core/shared/version.model';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { VersionHistory } from '../../core/shared/version-history.model';
|
||||
import { getAllSucceededRemoteData, getRemoteDataPayload } from '../../core/shared/operators';
|
||||
import { map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { PaginatedList } from '../../core/data/paginated-list';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { VersionHistoryDataService } from '../../core/data/version-history-data.service';
|
||||
import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-versions',
|
||||
templateUrl: './item-versions.component.html'
|
||||
})
|
||||
/**
|
||||
* Component listing all available versions of the history the provided item is a part of
|
||||
*/
|
||||
export class ItemVersionsComponent implements OnInit {
|
||||
/**
|
||||
* The item to display a version history for
|
||||
*/
|
||||
@Input() item: Item;
|
||||
|
||||
/**
|
||||
* The item's version
|
||||
*/
|
||||
versionRD$: Observable<RemoteData<Version>>;
|
||||
|
||||
/**
|
||||
* The item's full version history
|
||||
*/
|
||||
versionHistoryRD$: Observable<RemoteData<VersionHistory>>;
|
||||
|
||||
/**
|
||||
* The version history's list of versions
|
||||
*/
|
||||
versionsRD$: Observable<RemoteData<PaginatedList<Version>>>;
|
||||
|
||||
/**
|
||||
* Verify if the list of versions has at least one e-person to display
|
||||
* Used to hide the "Editor" column when no e-persons are present to display
|
||||
*/
|
||||
hasEpersons$: Observable<boolean>;
|
||||
|
||||
/**
|
||||
* The amount of versions to display per page
|
||||
*/
|
||||
pageSize = 10;
|
||||
|
||||
/**
|
||||
* The page options to use for fetching the versions
|
||||
* Start at page 1 and always use the set page size
|
||||
*/
|
||||
options = Object.assign(new PaginationComponentOptions(),{
|
||||
id: 'item-versions-options',
|
||||
currentPage: 1,
|
||||
pageSize: this.pageSize
|
||||
});
|
||||
|
||||
/**
|
||||
* The current page being displayed
|
||||
*/
|
||||
currentPage$ = new BehaviorSubject<number>(1);
|
||||
|
||||
constructor(private versionHistoryService: VersionHistoryDataService) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all observables
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.versionRD$ = this.item.version;
|
||||
this.versionHistoryRD$ = this.versionRD$.pipe(
|
||||
getAllSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
switchMap((version: Version) => version.versionhistory)
|
||||
);
|
||||
const versionHistory$ = this.versionHistoryRD$.pipe(
|
||||
getAllSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
);
|
||||
this.versionsRD$ = observableCombineLatest(versionHistory$, this.currentPage$).pipe(
|
||||
switchMap(([versionHistory, page]: [VersionHistory, number]) =>
|
||||
this.versionHistoryService.getVersions(versionHistory.id,
|
||||
new PaginatedSearchOptions({pagination: Object.assign({}, this.options, { currentPage: page })})))
|
||||
);
|
||||
this.hasEpersons$ = this.versionsRD$.pipe(
|
||||
getAllSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
map((versions: PaginatedList<Version>) => versions.page.filter((version: Version) => version.eperson !== undefined).length > 0),
|
||||
startWith(false)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current page
|
||||
* @param page
|
||||
*/
|
||||
switchPage(page: number) {
|
||||
this.currentPage$.next(page);
|
||||
}
|
||||
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
<div *ngIf="itemRD?.payload as item">
|
||||
<ds-view-tracker [object]="item"></ds-view-tracker>
|
||||
<ds-listable-object-component-loader [object]="item" [viewMode]="viewMode"></ds-listable-object-component-loader>
|
||||
<ds-item-versions class="mt-2" [item]="item"></ds-item-versions>
|
||||
</div>
|
||||
</div>
|
||||
<ds-error *ngIf="itemRD?.hasFailed" message="{{'error.item' | translate}}"></ds-error>
|
||||
|
@@ -6,6 +6,7 @@ import { mapsTo, relationship } from '../builders/build-decorators';
|
||||
import { Collection } from '../../shared/collection.model';
|
||||
import { Relationship } from '../../shared/item-relationships/relationship.model';
|
||||
import { Bundle } from '../../shared/bundle.model';
|
||||
import { Version } from '../../shared/version.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Item
|
||||
@@ -69,4 +70,11 @@ export class NormalizedItem extends NormalizedDSpaceObject<Item> {
|
||||
@relationship(Relationship, true)
|
||||
relationships: string[];
|
||||
|
||||
/**
|
||||
* The version this item represents in its history
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(Version, false)
|
||||
version: string;
|
||||
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import { TypedObject } from '../object-cache.reducer';
|
||||
import { NormalizedObject } from './normalized-object.model';
|
||||
import { Item } from '../../shared/item.model';
|
||||
import { VersionHistory } from '../../shared/version-history.model';
|
||||
import { EPerson } from '../../eperson/models/eperson.model';
|
||||
|
||||
/**
|
||||
* Normalized model class for a DSpace Version
|
||||
@@ -49,4 +50,11 @@ export class NormalizedVersion extends NormalizedObject<Version> implements Type
|
||||
@deserialize
|
||||
@relationship(Item, false)
|
||||
item: string;
|
||||
|
||||
/**
|
||||
* The e-person who created this version
|
||||
*/
|
||||
@deserialize
|
||||
@relationship(EPerson, false)
|
||||
eperson: string;
|
||||
}
|
||||
|
@@ -14,6 +14,9 @@ import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
||||
import { FindListOptions } from './request.models';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
|
||||
/**
|
||||
* Service responsible for handling requests related to the Version object
|
||||
*/
|
||||
@Injectable()
|
||||
export class VersionDataService extends DataService<Version> {
|
||||
protected linkPath = 'versions';
|
||||
|
@@ -11,12 +11,21 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
||||
import { FindListOptions } from './request.models';
|
||||
import { FindListOptions, GetRequest } from './request.models';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model';
|
||||
import { RemoteData } from './remote-data';
|
||||
import { PaginatedList } from './paginated-list';
|
||||
import { Version } from '../shared/version.model';
|
||||
import { map, switchMap, take } from 'rxjs/operators';
|
||||
|
||||
/**
|
||||
* Service responsible for handling requests related to the VersionHistory object
|
||||
*/
|
||||
@Injectable()
|
||||
export class VersionHistoryDataService extends DataService<VersionHistory> {
|
||||
protected linkPath = 'versionhistories';
|
||||
protected versionsEndpoint = 'versions';
|
||||
|
||||
constructor(
|
||||
protected requestService: RequestService,
|
||||
@@ -37,4 +46,33 @@ export class VersionHistoryDataService extends DataService<VersionHistory> {
|
||||
getBrowseEndpoint(options: FindListOptions = {}, linkPath?: string): Observable<string> {
|
||||
return this.halService.getEndpoint(this.linkPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the versions endpoint for a version history
|
||||
* @param versionHistoryId
|
||||
*/
|
||||
getVersionsEndpoint(versionHistoryId: number): Observable<string> {
|
||||
return this.getBrowseEndpoint().pipe(
|
||||
switchMap((href: string) => this.halService.getEndpoint(this.versionsEndpoint, `${href}/${versionHistoryId}`))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a version history's versions using paginated search options
|
||||
* @param versionHistoryId The version history's ID
|
||||
* @param searchOptions The search options to use
|
||||
*/
|
||||
getVersions(versionHistoryId: number, searchOptions?: PaginatedSearchOptions): Observable<RemoteData<PaginatedList<Version>>> {
|
||||
const hrefObs = this.getVersionsEndpoint(versionHistoryId).pipe(
|
||||
map((href) => searchOptions ? searchOptions.toRestUrl(href) : href)
|
||||
);
|
||||
hrefObs.pipe(
|
||||
take(1)
|
||||
).subscribe((href) => {
|
||||
const request = new GetRequest(this.requestService.generateRequestId(), href);
|
||||
this.requestService.configure(request);
|
||||
});
|
||||
|
||||
return this.rdbService.buildList<Version>(hrefObs);
|
||||
}
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ import { Bundle } from './bundle.model';
|
||||
import { GenericConstructor } from './generic-constructor';
|
||||
import { ListableObject } from '../../shared/object-collection/shared/listable-object.model';
|
||||
import { DEFAULT_ENTITY_TYPE } from '../../shared/metadata-representation/metadata-representation.decorator';
|
||||
import { Version } from './version.model';
|
||||
|
||||
/**
|
||||
* Class representing a DSpace Item
|
||||
@@ -67,6 +68,11 @@ export class Item extends DSpaceObject {
|
||||
|
||||
relationships: Observable<RemoteData<PaginatedList<Relationship>>>;
|
||||
|
||||
/**
|
||||
* The version this item represents in its history
|
||||
*/
|
||||
version: Observable<RemoteData<Version>>;
|
||||
|
||||
/**
|
||||
* Retrieves the thumbnail of this item
|
||||
* @returns {Observable<Bitstream>} the primaryBitstream of the 'THUMBNAIL' bundle
|
||||
|
@@ -7,6 +7,7 @@ import { Item } from './item.model';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { VersionHistory } from './version-history.model';
|
||||
import { EPerson } from '../eperson/models/eperson.model';
|
||||
|
||||
/**
|
||||
* Class representing a DSpace Version
|
||||
@@ -52,6 +53,12 @@ export class Version extends ListableObject implements CacheableObject {
|
||||
@excludeFromEquals
|
||||
item: Observable<RemoteData<Item>>;
|
||||
|
||||
/**
|
||||
* The e-person who created this version
|
||||
*/
|
||||
@excludeFromEquals
|
||||
eperson: Observable<RemoteData<EPerson>>;
|
||||
|
||||
/**
|
||||
* Method that returns as which type of object this object should be rendered
|
||||
*/
|
||||
|
Reference in New Issue
Block a user