Skip to content

Commit

Permalink
Merge 10cd618 into 103605c
Browse files Browse the repository at this point in the history
  • Loading branch information
Atmire-Kristof committed Mar 20, 2020
2 parents 103605c + 10cd618 commit f80e266
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 0 deletions.
4 changes: 4 additions & 0 deletions resources/i18n/en.json5
Expand Up @@ -1110,6 +1110,10 @@



"item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",



"journal.listelement.badge": "Journal",

"journal.page.description": "Description",
Expand Down
1 change: 1 addition & 0 deletions src/app/+item-page/full/full-item-page.component.html
@@ -1,6 +1,7 @@
<div class="container" *ngVar="(itemRD$ | async) as itemRD">
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
<div *ngIf="itemRD?.payload as item">
<ds-item-versions-notice [item]="item"></ds-item-versions-notice>
<ds-view-tracker [object]="item"></ds-view-tracker>
<ds-item-page-title-field [item]="item"></ds-item-page-title-field>
<div class="simple-view-link my-3">
Expand Down
1 change: 1 addition & 0 deletions src/app/+item-page/simple/item-page.component.html
@@ -1,6 +1,7 @@
<div class="container" *ngVar="(itemRD$ | async) as itemRD">
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
<div *ngIf="itemRD?.payload as item">
<ds-item-versions-notice [item]="item"></ds-item-versions-notice>
<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>
Expand Down
@@ -0,0 +1,5 @@
<ds-alert *ngIf="isLatestVersion$ && !(isLatestVersion$ | async)"
[content]="('item.version.notice' | translate:{ destination: getItemPage(((latestVersion$ | async)?.item | async)?.payload) })"
[dismissible]="false"
[type]="AlertTypeEnum.Warning">
</ds-alert>
@@ -0,0 +1,93 @@
import { ItemVersionsNoticeComponent } from './item-versions-notice.component';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
import { RouterTestingModule } from '@angular/router/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { VersionHistory } from '../../../../core/shared/version-history.model';
import { Version } from '../../../../core/shared/version.model';
import { createPaginatedList, createSuccessfulRemoteDataObject$ } from '../../../testing/utils';
import { Item } from '../../../../core/shared/item.model';
import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service';
import { By } from '@angular/platform-browser';

describe('ItemVersionsNoticeComponent', () => {
let component: ItemVersionsNoticeComponent;
let fixture: ComponentFixture<ItemVersionsNoticeComponent>;

const versionHistory = Object.assign(new VersionHistory(), {
id: '1'
});
const firstVersion = Object.assign(new Version(), {
id: '1',
version: 1,
created: new Date(2020, 1, 1),
summary: 'first version',
versionhistory: createSuccessfulRemoteDataObject$(versionHistory)
});
const latestVersion = Object.assign(new Version(), {
id: '2',
version: 2,
summary: 'latest version',
created: new Date(2020, 1, 2),
versionhistory: createSuccessfulRemoteDataObject$(versionHistory)
});
const versions = [latestVersion, firstVersion];
versionHistory.versions = createSuccessfulRemoteDataObject$(createPaginatedList(versions));
const firstItem = Object.assign(new Item(), {
id: 'first_item_id',
uuid: 'first_item_id',
handle: '123456789/1',
version: createSuccessfulRemoteDataObject$(firstVersion)
});
const latestItem = Object.assign(new Item(), {
id: 'latest_item_id',
uuid: 'latest_item_id',
handle: '123456789/2',
version: createSuccessfulRemoteDataObject$(latestVersion)
});
firstVersion.item = createSuccessfulRemoteDataObject$(firstItem);
latestVersion.item = createSuccessfulRemoteDataObject$(latestItem);
const versionHistoryService = jasmine.createSpyObj('versionHistoryService', {
getVersions: createSuccessfulRemoteDataObject$(createPaginatedList(versions))
});

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ItemVersionsNoticeComponent],
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([])],
providers: [
{ provide: VersionHistoryDataService, useValue: versionHistoryService }
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents();
}));

describe('when the item is the latest version', () => {
beforeEach(() => {
initComponentWithItem(latestItem);
});

it('should not display a notice', () => {
const alert = fixture.debugElement.query(By.css('ds-alert'));
expect(alert).toBeNull();
});
});

describe('when the item is not the latest version', () => {
beforeEach(() => {
initComponentWithItem(firstItem);
});

it('should display a notice', () => {
const alert = fixture.debugElement.query(By.css('ds-alert'));
expect(alert).not.toBeNull();
});
});

