diff --git a/src/app/home-page/home-page.component.html b/src/app/home-page/home-page.component.html index f319f3c105b..8f000a67618 100644 --- a/src/app/home-page/home-page.component.html +++ b/src/app/home-page/home-page.component.html @@ -1,5 +1,4 @@
-
diff --git a/src/app/home-page/home-page.component.scss b/src/app/home-page/home-page.component.scss index 7e1a4022cce..8c4b558f604 100644 --- a/src/app/home-page/home-page.component.scss +++ b/src/app/home-page/home-page.component.scss @@ -59,7 +59,7 @@ } .clarin-cut-bottom-2 { - margin-bottom: -25px; + margin-bottom: -24px; } .h5-font { diff --git a/src/app/item-page/clarin-ref-box/clarin-ref-box.component.html b/src/app/item-page/clarin-ref-box/clarin-ref-box.component.html index 6b415326c92..ed66dd735e5 100644 --- a/src/app/item-page/clarin-ref-box/clarin-ref-box.component.html +++ b/src/app/item-page/clarin-ref-box/clarin-ref-box.component.html @@ -1,4 +1,4 @@ -
+
diff --git a/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.scss b/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.scss index 9e5a56b24bc..d72dd3b937d 100644 --- a/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.scss +++ b/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.scss @@ -3,6 +3,7 @@ border: 1px solid #fbeed5 !important; color: #c09853; border-radius: 6px 6px 0 0; + width: 100%; } .clarin-ref-box-header { diff --git a/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.ts b/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.ts index 7a446bffdc8..4c44e5c72a0 100644 --- a/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.ts +++ b/src/app/item-page/clarin-ref-citation/clarin-ref-citation.component.ts @@ -131,7 +131,7 @@ export class ClarinRefCitationComponent implements OnInit { authorText = authorMetadata[0]?.value; // There are more authors for the item if (authorMetadata.length > 1) { - authorText = '; ' + ET_AL_TEXT; + authorText = authorText + '; ' + ET_AL_TEXT; } return authorText; diff --git a/src/app/item-page/clarin-statistics-button/clarin-statistics-button.component.ts b/src/app/item-page/clarin-statistics-button/clarin-statistics-button.component.ts index 2748d2d99bd..d053311618d 100644 --- a/src/app/item-page/clarin-statistics-button/clarin-statistics-button.component.ts +++ b/src/app/item-page/clarin-statistics-button/clarin-statistics-button.component.ts @@ -35,7 +35,7 @@ export class ClarinStatisticsButtonComponent implements OnInit { constructor(protected authorizationService: AuthorizationDataService) { } ngOnInit() { - this.isAuthorized$ = this.authorizationService.isAuthorized(FeatureID.CanViewUsageStatistics, this.dso.self); + this.isAuthorized$ = this.authorizationService.isAuthorized(FeatureID.CanEditMetadata, this.dso.self); } } diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index f773daff76d..d7f9f9bdfaf 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -45,6 +45,9 @@ import { ClarinRefCitationModalComponent } from './clarin-ref-citation-modal/cla import { ClarinMatomoStatisticsComponent } from './clarin-matomo-statistics/clarin-matomo-statistics.component'; import { ClarinStatisticsButtonComponent } from './clarin-statistics-button/clarin-statistics-button.component'; import { ChartsModule } from 'ng2-charts'; +import { ClarinGenericItemFieldComponent } from './simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component'; +import { ClarinCollectionsItemFieldComponent } from './simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component'; +import { ClarinFilesItemFieldComponent } from './simple/field-components/clarin-files-item-field/clarin-files-item-field.component'; const ENTRY_COMPONENTS = [ @@ -82,6 +85,15 @@ const DECLARATIONS = [ ReplacedTombstoneComponent, WithdrawnTombstoneComponent, ClarinLicenseInfoComponent, + ClarinRefBoxComponent, + ClarinRefCitationComponent, + ClarinRefFeaturedServicesComponent, + ClarinRefCitationModalComponent, + ClarinMatomoStatisticsComponent, + ClarinStatisticsButtonComponent, + ClarinGenericItemFieldComponent, + ClarinCollectionsItemFieldComponent, + ClarinFilesItemFieldComponent ]; @NgModule({ @@ -98,13 +110,7 @@ const DECLARATIONS = [ ], declarations: [ ...DECLARATIONS, - VersionedItemComponent, - ClarinRefBoxComponent, - ClarinRefCitationComponent, - ClarinRefFeaturedServicesComponent, - ClarinRefCitationModalComponent, - ClarinMatomoStatisticsComponent, - ClarinStatisticsButtonComponent, + VersionedItemComponent ], exports: [ ...DECLARATIONS diff --git a/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.html b/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.html new file mode 100644 index 00000000000..fdb7e3df0b6 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.html @@ -0,0 +1,27 @@ +
+
+
+
{{'item.page.collections' | translate}}
+
+
+ + +
+ {{'item.page.collections.loading' | translate}} +
+ + + {{'item.page.collections.load-more' | translate}} + +
+
diff --git a/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.scss b/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.scss new file mode 100644 index 00000000000..42f906e2209 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.scss @@ -0,0 +1 @@ +@import '../../item-page.component'; diff --git a/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.ts b/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.ts new file mode 100644 index 00000000000..a5aa756c599 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component.ts @@ -0,0 +1,132 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Item } from '../../../../core/shared/item.model'; +import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; +import { Collection } from '../../../../core/shared/collection.model'; +import { CollectionDataService } from '../../../../core/data/collection-data.service'; +import { + getAllCompletedRemoteData, + getAllSucceededRemoteDataPayload, + getFirstSucceededRemoteDataPayload, getPaginatedListPayload + } from '../../../../core/shared/operators'; +import { map, scan, startWith, switchMap, tap, withLatestFrom } from 'rxjs/operators'; +import { FindListOptions } from '../../../../core/data/request.models'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { hasValue } from '../../../../shared/empty.util'; + +@Component({ + selector: 'ds-clarin-collections-item-field', + templateUrl: './clarin-collections-item-field.component.html', + styleUrls: ['./clarin-collections-item-field.component.scss'] +}) +export class ClarinCollectionsItemFieldComponent implements OnInit { + + /** + * The item to display metadata for + */ + @Input() item: Item; + + /** + * Fontawesome v5. icon name with default settings. + */ + @Input() iconName: string; + + /** + * Separator string between multiple values of the metadata fields defined + * @type {string} + */ + @Input() separator: string; + + /** + * Name of the metadata field. + */ + label: 'item.page.collections'; + + /** + * Amount of mapped collections that should be fetched at once. + */ + pageSize = 5; + + /** + * Last page of the mapped collections that has been fetched. + */ + lastPage$: BehaviorSubject = new BehaviorSubject(0); + + /** + * Push an event to this observable to fetch the next page of mapped collections. + * Because this observable is a behavior subject, the first page will be requested + * immediately after subscription. + */ + loadMore$: BehaviorSubject = new BehaviorSubject(undefined); + + /** + * Whether or not a page of mapped collections is currently being loaded. + */ + isLoading$: BehaviorSubject = new BehaviorSubject(true); + + /** + * Whether or not more pages of mapped collections are available. + */ + hasMore$: BehaviorSubject = new BehaviorSubject(true); + + /** + * All collections that have been retrieved so far. This includes the owning collection, + * as well as any number of pages of mapped collections. + */ + collections$: Observable; + + constructor(private cds: CollectionDataService) { + + } + + ngOnInit(): void { + const owningCollection$: Observable = this.cds.findOwningCollectionFor(this.item).pipe( + getFirstSucceededRemoteDataPayload(), + startWith(null as Collection), + ); + + const mappedCollections$: Observable = this.loadMore$.pipe( + // update isLoading$ + tap(() => this.isLoading$.next(true)), + + // request next batch of mapped collections + withLatestFrom(this.lastPage$), + switchMap(([_, lastPage]: [void, number]) => { + return this.cds.findMappedCollectionsFor(this.item, Object.assign(new FindListOptions(), { + elementsPerPage: this.pageSize, + currentPage: lastPage + 1, + })); + }), + + getAllCompletedRemoteData>(), + + // update isLoading$ + tap(() => this.isLoading$.next(false)), + + getAllSucceededRemoteDataPayload(), + + // update hasMore$ + tap((response: PaginatedList) => this.hasMore$.next(response.currentPage < response.totalPages)), + + // update lastPage$ + tap((response: PaginatedList) => this.lastPage$.next(response.currentPage)), + + getPaginatedListPayload(), + + // add current batch to list of collections + scan((prev: Collection[], current: Collection[]) => [...prev, ...current], []), + + startWith([]), + ) as Observable; + + this.collections$ = combineLatest([owningCollection$, mappedCollections$]).pipe( + map(([owningCollection, mappedCollections]: [Collection, Collection[]]) => { + return [owningCollection, ...mappedCollections].filter(collection => hasValue(collection)); + }), + ); + } + + handleLoadMore() { + this.loadMore$.next(); + } + +} diff --git a/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.html b/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.html new file mode 100644 index 00000000000..de09807c1f5 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.html @@ -0,0 +1,22 @@ +
+
+
+
{{'item.page.files' | translate}}
+
+
+
+ + {{file?.name}} + ({{(file?.sizeBytes) | dsFileSize }}) + + + + + +
+
+
diff --git a/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.scss b/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.scss new file mode 100644 index 00000000000..42f906e2209 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.scss @@ -0,0 +1 @@ +@import '../../item-page.component'; diff --git a/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.ts b/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.ts new file mode 100644 index 00000000000..6c12f134410 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-files-item-field/clarin-files-item-field.component.ts @@ -0,0 +1,92 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Item } from '../../../../core/shared/item.model'; +import { BehaviorSubject } from 'rxjs'; +import { Bitstream } from '../../../../core/shared/bitstream.model'; +import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; +import { NotificationsService } from '../../../../shared/notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; +import { getFirstCompletedRemoteData } from '../../../../core/shared/operators'; +import { RemoteData } from '../../../../core/data/remote-data'; +import { PaginatedList } from '../../../../core/data/paginated-list.model'; +import { hasValue } from '../../../../shared/empty.util'; + +@Component({ + selector: 'ds-clarin-files-item-field', + templateUrl: './clarin-files-item-field.component.html', + styleUrls: ['./clarin-files-item-field.component.scss'] +}) +export class ClarinFilesItemFieldComponent implements OnInit { + + /** + * The item to display metadata for + */ + @Input() item: Item; + + /** + * Fontawesome v5. icon name with default settings. + */ + @Input() iconName: string; + + /** + * Separator string between multiple values of the metadata fields defined + * @type {string} + */ + @Input() separator: string; + + /** + * Name of the metadata field. + */ + label = 'item.page.files'; + + bitstreams$: BehaviorSubject; + + currentPage: number; + + isLoading: boolean; + + isLastPage: boolean; + + pageSize = 5; + + constructor( + protected bitstreamDataService: BitstreamDataService, + protected notificationsService: NotificationsService, + protected translateService: TranslateService + ) { + } + + ngOnInit(): void { + this.getNextPage(); + } + + /** + * This method will retrieve the next page of Bitstreams from the external BitstreamDataService call. + * It'll retrieve the currentPage from the class variables and it'll add the next page of bitstreams with the + * already existing one. + * If the currentPage variable is undefined, we'll set it to 1 and retrieve the first page of Bitstreams + */ + getNextPage(): void { + this.isLoading = true; + if (this.currentPage === undefined) { + this.currentPage = 1; + this.bitstreams$ = new BehaviorSubject([]); + } else { + this.currentPage++; + } + this.bitstreamDataService.findAllByItemAndBundleName(this.item, 'ORIGINAL', { + currentPage: this.currentPage, + elementsPerPage: this.pageSize + }).pipe( + getFirstCompletedRemoteData(), + ).subscribe((bitstreamsRD: RemoteData>) => { + if (bitstreamsRD.errorMessage) { + this.notificationsService.error(this.translateService.get('file-section.error.header'), `${bitstreamsRD.statusCode} ${bitstreamsRD.errorMessage}`); + } else if (hasValue(bitstreamsRD.payload)) { + const current: Bitstream[] = this.bitstreams$.getValue(); + this.bitstreams$.next([...current, ...bitstreamsRD.payload.page]); + this.isLoading = false; + this.isLastPage = this.currentPage === bitstreamsRD.payload.totalPages; + } + }); + } +} diff --git a/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.html b/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.html new file mode 100644 index 00000000000..d993db6ae2c --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.html @@ -0,0 +1,16 @@ +
+
+
+
{{label | translate}}
+
+
+
+ + {{mdValue.value}} + + {{mdValue.value}} + + +
+
+
diff --git a/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.scss b/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.scss new file mode 100644 index 00000000000..42f906e2209 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.scss @@ -0,0 +1 @@ +@import '../../item-page.component'; diff --git a/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.ts b/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.ts new file mode 100644 index 00000000000..ae4120b1b96 --- /dev/null +++ b/src/app/item-page/simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component.ts @@ -0,0 +1,54 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Item } from '../../../../core/shared/item.model'; +import { isNotUndefined } from '../../../../shared/empty.util'; + +@Component({ + selector: 'ds-clarin-generic-item-field', + templateUrl: './clarin-generic-item-field.component.html', + styleUrls: ['./clarin-generic-item-field.component.scss'] +}) +export class ClarinGenericItemFieldComponent implements OnInit { + + /** + * The item to display metadata for + */ + @Input() item: Item; + + /** + * Fontawesome v5. icon name with default settings. + */ + @Input() iconName: string; + + /** + * For now the specific type could be only 'hyperlink' which redirects to the page from the metadata value. + */ + @Input() type: string; + + /** + * Separator string between multiple values of the metadata fields defined + * @type {string} + */ + @Input() separator: string; + + /** + * Fields (schema.element.qualifier) used to render their values. + */ + @Input() fields: string[]; + + /** + * Label i18n key for the rendered metadata + */ + @Input() label: string; + + // tslint:disable-next-line:no-empty + constructor() { } + + // tslint:disable-next-line:no-empty + ngOnInit(): void { + } + + public hasMetadataValue() { + return isNotUndefined(this.item.firstMetadataValue(this.fields)); + } + +} diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index a95edcac5a1..c4c245e5604 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -1,4 +1,5 @@ -
+
@@ -7,9 +8,9 @@ - - - + + +
diff --git a/src/app/item-page/simple/item-page.component.scss b/src/app/item-page/simple/item-page.component.scss index a99cbd688fe..f28ce613865 100644 --- a/src/app/item-page/simple/item-page.component.scss +++ b/src/app/item-page/simple/item-page.component.scss @@ -4,3 +4,26 @@ max-width: none; } } + +.clarin-item-page-field { + border-bottom: 1px dotted #f8f8f8; + padding-top: 10px; + padding-bottom: 10px; +} + +.clarin-home-page-borders { + border-left: 1px solid silver; + border-right: 1px solid silver; +} + +.clarin-shadow { + box-shadow: 8px 0px 8px -7px rgb(0 0 0 / 8%), -8px 0px 8px -7px rgb(0 0 0 / 8%); +} + +.clarin-cut-bottom-2 { + margin-bottom: -24px; +} + +.clarin-cut-top-1 { + margin-top: -16px; +} diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index bace9fcd0ad..08b00d61f2c 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -1,4 +1,4 @@ -
+
-
+

- {{'publication.page.titleprefix' | translate}} +

+
-
- - - - - +
+ - - - - - - - - - - - - -
- diff --git a/src/app/item-page/simple/item-types/publication/publication.component.scss b/src/app/item-page/simple/item-types/publication/publication.component.scss index 3575cae797d..d21979ab1bb 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.scss +++ b/src/app/item-page/simple/item-types/publication/publication.component.scss @@ -1 +1,2 @@ @import '../../../../../styles/variables.scss'; +@import "../../item-page.component"; diff --git a/src/app/item-page/simple/item-types/publication/publication.component.spec.ts b/src/app/item-page/simple/item-types/publication/publication.component.spec.ts index 761849f2328..0b55e5e9cdd 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.spec.ts +++ b/src/app/item-page/simple/item-types/publication/publication.component.spec.ts @@ -103,35 +103,10 @@ describe('PublicationComponent', () => { fixture.detectChanges(); })); - it('should contain a component to display the date', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-date-field')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); - it('should not contain a metadata only author field', () => { const fields = fixture.debugElement.queryAll(By.css('ds-item-page-author-field')); expect(fields.length).toBe(0); }); - - it('should contain a mixed metadata and relationship field for authors', () => { - const fields = fixture.debugElement.queryAll(By.css('.ds-item-page-mixed-author-field')); - expect(fields.length).toBe(1); - }); - - it('should contain a component to display the abstract', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-abstract-field')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); - - it('should contain a component to display the uri', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-uri-field')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); - - it('should contain a component to display the collections', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-collections')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); }); describe('with IIIF viewer', () => { diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 4c4ddabb302..1524db659fe 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -1,4 +1,4 @@ -
+
-
+

@@ -20,66 +20,88 @@

-
- - - - - +
+ - - - - - - - - - - - - -
- diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.scss b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.scss index 3575cae797d..ae2660b26c8 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.scss +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.scss @@ -1 +1,3 @@ @import '../../../../../styles/variables.scss'; +@import "../../item-page.component"; + diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts index efbb4672a5e..f2845784ff3 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.spec.ts @@ -119,36 +119,11 @@ describe('UntypedItemComponent', () => { fixture.detectChanges(); })); - it('should contain a component to display the date', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-date-field')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); - it('should not contain a metadata only author field', () => { const fields = fixture.debugElement.queryAll(By.css('ds-item-page-author-field')); expect(fields.length).toBe(0); }); - it('should contain a mixed metadata and relationship field for authors', () => { - const fields = fixture.debugElement.queryAll(By.css('.ds-item-page-mixed-author-field')); - expect(fields.length).toBe(1); - }); - - it('should contain a component to display the abstract', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-abstract-field')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); - - it('should contain a component to display the uri', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-uri-field')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); - - it('should contain a component to display the collections', () => { - const fields = fixture.debugElement.queryAll(By.css('ds-item-page-collections')); - expect(fields.length).toBeGreaterThanOrEqual(1); - }); - it('should not contain an iiif viewer component', () => { const fields = fixture.debugElement.queryAll(By.css('ds-mirador-viewer')); expect(fields.length).toBe(0); diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 84438d3f1e2..7715481d8da 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2233,6 +2233,18 @@ "item.search.title": "Item Search", + "item.page.project-url": "Project URL", + + "item.page.referenced-by": "Referenced by", + + "item.page.type": "Type", + + "item.page.size-info": "Size", + + "item.page.language": "Language(s)", + + "item.page.sponsor": "Acknowledgement", + "item.page.abstract": "Abstract", @@ -2266,7 +2278,7 @@ "item.page.journal.search.title": "Articles in this journal", - "item.page.link.full": "Full item page", + "item.page.link.full": "Show full item record", "item.page.link.simple": "Simple item page", @@ -2284,9 +2296,9 @@ "item.page.relationships.isOrgUnitOfProject": "Research Projects", - "item.page.subject": "Keywords", + "item.page.subject": "Subject(s)", - "item.page.uri": "URI", + "item.page.uri": "Item identifier", "item.page.bitstreams.view-more": "Show more",