function initComponentWithItem(item: Item) {
fixture = TestBed.createComponent(ItemVersionsNoticeComponent);
component = fixture.componentInstance;
component.item = item;
fixture.detectChanges();
}
});
@@ -0,0 +1,114 @@
import { Component, Input, OnInit } from '@angular/core';
import { Item } from '../../../../core/shared/item.model';
import { PaginationComponentOptions } from '../../../pagination/pagination-component-options.model';
import { PaginatedSearchOptions } from '../../../search/paginated-search-options.model';
import { Observable } from 'rxjs/internal/Observable';
import { RemoteData } from '../../../../core/data/remote-data';
import { VersionHistory } from '../../../../core/shared/version-history.model';
import { Version } from '../../../../core/shared/version.model';
import { hasValue } from '../../../empty.util';
import { getAllSucceededRemoteData, getRemoteDataPayload } from '../../../../core/shared/operators';
import { filter, map, startWith, switchMap } from 'rxjs/operators';
import { followLink } from '../../../utils/follow-link-config.model';
import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service';
import { AlertType } from '../../../alert/aletr-type';
import { combineLatest as observableCombineLatest } from 'rxjs';
import { getItemPageRoute } from '../../../../+item-page/item-page-routing.module';

@Component({
selector: 'ds-item-versions-notice',
templateUrl: './item-versions-notice.component.html'
})
/**
* Component for displaying a warning notice when the item is not the latest version within its version history
* The notice contains a link to the latest version's item page
*/
export class ItemVersionsNoticeComponent implements OnInit {
/**
* The item to display a version notice for
*/
@Input() item: Item;

/**
* The item's version
*/
versionRD$: Observable<RemoteData<Version>>;

/**
* The item's full version history
*/
versionHistoryRD$: Observable<RemoteData<VersionHistory>>;

/**
* The latest version of the item's version history
*/
latestVersion$: Observable<Version>;

/**
* Is the item's version equal to the latest version from the version history?
* This will determine whether or not to display a notice linking to the latest version
*/
isLatestVersion$: Observable<boolean>;

/**
* Pagination options to fetch a single version on the first page (this is the latest version in the history)
*/
latestVersionOptions = Object.assign(new PaginationComponentOptions(),{
id: 'item-newest-version-options',
currentPage: 1,
pageSize: 1
});

/**
* The AlertType enumeration
* @type {AlertType}
*/
public AlertTypeEnum = AlertType;

constructor(private versionHistoryService: VersionHistoryDataService) {
}

/**
* Initialize the component's observables
*/
ngOnInit(): void {
const latestVersionSearch = new PaginatedSearchOptions({pagination: this.latestVersionOptions});
if (hasValue(this.item.version)) {
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.latestVersion$ = versionHistory$.pipe(
switchMap((versionHistory: VersionHistory) =>
this.versionHistoryService.getVersions(versionHistory.id, latestVersionSearch, followLink('item'))),
getAllSucceededRemoteData(),
getRemoteDataPayload(),
filter((versions) => versions.page.length > 0),
map((versions) => versions.page[0])
);

this.isLatestVersion$ = observableCombineLatest(
this.versionRD$.pipe(getAllSucceededRemoteData(), getRemoteDataPayload()), this.latestVersion$
).pipe(
map(([itemVersion, latestVersion]: [Version, Version]) => itemVersion.id === latestVersion.id),
startWith(true)
)
}
}

/**
* Get the item page url
* @param item The item for which the url is requested
*/
getItemPage(item: Item): string {
if (hasValue(item)) {
return getItemPageRoute(item.id);
}
}
}
3 changes: 3 additions & 0 deletions src/app/shared/shared.module.ts
Expand Up @@ -179,6 +179,7 @@ import { ExistingMetadataListElementComponent } from './form/builder/ds-dynamic-
import { ItemVersionsComponent } from './item/item-versions/item-versions.component';
import { SortablejsModule } from 'ngx-sortablejs';
import { MissingTranslationHelper } from './translate/missing-translation.helper';
import { ItemVersionsNoticeComponent } from './item/item-versions/notice/item-versions-notice.component';

const MODULES = [
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
Expand Down Expand Up @@ -347,6 +348,7 @@ const COMPONENTS = [
ExistingMetadataListElementComponent,
ItemVersionsComponent,
PublicationSearchResultListElementComponent,
ItemVersionsNoticeComponent
];

const ENTRY_COMPONENTS = [
Expand Down Expand Up @@ -411,6 +413,7 @@ const ENTRY_COMPONENTS = [
DsDynamicLookupRelationExternalSourceTabComponent,
ExternalSourceEntryImportModalComponent,
ItemVersionsComponent,
ItemVersionsNoticeComponent
];

const SHARED_ITEM_PAGE_COMPONENTS = [
Expand Down

0 comments on commit f80e266

Please sign in to comment.