From ec96962a87a5ff3d530d4aa435b50ca4aa3d325f Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Mon, 8 Oct 2018 17:50:52 +0200 Subject: [PATCH 01/33] 55946: Start of Edit Item Page Conflicts: resources/i18n/en.json --- resources/i18n/en.json | 61 +++++++++++++++++++ .../edit-item-page.component.html | 52 ++++++++++++++++ .../edit-item-page.component.scss | 0 .../edit-item-page.component.spec.ts | 0 .../edit-item-page.component.ts | 55 +++++++++++++++++ .../+item-page/item-page-routing.module.ts | 10 +++ src/app/+item-page/item-page.module.ts | 4 +- 7 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 src/app/+item-page/edit-item-page/edit-item-page.component.html create mode 100644 src/app/+item-page/edit-item-page/edit-item-page.component.scss create mode 100644 src/app/+item-page/edit-item-page/edit-item-page.component.spec.ts create mode 100644 src/app/+item-page/edit-item-page/edit-item-page.component.ts diff --git a/resources/i18n/en.json b/resources/i18n/en.json index b6a23068d7..deebe09760 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -43,6 +43,67 @@ "simple": "Simple item page", "full": "Full item page" } + }, + "select": { + "table": { + "collection": "Collection", + "author": "Author", + "title": "Title" + }, + "confirm": "Confirm selected" + }, + "edit": { + "head": "Edit Item", + "tabs": { + "status": { + "head": "Item Status", + "description": "Welcome to the item management page. From here you can withdraw, reinstate, move or delete the item. You may also update or add new metadata / bitstreams on the other tabs.", + "labels": { + "id": "Item Internal ID", + "handle": "Handle", + "lastModified": "Last Modified", + "itemPage": "Item Page" + }, + "buttons": { + "authorizations": { + "label": "Edit item's authorization policies", + "button": "Authorizations..." + }, + "withdraw": { + "label": "Withdraw item from the repository", + "button": "Withdraw..." + }, + "move": { + "label": "Move item to another collection", + "button": "Move..." + }, + "private": { + "label": "Make item private", + "button": "Make it private..." + }, + "delete": { + "label": "Completely expunge item", + "button": "Permanently delete" + }, + "mapped-collections": { + "label": "Manage mapped collections", + "button": "Mapped collections" + } + } + }, + "bitstreams": { + "head": "Item Bitstreams" + }, + "metadata": { + "head": "Item Metadata" + }, + "view": { + "head": "View Item" + }, + "curate": { + "head": "Curate" + } + } } }, "nav": { diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.html b/src/app/+item-page/edit-item-page/edit-item-page.component.html new file mode 100644 index 0000000000..ca15e83ab9 --- /dev/null +++ b/src/app/+item-page/edit-item-page/edit-item-page.component.html @@ -0,0 +1,52 @@ +
+
+
+

{{'item.edit.head' | translate}}

+
+ + + +

{{'item.edit.tabs.status.description' | translate}}

+
+
+
+ {{'item.edit.tabs.status.labels.' + statusKey | translate}}: +
+
+ {{(statusData$ | async)[statusKey]}} +
+
+
+ {{'item.edit.tabs.status.labels.itemPage' | translate}}: +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.scss b/src/app/+item-page/edit-item-page/edit-item-page.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.spec.ts b/src/app/+item-page/edit-item-page/edit-item-page.component.spec.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.ts b/src/app/+item-page/edit-item-page/edit-item-page.component.ts new file mode 100644 index 0000000000..eb017669fc --- /dev/null +++ b/src/app/+item-page/edit-item-page/edit-item-page.component.ts @@ -0,0 +1,55 @@ +import { fadeIn, fadeInOut } from '../../shared/animations/fade'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { ItemDataService } from '../../core/data/item-data.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import { RemoteData } from '../../core/data/remote-data'; +import { Item } from '../../core/shared/item.model'; +import { getSucceededRemoteData } from '../../core/shared/operators'; +import { map } from 'rxjs/operators'; + +@Component({ + selector: 'ds-edit-item-page', + styleUrls: ['./edit-item-page.component.scss'], + templateUrl: './edit-item-page.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + animations: [ + fadeIn, + fadeInOut + ] +}) +/** + * Page component for editing an item + */ +export class EditItemPageComponent implements OnInit { + + objectKeys = Object.keys; + + /** + * The item to edit + */ + itemRD$: Observable>; + statusData$: Observable; + + constructor(private route: ActivatedRoute, + private router: Router) { + } + + ngOnInit(): void { + this.itemRD$ = this.route.data.map((data) => data.item); + this.statusData$ = this.itemRD$.pipe( + getSucceededRemoteData(), + map((itemRD: RemoteData) => itemRD.payload), + map((item: Item) => Object.assign({ + id: item.id, + handle: item.handle, + lastModified: item.lastModified + })) + ) + } + + getItemPage(): string { + return this.router.url.substr(0, this.router.url.lastIndexOf('/')); + } + +} diff --git a/src/app/+item-page/item-page-routing.module.ts b/src/app/+item-page/item-page-routing.module.ts index 96158b867e..0105c947e9 100644 --- a/src/app/+item-page/item-page-routing.module.ts +++ b/src/app/+item-page/item-page-routing.module.ts @@ -4,6 +4,8 @@ import { RouterModule } from '@angular/router'; import { ItemPageComponent } from './simple/item-page.component'; import { FullItemPageComponent } from './full/full-item-page.component'; import { ItemPageResolver } from './item-page.resolver'; +import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; +import { EditItemPageComponent } from './edit-item-page/edit-item-page.component'; @NgModule({ imports: [ @@ -22,6 +24,14 @@ import { ItemPageResolver } from './item-page.resolver'; resolve: { item: ItemPageResolver } + }, + { + path: ':id/edit', + component: EditItemPageComponent, + resolve: { + item: ItemPageResolver + }, + canActivate: [AuthenticatedGuard] } ]) ], diff --git a/src/app/+item-page/item-page.module.ts b/src/app/+item-page/item-page.module.ts index bd801923e3..45251bb1d8 100644 --- a/src/app/+item-page/item-page.module.ts +++ b/src/app/+item-page/item-page.module.ts @@ -18,6 +18,7 @@ import { FileSectionComponent } from './simple/field-components/file-section/fil import { CollectionsComponent } from './field-components/collections/collections.component'; import { FullItemPageComponent } from './full/full-item-page.component'; import { FullFileSectionComponent } from './full/field-components/file-section/full-file-section.component'; +import { EditItemPageComponent } from './edit-item-page/edit-item-page.component'; @NgModule({ imports: [ @@ -39,7 +40,8 @@ import { FullFileSectionComponent } from './full/field-components/file-section/f ItemPageSpecificFieldComponent, FileSectionComponent, CollectionsComponent, - FullFileSectionComponent + FullFileSectionComponent, + EditItemPageComponent ] }) export class ItemPageModule { From 05a4918ef0a15ba27c5a80c87767b88f7ed3352f Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Tue, 9 Oct 2018 11:51:52 +0200 Subject: [PATCH 02/33] 55946: Finished edit-item-page and start of collection mapper --- resources/i18n/en.json | 2 +- .../edit-item-page.component.html | 18 +--- .../edit-item-page.component.ts | 24 +----- .../edit-item-page/edit-item-page.module.ts | 23 ++++++ .../edit-item-page.routing.module.ts | 32 ++++++++ .../item-collection-mapper.component.html | 7 ++ .../item-collection-mapper.component.scss | 0 .../item-collection-mapper.component.spec.ts | 0 .../item-collection-mapper.component.ts | 19 +++++ .../item-status/item-status.component.html | 30 +++++++ .../item-status/item-status.component.scss | 0 .../item-status/item-status.component.spec.ts | 0 .../item-status/item-status.component.ts | 82 +++++++++++++++++++ .../+item-page/item-page-routing.module.ts | 6 +- src/app/+item-page/item-page.module.ts | 6 +- 15 files changed, 201 insertions(+), 48 deletions(-) create mode 100644 src/app/+item-page/edit-item-page/edit-item-page.module.ts create mode 100644 src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts create mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html create mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.scss create mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts create mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts create mode 100644 src/app/+item-page/edit-item-page/item-status/item-status.component.html create mode 100644 src/app/+item-page/edit-item-page/item-status/item-status.component.scss create mode 100644 src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts create mode 100644 src/app/+item-page/edit-item-page/item-status/item-status.component.ts diff --git a/resources/i18n/en.json b/resources/i18n/en.json index deebe09760..5cd54869d2 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -85,7 +85,7 @@ "label": "Completely expunge item", "button": "Permanently delete" }, - "mapped-collections": { + "mappedCollections": { "label": "Manage mapped collections", "button": "Mapped collections" } diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.html b/src/app/+item-page/edit-item-page/edit-item-page.component.html index ca15e83ab9..001b484c2c 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.component.html +++ b/src/app/+item-page/edit-item-page/edit-item-page.component.html @@ -6,23 +6,7 @@ -

{{'item.edit.tabs.status.description' | translate}}

-
-
-
- {{'item.edit.tabs.status.labels.' + statusKey | translate}}: -
-
- {{(statusData$ | async)[statusKey]}} -
-
-
- {{'item.edit.tabs.status.labels.itemPage' | translate}}: -
- -
+
diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.ts b/src/app/+item-page/edit-item-page/edit-item-page.component.ts index eb017669fc..7702fc94e8 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.component.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.component.ts @@ -1,12 +1,9 @@ import { fadeIn, fadeInOut } from '../../shared/animations/fade'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { ItemDataService } from '../../core/data/item-data.service'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import { RemoteData } from '../../core/data/remote-data'; import { Item } from '../../core/shared/item.model'; -import { getSucceededRemoteData } from '../../core/shared/operators'; -import { map } from 'rxjs/operators'; @Component({ selector: 'ds-edit-item-page', @@ -23,33 +20,16 @@ import { map } from 'rxjs/operators'; */ export class EditItemPageComponent implements OnInit { - objectKeys = Object.keys; - /** * The item to edit */ itemRD$: Observable>; - statusData$: Observable; - constructor(private route: ActivatedRoute, - private router: Router) { + constructor(private route: ActivatedRoute) { } ngOnInit(): void { this.itemRD$ = this.route.data.map((data) => data.item); - this.statusData$ = this.itemRD$.pipe( - getSucceededRemoteData(), - map((itemRD: RemoteData) => itemRD.payload), - map((item: Item) => Object.assign({ - id: item.id, - handle: item.handle, - lastModified: item.lastModified - })) - ) - } - - getItemPage(): string { - return this.router.url.substr(0, this.router.url.lastIndexOf('/')); } } diff --git a/src/app/+item-page/edit-item-page/edit-item-page.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.module.ts new file mode 100644 index 0000000000..70f6fc7d3b --- /dev/null +++ b/src/app/+item-page/edit-item-page/edit-item-page.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SharedModule } from '../../shared/shared.module'; +import { EditItemPageRoutingModule } from './edit-item-page.routing.module'; +import { EditItemPageComponent } from './edit-item-page.component'; +import { ItemCollectionMapperComponent } from './item-collection-mapper/item-collection-mapper.component'; +import { ItemStatusComponent } from './item-status/item-status.component'; + +@NgModule({ + imports: [ + CommonModule, + SharedModule, + EditItemPageRoutingModule + ], + declarations: [ + EditItemPageComponent, + ItemStatusComponent, + ItemCollectionMapperComponent + ] +}) +export class EditItemPageModule { + +} diff --git a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts new file mode 100644 index 0000000000..f2209cddcc --- /dev/null +++ b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts @@ -0,0 +1,32 @@ +import { ItemPageResolver } from '../item-page.resolver'; +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { EditItemPageComponent } from './edit-item-page.component'; +import { ItemCollectionMapperComponent } from './item-collection-mapper/item-collection-mapper.component'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { + path: '', + component: EditItemPageComponent, + resolve: { + item: ItemPageResolver + } + }, + { + path: 'map', + component: ItemCollectionMapperComponent, + resolve: { + item: ItemPageResolver + } + } + ]) + ], + providers: [ + ItemPageResolver, + ] +}) +export class EditItemPageRoutingModule { + +} diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html new file mode 100644 index 0000000000..3fb829fe8b --- /dev/null +++ b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html @@ -0,0 +1,7 @@ +
+
+
+

It works!

+
+
+
diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.scss b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts new file mode 100644 index 0000000000..592e3bd26c --- /dev/null +++ b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts @@ -0,0 +1,19 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { fadeIn, fadeInOut } from '../../../shared/animations/fade'; + +@Component({ + selector: 'ds-item-collection-mapper', + styleUrls: ['./item-collection-mapper.component.scss'], + templateUrl: './item-collection-mapper.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + animations: [ + fadeIn, + fadeInOut + ] +}) +/** + * Component for mapping collections to an item + */ +export class ItemCollectionMapperComponent { + +} diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.html b/src/app/+item-page/edit-item-page/item-status/item-status.component.html new file mode 100644 index 0000000000..0a93e7659d --- /dev/null +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.html @@ -0,0 +1,30 @@ +

{{'item.edit.tabs.status.description' | translate}}

+
+
+
+ {{'item.edit.tabs.status.labels.' + statusKey | translate}}: +
+
+ {{statusData[statusKey]}} +
+
+
+ {{'item.edit.tabs.status.labels.itemPage' | translate}}: +
+ + +
+
+ + {{'item.edit.tabs.status.buttons.' + actionKey + '.label' | translate}} + +
+ +
+
diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.scss b/src/app/+item-page/edit-item-page/item-status/item-status.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts new file mode 100644 index 0000000000..715614c1d9 --- /dev/null +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts @@ -0,0 +1,82 @@ +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { fadeIn, fadeInOut } from '../../../shared/animations/fade'; +import { Item } from '../../../core/shared/item.model'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'ds-item-status', + styleUrls: ['./item-status.component.scss'], + templateUrl: './item-status.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, + animations: [ + fadeIn, + fadeInOut + ] +}) +/** + * Component for displaying an item's status + */ +export class ItemStatusComponent implements OnInit { + + /** + * The item to display the status for + */ + @Input() item: Item; + + /** + * The data to show in the status + */ + statusData: any; + /** + * The keys of the data (to loop over) + */ + statusDataKeys; + + /** + * The possible actions that can be performed on the item + * key: id value: url to action's component + */ + actions: any; + /** + * The keys of the actions (to loop over) + */ + actionsKeys; + + constructor(private router: Router) { + } + + ngOnInit(): void { + this.statusData = Object.assign({ + id: this.item.id, + handle: this.item.handle, + lastModified: this.item.lastModified + }); + this.statusDataKeys = Object.keys(this.statusData); + + this.actions = Object.assign({ + mappedCollections: this.getCurrentUrl() + '/map' + }); + this.actionsKeys = Object.keys(this.actions); + } + + /** + * Get the url to the simple item page + * @returns {string} url + */ + getItemPage(): string { + return this.router.url.substr(0, this.router.url.lastIndexOf('/')); + } + + /** + * Get the current url without query params + * @returns {string} url + */ + getCurrentUrl(): string { + if (this.router.url.indexOf('?') > -1) { + return this.router.url.substr(0, this.router.url.indexOf('?')); + } else { + return this.router.url; + } + } + +} diff --git a/src/app/+item-page/item-page-routing.module.ts b/src/app/+item-page/item-page-routing.module.ts index 0105c947e9..be31b0a82d 100644 --- a/src/app/+item-page/item-page-routing.module.ts +++ b/src/app/+item-page/item-page-routing.module.ts @@ -5,7 +5,6 @@ import { ItemPageComponent } from './simple/item-page.component'; import { FullItemPageComponent } from './full/full-item-page.component'; import { ItemPageResolver } from './item-page.resolver'; import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; -import { EditItemPageComponent } from './edit-item-page/edit-item-page.component'; @NgModule({ imports: [ @@ -27,10 +26,7 @@ import { EditItemPageComponent } from './edit-item-page/edit-item-page.component }, { path: ':id/edit', - component: EditItemPageComponent, - resolve: { - item: ItemPageResolver - }, + loadChildren: './edit-item-page/edit-item-page.module#EditItemPageModule', canActivate: [AuthenticatedGuard] } ]) diff --git a/src/app/+item-page/item-page.module.ts b/src/app/+item-page/item-page.module.ts index 45251bb1d8..d383189a9c 100644 --- a/src/app/+item-page/item-page.module.ts +++ b/src/app/+item-page/item-page.module.ts @@ -18,12 +18,13 @@ import { FileSectionComponent } from './simple/field-components/file-section/fil import { CollectionsComponent } from './field-components/collections/collections.component'; import { FullItemPageComponent } from './full/full-item-page.component'; import { FullFileSectionComponent } from './full/field-components/file-section/full-file-section.component'; -import { EditItemPageComponent } from './edit-item-page/edit-item-page.component'; +import { EditItemPageModule } from './edit-item-page/edit-item-page.module'; @NgModule({ imports: [ CommonModule, SharedModule, + EditItemPageModule, ItemPageRoutingModule ], declarations: [ @@ -40,8 +41,7 @@ import { EditItemPageComponent } from './edit-item-page/edit-item-page.component ItemPageSpecificFieldComponent, FileSectionComponent, CollectionsComponent, - FullFileSectionComponent, - EditItemPageComponent + FullFileSectionComponent ] }) export class ItemPageModule { From fb0e1d81e4f461c8eac754831877d2494cb74ac7 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Tue, 9 Oct 2018 14:30:40 +0200 Subject: [PATCH 03/33] 55946: Edit item page cleanup --- .../edit-item-page/edit-item-page.module.ts | 4 +--- .../edit-item-page.routing.module.ts | 8 -------- .../item-collection-mapper.component.html | 7 ------- .../item-collection-mapper.component.scss | 0 .../item-collection-mapper.component.spec.ts | 0 .../item-collection-mapper.component.ts | 19 ------------------- .../item-status/item-status.component.ts | 8 +++++++- 7 files changed, 8 insertions(+), 38 deletions(-) delete mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html delete mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.scss delete mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts delete mode 100644 src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts diff --git a/src/app/+item-page/edit-item-page/edit-item-page.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.module.ts index 70f6fc7d3b..e7016eb05d 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.module.ts @@ -3,7 +3,6 @@ import { CommonModule } from '@angular/common'; import { SharedModule } from '../../shared/shared.module'; import { EditItemPageRoutingModule } from './edit-item-page.routing.module'; import { EditItemPageComponent } from './edit-item-page.component'; -import { ItemCollectionMapperComponent } from './item-collection-mapper/item-collection-mapper.component'; import { ItemStatusComponent } from './item-status/item-status.component'; @NgModule({ @@ -14,8 +13,7 @@ import { ItemStatusComponent } from './item-status/item-status.component'; ], declarations: [ EditItemPageComponent, - ItemStatusComponent, - ItemCollectionMapperComponent + ItemStatusComponent ] }) export class EditItemPageModule { diff --git a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts index f2209cddcc..46e8dab609 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts @@ -2,7 +2,6 @@ import { ItemPageResolver } from '../item-page.resolver'; import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { EditItemPageComponent } from './edit-item-page.component'; -import { ItemCollectionMapperComponent } from './item-collection-mapper/item-collection-mapper.component'; @NgModule({ imports: [ @@ -13,13 +12,6 @@ import { ItemCollectionMapperComponent } from './item-collection-mapper/item-col resolve: { item: ItemPageResolver } - }, - { - path: 'map', - component: ItemCollectionMapperComponent, - resolve: { - item: ItemPageResolver - } } ]) ], diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html deleted file mode 100644 index 3fb829fe8b..0000000000 --- a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.html +++ /dev/null @@ -1,7 +0,0 @@ -
-
-
-

It works!

-
-
-
diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.scss b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.spec.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts b/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts deleted file mode 100644 index 592e3bd26c..0000000000 --- a/src/app/+item-page/edit-item-page/item-collection-mapper/item-collection-mapper.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { fadeIn, fadeInOut } from '../../../shared/animations/fade'; - -@Component({ - selector: 'ds-item-collection-mapper', - styleUrls: ['./item-collection-mapper.component.scss'], - templateUrl: './item-collection-mapper.component.html', - changeDetection: ChangeDetectionStrategy.OnPush, - animations: [ - fadeIn, - fadeInOut - ] -}) -/** - * Component for mapping collections to an item - */ -export class ItemCollectionMapperComponent { - -} diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts index 715614c1d9..8d68a9e961 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts @@ -53,8 +53,14 @@ export class ItemStatusComponent implements OnInit { }); this.statusDataKeys = Object.keys(this.statusData); + /* + The key is used to build messages + i18n example: 'item.edit.tabs.status.buttons..label' + The value is supposed to be a href for the button + */ this.actions = Object.assign({ - mappedCollections: this.getCurrentUrl() + '/map' + // TODO: Create mapping component on item level + mappedCollections: this.getCurrentUrl() + '/' }); this.actionsKeys = Object.keys(this.actions); } From 7d9afeefea78ee1cbe60a2ba74a687cf6014658f Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Tue, 9 Oct 2018 15:32:55 +0200 Subject: [PATCH 04/33] 55946: Removed unnecessary files and created tests --- .../edit-item-page.component.scss | 0 .../edit-item-page.component.spec.ts | 0 .../edit-item-page.component.ts | 1 - .../item-status/item-status.component.html | 12 ++-- .../item-status/item-status.component.scss | 0 .../item-status/item-status.component.spec.ts | 67 +++++++++++++++++++ .../item-status/item-status.component.ts | 1 - 7 files changed, 73 insertions(+), 8 deletions(-) delete mode 100644 src/app/+item-page/edit-item-page/edit-item-page.component.scss delete mode 100644 src/app/+item-page/edit-item-page/edit-item-page.component.spec.ts delete mode 100644 src/app/+item-page/edit-item-page/item-status/item-status.component.scss diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.scss b/src/app/+item-page/edit-item-page/edit-item-page.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.spec.ts b/src/app/+item-page/edit-item-page/edit-item-page.component.spec.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.ts b/src/app/+item-page/edit-item-page/edit-item-page.component.ts index 7702fc94e8..8bcf53f140 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.component.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.component.ts @@ -7,7 +7,6 @@ import { Item } from '../../core/shared/item.model'; @Component({ selector: 'ds-edit-item-page', - styleUrls: ['./edit-item-page.component.scss'], templateUrl: './edit-item-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, animations: [ diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.html b/src/app/+item-page/edit-item-page/item-status/item-status.component.html index 0a93e7659d..78ab9174eb 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.html +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.html @@ -1,27 +1,27 @@

{{'item.edit.tabs.status.description' | translate}}

-
+
{{'item.edit.tabs.status.labels.' + statusKey | translate}}:
-
+
{{statusData[statusKey]}}
-
+
{{'item.edit.tabs.status.labels.itemPage' | translate}}:
-
+
-
+
{{'item.edit.tabs.status.buttons.' + actionKey + '.label' | translate}}
-
+
{{'item.edit.tabs.status.buttons.' + actionKey + '.button' | translate}} diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.scss b/src/app/+item-page/edit-item-page/item-status/item-status.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts index e69de29bb2..2df4b977cb 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts @@ -0,0 +1,67 @@ +import { ItemStatusComponent } from './item-status.component'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { CommonModule } from '@angular/common'; +import { HostWindowServiceStub } from '../../../shared/testing/host-window-service-stub'; +import { HostWindowService } from '../../../shared/host-window.service'; +import { RouterTestingModule } from '@angular/router/testing'; +import { Router } from '@angular/router'; +import { RouterStub } from '../../../shared/testing/router-stub'; +import { Item } from '../../../core/shared/item.model'; +import { By } from '@angular/platform-browser'; + +describe('ItemStatusComponent', () => { + let comp: ItemStatusComponent; + let fixture: ComponentFixture; + + const mockItem = Object.assign(new Item(), { + id: 'fake-id', + handle: 'fake/handle', + lastModified: '2018' + }); + + const itemPageUrl = `fake-url/${mockItem.id}`; + const routerStub = Object.assign(new RouterStub(), { + url: `${itemPageUrl}/edit` + }); + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule.forRoot()], + declarations: [ItemStatusComponent], + providers: [ + { provide: Router, useValue: routerStub }, + { provide: HostWindowService, useValue: new HostWindowServiceStub(0) } + ] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemStatusComponent); + comp = fixture.componentInstance; + comp.item = mockItem; + fixture.detectChanges(); + }); + + it('should display the item\'s internal id', () => { + const statusId: HTMLElement = fixture.debugElement.query(By.css('.status-data#status-id')).nativeElement; + expect(statusId.textContent).toContain(mockItem.id); + }); + + it('should display the item\'s handle', () => { + const statusHandle: HTMLElement = fixture.debugElement.query(By.css('.status-data#status-handle')).nativeElement; + expect(statusHandle.textContent).toContain(mockItem.handle); + }); + + it('should display the item\'s last modified date', () => { + const statusLastModified: HTMLElement = fixture.debugElement.query(By.css('.status-data#status-lastModified')).nativeElement; + expect(statusLastModified.textContent).toContain(mockItem.lastModified); + }); + + it('should display the item\'s page url', () => { + const statusItemPage: HTMLElement = fixture.debugElement.query(By.css('.status-data#status-itemPage')).nativeElement; + expect(statusItemPage.textContent).toContain(itemPageUrl); + }); + +}); diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts index 8d68a9e961..bc9dda61ec 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts @@ -5,7 +5,6 @@ import { Router } from '@angular/router'; @Component({ selector: 'ds-item-status', - styleUrls: ['./item-status.component.scss'], templateUrl: './item-status.component.html', changeDetection: ChangeDetectionStrategy.OnPush, animations: [ From 8570ff25784f2ccf93913f6e7a4954621de50e8c Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 25 Oct 2018 18:13:49 +0200 Subject: [PATCH 05/33] 55990: Item move component --- .../item-move/item-move.component.html | 51 +++++++++++++++++++ .../item-move/item-move.component.ts | 0 .../item-operation.component.html | 10 ++++ .../item-operation.component.ts | 0 .../item-operation/itemOperation.model.ts | 0 5 files changed, 61 insertions(+) create mode 100644 src/app/+item-page/edit-item-page/item-move/item-move.component.html create mode 100644 src/app/+item-page/edit-item-page/item-move/item-move.component.ts create mode 100644 src/app/+item-page/edit-item-page/item-operation/item-operation.component.html create mode 100644 src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts create mode 100644 src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.html b/src/app/+item-page/edit-item-page/item-move/item-move.component.html new file mode 100644 index 0000000000..a060aa0fed --- /dev/null +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.html @@ -0,0 +1,51 @@ +import {Component, OnInit} from '@angular/core'; +import {Collection} from '../../../core/shared/collection.model'; +import {RemoteData} from '../../../core/data/remote-data'; +import {Item} from '../../../core/shared/item.model'; +import {getSucceededRemoteData} from '../../../core/shared/operators'; +import {Observable} from 'rxjs'; +import {PaginatedList} from '../../../core/data/paginated-list'; +import {TranslateService} from '@ngx-translate/core'; +import {NotificationsService} from '../../../shared/notifications/notifications.service'; +import {SearchService} from '../../../+search-page/search-service/search.service'; +import {SearchConfigurationService} from '../../../+search-page/search-service/search-configuration.service'; +import {ActivatedRoute, Router} from '@angular/router'; +import {CollectionDataService} from '../../../core/data/collection-data.service'; + +@Component({ + selector: 'ds-item-move', + templateUrl: './item-move.component.html' +}) +export class ItemMoveComponent implements OnInit { + inheritPolicies: boolean; + + itemRD$: Observable>; + + /** + * List of collections to show under the "Browse" tab + * Collections that are mapped to the item + */ + itemCollectionsRD$: Observable>>; + + constructor(private route: ActivatedRoute, + private router: Router, + private searchConfigService: SearchConfigurationService, + private searchService: SearchService, + private notificationsService: NotificationsService, + private collectionDataService: CollectionDataService, + private translateService: TranslateService) { + } + + ngOnInit(): void { + this.itemRD$ = this.route.data.map((data) => data.item).pipe(getSucceededRemoteData()) as Observable>; + this.loadCollectionLists(); + } + + /** + * Load all available collections to move the item to. + * TODO: When the API support it, only fetch collections where user has ADD rights to. + */ + loadCollectionLists() { + this.itemCollectionsRD$ = this.collectionDataService.findAll(); + } +} diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.html b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.html new file mode 100644 index 0000000000..59b625d8c0 --- /dev/null +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.html @@ -0,0 +1,10 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'ds-item-operation', + templateUrl: './ds-item-operation.html' +}) + +export class ItemOperationComponent { + +} diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts b/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts new file mode 100644 index 0000000000..e69de29bb2 From d26bba8e14847294d2453f575aab1aba0eb54c61 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 25 Oct 2018 18:14:22 +0200 Subject: [PATCH 06/33] 5590: Item move component --- resources/i18n/en.json | 10 ++ .../edit-item-page/edit-item-page.module.ts | 8 +- .../edit-item-page.routing.module.ts | 24 +++- .../item-move/item-move.component.html | 90 +++++++------- .../item-move/item-move.component.ts | 111 ++++++++++++++++++ .../item-operation.component.html | 25 ++-- .../item-operation.component.ts | 13 ++ .../item-operation/itemOperation.model.ts | 12 ++ .../item-status/item-status.component.html | 13 +- .../item-status/item-status.component.ts | 12 +- .../+item-page/item-page-routing.module.ts | 25 ++-- src/app/+search-page/search-page.module.ts | 80 +++++++------ src/app/app-routing.module.ts | 6 +- src/app/core/data/item-data.service.ts | 53 ++++++--- .../input-suggestions.component.ts | 9 ++ 15 files changed, 351 insertions(+), 140 deletions(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 5cd54869d2..2d20f21d17 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -103,6 +103,16 @@ "curate": { "head": "Curate" } + }, + "move": { + "head":"Move item: {{id}}", + "description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", + "inheritpolicies": { + "description": "Inherit the default policies of the destination collection", + "checkbox": "Inherit policies" + }, + "move": "Move", + "cancel": "Cancel" } } }, diff --git a/src/app/+item-page/edit-item-page/edit-item-page.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.module.ts index e7016eb05d..09a5e1d588 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.module.ts @@ -4,15 +4,21 @@ import { SharedModule } from '../../shared/shared.module'; import { EditItemPageRoutingModule } from './edit-item-page.routing.module'; import { EditItemPageComponent } from './edit-item-page.component'; import { ItemStatusComponent } from './item-status/item-status.component'; +import {ItemOperationComponent} from './item-operation/item-operation.component'; +import {ItemMoveComponent} from './item-move/item-move.component'; +import {SearchPageModule} from '../../+search-page/search-page.module'; @NgModule({ imports: [ CommonModule, SharedModule, - EditItemPageRoutingModule + EditItemPageRoutingModule, + SearchPageModule.forRoot(), ], declarations: [ EditItemPageComponent, + ItemOperationComponent, + ItemMoveComponent, ItemStatusComponent ] }) diff --git a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts index 46e8dab609..e9b0643cc1 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts @@ -1,7 +1,16 @@ -import { ItemPageResolver } from '../item-page.resolver'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; -import { EditItemPageComponent } from './edit-item-page.component'; +import {ItemPageResolver} from '../item-page.resolver'; +import {NgModule} from '@angular/core'; +import {RouterModule} from '@angular/router'; +import {EditItemPageComponent} from './edit-item-page.component'; +import {ItemMoveComponent} from './item-move/item-move.component'; +import {URLCombiner} from '../../core/url-combiner/url-combiner'; +import {getItemEditPath} from '../item-page-routing.module'; + +const ITEM_EDIT_MOVE_PATH = 'move'; + +export function getItemEditMovePath(id: string) { + return new URLCombiner(getItemEditPath(id), ITEM_EDIT_MOVE_PATH); +} @NgModule({ imports: [ @@ -12,6 +21,13 @@ import { EditItemPageComponent } from './edit-item-page.component'; resolve: { item: ItemPageResolver } + }, + { + path: ITEM_EDIT_MOVE_PATH, + component: ItemMoveComponent, + resolve: { + item: ItemPageResolver + } } ]) ], diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.html b/src/app/+item-page/edit-item-page/item-move/item-move.component.html index a060aa0fed..fe27ed36a5 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.html +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.html @@ -1,51 +1,41 @@ -import {Component, OnInit} from '@angular/core'; -import {Collection} from '../../../core/shared/collection.model'; -import {RemoteData} from '../../../core/data/remote-data'; -import {Item} from '../../../core/shared/item.model'; -import {getSucceededRemoteData} from '../../../core/shared/operators'; -import {Observable} from 'rxjs'; -import {PaginatedList} from '../../../core/data/paginated-list'; -import {TranslateService} from '@ngx-translate/core'; -import {NotificationsService} from '../../../shared/notifications/notifications.service'; -import {SearchService} from '../../../+search-page/search-service/search.service'; -import {SearchConfigurationService} from '../../../+search-page/search-service/search-configuration.service'; -import {ActivatedRoute, Router} from '@angular/router'; -import {CollectionDataService} from '../../../core/data/collection-data.service'; +
+
+
+

{{'item.edit.move.head' | translate: { id: (itemRD$ | async)?.payload?.id} }}

+

{{'item.edit.move.description' | translate}}

+
+
+ + +
+
+
+
+

+ + +

+

+ {{'item.edit.move.inheritpolicies.description' | translate}} +

+
+
-@Component({ - selector: 'ds-item-move', - templateUrl: './item-move.component.html' -}) -export class ItemMoveComponent implements OnInit { - inheritPolicies: boolean; - - itemRD$: Observable>; - - /** - * List of collections to show under the "Browse" tab - * Collections that are mapped to the item - */ - itemCollectionsRD$: Observable>>; - - constructor(private route: ActivatedRoute, - private router: Router, - private searchConfigService: SearchConfigurationService, - private searchService: SearchService, - private notificationsService: NotificationsService, - private collectionDataService: CollectionDataService, - private translateService: TranslateService) { - } - - ngOnInit(): void { - this.itemRD$ = this.route.data.map((data) => data.item).pipe(getSucceededRemoteData()) as Observable>; - this.loadCollectionLists(); - } - - /** - * Load all available collections to move the item to. - * TODO: When the API support it, only fetch collections where user has ADD rights to. - */ - loadCollectionLists() { - this.itemCollectionsRD$ = this.collectionDataService.findAll(); - } -} + + +
+
+
diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts index e69de29bb2..e0819257c2 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts @@ -0,0 +1,111 @@ +import {Component, OnInit} from '@angular/core'; +import {SearchService} from '../../../+search-page/search-service/search.service'; +import {Observable} from 'rxjs/Observable'; +import {map} from 'rxjs/operators'; +import {DSpaceObjectType} from '../../../core/shared/dspace-object-type.model'; +import {SearchOptions} from '../../../+search-page/search-options.model'; +import {RemoteData} from '../../../core/data/remote-data'; +import {DSpaceObject} from '../../../core/shared/dspace-object.model'; +import {PaginatedList} from '../../../core/data/paginated-list'; +import {SearchResult} from '../../../+search-page/search-result.model'; +import {PaginatedSearchOptions} from '../../../+search-page/paginated-search-options.model'; +import {Item} from '../../../core/shared/item.model'; +import {ActivatedRoute, Router} from '@angular/router'; +import {NotificationsService} from '../../../shared/notifications/notifications.service'; +import {CollectionDataService} from '../../../core/data/collection-data.service'; +import {SearchConfigurationService} from '../../../+search-page/search-service/search-configuration.service'; +import {TranslateService} from '@ngx-translate/core'; +import {getSucceededRemoteData} from '../../../core/shared/operators'; +import {ItemDataService} from '../../../core/data/item-data.service'; +import {RestResponse} from '../../../core/cache/response-cache.models'; +import {getItemEditPath} from '../../item-page-routing.module'; + +@Component({ + selector: 'ds-item-move', + templateUrl: './item-move.component.html' +}) +export class ItemMoveComponent implements OnInit { + + inheritPolicies = false; + itemRD$: Observable>; + /** + * Search options + */ + searchOptions$: Observable; + filterSearchResults: Observable = Observable.of([]); + selectedCollection: string; + + selectedCollectionId: string; + itemId: string; + + constructor(private route: ActivatedRoute, + private router: Router, + private notificationsService: NotificationsService, + private collectionDataService: CollectionDataService, + private itemDataService: ItemDataService, + private searchConfigService: SearchConfigurationService, + private searchService: SearchService, + private translateService: TranslateService) { + } + + ngOnInit(): void { + this.itemRD$ = this.route.data.map((data) => data.item).pipe(getSucceededRemoteData()) as Observable>; + this.itemRD$.first().subscribe((rd) => { + this.itemId = rd.payload.id; + } + ); + this.searchOptions$ = this.searchConfigService.paginatedSearchOptions; + this.loadSuggestions(''); + } + + findSuggestions(query): void { + this.loadSuggestions(query); + } + + /** + * Load all available collections to move the item to. + * TODO: When the API support it, only fetch collections where user has ADD rights to. + */ + loadSuggestions(query): void { + this.filterSearchResults = this.searchService.search(new SearchOptions({ + dsoType: DSpaceObjectType.COLLECTION, + query: query + })).first().pipe( + map((rd: RemoteData>>) => { + return rd.payload.page.map((searchResult) => { + return { + displayValue: searchResult.dspaceObject.name, + value: {name: searchResult.dspaceObject.name, id: searchResult.dspaceObject.uuid} + }; + }); + }) + ); + + } + + onClick(data: any): void { + this.selectedCollection = data.name; + this.selectedCollectionId = data.id; + } + + /** + * @returns {string} the current URL + */ + getCurrentUrl() { + return this.router.url; + } + + moveCollection() { + this.itemDataService.moveToCollection(this.itemId, this.selectedCollectionId).first().subscribe( + (response: RestResponse) => { + this.router.navigate([getItemEditPath(this.itemId)]); + if (response.isSuccessful) { + this.notificationsService.success(this.translateService.get('item.move.success')); + } else { + this.notificationsService.error(this.translateService.get('item.move.error')); + } + } + ); + + } +} diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.html b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.html index 59b625d8c0..4623195437 100644 --- a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.html +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.html @@ -1,10 +1,15 @@ -import {Component} from '@angular/core'; - -@Component({ - selector: 'ds-item-operation', - templateUrl: './ds-item-operation.html' -}) - -export class ItemOperationComponent { - -} +
+ + {{'item.edit.tabs.status.buttons.' + operation.operationKey + '.label' | translate}} + +
+ +
+ + {{'item.edit.tabs.status.buttons.' + operation.operationKey + '.button' | translate}} + +
\ No newline at end of file diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts index e69de29bb2..951d66cbd8 100644 --- a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts @@ -0,0 +1,13 @@ +import {Component, Input} from '@angular/core'; +import {ItemOperation} from './itemOperation.model'; + +@Component({ + selector: 'ds-item-operation', + templateUrl: './item-operation.component.html' +}) + +export class ItemOperationComponent { + + @Input() operation: ItemOperation; + +} diff --git a/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts b/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts index e69de29bb2..6a54744fcb 100644 --- a/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts +++ b/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts @@ -0,0 +1,12 @@ +export class ItemOperation { + + operationKey: string; + operationUrl: string; + disabled: boolean; + + constructor(operationKey: string, operationUrl: string) { + this.operationKey = operationKey; + this.operationUrl = operationUrl; + } + +} diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.html b/src/app/+item-page/edit-item-page/item-status/item-status.component.html index 78ab9174eb..0f7d9a5607 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.html +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.html @@ -15,16 +15,7 @@ {{getItemPage()}}
-
-
- - {{'item.edit.tabs.status.buttons.' + actionKey + '.label' | translate}} - -
- +
+
diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts index bc9dda61ec..e92ae10b55 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts @@ -2,6 +2,7 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core import { fadeIn, fadeInOut } from '../../../shared/animations/fade'; import { Item } from '../../../core/shared/item.model'; import { Router } from '@angular/router'; +import {ItemOperation} from '../item-operation/itemOperation.model'; @Component({ selector: 'ds-item-status', @@ -35,7 +36,7 @@ export class ItemStatusComponent implements OnInit { * The possible actions that can be performed on the item * key: id value: url to action's component */ - actions: any; + operations: ItemOperation[]; /** * The keys of the actions (to loop over) */ @@ -57,11 +58,10 @@ export class ItemStatusComponent implements OnInit { i18n example: 'item.edit.tabs.status.buttons..label' The value is supposed to be a href for the button */ - this.actions = Object.assign({ - // TODO: Create mapping component on item level - mappedCollections: this.getCurrentUrl() + '/' - }); - this.actionsKeys = Object.keys(this.actions); + this.operations = [ + new ItemOperation('mappedCollections',this.getCurrentUrl() + '/'), + new ItemOperation('move', this.getCurrentUrl() + '/move'), + ] } /** diff --git a/src/app/+item-page/item-page-routing.module.ts b/src/app/+item-page/item-page-routing.module.ts index be31b0a82d..a155d00cc0 100644 --- a/src/app/+item-page/item-page-routing.module.ts +++ b/src/app/+item-page/item-page-routing.module.ts @@ -1,10 +1,21 @@ -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; +import {NgModule} from '@angular/core'; +import {RouterModule} from '@angular/router'; -import { ItemPageComponent } from './simple/item-page.component'; -import { FullItemPageComponent } from './full/full-item-page.component'; -import { ItemPageResolver } from './item-page.resolver'; -import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; +import {ItemPageComponent} from './simple/item-page.component'; +import {FullItemPageComponent} from './full/full-item-page.component'; +import {ItemPageResolver} from './item-page.resolver'; +import {AuthenticatedGuard} from '../core/auth/authenticated.guard'; +import {URLCombiner} from '../core/url-combiner/url-combiner'; +import {getItemModulePath} from '../app-routing.module'; + +export function getItemPageRoute(itemId: string) { + return new URLCombiner(getItemModulePath(), itemId).toString(); +} +export function getItemEditPath(id: string) { + return new URLCombiner(getItemModulePath(),ITEM_EDIT_PATH.replace(/:id/, id)).toString() +} + +const ITEM_EDIT_PATH = ':id/edit'; @NgModule({ imports: [ @@ -25,7 +36,7 @@ import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; } }, { - path: ':id/edit', + path: ITEM_EDIT_PATH, loadChildren: './edit-item-page/edit-item-page.module#EditItemPageModule', canActivate: [AuthenticatedGuard] } diff --git a/src/app/+search-page/search-page.module.ts b/src/app/+search-page/search-page.module.ts index 0c8a4ee306..a231d8da5a 100644 --- a/src/app/+search-page/search-page.module.ts +++ b/src/app/+search-page/search-page.module.ts @@ -1,38 +1,45 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '../core/core.module'; -import { SharedModule } from '../shared/shared.module'; -import { SearchPageRoutingModule } from './search-page-routing.module'; -import { SearchPageComponent } from './search-page.component'; -import { SearchResultsComponent } from './search-results/search-results.component'; -import { ItemSearchResultListElementComponent } from '../shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component'; -import { CollectionSearchResultListElementComponent } from '../shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component'; -import { CommunitySearchResultListElementComponent } from '../shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component'; -import { ItemSearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component'; -import { CommunitySearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component' -import { CollectionSearchResultGridElementComponent } from '../shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component'; -import { SearchService } from './search-service/search.service'; -import { SearchSidebarComponent } from './search-sidebar/search-sidebar.component'; -import { SearchSidebarService } from './search-sidebar/search-sidebar.service'; -import { SearchSidebarEffects } from './search-sidebar/search-sidebar.effects'; -import { SearchSettingsComponent } from './search-settings/search-settings.component'; -import { EffectsModule } from '@ngrx/effects'; -import { SearchFiltersComponent } from './search-filters/search-filters.component'; -import { SearchFilterComponent } from './search-filters/search-filter/search-filter.component'; -import { SearchFacetFilterComponent } from './search-filters/search-filter/search-facet-filter/search-facet-filter.component'; -import { SearchFilterService } from './search-filters/search-filter/search-filter.service'; -import { SearchLabelsComponent } from './search-labels/search-labels.component'; -import { SearchRangeFilterComponent } from './search-filters/search-filter/search-range-filter/search-range-filter.component'; -import { SearchTextFilterComponent } from './search-filters/search-filter/search-text-filter/search-text-filter.component'; -import { SearchFacetFilterWrapperComponent } from './search-filters/search-filter/search-facet-filter-wrapper/search-facet-filter-wrapper.component'; -import { SearchBooleanFilterComponent } from './search-filters/search-filter/search-boolean-filter/search-boolean-filter.component'; -import { SearchHierarchyFilterComponent } from './search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component'; -import { SearchConfigurationService } from './search-service/search-configuration.service'; +import {ModuleWithProviders, NgModule} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {CoreModule} from '../core/core.module'; +import {SharedModule} from '../shared/shared.module'; +import {SearchPageRoutingModule} from './search-page-routing.module'; +import {SearchPageComponent} from './search-page.component'; +import {SearchResultsComponent} from './search-results/search-results.component'; +import {ItemSearchResultListElementComponent} from '../shared/object-list/search-result-list-element/item-search-result/item-search-result-list-element.component'; +import {CollectionSearchResultListElementComponent} from '../shared/object-list/search-result-list-element/collection-search-result/collection-search-result-list-element.component'; +import {CommunitySearchResultListElementComponent} from '../shared/object-list/search-result-list-element/community-search-result/community-search-result-list-element.component'; +import {ItemSearchResultGridElementComponent} from '../shared/object-grid/search-result-grid-element/item-search-result/item-search-result-grid-element.component'; +import {CommunitySearchResultGridElementComponent} from '../shared/object-grid/search-result-grid-element/community-search-result/community-search-result-grid-element.component'; +import {CollectionSearchResultGridElementComponent} from '../shared/object-grid/search-result-grid-element/collection-search-result/collection-search-result-grid-element.component'; +import {SearchService} from './search-service/search.service'; +import {SearchSidebarComponent} from './search-sidebar/search-sidebar.component'; +import {SearchSidebarService} from './search-sidebar/search-sidebar.service'; +import {SearchSidebarEffects} from './search-sidebar/search-sidebar.effects'; +import {SearchSettingsComponent} from './search-settings/search-settings.component'; +import {EffectsModule} from '@ngrx/effects'; +import {SearchFiltersComponent} from './search-filters/search-filters.component'; +import {SearchFilterComponent} from './search-filters/search-filter/search-filter.component'; +import {SearchFacetFilterComponent} from './search-filters/search-filter/search-facet-filter/search-facet-filter.component'; +import {SearchFilterService} from './search-filters/search-filter/search-filter.service'; +import {SearchLabelsComponent} from './search-labels/search-labels.component'; +import {SearchRangeFilterComponent} from './search-filters/search-filter/search-range-filter/search-range-filter.component'; +import {SearchTextFilterComponent} from './search-filters/search-filter/search-text-filter/search-text-filter.component'; +import {SearchFacetFilterWrapperComponent} from './search-filters/search-filter/search-facet-filter-wrapper/search-facet-filter-wrapper.component'; +import {SearchBooleanFilterComponent} from './search-filters/search-filter/search-boolean-filter/search-boolean-filter.component'; +import {SearchHierarchyFilterComponent} from './search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component'; +import {SearchConfigurationService} from './search-service/search-configuration.service'; const effects = [ SearchSidebarEffects ]; +const PROVIDERS = [ + SearchService, + SearchSidebarService, + SearchFilterService, + SearchConfigurationService +]; + @NgModule({ imports: [ SearchPageRoutingModule, @@ -65,10 +72,7 @@ const effects = [ SearchBooleanFilterComponent, ], providers: [ - SearchService, - SearchSidebarService, - SearchFilterService, - SearchConfigurationService + ...PROVIDERS ], entryComponents: [ ItemSearchResultListElementComponent, @@ -89,4 +93,12 @@ const effects = [ * This module handles all components and pipes that are necessary for the search page */ export class SearchPageModule { + static forRoot(): ModuleWithProviders { + return { + ngModule: CoreModule, + providers: [ + ...PROVIDERS + ] + }; + } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 7de83651ff..e7ea10598d 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,6 +3,10 @@ import { RouterModule } from '@angular/router'; import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component'; +const ITEM_MODULE_PATH = 'items'; +export function getItemModulePath() { + return `/${ITEM_MODULE_PATH}`; +} @NgModule({ imports: [ RouterModule.forRoot([ @@ -10,7 +14,7 @@ import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component'; { path: 'home', loadChildren: './+home-page/home-page.module#HomePageModule' }, { path: 'communities', loadChildren: './+community-page/community-page.module#CommunityPageModule' }, { path: 'collections', loadChildren: './+collection-page/collection-page.module#CollectionPageModule' }, - { path: 'items', loadChildren: './+item-page/item-page.module#ItemPageModule' }, + { path: ITEM_MODULE_PATH, loadChildren: './+item-page/item-page.module#ItemPageModule' }, { path: 'search', loadChildren: './+search-page/search-page.module#SearchPageModule' }, { path: 'browse', loadChildren: './+browse-by/browse-by.module#BrowseByModule' }, { path: 'admin', loadChildren: './+admin/admin.module#AdminModule' }, diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index f984dceb12..90311a6f82 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -1,21 +1,24 @@ -import { Inject, Injectable } from '@angular/core'; +import {Injectable} from '@angular/core'; -import { Store } from '@ngrx/store'; -import { Observable } from 'rxjs/Observable'; -import { GLOBAL_CONFIG, GlobalConfig } from '../../../config'; -import { isEmpty, isNotEmpty } from '../../shared/empty.util'; -import { BrowseService } from '../browse/browse.service'; -import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { NormalizedItem } from '../cache/models/normalized-item.model'; -import { ResponseCacheService } from '../cache/response-cache.service'; -import { CoreState } from '../core.reducers'; -import { Item } from '../shared/item.model'; -import { URLCombiner } from '../url-combiner/url-combiner'; +import {Store} from '@ngrx/store'; +import {Observable} from 'rxjs/Observable'; +import {isNotEmpty, isNotEmptyOperator} from '../../shared/empty.util'; +import {BrowseService} from '../browse/browse.service'; +import {RemoteDataBuildService} from '../cache/builders/remote-data-build.service'; +import {NormalizedItem} from '../cache/models/normalized-item.model'; +import {ResponseCacheService} from '../cache/response-cache.service'; +import {CoreState} from '../core.reducers'; +import {Item} from '../shared/item.model'; +import {URLCombiner} from '../url-combiner/url-combiner'; -import { DataService } from './data.service'; -import { RequestService } from './request.service'; -import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { FindAllOptions } from './request.models'; +import {DataService} from './data.service'; +import {RequestService} from './request.service'; +import {HALEndpointService} from '../shared/hal-endpoint.service'; +import {FindAllOptions, PostRequest, RestRequest} from './request.models'; +import {distinctUntilChanged, map} from 'rxjs/operators'; +import {RestResponse} from '../cache/response-cache.models'; +import {configureRequest, getResponseFromSelflink} from '../shared/operators'; +import {ResponseCacheEntry} from '../cache/response-cache.reducer'; @Injectable() export class ItemDataService extends DataService { @@ -48,4 +51,22 @@ export class ItemDataService extends DataService { .distinctUntilChanged(); } + public getMoveItemEndpoint(itemId: string, collectionId?: string): Observable { + return this.halService.getEndpoint(this.linkPath).pipe( + map((endpoint: string) => this.getFindByIDHref(endpoint, itemId)), + map((endpoint: string) => `${endpoint}/owningCollection/move/${collectionId ? `/${collectionId}` : ''}`) + ); + } + + public moveToCollection(itemId: string, collectionId: string): Observable { + return this.getMoveItemEndpoint(itemId, collectionId).pipe( + // isNotEmptyOperator(), + distinctUntilChanged(), + map((endpointURL: string) => new PostRequest(this.requestService.generateRequestId(), endpointURL)), + configureRequest(this.requestService), + map((request: RestRequest) => request.href), + getResponseFromSelflink(this.responseCache), + map((responseCacheEntry: ResponseCacheEntry) => responseCacheEntry.response) + ); + } } diff --git a/src/app/shared/input-suggestions/input-suggestions.component.ts b/src/app/shared/input-suggestions/input-suggestions.component.ts index eb28583eaa..ae15a805e9 100644 --- a/src/app/shared/input-suggestions/input-suggestions.component.ts +++ b/src/app/shared/input-suggestions/input-suggestions.component.ts @@ -159,6 +159,15 @@ export class InputSuggestionsComponent { this.show.next(false); } + /** + * Changes the show variable so the suggestion dropdown opens + */ + open() { + if (!this.blockReopen) { + this.show.next(true); + } + } + /** * For usage of the isNotEmpty function in the template */ From 4411c312e5861b4e3702e6325a34dfd306f692c7 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Mon, 26 Nov 2018 16:28:39 +0100 Subject: [PATCH 07/33] 55990: Add move item component --- .../item-move/item-move.component.html | 2 +- .../item-move/item-move.component.spec.ts | 179 ++++++++++++++++++ .../item-move/item-move.component.ts | 28 +-- .../item-operation.component.spec.ts | 44 +++++ .../item-operation.component.ts | 4 +- .../item-operation/itemOperation.model.ts | 9 + .../item-status/item-status.component.spec.ts | 3 +- .../search-hierarchy-filter.component.html | 2 +- .../search-text-filter.component.html | 2 +- 9 files changed, 256 insertions(+), 17 deletions(-) create mode 100644 src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts create mode 100644 src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.html b/src/app/+item-page/edit-item-page/item-move/item-move.component.html index fe27ed36a5..0c97628d4c 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.html +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.html @@ -6,7 +6,7 @@
; + +const mockItem = Object.assign(new Item(), { + id: 'fake-id', + handle: 'fake/handle', + lastModified: '2018' +}); + +const itemPageUrl = `fake-url/${mockItem.id}`; +const routerStub = Object.assign(new RouterStub(), { + url: `${itemPageUrl}/edit` +}); + +const mockItemDataService = jasmine.createSpyObj({ + moveToCollection: Observable.of(new RestResponse(true, '200')) +}); + +const mockItemDataServiceFail = jasmine.createSpyObj({ + moveToCollection: Observable.of(new RestResponse(false, '500')) +}); + +const routeStub = { + data: Observable.of({ + item: new RemoteData(false, false, true, null, { + id: 'item1' + }) + }) +}; + +const mockSearchService = { + search: () => { + return Observable.of(new RemoteData(false, false, true, null, + new PaginatedList(null, [ + { + dspaceObject: { + name: 'Test collection 1', + uuid: 'collection1' + }, hitHighlights: {} + }, { + dspaceObject: { + name: 'Test collection 2', + uuid: 'collection2' + }, hitHighlights: {} + } + ]))); + } +}; + +const notificationsServiceStub = new NotificationsServiceStub(); + +describe('ItemMoveComponent', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [CommonModule, FormsModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule.forRoot()], + declarations: [ItemMoveComponent], + providers: [ + {provide: ActivatedRoute, useValue: routeStub}, + {provide: Router, useValue: routerStub}, + {provide: ItemDataService, useValue: mockItemDataService}, + {provide: NotificationsService, useValue: notificationsServiceStub}, + {provide: SearchService, useValue: mockSearchService}, + ], schemas: [ + CUSTOM_ELEMENTS_SCHEMA + ] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemMoveComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); + }); + it('should load suggestions', () => { + const expected = [ + { + displayValue: 'Test collection 1', + value: { + name: 'Test collection 1', + id: 'collection1', + } + }, + { + displayValue: 'Test collection 2', + value: { + name: 'Test collection 2', + id: 'collection2', + } + } + ]; + + comp.CollectionSearchResults.subscribe((value) => { + expect(value).toEqual(expected); + } + ); + }); + it('should get current url ', () => { + expect(comp.getCurrentUrl()).toEqual('fake-url/fake-id/edit'); + }); + it('should on click select the correct collection name and id', () => { + const data = { + name: 'Test collection 1', + id: 'collection1', + }; + comp.onClick(data); + + expect(comp.selectedCollection).toEqual('Test collection 1'); + expect(comp.selectedCollectionId).toEqual('collection1'); + }); + describe('moveCollection', () => { + it('should call itemDataService.moveToCollection', () => { + comp.itemId = 'item-id'; + comp.selectedCollectionId = 'selected-collection-id'; + comp.moveCollection(); + + expect(mockItemDataService.moveToCollection).toHaveBeenCalledWith('item-id', 'selected-collection-id'); + }); + it('should call notificationsService success message on success', () => { + spyOn(notificationsServiceStub, 'success'); + + comp.moveCollection(); + + expect(notificationsServiceStub.success).toHaveBeenCalled(); + }); + }); +}); + +describe('ItemMoveComponent fail', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [CommonModule, FormsModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule.forRoot()], + declarations: [ItemMoveComponent], + providers: [ + {provide: ActivatedRoute, useValue: routeStub}, + {provide: Router, useValue: routerStub}, + {provide: ItemDataService, useValue: mockItemDataServiceFail}, + {provide: NotificationsService, useValue: notificationsServiceStub}, + {provide: SearchService, useValue: mockSearchService}, + ], schemas: [ + CUSTOM_ELEMENTS_SCHEMA + ] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ItemMoveComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should call notificationsService error message on fail', () => { + spyOn(notificationsServiceStub, 'error'); + + comp.moveCollection(); + + expect(notificationsServiceStub.error).toHaveBeenCalled(); + }); +}); diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts index e0819257c2..338d4b96a3 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts @@ -8,12 +8,9 @@ import {RemoteData} from '../../../core/data/remote-data'; import {DSpaceObject} from '../../../core/shared/dspace-object.model'; import {PaginatedList} from '../../../core/data/paginated-list'; import {SearchResult} from '../../../+search-page/search-result.model'; -import {PaginatedSearchOptions} from '../../../+search-page/paginated-search-options.model'; import {Item} from '../../../core/shared/item.model'; import {ActivatedRoute, Router} from '@angular/router'; import {NotificationsService} from '../../../shared/notifications/notifications.service'; -import {CollectionDataService} from '../../../core/data/collection-data.service'; -import {SearchConfigurationService} from '../../../+search-page/search-service/search-configuration.service'; import {TranslateService} from '@ngx-translate/core'; import {getSucceededRemoteData} from '../../../core/shared/operators'; import {ItemDataService} from '../../../core/data/item-data.service'; @@ -24,15 +21,14 @@ import {getItemEditPath} from '../../item-page-routing.module'; selector: 'ds-item-move', templateUrl: './item-move.component.html' }) +/** + * Component that handles the moving of an item to a different collection + */ export class ItemMoveComponent implements OnInit { inheritPolicies = false; itemRD$: Observable>; - /** - * Search options - */ - searchOptions$: Observable; - filterSearchResults: Observable = Observable.of([]); + CollectionSearchResults: Observable = Observable.of([]); selectedCollection: string; selectedCollectionId: string; @@ -41,9 +37,7 @@ export class ItemMoveComponent implements OnInit { constructor(private route: ActivatedRoute, private router: Router, private notificationsService: NotificationsService, - private collectionDataService: CollectionDataService, private itemDataService: ItemDataService, - private searchConfigService: SearchConfigurationService, private searchService: SearchService, private translateService: TranslateService) { } @@ -54,10 +48,13 @@ export class ItemMoveComponent implements OnInit { this.itemId = rd.payload.id; } ); - this.searchOptions$ = this.searchConfigService.paginatedSearchOptions; this.loadSuggestions(''); } + /** + * Find suggestions based on entered query + * @param query - Search query + */ findSuggestions(query): void { this.loadSuggestions(query); } @@ -67,7 +64,7 @@ export class ItemMoveComponent implements OnInit { * TODO: When the API support it, only fetch collections where user has ADD rights to. */ loadSuggestions(query): void { - this.filterSearchResults = this.searchService.search(new SearchOptions({ + this.CollectionSearchResults = this.searchService.search(new SearchOptions({ dsoType: DSpaceObjectType.COLLECTION, query: query })).first().pipe( @@ -83,6 +80,10 @@ export class ItemMoveComponent implements OnInit { } + /** + * Set the collection name and id based on the selected value + * @param data - obtained from the ds-input-suggestions component + */ onClick(data: any): void { this.selectedCollection = data.name; this.selectedCollectionId = data.id; @@ -95,6 +96,9 @@ export class ItemMoveComponent implements OnInit { return this.router.url; } + /** + * Moves the item to a new collection based on the selected collection + */ moveCollection() { this.itemDataService.moveToCollection(this.itemId, this.selectedCollectionId).first().subscribe( (response: RestResponse) => { diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts new file mode 100644 index 0000000000..092f3af0ac --- /dev/null +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts @@ -0,0 +1,44 @@ +import {ItemOperation} from './itemOperation.model'; +import {async, TestBed} from '@angular/core/testing'; +import {ItemOperationComponent} from './item-operation.component'; +import {TranslateModule} from '@ngx-translate/core'; +import {By} from '@angular/platform-browser'; + +describe('ItemOperationComponent', () => { + const itemOperation: ItemOperation = new ItemOperation('key1', 'url1'); + + let fixture; + let comp; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [ItemOperationComponent] + }).compileComponents(); + })); + + beforeEach(() => { + + fixture = TestBed.createComponent(ItemOperationComponent); + comp = fixture.componentInstance; + comp.operation = itemOperation; + fixture.detectChanges(); + }); + + it('should render operation row', () => { + const span = fixture.debugElement.query(By.css('span')).nativeElement; + expect(span.textContent).toContain('item.edit.tabs.status.buttons.key1.label'); + const link = fixture.debugElement.query(By.css('a')).nativeElement; + expect(link.href).toContain('url1'); + expect(link.textContent).toContain('item.edit.tabs.status.buttons.key1.button'); + }); + it('should render disabled operation row', () => { + itemOperation.setDisabled(true); + fixture.detectChanges(); + + const span = fixture.debugElement.query(By.css('span')).nativeElement; + expect(span.textContent).toContain('item.edit.tabs.status.buttons.key1.label'); + const span2 = fixture.debugElement.query(By.css('span.btn-danger')).nativeElement; + expect(span2.textContent).toContain('item.edit.tabs.status.buttons.key1.button'); + }); +}); diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts index 951d66cbd8..76d056df95 100644 --- a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.ts @@ -5,7 +5,9 @@ import {ItemOperation} from './itemOperation.model'; selector: 'ds-item-operation', templateUrl: './item-operation.component.html' }) - +/** + * Operation that can be performed on an item + */ export class ItemOperationComponent { @Input() operation: ItemOperation; diff --git a/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts b/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts index 6a54744fcb..0104dfbdb3 100644 --- a/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts +++ b/src/app/+item-page/edit-item-page/item-operation/itemOperation.model.ts @@ -7,6 +7,15 @@ export class ItemOperation { constructor(operationKey: string, operationUrl: string) { this.operationKey = operationKey; this.operationUrl = operationUrl; + this.setDisabled(false); + } + + /** + * Set whether this operation should be disabled + * @param disabled + */ + setDisabled(disabled: boolean): void { + this.disabled = disabled; } } diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts index 2df4b977cb..319d4c47ae 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.spec.ts @@ -10,6 +10,7 @@ import { Router } from '@angular/router'; import { RouterStub } from '../../../shared/testing/router-stub'; import { Item } from '../../../core/shared/item.model'; import { By } from '@angular/platform-browser'; +import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; describe('ItemStatusComponent', () => { let comp: ItemStatusComponent; @@ -33,7 +34,7 @@ describe('ItemStatusComponent', () => { providers: [ { provide: Router, useValue: routerStub }, { provide: HostWindowService, useValue: new HostWindowServiceStub(0) } - ] + ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }).compileComponents(); })); diff --git a/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html b/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html index 812f543716..962d09e6c4 100644 --- a/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html +++ b/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html @@ -30,7 +30,7 @@ | translate}}
-
- Date: Tue, 27 Nov 2018 14:38:19 +0100 Subject: [PATCH 08/33] 55990: Fix param name --- .../edit-item-page/item-move/item-move.component.html | 2 +- .../edit-item-page/item-move/item-move.component.spec.ts | 2 +- .../edit-item-page/item-move/item-move.component.ts | 4 ++-- .../search-hierarchy-filter.component.html | 2 +- .../search-text-filter/search-text-filter.component.html | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.html b/src/app/+item-page/edit-item-page/item-move/item-move.component.html index 0c97628d4c..0a8e4b68b5 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.html +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.html @@ -6,7 +6,7 @@
{ } ]; - comp.CollectionSearchResults.subscribe((value) => { + comp.collectionSearchResults.subscribe((value) => { expect(value).toEqual(expected); } ); diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts index 338d4b96a3..359c04c8e7 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts @@ -28,7 +28,7 @@ export class ItemMoveComponent implements OnInit { inheritPolicies = false; itemRD$: Observable>; - CollectionSearchResults: Observable = Observable.of([]); + collectionSearchResults: Observable = Observable.of([]); selectedCollection: string; selectedCollectionId: string; @@ -64,7 +64,7 @@ export class ItemMoveComponent implements OnInit { * TODO: When the API support it, only fetch collections where user has ADD rights to. */ loadSuggestions(query): void { - this.CollectionSearchResults = this.searchService.search(new SearchOptions({ + this.collectionSearchResults = this.searchService.search(new SearchOptions({ dsoType: DSpaceObjectType.COLLECTION, query: query })).first().pipe( diff --git a/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html b/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html index 962d09e6c4..812f543716 100644 --- a/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html +++ b/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html @@ -30,7 +30,7 @@ | translate}}
-
- Date: Thu, 29 Nov 2018 11:39:57 +0100 Subject: [PATCH 09/33] 55990: Move item component - fix message --- resources/i18n/en.json | 1 + .../edit-item-page/item-move/item-move.component.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 395838c289..3cdf0bc180 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -107,6 +107,7 @@ "move": { "head":"Move item: {{id}}", "description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", + "search.placeholder": "Enter a search query to look for collections", "inheritpolicies": { "description": "Inherit the default policies of the destination collection", "checkbox": "Inherit policies" diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.html b/src/app/+item-page/edit-item-page/item-move/item-move.component.html index 0a8e4b68b5..b3627e65bb 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.html +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.html @@ -7,7 +7,7 @@
Date: Fri, 30 Nov 2018 11:18:57 +0100 Subject: [PATCH 10/33] 55990: Item move - tweaks --- resources/i18n/en.json | 4 +++- .../edit-item-page/item-move/item-move.component.html | 4 ++-- .../edit-item-page/item-move/item-move.component.ts | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 3cdf0bc180..cf87e423a7 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -113,7 +113,9 @@ "checkbox": "Inherit policies" }, "move": "Move", - "cancel": "Cancel" + "cancel": "Cancel", + "success": "The item has been moved succesfully", + "error": "An error occured when attempting to move the item" } } }, diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.html b/src/app/+item-page/edit-item-page/item-move/item-move.component.html index b3627e65bb..063028c719 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.html +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.html @@ -1,7 +1,7 @@
-

{{'item.edit.move.head' | translate: { id: (itemRD$ | async)?.payload?.id} }}

+

{{'item.edit.move.head' | translate: { id: (itemRD$ | async)?.payload?.handle} }}

{{'item.edit.move.description' | translate}}

@@ -33,7 +33,7 @@ -
diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts index 359c04c8e7..07894c4504 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts @@ -104,9 +104,9 @@ export class ItemMoveComponent implements OnInit { (response: RestResponse) => { this.router.navigate([getItemEditPath(this.itemId)]); if (response.isSuccessful) { - this.notificationsService.success(this.translateService.get('item.move.success')); + this.notificationsService.success(this.translateService.get('item.edit.move.success')); } else { - this.notificationsService.error(this.translateService.get('item.move.error')); + this.notificationsService.error(this.translateService.get('item.edit.move.error')); } } ); From a698b56ae804ab3a51726c1a4170942da4d561cb Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 6 Dec 2018 10:42:37 +0100 Subject: [PATCH 11/33] 55990: Fix issues to move item component after master merge --- .../edit-item-page.component.ts | 11 +++++----- .../item-move/item-move.component.spec.ts | 13 ++++++------ .../item-move/item-move.component.ts | 21 ++++++++++++------- .../item-operation.component.spec.ts | 8 +++---- src/app/core/data/item-data.service.ts | 7 +++---- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/app/+item-page/edit-item-page/edit-item-page.component.ts b/src/app/+item-page/edit-item-page/edit-item-page.component.ts index 8bcf53f140..de40239b3e 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.component.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.component.ts @@ -1,9 +1,10 @@ -import { fadeIn, fadeInOut } from '../../shared/animations/fade'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { Observable } from 'rxjs/Observable'; -import { RemoteData } from '../../core/data/remote-data'; -import { Item } from '../../core/shared/item.model'; +import {fadeIn, fadeInOut} from '../../shared/animations/fade'; +import {Observable} from 'rxjs'; +import {RemoteData} from '../../core/data/remote-data'; +import {Item} from '../../core/shared/item.model'; +import {map} from 'rxjs/operators'; @Component({ selector: 'ds-edit-item-page', @@ -28,7 +29,7 @@ export class EditItemPageComponent implements OnInit { } ngOnInit(): void { - this.itemRD$ = this.route.data.map((data) => data.item); + this.itemRD$ = this.route.data.pipe(map((data) => data.item)); } } diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts index c61a9ed0d3..eaf8e15fa4 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts @@ -10,14 +10,13 @@ import {ItemMoveComponent} from './item-move.component'; import {NotificationsServiceStub} from '../../../shared/testing/notifications-service-stub'; import {NotificationsService} from '../../../shared/notifications/notifications.service'; import {SearchService} from '../../../+search-page/search-service/search.service'; -import {Observable} from 'rxjs/Observable'; -import 'rxjs/add/observable/of'; -import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; +import {of as observableOf} from 'rxjs'; import {FormsModule} from '@angular/forms'; import {ItemDataService} from '../../../core/data/item-data.service'; import {RestResponse} from '../../../core/cache/response-cache.models'; import {RemoteData} from '../../../core/data/remote-data'; import {PaginatedList} from '../../../core/data/paginated-list'; +import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; let comp: ItemMoveComponent; let fixture: ComponentFixture; @@ -34,15 +33,15 @@ const routerStub = Object.assign(new RouterStub(), { }); const mockItemDataService = jasmine.createSpyObj({ - moveToCollection: Observable.of(new RestResponse(true, '200')) + moveToCollection: observableOf(new RestResponse(true, '200')) }); const mockItemDataServiceFail = jasmine.createSpyObj({ - moveToCollection: Observable.of(new RestResponse(false, '500')) + moveToCollection: observableOf(new RestResponse(false, '500')) }); const routeStub = { - data: Observable.of({ + data: observableOf({ item: new RemoteData(false, false, true, null, { id: 'item1' }) @@ -51,7 +50,7 @@ const routeStub = { const mockSearchService = { search: () => { - return Observable.of(new RemoteData(false, false, true, null, + return observableOf(new RemoteData(false, false, true, null, new PaginatedList(null, [ { dspaceObject: { diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts index 07894c4504..9147ae2238 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts @@ -1,7 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {SearchService} from '../../../+search-page/search-service/search.service'; -import {Observable} from 'rxjs/Observable'; -import {map} from 'rxjs/operators'; +import {first, map} from 'rxjs/operators'; import {DSpaceObjectType} from '../../../core/shared/dspace-object-type.model'; import {SearchOptions} from '../../../+search-page/search-options.model'; import {RemoteData} from '../../../core/data/remote-data'; @@ -16,6 +15,8 @@ import {getSucceededRemoteData} from '../../../core/shared/operators'; import {ItemDataService} from '../../../core/data/item-data.service'; import {RestResponse} from '../../../core/cache/response-cache.models'; import {getItemEditPath} from '../../item-page-routing.module'; +import {Observable} from 'rxjs'; +import {of as observableOf} from 'rxjs'; @Component({ selector: 'ds-item-move', @@ -25,10 +26,13 @@ import {getItemEditPath} from '../../item-page-routing.module'; * Component that handles the moving of an item to a different collection */ export class ItemMoveComponent implements OnInit { - + /** + * TODO: There is currently no backend support to change the owningCollection and inherit policies, + * TODO: when this is added, the inherit policies option should be used. + */ inheritPolicies = false; itemRD$: Observable>; - collectionSearchResults: Observable = Observable.of([]); + collectionSearchResults: Observable = observableOf([]); selectedCollection: string; selectedCollectionId: string; @@ -43,8 +47,8 @@ export class ItemMoveComponent implements OnInit { } ngOnInit(): void { - this.itemRD$ = this.route.data.map((data) => data.item).pipe(getSucceededRemoteData()) as Observable>; - this.itemRD$.first().subscribe((rd) => { + this.itemRD$ = this.route.data.pipe(map((data) => data.item),getSucceededRemoteData()) as Observable>; + this.itemRD$.subscribe((rd) => { this.itemId = rd.payload.id; } ); @@ -67,7 +71,8 @@ export class ItemMoveComponent implements OnInit { this.collectionSearchResults = this.searchService.search(new SearchOptions({ dsoType: DSpaceObjectType.COLLECTION, query: query - })).first().pipe( + })).pipe( + first(), map((rd: RemoteData>>) => { return rd.payload.page.map((searchResult) => { return { @@ -100,7 +105,7 @@ export class ItemMoveComponent implements OnInit { * Moves the item to a new collection based on the selected collection */ moveCollection() { - this.itemDataService.moveToCollection(this.itemId, this.selectedCollectionId).first().subscribe( + this.itemDataService.moveToCollection(this.itemId, this.selectedCollectionId).pipe(first()).subscribe( (response: RestResponse) => { this.router.navigate([getItemEditPath(this.itemId)]); if (response.isSuccessful) { diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts index 092f3af0ac..15feb5aeda 100644 --- a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts @@ -4,11 +4,11 @@ import {ItemOperationComponent} from './item-operation.component'; import {TranslateModule} from '@ngx-translate/core'; import {By} from '@angular/platform-browser'; -describe('ItemOperationComponent', () => { - const itemOperation: ItemOperation = new ItemOperation('key1', 'url1'); +const itemOperation: ItemOperation = new ItemOperation('key1', 'url1'); - let fixture; - let comp; +let fixture; +let comp; +describe('ItemOperationComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index d6c76bff2b..84eca23507 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -1,7 +1,6 @@ import {Injectable} from '@angular/core'; - import {distinctUntilChanged, map, filter} from 'rxjs/operators'; -import { Injectable } from '@angular/core';import {Store} from '@ngrx/store'; +import {Store} from '@ngrx/store'; import {Observable} from 'rxjs'; import {isNotEmpty, isNotEmptyOperator} from '../../shared/empty.util'; import {BrowseService} from '../browse/browse.service'; @@ -15,7 +14,7 @@ import {URLCombiner} from '../url-combiner/url-combiner'; import {DataService} from './data.service'; import {RequestService} from './request.service'; import {HALEndpointService} from '../shared/hal-endpoint.service'; -import {FindAllOptions, PostRequest, RestRequest} from './request.models'; +import {FindAllOptions, PostRequest, PutRequest, RestRequest} from './request.models'; import {RestResponse} from '../cache/response-cache.models'; import {configureRequest, getResponseFromSelflink} from '../shared/operators'; import {ResponseCacheEntry} from '../cache/response-cache.reducer'; @@ -62,7 +61,7 @@ export class ItemDataService extends DataService { return this.getMoveItemEndpoint(itemId, collectionId).pipe( // isNotEmptyOperator(), distinctUntilChanged(), - map((endpointURL: string) => new PostRequest(this.requestService.generateRequestId(), endpointURL)), + map((endpointURL: string) => new PutRequest(this.requestService.generateRequestId(), endpointURL)), configureRequest(this.requestService), map((request: RestRequest) => request.href), getResponseFromSelflink(this.responseCache), From e2420c56d38cb3d34d8738985acb991d9dc9dd73 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 6 Dec 2018 15:59:45 +0100 Subject: [PATCH 12/33] Fix item opertation test issue --- .../item-operation/item-operation.component.spec.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts index 15feb5aeda..54d5a8fe4a 100644 --- a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts @@ -4,11 +4,11 @@ import {ItemOperationComponent} from './item-operation.component'; import {TranslateModule} from '@ngx-translate/core'; import {By} from '@angular/platform-browser'; -const itemOperation: ItemOperation = new ItemOperation('key1', 'url1'); - -let fixture; -let comp; describe('ItemOperationComponent', () => { + let itemOperation: ItemOperation; + + let fixture; + let comp; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -19,6 +19,8 @@ describe('ItemOperationComponent', () => { beforeEach(() => { + itemOperation = new ItemOperation('key1', 'url1'); + fixture = TestBed.createComponent(ItemOperationComponent); comp = fixture.componentInstance; comp.operation = itemOperation; From 1e6226205083dcc02c50b2320c4d77be9c0f5933 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Wed, 19 Dec 2018 13:20:42 +0100 Subject: [PATCH 13/33] Remove unrelated ItemOperation --- .../edit-item-page/item-status/item-status.component.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts index e92ae10b55..70f7c737f6 100644 --- a/src/app/+item-page/edit-item-page/item-status/item-status.component.ts +++ b/src/app/+item-page/edit-item-page/item-status/item-status.component.ts @@ -59,8 +59,7 @@ export class ItemStatusComponent implements OnInit { The value is supposed to be a href for the button */ this.operations = [ - new ItemOperation('mappedCollections',this.getCurrentUrl() + '/'), - new ItemOperation('move', this.getCurrentUrl() + '/move'), + new ItemOperation('move', this.getCurrentUrl() + '/move') ] } From 395a78c360aa927b515ebf61d2f80083340cac4e Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Tue, 28 May 2019 13:14:59 +0200 Subject: [PATCH 14/33] 62571: Update item move method --- .../item-move/item-move.component.ts | 5 ++++- src/app/core/data/item-data.service.ts | 22 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts index 7eb0e4c10e..4f6f9bbe08 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts @@ -17,6 +17,7 @@ import {getItemEditPath} from '../../item-page-routing.module'; import {Observable} from 'rxjs'; import {of as observableOf} from 'rxjs'; import { RestResponse } from '../../../core/cache/response.models'; +import { Collection } from '../../../core/shared/collection.model'; @Component({ selector: 'ds-item-move', @@ -34,6 +35,7 @@ export class ItemMoveComponent implements OnInit { itemRD$: Observable>; collectionSearchResults: Observable = observableOf([]); selectedCollection: string; + selectedCollectionObject: Collection; selectedCollectionId: string; itemId: string; @@ -92,6 +94,7 @@ export class ItemMoveComponent implements OnInit { onClick(data: any): void { this.selectedCollection = data.name; this.selectedCollectionId = data.id; + this.selectedCollectionObject = data; } /** @@ -105,7 +108,7 @@ export class ItemMoveComponent implements OnInit { * Moves the item to a new collection based on the selected collection */ moveCollection() { - this.itemDataService.moveToCollection(this.itemId, this.selectedCollectionId).pipe(first()).subscribe( + this.itemDataService.moveToCollection(this.itemId, this.selectedCollectionObject).pipe(first()).subscribe( (response: RestResponse) => { this.router.navigate([getItemEditPath(this.itemId)]); if (response.isSuccessful) { diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index 1e6f3e50de..9d686d98d1 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -12,15 +12,17 @@ import { URLCombiner } from '../url-combiner/url-combiner'; import { DataService } from './data.service'; import { RequestService } from './request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { DeleteByIDRequest, FindAllOptions, PatchRequest, PutRequest, RestRequest } from './request.models'; +import { FindAllOptions, PatchRequest, PutRequest, RestRequest } from './request.models'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service'; import { configureRequest, getRequestFromRequestHref } from '../shared/operators'; import { RequestEntry } from './request.reducer'; import { RestResponse } from '../cache/response.models'; +import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service'; +import { Collection } from '../shared/collection.model'; @Injectable() export class ItemDataService extends DataService { @@ -120,22 +122,26 @@ export class ItemDataService extends DataService { ); } - public getMoveItemEndpoint(itemId: string, collectionId?: string): Observable { + public getMoveItemEndpoint(itemId: string): Observable { return this.halService.getEndpoint(this.linkPath).pipe( map((endpoint: string) => this.getIDHref(endpoint, itemId)), - map((endpoint: string) => `${endpoint}/owningCollection/move/${collectionId ? `/${collectionId}` : ''}`) + map((endpoint: string) => `${endpoint}/owningCollection`) ); } - public moveToCollection(itemId: string, collectionId: string): Observable { - const requestId = this.requestService.generateRequestId(); + public moveToCollection(itemId: string, collection: Collection): Observable { + const options: HttpOptions = Object.create({}); + let headers = new HttpHeaders(); + headers = headers.append('Content-Type', 'text/uri-list'); + options.headers = headers; - const hrefObs = this.getMoveItemEndpoint(itemId, collectionId); + const requestId = this.requestService.generateRequestId(); + const hrefObs = this.getMoveItemEndpoint(itemId); hrefObs.pipe( find((href: string) => hasValue(href)), map((href: string) => { - const request = new PutRequest(requestId, href); + const request = new PutRequest(requestId, href, collection.self, options); this.requestService.configure(request); }) ).subscribe(); From 74bf69f984688a8195e4a5f3b19472e537843763 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Tue, 28 May 2019 15:47:42 +0200 Subject: [PATCH 15/33] 62571: Move item update and test fixes --- .../edit-item-page/edit-item-page.module.ts | 2 + .../item-move/item-move.component.spec.ts | 78 ++++++++++--------- .../item-move/item-move.component.ts | 8 +- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/app/+item-page/edit-item-page/edit-item-page.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.module.ts index e2f63ac5fc..de672c9ea7 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.module.ts @@ -15,6 +15,7 @@ import { ItemMetadataComponent } from './item-metadata/item-metadata.component'; import { EditInPlaceFieldComponent } from './item-metadata/edit-in-place-field/edit-in-place-field.component'; import { ItemBitstreamsComponent } from './item-bitstreams/item-bitstreams.component'; import { ItemMoveComponent } from './item-move/item-move.component'; +import { EditItemPageRoutingModule } from './edit-item-page.routing.module'; /** * Module that contains all components related to the Edit Item page administrator functionality @@ -23,6 +24,7 @@ import { ItemMoveComponent } from './item-move/item-move.component'; imports: [ CommonModule, SharedModule, + EditItemPageRoutingModule ], declarations: [ EditItemPageComponent, diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts index 8f95441bad..3d947fdabe 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.spec.ts @@ -1,22 +1,23 @@ -import {async, ComponentFixture, TestBed} from '@angular/core/testing'; -import {Item} from '../../../core/shared/item.model'; -import {RouterStub} from '../../../shared/testing/router-stub'; -import {CommonModule} from '@angular/common'; -import {RouterTestingModule} from '@angular/router/testing'; -import {TranslateModule} from '@ngx-translate/core'; -import {NgbModule} from '@ng-bootstrap/ng-bootstrap'; -import {ActivatedRoute, Router} from '@angular/router'; -import {ItemMoveComponent} from './item-move.component'; -import {NotificationsServiceStub} from '../../../shared/testing/notifications-service-stub'; -import {NotificationsService} from '../../../shared/notifications/notifications.service'; -import {SearchService} from '../../../+search-page/search-service/search.service'; -import {of as observableOf} from 'rxjs'; -import {FormsModule} from '@angular/forms'; -import {ItemDataService} from '../../../core/data/item-data.service'; -import {RemoteData} from '../../../core/data/remote-data'; -import {PaginatedList} from '../../../core/data/paginated-list'; -import {CUSTOM_ELEMENTS_SCHEMA} from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { Item } from '../../../core/shared/item.model'; +import { RouterStub } from '../../../shared/testing/router-stub'; +import { CommonModule } from '@angular/common'; +import { RouterTestingModule } from '@angular/router/testing'; +import { TranslateModule } from '@ngx-translate/core'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ItemMoveComponent } from './item-move.component'; +import { NotificationsServiceStub } from '../../../shared/testing/notifications-service-stub'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { SearchService } from '../../../+search-page/search-service/search.service'; +import { of as observableOf } from 'rxjs'; +import { FormsModule } from '@angular/forms'; +import { ItemDataService } from '../../../core/data/item-data.service'; +import { RemoteData } from '../../../core/data/remote-data'; +import { PaginatedList } from '../../../core/data/paginated-list'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { RestResponse } from '../../../core/cache/response.models'; +import { Collection } from '../../../core/shared/collection.model'; describe('ItemMoveComponent', () => { let comp: ItemMoveComponent; @@ -49,20 +50,28 @@ describe('ItemMoveComponent', () => { }) }; + const collection1 = Object.assign(new Collection(),{ + uuid: 'collection-uuid-1', + name: 'Test collection 1', + self: 'self-link-1', + }); + + const collection2 = Object.assign(new Collection(),{ + uuid: 'collection-uuid-2', + name: 'Test collection 2', + self: 'self-link-2', + }); + const mockSearchService = { search: () => { return observableOf(new RemoteData(false, false, true, null, new PaginatedList(null, [ { - dspaceObject: { - name: 'Test collection 1', - uuid: 'collection1' - }, hitHighlights: {} + indexableObject: collection1, + hitHighlights: {} }, { - dspaceObject: { - name: 'Test collection 2', - uuid: 'collection2' - }, hitHighlights: {} + indexableObject: collection2, + hitHighlights: {} } ]))); } @@ -98,14 +107,14 @@ describe('ItemMoveComponent', () => { displayValue: 'Test collection 1', value: { name: 'Test collection 1', - id: 'collection1', + object: collection1, } }, { displayValue: 'Test collection 2', value: { name: 'Test collection 2', - id: 'collection2', + object: collection2, } } ]; @@ -121,24 +130,23 @@ describe('ItemMoveComponent', () => { it('should on click select the correct collection name and id', () => { const data = { name: 'Test collection 1', - id: 'collection1', + object: collection1, }; comp.onClick(data); expect(comp.selectedCollection).toEqual('Test collection 1'); - expect(comp.selectedCollectionId).toEqual('collection1'); + expect(comp.selectedCollectionObject).toEqual(collection1); }); describe('moveCollection', () => { it('should call itemDataService.moveToCollection', () => { comp.itemId = 'item-id'; - comp.selectedCollectionId = 'selected-collection-id'; + comp.selectedCollection = 'selected-collection-id'; + comp.selectedCollectionObject = collection1; comp.moveCollection(); - expect(mockItemDataService.moveToCollection).toHaveBeenCalledWith('item-id', 'selected-collection-id'); + expect(mockItemDataService.moveToCollection).toHaveBeenCalledWith('item-id', collection1); }); it('should call notificationsService success message on success', () => { - // spyOn(notificationsServiceStub, 'success'); - comp.moveCollection(); expect(notificationsServiceStub.success).toHaveBeenCalled(); @@ -170,8 +178,6 @@ describe('ItemMoveComponent', () => { }); it('should call notificationsService error message on fail', () => { - // spyOn(notificationsServiceStub, 'error'); - comp.moveCollection(); expect(notificationsServiceStub.error).toHaveBeenCalled(); diff --git a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts index 4f6f9bbe08..4cca0cd3a4 100644 --- a/src/app/+item-page/edit-item-page/item-move/item-move.component.ts +++ b/src/app/+item-page/edit-item-page/item-move/item-move.component.ts @@ -37,7 +37,6 @@ export class ItemMoveComponent implements OnInit { selectedCollection: string; selectedCollectionObject: Collection; - selectedCollectionId: string; itemId: string; constructor(private route: ActivatedRoute, @@ -78,8 +77,8 @@ export class ItemMoveComponent implements OnInit { map((rd: RemoteData>>) => { return rd.payload.page.map((searchResult) => { return { - displayValue: searchResult.dspaceObject.name, - value: {name: searchResult.dspaceObject.name, id: searchResult.dspaceObject.uuid} + displayValue: searchResult.indexableObject.name, + value: {name: searchResult.indexableObject.name, object: searchResult.indexableObject} }; }); }) @@ -93,8 +92,7 @@ export class ItemMoveComponent implements OnInit { */ onClick(data: any): void { this.selectedCollection = data.name; - this.selectedCollectionId = data.id; - this.selectedCollectionObject = data; + this.selectedCollectionObject = data.object; } /** From a419e64cef6f1e72448ef8d6130acd7466865f42 Mon Sep 17 00:00:00 2001 From: Philip Vissenaekens Date: Tue, 28 May 2019 17:13:18 +0200 Subject: [PATCH 16/33] 62571: removed duplicate line --- .../item-operation/item-operation.component.spec.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts index 9b0c516083..1901bf5fb4 100644 --- a/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-operation/item-operation.component.spec.ts @@ -20,8 +20,6 @@ describe('ItemOperationComponent', () => { beforeEach(() => { itemOperation = new ItemOperation('key1', 'url1'); - itemOperation = new ItemOperation('key1', 'url1'); - fixture = TestBed.createComponent(ItemOperationComponent); comp = fixture.componentInstance; comp.operation = itemOperation; From 359cb10fa34a26a0bdd6d2d298dc860a659eda62 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Fri, 26 Jul 2019 17:21:57 +0200 Subject: [PATCH 17/33] add json5 support --- package.json | 2 + resources/i18n/{cs.json => cs.json5} | 31 ++++++- resources/i18n/{de.json => de.json5} | 30 ++++++- resources/i18n/{en.json => en.json5} | 80 +++++++++++++++++-- resources/i18n/{nl.json => nl.json5} | 30 ++++++- src/modules/app/browser-app.module.ts | 5 +- src/modules/app/server-app.module.ts | 4 +- .../translate-json5-http.loader.ts | 15 ++++ .../translate-json5-universal.loader.ts} | 5 +- yarn.lock | 12 +++ 10 files changed, 196 insertions(+), 18 deletions(-) rename resources/i18n/{cs.json => cs.json5} (99%) rename resources/i18n/{de.json => de.json5} (99%) rename resources/i18n/{en.json => en.json5} (99%) rename resources/i18n/{nl.json => nl.json5} (99%) create mode 100644 src/ngx-translate-loaders/translate-json5-http.loader.ts rename src/{modules/translate-universal-loader.ts => ngx-translate-loaders/translate-json5-universal.loader.ts} (65%) diff --git a/package.json b/package.json index 5ec7b2d694..d53a36dac3 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,7 @@ "https": "1.0.0", "js-cookie": "2.2.0", "js.clone": "0.0.3", + "json5": "^2.1.0", "jsonschema": "1.2.2", "jwt-decode": "^2.2.0", "methods": "1.1.2", @@ -152,6 +153,7 @@ "@types/hammerjs": "2.0.35", "@types/jasmine": "^2.8.6", "@types/js-cookie": "2.1.0", + "@types/json5": "^0.0.30", "@types/lodash": "^4.14.110", "@types/memory-cache": "0.2.0", "@types/mime": "2.0.0", diff --git a/resources/i18n/cs.json b/resources/i18n/cs.json5 similarity index 99% rename from resources/i18n/cs.json rename to resources/i18n/cs.json5 index d658030b6b..fea79b3667 100644 --- a/resources/i18n/cs.json +++ b/resources/i18n/cs.json5 @@ -2,6 +2,7 @@ "404.help": "Nepodařilo se najít stránku, kterou hledáte. Je možné, že stránka byla přesunuta nebo smazána. Pomocí tlačítka níže můžete přejít na domovskou stránku. ", "404.link.home-page": "Přejít na domovskou stránku", "404.page-not-found": "stránka nenalezena", + "admin.registries.bitstream-formats.description": "Tento seznam formátů souborů poskytuje informace o známých formátech a o úrovni jejich podpory.", "admin.registries.bitstream-formats.formats.no-items": "Žádné formáty souborů.", "admin.registries.bitstream-formats.formats.table.internal": "interní", @@ -13,6 +14,7 @@ "admin.registries.bitstream-formats.formats.table.supportLevel.head": "Úroveň podpory", "admin.registries.bitstream-formats.head": "Registr formátů souborů", "admin.registries.bitstream-formats.title": "DSpace Angular :: Registr formátů souborů", + "admin.registries.metadata.description": "Registr metadat je seznam všech metadatových polí dostupných v repozitáři. Tyto pole mohou být rozdělena do více schémat. DSpace však vyžaduje použití schématu kvalifikový Dublin Core.", "admin.registries.metadata.head": "Registr metadat", "admin.registries.metadata.schemas.no-items": "Žádná schémata metadat.", @@ -20,6 +22,7 @@ "admin.registries.metadata.schemas.table.name": "Název", "admin.registries.metadata.schemas.table.namespace": "Jmenný prostor", "admin.registries.metadata.title": "DSpace Angular :: Registr metadat", + "admin.registries.schema.description": "Toto je schéma metadat pro „{{namespace}}“.", "admin.registries.schema.fields.head": "Pole schématu metadat", "admin.registries.schema.fields.no-items": "Žádná metadatová pole.", @@ -27,15 +30,20 @@ "admin.registries.schema.fields.table.scopenote": "Poznámka o rozsahu", "admin.registries.schema.head": "Metadata Schema", "admin.registries.schema.title": "DSpace Angular :: Registr schémat metadat", + "auth.errors.invalid-user": "Neplatná e-mailová adresa nebo heslo.", "auth.messages.expired": "Vaše relace vypršela. Prosím, znova se přihlaste.", + "browse.title": "Prohlížíte {{ collection }} dle {{ field }} {{ value }}", + "collection.page.browse.recent.head": "Poslední příspěvky", "collection.page.license": "Licence", "collection.page.news": "Novinky", + "community.page.license": "Licence", "community.page.news": "Novinky", "community.sub-collection-list.head": "Kolekce v této komunitě", + "error.browse-by": "Chyba během stahování záznamů", "error.collection": "Chyba během stahování kolekce", "error.community": "Chyba během stahování komunity", @@ -48,9 +56,11 @@ "error.top-level-communities": "Chyba během stahování komunit nejvyšší úrovně", "error.validation.license.notgranted": "Pro dokončení zaslání Musíte udělit licenci. Pokud v tuto chvíli tuto licenci nemůžete udělit, můžete svou práci uložit a později se k svému příspěveku vrátit nebo jej smazat.", "error.validation.pattern": "Tento vstup je omezen dle vzoru: {{ pattern }}.", + "footer.copyright": "copyright © 2002-{{ year }}", "footer.link.dspace": "software DSpace", "footer.link.duraspace": "DuraSpace", + "form.cancel": "Zrušit", "form.first-name": "Křestní jméno", "form.group-collapse": "Sbalit", @@ -64,10 +74,12 @@ "form.remove": "Smazat", "form.search": "Hledat", "form.submit": "Odeslat", + "home.description": "", "home.title": "DSpace Angular :: Domů", "home.top-level-communities.head": "Komunity v DSpace", "home.top-level-communities.help": "Vybráním komunity můžete prohlížet její kolekce.", + "item.page.abstract": "Abstract", "item.page.author": "Autor", "item.page.collections": "Kolekce", @@ -81,6 +93,7 @@ "item.page.link.full": "Úplný záznam", "item.page.link.simple": "Minimální záznam", "item.page.uri": "URI", + "loading.browse-by": "Načítají se záznamy...", "loading.collection": "Načítá se kolekce...", "loading.community": "Načítá se komunita...", @@ -91,6 +104,7 @@ "loading.search-results": "Načítají se výsledky hledání...", "loading.sub-collections": "Načítají se subkolekce...", "loading.top-level-communities": "Načítají se komunity nejvyšší úrovně...", + "login.form.email": "E-mailová adresa", "login.form.forgot-password": "Zapomněli jste své heslo?", "login.form.header": "Prosím, přihlaste se do DSpace", @@ -98,22 +112,29 @@ "login.form.password": "Heslo", "login.form.submit": "Přihlásit se", "login.title": "Přihlásit se", + "logout.form.header": "Odhlásit se z DSpace", "logout.form.submit": "Odhlásit se", "logout.title": "Odhlásit se", + "nav.home": "Domů", "nav.login": "Přihlásit se", "nav.logout": "Odhlásit se", + "pagination.results-per-page": "Výsledků na stránku", "pagination.showing.detail": "{{ range }} z {{ total }}", "pagination.showing.label": "Zobrazují se záznamy ", "pagination.sort-direction": "Seřazení", + "search.description": "", + "search.title": "DSpace Angular :: Hledat", + "search.filters.applied.f.author": "Autor", "search.filters.applied.f.dateIssued.max": "Do data", "search.filters.applied.f.dateIssued.min": "Od data", "search.filters.applied.f.has_content_in_original_bundle": "Má soubory", "search.filters.applied.f.subject": "Předmět", + "search.filters.filter.author.head": "Autor", "search.filters.filter.author.placeholder": "Jméno autora", "search.filters.filter.dateIssued.head": "Datum", @@ -126,12 +147,16 @@ "search.filters.filter.show-more": "Zobrazit více", "search.filters.filter.subject.head": "Předmět", "search.filters.filter.subject.placeholder": "Předmět", + "search.filters.head": "Filtry", "search.filters.reset": "Obnovit filtry", + "search.form.search": "Hledat", "search.form.search_dspace": "Hledat v DSpace", + "search.results.head": "Výsledky hledání", "search.results.no-results": "Nebyli nalezeny žádné výsledky", + "search.sidebar.close": "Zpět na výsledky", "search.sidebar.filters.title": "Filtry", "search.sidebar.open": "Vyhledávací nástroje", @@ -139,11 +164,13 @@ "search.sidebar.settings.rpp": "Výsledků na stránku", "search.sidebar.settings.sort-by": "Řadit dle", "search.sidebar.settings.title": "Nastavení", - "search.title": "DSpace Angular :: Hledat", + "search.view-switch.show-grid": "Zobrazit mřížku", "search.view-switch.show-list": "Zobrazit seznam", + "sorting.dc.title.ASC": "Název vzestupně", "sorting.dc.title.DESC": "Název sestupně", "sorting.score.DESC": "Relevance", - "title": "DSpace" + + "title": "DSpace", } diff --git a/resources/i18n/de.json b/resources/i18n/de.json5 similarity index 99% rename from resources/i18n/de.json rename to resources/i18n/de.json5 index d184e7d091..29e3073592 100644 --- a/resources/i18n/de.json +++ b/resources/i18n/de.json5 @@ -2,6 +2,7 @@ "404.help": "Die Seite, die Sie aufrufen wollten, konnte nicht gefunden werden. Sie könnte verschoben oder gelöscht worden sein. Mit dem Link unten kommen Sie zurück zur Startseite. ", "404.link.home-page": "Zurück zur Startseite", "404.page-not-found": "Seite nicht gefunden", + "admin.registries.bitstream-formats.description": "Diese Liste enhtält die in diesem Repositorium zulässigen Dateiformate und den jeweiligen Unterstützungsgrad.", "admin.registries.bitstream-formats.formats.no-items": "Es gibt keine Formate in dieser Referenzliste.", "admin.registries.bitstream-formats.formats.table.internal": "intern", @@ -13,6 +14,7 @@ "admin.registries.bitstream-formats.formats.table.supportLevel.head": "Unterstützungsgrad", "admin.registries.bitstream-formats.head": "Referenzliste der Dateiformate", "admin.registries.bitstream-formats.title": "DSpace Angular :: Referenzliste der Dateiformate", + "admin.registries.metadata.description": "Die Metadatenreferenzliste beinhaltet alle Metadatenfelder, die zur Verfügung stehen. Die Felder können in unterschiedlichen Schemata enthalten sein. Nichtsdestotrotz benötigt DSpace mindestens qualifiziertes Dublin Core.", "admin.registries.metadata.head": "Metadatenreferenzliste", "admin.registries.metadata.schemas.no-items": "Es gbit keine Metadatenschemata.", @@ -20,6 +22,7 @@ "admin.registries.metadata.schemas.table.name": "Name", "admin.registries.metadata.schemas.table.namespace": "Namensraum", "admin.registries.metadata.title": "DSpace Angular :: Metadatenreferenzliste", + "admin.registries.schema.description": "Dies ist das Metadatenschema für \"{{namespace}}\".", "admin.registries.schema.fields.head": "Felder in diesem Schema", "admin.registries.schema.fields.no-items": "Es gibt keine Felder in diesem Schema.", @@ -27,15 +30,19 @@ "admin.registries.schema.fields.table.scopenote": "Gültigkeitsbereich", "admin.registries.schema.head": "Metadatenschemata", "admin.registries.schema.title": "DSpace Angular :: Referenzliste der Metadatenschemata", + "auth.errors.invalid-user": "Ungültige E-Mail-Adresse oder Passwort.", "auth.messages.expired": "Ihre Sitzung ist abgelaufen, bitte melden Sie sich erneut an.", + "browse.title": "Anzeige {{ collection }} nach {{ field }} {{ value }}", "collection.page.browse.recent.head": "Aktuellste Veröffentlichungen", "collection.page.license": "Lizenz", "collection.page.news": "Neuigkeiten", + "community.page.license": "Lizenz", "community.page.news": "Neuigkeiten", "community.sub-collection-list.head": "Sammlungen in diesem Bereich", + "error.browse-by": "Fehler beim Laden der Ressourcen", "error.collection": "Fehler beim Laden der Sammlung.", "error.community": "Fehler beim Laden des Bereiches.", @@ -48,9 +55,11 @@ "error.top-level-communities": "Fehler beim Laden der Hauptbereiche.", "error.validation.license.notgranted": "Sie müssen der Lizenz zustimmen, um die Ressource einzureichen. Wenn dies zur Zeit nicht geht, können Sie die Einreichung speichern und später wiederaufnehmen oder löschen.", "error.validation.pattern": "Die Eingabe kann nur folgendes Muster haben: {{ pattern }}.", + "footer.copyright": "Copyright © 2002-{{ year }}", "footer.link.dspace": "DSpace Software", "footer.link.duraspace": "DuraSpace", + "form.cancel": "Abbrechen", "form.first-name": "Vorname", "form.group-collapse": "Weniger", @@ -64,10 +73,12 @@ "form.remove": "Löschen", "form.search": "Suchen", "form.submit": "Los", + "home.description": "", "home.title": "DSpace Angular :: Startseite", "home.top-level-communities.head": "Bereiche in DSpace", "home.top-level-communities.help": "Wählen Sie einen Bereich, um seine Sammlungen einzusehen.", + "item.page.abstract": "Kurzfassung", "item.page.author": "Autor", "item.page.collections": "Sammlungen", @@ -81,6 +92,7 @@ "item.page.link.full": "Vollanzeige", "item.page.link.simple": "Kurzanzeige", "item.page.uri": "URI", + "loading.browse-by": "Die Ressourcen werden geladen ...", "loading.collection": "Die Sammlung wird geladen ...", "loading.community": "Der Bereich wird geladen ...", @@ -91,6 +103,7 @@ "loading.search-results": "Die Suchergebnisse werden geladen ...", "loading.sub-collections": "Die untergeordneten Sammlungen werden geladen ...", "loading.top-level-communities": "Die Hauptbereiche werden geladen ...", + "login.form.email": "E-Mail-Adresse", "login.form.forgot-password": "Haben Sie Ihr Passwort vergessen?", "login.form.header": "Bitte Loggen Sie sich ein.", @@ -98,22 +111,29 @@ "login.form.password": "Passwort", "login.form.submit": "Einloggen", "login.title": "Einloggen", + "logout.form.header": "Ausloggen aus DSpace", "logout.form.submit": "Ausloggen", "logout.title": "Ausloggen", + "nav.home": "Zur Startseite", "nav.login": "Anmelden", "nav.logout": "Abmelden", + "pagination.results-per-page": "Ergebnisse pro Seite", "pagination.showing.detail": "{{ range }} bis {{ total }}", "pagination.showing.label": "Anzeige der Treffer ", "pagination.sort-direction": "Sortiermöglichkeiten", + "search.description": "", + "search.title": "DSpace Angular :: Suche", + "search.filters.applied.f.author": "Autor", "search.filters.applied.f.dateIssued.max": "Enddatum", "search.filters.applied.f.dateIssued.min": "Anfangsdatum", "search.filters.applied.f.has_content_in_original_bundle": "Besitzt Dateien", "search.filters.applied.f.subject": "Thema", + "search.filters.filter.author.head": "Autor", "search.filters.filter.author.placeholder": "Autor", "search.filters.filter.dateIssued.head": "Datum", @@ -126,12 +146,16 @@ "search.filters.filter.show-more": "Zeige mehr", "search.filters.filter.subject.head": "Schlagwort", "search.filters.filter.subject.placeholder": "Schlagwort", + "search.filters.head": "Filter", "search.filters.reset": "Filter zurücksetzen", + "search.form.search": "Suche", "search.form.search_dspace": "DSpace durchsuchen", + "search.results.head": "Suchergebnisse", "search.results.no-results": "Zu dieser Suche gibt es keine Treffer.", + "search.sidebar.close": "Zurück zu den Ergebnissen", "search.sidebar.filters.title": "Filter", "search.sidebar.open": "Suchwerkzeuge", @@ -139,11 +163,13 @@ "search.sidebar.settings.rpp": "Treffer pro Seite", "search.sidebar.settings.sort-by": "Sortiere nach", "search.sidebar.settings.title": "Einstellungen", - "search.title": "DSpace Angular :: Suche", + "search.view-switch.show-grid": "Zeige als Raster", "search.view-switch.show-list": "Zeige als Liste", + "sorting.dc.title.ASC": "Titel aufsteigend", "sorting.dc.title.DESC": "Titel absteigend", "sorting.score.DESC": "Relevanz", - "title": "DSpace" + + "title": "DSpace", } diff --git a/resources/i18n/en.json b/resources/i18n/en.json5 similarity index 99% rename from resources/i18n/en.json rename to resources/i18n/en.json5 index 63bc598304..1ae31109c8 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json5 @@ -2,6 +2,7 @@ "404.help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ", "404.link.home-page": "Take me to the home page", "404.page-not-found": "page not found", + "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", "admin.registries.bitstream-formats.formats.no-items": "No bitstream formats to show.", "admin.registries.bitstream-formats.formats.table.internal": "internal", @@ -13,6 +14,7 @@ "admin.registries.bitstream-formats.formats.table.supportLevel.head": "Support Level", "admin.registries.bitstream-formats.head": "Bitstream Format Registry", "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Format Registry", + "admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.", "admin.registries.metadata.form.create": "Create metadata schema", "admin.registries.metadata.form.edit": "Edit metadata schema", @@ -25,6 +27,7 @@ "admin.registries.metadata.schemas.table.name": "Name", "admin.registries.metadata.schemas.table.namespace": "Namespace", "admin.registries.metadata.title": "DSpace Angular :: Metadata Registry", + "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", "admin.registries.schema.fields.head": "Schema metadata fields", "admin.registries.schema.fields.no-items": "No metadata fields to show.", @@ -49,8 +52,10 @@ "admin.registries.schema.notification.success": "Success", "admin.registries.schema.return": "Return", "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Registry", + "auth.errors.invalid-user": "Invalid email address or password.", "auth.messages.expired": "Your session has expired. Please log in again.", + "browse.comcol.by.author": "By Author", "browse.comcol.by.dateissued": "By Issue Date", "browse.comcol.by.subject": "By Subject", @@ -81,7 +86,9 @@ "browse.startsWith.type_date": "Or type in a date (year-month):", "browse.startsWith.type_text": "Or enter first few letters:", "browse.title": "Browsing {{ collection }} by {{ field }} {{ value }}", + "chips.remove": "Remove chip", + "collection.create.head": "Create a Collection", "collection.create.sub-head": "Create a Collection for Community {{ parent }}", "collection.delete.cancel": "Cancel", @@ -103,6 +110,7 @@ "collection.page.browse.recent.head": "Recent Submissions", "collection.page.license": "License", "collection.page.news": "News", + "community.create.head": "Create a Community", "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", "community.delete.cancel": "Cancel", @@ -123,6 +131,7 @@ "community.page.news": "News", "community.sub-collection-list.head": "Collections of this Community", "community.sub-community-list.head": "Communities of this Community", + "dso-selector.create.collection.head": "New collection", "dso-selector.create.community.head": "New community", "dso-selector.create.community.sub-level": "Create a new community in", @@ -133,6 +142,7 @@ "dso-selector.edit.item.head": "Edit item", "dso-selector.no-results": "No {{ type }} found", "dso-selector.placeholder": "Search for a {{ type }}", + "error.browse-by": "Error fetching items", "error.collection": "Error fetching collection", "error.community": "Error fetching community", @@ -147,9 +157,11 @@ "error.top-level-communities": "Error fetching top-level communities", "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", + "footer.copyright": "copyright © 2002-{{ year }}", "footer.link.dspace": "DSpace software", "footer.link.duraspace": "DuraSpace", + "form.cancel": "Cancel", "form.clear": "Clear", "form.clear-help": "Click here to remove the selected value", @@ -171,10 +183,12 @@ "form.search": "Search", "form.search-help": "Click here to looking for an existing correspondence", "form.submit": "Submit", + "home.description": "", "home.title": "DSpace Angular :: Home", "home.top-level-communities.head": "Communities in DSpace", "home.top-level-communities.help": "Select a community to browse its collections.", + "item.edit.delete.cancel": "Cancel", "item.edit.delete.confirm": "Delete", "item.edit.delete.description": "Are you sure this item should be completely deleted? Caution: At present, no tombstone would be left.", @@ -182,6 +196,7 @@ "item.edit.delete.header": "Delete item: {{ id }}", "item.edit.delete.success": "The item has been deleted", "item.edit.head": "Edit Item", + "item.edit.metadata.add-button": "Add", "item.edit.metadata.discard-button": "Discard", "item.edit.metadata.edit.buttons.edit": "Edit", @@ -203,27 +218,32 @@ "item.edit.metadata.notifications.saved.title": "Metadata saved", "item.edit.metadata.reinstate-button": "Undo", "item.edit.metadata.save-button": "Save", + "item.edit.modify.overview.field": "Field", "item.edit.modify.overview.language": "Language", "item.edit.modify.overview.value": "Value", + "item.edit.private.cancel": "Cancel", "item.edit.private.confirm": "Make it Private", "item.edit.private.description": "Are you sure this item should be made private in the archive?", "item.edit.private.error": "An error occurred while making the item private", "item.edit.private.header": "Make item private: {{ id }}", "item.edit.private.success": "The item is now private", + "item.edit.public.cancel": "Cancel", "item.edit.public.confirm": "Make it Public", "item.edit.public.description": "Are you sure this item should be made public in the archive?", "item.edit.public.error": "An error occurred while making the item public", "item.edit.public.header": "Make item public: {{ id }}", "item.edit.public.success": "The item is now public", + "item.edit.reinstate.cancel": "Cancel", "item.edit.reinstate.confirm": "Reinstate", "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", "item.edit.reinstate.error": "An error occurred while reinstating the item", "item.edit.reinstate.header": "Reinstate item: {{ id }}", "item.edit.reinstate.success": "The item was reinstated successfully", + "item.edit.tabs.bitstreams.head": "Item Bitstreams", "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", "item.edit.tabs.curate.head": "Curate", @@ -255,12 +275,14 @@ "item.edit.tabs.status.title": "Item Edit - Status", "item.edit.tabs.view.head": "View Item", "item.edit.tabs.view.title": "Item Edit - View", + "item.edit.withdraw.cancel": "Cancel", "item.edit.withdraw.confirm": "Withdraw", "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", "item.edit.withdraw.error": "An error occurred while withdrawing the item", "item.edit.withdraw.header": "Withdraw item: {{ id }}", "item.edit.withdraw.success": "The item was withdrawn successfully", + "item.page.abstract": "Abstract", "item.page.author": "Authors", "item.page.citation": "Citation", @@ -278,10 +300,12 @@ "item.page.person.search.title": "Articles by this author", "item.page.subject": "Keywords", "item.page.uri": "URI", + "item.select.confirm": "Confirm selected", "item.select.table.author": "Author", "item.select.table.collection": "Collection", "item.select.table.title": "Title", + "journal.listelement.badge": "Journal", "journal.page.description": "Description", "journal.page.editor": "Editor-in-Chief", @@ -290,6 +314,7 @@ "journal.page.titleprefix": "Journal: ", "journal.search.results.head": "Journal Search Results", "journal.search.title": "DSpace Angular :: Journal Search", + "journalissue.listelement.badge": "Journal Issue", "journalissue.page.description": "Description", "journalissue.page.issuedate": "Issue Date", @@ -298,11 +323,13 @@ "journalissue.page.keyword": "Keywords", "journalissue.page.number": "Number", "journalissue.page.titleprefix": "Journal Issue: ", + "journalvolume.listelement.badge": "Journal Volume", "journalvolume.page.description": "Description", "journalvolume.page.issuedate": "Issue Date", "journalvolume.page.titleprefix": "Journal Volume: ", "journalvolume.page.volume": "Volume", + "loading.browse-by": "Loading items...", "loading.browse-by-page": "Loading page...", "loading.collection": "Loading collection...", @@ -316,6 +343,7 @@ "loading.sub-collections": "Loading sub-collections...", "loading.sub-communities": "Loading sub-communities...", "loading.top-level-communities": "Loading top-level communities...", + "login.form.email": "Email address", "login.form.forgot-password": "Have you forgotten your password?", "login.form.header": "Please log in to DSpace", @@ -323,15 +351,19 @@ "login.form.password": "Password", "login.form.submit": "Log in", "login.title": "Login", + "logout.form.header": "Log out from DSpace", "logout.form.submit": "Log out", "logout.title": "Logout", + "menu.header.admin": "Admin", "menu.header.image.logo": "Repository logo", + "menu.section.access_control": "Access Control", "menu.section.access_control_authorizations": "Authorizations", "menu.section.access_control_groups": "Groups", "menu.section.access_control_people": "People", + "menu.section.browse_community": "This Community", "menu.section.browse_community_by_author": "By Author", "menu.section.browse_community_by_issue_date": "By Issue Date", @@ -342,21 +374,26 @@ "menu.section.browse_global_by_subject": "By Subject", "menu.section.browse_global_by_title": "By Title", "menu.section.browse_global_communities_and_collections": "Communities & Collections", + "menu.section.control_panel": "Control Panel", "menu.section.curation_task": "Curation Task", + "menu.section.edit": "Edit", "menu.section.edit_collection": "Collection", "menu.section.edit_community": "Community", "menu.section.edit_item": "Item", + "menu.section.export": "Export", "menu.section.export_collection": "Collection", "menu.section.export_community": "Community", "menu.section.export_item": "Item", "menu.section.export_metadata": "Metadata", + "menu.section.find": "Find", "menu.section.find_items": "Items", "menu.section.find_private_items": "Private Items", "menu.section.find_withdrawn_items": "Withdrawn Items", + "menu.section.icon.access_control": "Access Control menu section", "menu.section.icon.control_panel": "Control Panel menu section", "menu.section.icon.curation_task": "Curation Task menu section", @@ -369,20 +406,27 @@ "menu.section.icon.registries": "Registries menu section", "menu.section.icon.statistics_task": "Statistics Task menu section", "menu.section.icon.unpin": "Unpin sidebar", + "menu.section.import": "Import", "menu.section.import_batch": "Batch Import (ZIP)", "menu.section.import_metadata": "Metadata", + "menu.section.new": "New", "menu.section.new_collection": "Collection", "menu.section.new_community": "Community", "menu.section.new_item": "Item", "menu.section.new_item_version": "Item Version", + "menu.section.pin": "Pin sidebar", + "menu.section.unpin": "Unpin sidebar", + "menu.section.registries": "Registries", "menu.section.registries_format": "Format", "menu.section.registries_metadata": "Metadata", + "menu.section.statistics": "Statistics", "menu.section.statistics_task": "Statistics Task", + "menu.section.toggle.access_control": "Toggle Access Control section", "menu.section.toggle.control_panel": "Toggle Control Panel section", "menu.section.toggle.curation_task": "Toggle Curation Task section", @@ -393,7 +437,7 @@ "menu.section.toggle.new": "Toggle New section", "menu.section.toggle.registries": "Toggle Registries section", "menu.section.toggle.statistics_task": "Toggle Statistics Task section", - "menu.section.unpin": "Unpin sidebar", + "mydspace.description": "", "mydspace.general.text-here": "HERE", "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", @@ -431,6 +475,7 @@ "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", "mydspace.view-btn": "View", + "nav.browse.header": "All of DSpace", "nav.community-browse.header": "By Community", "nav.language": "Language switch", @@ -439,6 +484,7 @@ "nav.mydspace": "MyDSpace", "nav.search": "Search", "nav.statistics.header": "Statistics", + "orgunit.listelement.badge": "Organizational Unit", "orgunit.page.city": "City", "orgunit.page.country": "Country", @@ -446,10 +492,12 @@ "orgunit.page.description": "Description", "orgunit.page.id": "ID", "orgunit.page.titleprefix": "Organizational Unit: ", + "pagination.results-per-page": "Results Per Page", "pagination.showing.detail": "{{ range }} of {{ total }}", "pagination.showing.label": "Now showing ", "pagination.sort-direction": "Sort Options", + "person.listelement.badge": "Person", "person.page.birthdate": "Birth Date", "person.page.email": "Email Address", @@ -462,6 +510,7 @@ "person.page.titleprefix": "Person: ", "person.search.results.head": "Person Search Results", "person.search.title": "DSpace Angular :: Person Search", + "project.listelement.badge": "Research Project", "project.page.contributor": "Contributors", "project.page.description": "Description", @@ -471,6 +520,7 @@ "project.page.keyword": "Keywords", "project.page.status": "Status", "project.page.titleprefix": "Research Project: ", + "publication.listelement.badge": "Publication", "publication.page.description": "Description", "publication.page.journal-issn": "Journal ISSN", @@ -480,6 +530,7 @@ "publication.page.volume-title": "Volume Title", "publication.search.results.head": "Publication Search Results", "publication.search.title": "DSpace Angular :: Publication Search", + "relationships.isAuthorOf": "Authors", "relationships.isIssueOf": "Journal Issues", "relationships.isJournalIssueOf": "Journal Issue", @@ -492,7 +543,11 @@ "relationships.isSingleJournalOf": "Journal", "relationships.isSingleVolumeOf": "Journal Volume", "relationships.isVolumeOf": "Journal Volumes", + "search.description": "", + "search.switch-configuration.title": "Show", + "search.title": "DSpace Angular :: Search", + "search.filters.applied.f.author": "Author", "search.filters.applied.f.dateIssued.max": "End date", "search.filters.applied.f.dateIssued.min": "Start date", @@ -503,6 +558,7 @@ "search.filters.applied.f.namedresourcetype": "Status", "search.filters.applied.f.subject": "Subject", "search.filters.applied.f.submitter": "Submitter", + "search.filters.filter.author.head": "Author", "search.filters.filter.author.placeholder": "Author name", "search.filters.filter.birthDate.head": "Birth Date", @@ -547,14 +603,18 @@ "search.filters.filter.subject.placeholder": "Subject", "search.filters.filter.submitter.head": "Submitter", "search.filters.filter.submitter.placeholder": "Submitter", + "search.filters.head": "Filters", "search.filters.reset": "Reset filters", + "search.form.search": "Search", "search.form.search_dspace": "Search DSpace", "search.form.search_mydspace": "Search MyDSpace", + "search.results.head": "Search Results", "search.results.no-results": "Your search returned no results. Having trouble finding what you're looking for? Try putting", "search.results.no-results-link": "quotes around it", + "search.sidebar.close": "Back to results", "search.sidebar.filters.title": "Filters", "search.sidebar.open": "Search Tools", @@ -562,14 +622,15 @@ "search.sidebar.settings.rpp": "Results per page", "search.sidebar.settings.sort-by": "Sort By", "search.sidebar.settings.title": "Settings", - "search.switch-configuration.title": "Show", - "search.title": "DSpace Angular :: Search", + "search.view-switch.show-detail": "Show detail", "search.view-switch.show-grid": "Show as grid", "search.view-switch.show-list": "Show as list", + "sorting.dc.title.ASC": "Title Ascending", "sorting.dc.title.DESC": "Title Descending", "sorting.score.DESC": "Relevance", + "submission.edit.title": "Edit Submission", "submission.general.cannot_submit": "You have not the privilege to make a new submission.", "submission.general.deposit": "Deposit", @@ -580,7 +641,7 @@ "submission.general.discard.submit": "Discard", "submission.general.save": "Save", "submission.general.save-later": "Save for later", - "submission.mydspace": {}, + "submission.sections.general.add-more": "Add more", "submission.sections.general.collection": "Collection", "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", @@ -595,6 +656,7 @@ "submission.sections.general.save_success_notice": "Submission saved successfully.", "submission.sections.general.search-collection": "Search for a collection", "submission.sections.general.sections_not_valid": "There are incomplete sections.", + "submission.sections.submit.progressbar.cclicense": "Creative commons license", "submission.sections.submit.progressbar.describe.recycle": "Recycle", "submission.sections.submit.progressbar.describe.stepcustom": "Describe", @@ -603,6 +665,7 @@ "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates", "submission.sections.submit.progressbar.license": "Deposit license", "submission.sections.submit.progressbar.upload": "Upload files", + "submission.sections.upload.delete.confirm.cancel": "Cancel", "submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?", "submission.sections.upload.delete.confirm.submit": "Yes, I'm sure", @@ -626,13 +689,16 @@ "submission.sections.upload.undo": "Cancel", "submission.sections.upload.upload-failed": "Upload failed", "submission.sections.upload.upload-successful": "Upload successful", + "submission.submit.title": "Submission", + "submission.workflow.generic.delete": "Delete", "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", "submission.workflow.generic.edit": "Edit", "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", "submission.workflow.generic.view": "View", "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", + "submission.workflow.tasks.claimed.approve": "Approve", "submission.workflow.tasks.claimed.approve_help": "If you have reviewed the item and it is suitable for inclusion in the collection, select \"Approve\".", "submission.workflow.tasks.claimed.edit": "Edit", @@ -645,18 +711,22 @@ "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return_help": "Return the task to the pool so that another user may perform the task.", + "submission.workflow.tasks.generic.error": "Error occurred during operation...", "submission.workflow.tasks.generic.processing": "Processing...", "submission.workflow.tasks.generic.submitter": "Submitter", "submission.workflow.tasks.generic.success": "Operation successful", + "submission.workflow.tasks.pool.claim": "Claim", "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", "submission.workflow.tasks.pool.hide-detail": "Hide detail", "submission.workflow.tasks.pool.show-detail": "Show detail", + "title": "DSpace", + "uploader.browse": "browse", "uploader.drag-message": "Drag & Drop your files here", "uploader.or": ", or", "uploader.processing": "Processing", - "uploader.queue-lenght": "Queue length" + "uploader.queue-lenght": "Queue length", } diff --git a/resources/i18n/nl.json b/resources/i18n/nl.json5 similarity index 99% rename from resources/i18n/nl.json rename to resources/i18n/nl.json5 index da12ff0518..a195e13e01 100644 --- a/resources/i18n/nl.json +++ b/resources/i18n/nl.json5 @@ -2,6 +2,7 @@ "404.help": "De pagina die u zoekt kan niet gevonden worden. De pagina werd mogelijk verplaatst of verwijderd. U kan onderstaande knop gebruiken om terug naar de homepagina te gaan. ", "404.link.home-page": "Terug naar de homepagina", "404.page-not-found": "Pagina niet gevonden", + "admin.registries.bitstream-formats.description": "Deze lijst van Bitstream formaten biedt informatie over de formaten die in deze repository zijn toegelaten en op welke manier ze ondersteund worden. De term Bitstream wordt in DSpace gebruikt om een bestand aan te duiden dat samen met metadata onderdeel uitmaakt van een item. De naam bitstream duidt op het feit dat het bestand achterliggend wordt opgeslaan zonder bestandsextensie.", "admin.registries.bitstream-formats.formats.no-items": "Er kunnen geen bitstreamformaten getoond worden.", "admin.registries.bitstream-formats.formats.table.internal": "intern", @@ -13,6 +14,7 @@ "admin.registries.bitstream-formats.formats.table.supportLevel.head": "Ondersteuning", "admin.registries.bitstream-formats.head": "Bitstream Formaat Register", "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Formaat Register", + "admin.registries.metadata.description": "Het metadataregister omvat de lijst van alle metadatavelden die beschikbaar zijn in het systeem. Deze velden kunnen verspreid zijn over verschillende metadataschema's. Het qualified Dublin Core schema (dc) is een verplicht schema en kan niet worden verwijderd.", "admin.registries.metadata.head": "Metadata Register", "admin.registries.metadata.schemas.no-items": "Er kunnen geen metadataschema's getoond worden.", @@ -20,6 +22,7 @@ "admin.registries.metadata.schemas.table.name": "Naam", "admin.registries.metadata.schemas.table.namespace": "Naamruimte", "admin.registries.metadata.title": "DSpace Angular :: Metadata Register", + "admin.registries.schema.description": "Dit is het metadataschema voor \"{{namespace}}\".", "admin.registries.schema.fields.head": "Schema metadatavelden", "admin.registries.schema.fields.no-items": "Er kunnen geen metadatavelden getoond worden.", @@ -27,15 +30,20 @@ "admin.registries.schema.fields.table.scopenote": "Opmerking over bereik", "admin.registries.schema.head": "Metadata Schema", "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Register", + "auth.errors.invalid-user": "Ongeldig e-mailadres of wachtwoord.", "auth.messages.expired": "Uw sessie is vervallen. Gelieve opnieuw aan te melden.", + "browse.title": "Verken {{ collection }} volgens {{ field }} {{ value }}", + "collection.page.browse.recent.head": "Recent toegevoegd", "collection.page.license": "Licentie", "collection.page.news": "Nieuws", + "community.page.license": "Licentie", "community.page.news": "Nieuws", "community.sub-collection-list.head": "Collecties in deze Community", + "error.browse-by": "Fout bij het ophalen van items", "error.collection": "Fout bij het ophalen van een collectie", "error.community": "Fout bij het ophalen van een community", @@ -48,9 +56,11 @@ "error.top-level-communities": "Fout bij het inladen van communities op het hoogste niveau", "error.validation.license.notgranted": "U moet de invoerlicentie goedkeuren om de invoer af te werken. Indien u deze licentie momenteel niet kan of mag goedkeuren, kan u uw werk opslaan en de invoer later afwerken. U kunt dit nieuwe item ook verwijderen indien u niet voldoet aan de vereisten van de invoerlicentie.", "error.validation.pattern": "Deze invoer is niet toegelaten volgens dit patroon: {{ pattern }}.", + "footer.copyright": "copyright © 2002-{{ year }}", "footer.link.dspace": "DSpace software", "footer.link.duraspace": "DuraSpace", + "form.cancel": "Annuleer", "form.first-name": "Voornaam", "form.group-collapse": "Inklappen", @@ -64,10 +74,12 @@ "form.remove": "Verwijder", "form.search": "Zoek", "form.submit": "Verstuur", + "home.description": "", "home.title": "DSpace Angular :: Home", "home.top-level-communities.head": "Communities in DSpace", "home.top-level-communities.help": "Selecteer een community om diens collecties te verkennen.", + "item.page.abstract": "Abstract", "item.page.author": "Auteur", "item.page.collections": "Collecties", @@ -81,6 +93,7 @@ "item.page.link.full": "Volledige itemweergave", "item.page.link.simple": "Eenvoudige itemweergave", "item.page.uri": "URI", + "loading.browse-by": "Items worden ingeladen...", "loading.collection": "Collectie wordt ingeladen...", "loading.community": "Community wordt ingeladen...", @@ -91,6 +104,7 @@ "loading.search-results": "Zoekresultaten worden ingeladen...", "loading.sub-collections": "De sub-collecties worden ingeladen...", "loading.top-level-communities": "Inladen van de Communities op het hoogste niveau...", + "login.form.email": "Email adres", "login.form.forgot-password": "Bent u uw wachtwoord vergeten?", "login.form.header": "Gelieve in te loggen in DSpace", @@ -98,17 +112,23 @@ "login.form.password": "Wachtwoord", "login.form.submit": "Aanmelden", "login.title": "Aanmelden", + "logout.form.header": "Afmelden in DSpace", "logout.form.submit": "Afmelden", "logout.title": "Afmelden", + "nav.home": "Home", "nav.login": "Log In", "nav.logout": "Log Uit", + "pagination.results-per-page": "Resultaten per pagina", "pagination.showing.detail": "{{ range }} van {{ total }}", "pagination.showing.label": "Resultaten ", "pagination.sort-direction": "Sorteermogelijkheden", + "search.description": "", + "search.title": "DSpace Angular :: Zoek", + "search.filters.applied.f.author": "Auteur", "search.filters.applied.f.dateIssued.max": "Einddatum", "search.filters.applied.f.dateIssued.min": "Startdatum", @@ -126,12 +146,16 @@ "search.filters.filter.show-more": "Toon meer", "search.filters.filter.subject.head": "Onderwerp", "search.filters.filter.subject.placeholder": "Onderwerp", + "search.filters.head": "Filters", "search.filters.reset": "Filters verwijderen", + "search.form.search": "Zoek", "search.form.search_dspace": "Zoek in DSpace", + "search.results.head": "Zoekresultaten", "search.results.no-results": "Er waren geen resultaten voor deze zoekopdracht", + "search.sidebar.close": "Terug naar de resultaten", "search.sidebar.filters.title": "Filters", "search.sidebar.open": "Zoek Tools", @@ -139,11 +163,13 @@ "search.sidebar.settings.rpp": "Resultaten per pagina", "search.sidebar.settings.sort-by": "Sorteer volgens", "search.sidebar.settings.title": "Instellingen", - "search.title": "DSpace Angular :: Zoek", + "search.view-switch.show-grid": "Toon in raster", "search.view-switch.show-list": "Toon als lijst", + "sorting.dc.title.ASC": "Oplopend op titel", "sorting.dc.title.DESC": "Aflopend op titel", "sorting.score.DESC": "Relevantie", - "title": "DSpace" + + "title": "DSpace", } diff --git a/src/modules/app/browser-app.module.ts b/src/modules/app/browser-app.module.ts index b20894880b..a90887e987 100644 --- a/src/modules/app/browser-app.module.ts +++ b/src/modules/app/browser-app.module.ts @@ -6,7 +6,7 @@ import { RouterModule } from '@angular/router'; import { REQUEST } from '@nguniversal/express-engine/tokens'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +import { TranslateJson5HttpLoader } from '../../ngx-translate-loaders/translate-json5-http.loader'; import { IdlePreload, IdlePreloadModule } from 'angular-idle-preload'; @@ -20,13 +20,12 @@ import { CookieService } from '../../app/shared/services/cookie.service'; import { AuthService } from '../../app/core/auth/auth.service'; import { Angulartics2Module } from 'angulartics2'; import { Angulartics2GoogleAnalytics } from 'angulartics2/ga'; -import { ServerSubmissionService } from '../../app/submission/server-submission.service'; import { SubmissionService } from '../../app/submission/submission.service'; export const REQ_KEY = makeStateKey('req'); export function createTranslateLoader(http: HttpClient) { - return new TranslateHttpLoader(http, 'assets/i18n/', '.json'); + return new TranslateJson5HttpLoader(http, 'assets/i18n/', '.json5'); } export function getRequest(transferState: TransferState): any { diff --git a/src/modules/app/server-app.module.ts b/src/modules/app/server-app.module.ts index d809d3cced..4a4efe2bdd 100644 --- a/src/modules/app/server-app.module.ts +++ b/src/modules/app/server-app.module.ts @@ -12,7 +12,7 @@ import { AppModule } from '../../app/app.module'; import { DSpaceServerTransferStateModule } from '../transfer-state/dspace-server-transfer-state.module'; import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service'; -import { TranslateUniversalLoader } from '../translate-universal-loader'; +import { TranslateJson5UniversalLoader } from '../../ngx-translate-loaders/translate-json5-universal.loader'; import { CookieService } from '../../app/shared/services/cookie.service'; import { ServerCookieService } from '../../app/shared/services/server-cookie.service'; import { AuthService } from '../../app/core/auth/auth.service'; @@ -24,7 +24,7 @@ import { SubmissionService } from '../../app/submission/submission.service'; import { ServerSubmissionService } from '../../app/submission/server-submission.service'; export function createTranslateLoader() { - return new TranslateUniversalLoader('dist/assets/i18n/', '.json'); + return new TranslateJson5UniversalLoader('dist/assets/i18n/', '.json5'); } @NgModule({ diff --git a/src/ngx-translate-loaders/translate-json5-http.loader.ts b/src/ngx-translate-loaders/translate-json5-http.loader.ts new file mode 100644 index 0000000000..edc467d99f --- /dev/null +++ b/src/ngx-translate-loaders/translate-json5-http.loader.ts @@ -0,0 +1,15 @@ +import { HttpClient } from '@angular/common/http'; +import { TranslateLoader } from '@ngx-translate/core'; +import { map } from 'rxjs/operators'; +import JSON5 from 'json5' + +export class TranslateJson5HttpLoader implements TranslateLoader { + constructor(private http: HttpClient, public prefix?: string, public suffix?: string) { + } + + getTranslation(lang: string): any { + return this.http.get('' + this.prefix + lang + this.suffix, {responseType: 'text'}).pipe( + map((json: any) => JSON5.parse(json)) + ); + } +} diff --git a/src/modules/translate-universal-loader.ts b/src/ngx-translate-loaders/translate-json5-universal.loader.ts similarity index 65% rename from src/modules/translate-universal-loader.ts rename to src/ngx-translate-loaders/translate-json5-universal.loader.ts index b2efaf2395..ca266f0153 100644 --- a/src/modules/translate-universal-loader.ts +++ b/src/ngx-translate-loaders/translate-json5-universal.loader.ts @@ -1,14 +1,15 @@ import { TranslateLoader } from '@ngx-translate/core'; import { Observable } from 'rxjs'; +import JSON5 from 'json5' import * as fs from 'fs'; -export class TranslateUniversalLoader implements TranslateLoader { +export class TranslateJson5UniversalLoader implements TranslateLoader { constructor(private prefix: string = 'dist/assets/i18n/', private suffix: string = '.json') { } public getTranslation(lang: string): Observable { return Observable.create((observer: any) => { - observer.next(JSON.parse(fs.readFileSync(`${this.prefix}${lang}${this.suffix}`, 'utf8'))); + observer.next(JSON5.parse(fs.readFileSync(`${this.prefix}${lang}${this.suffix}`, 'utf8'))); observer.complete(); }); } diff --git a/yarn.lock b/yarn.lock index eb0733e695..2d9aa7b0d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -371,6 +371,11 @@ resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.1.0.tgz#a8916246aa994db646c66d54c854916213300a51" integrity sha512-vPT5MV1pD71RFUD0ytp6Yw51W6zKJ9Qn2AcJXSD2TZqYKaXUtCxB3WZIXXFZtbAEVMgC59nmvVPSOH0EIvkaZg== +"@types/json5@^0.0.30": + version "0.0.30" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.30.tgz#44cb52f32a809734ca562e685c6473b5754a7818" + integrity sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA== + "@types/lodash@4.14.74": version "4.14.74" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.74.tgz#ac3bd8db988e7f7038e5d22bd76a7ba13f876168" @@ -5651,6 +5656,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" From 5c101d116a8db8ac40da236723744deb1e229508 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 8 Aug 2019 15:43:29 +0200 Subject: [PATCH 18/33] 63838: Refactor input suggestions to support DSpaceObjects as suggestions --- .../edit-item-page/edit-item-page.module.ts | 2 +- .../edit-item-page.routing.module.ts | 1 + .../edit-in-place-field.component.html | 4 +- .../edit-in-place-field.component.spec.ts | 2 +- .../edit-in-place-field.component.ts | 2 +- .../search-authority-filter.component.html | 4 +- .../search-facet-filter.component.ts | 2 +- .../search-hierarchy-filter.component.html | 4 +- .../search-text-filter.component.html | 4 +- .../dso-input-suggestions.component.html | 23 ++++++ .../dso-input-suggestions.component.spec.ts | 71 +++++++++++++++++++ .../dso-input-suggestions.component.ts | 47 ++++++++++++ .../filter-input-suggestions.component.html | 22 ++++++ ...filter-input-suggestions.component.spec.ts | 57 +++++++++++++++ .../filter-input-suggestions.component.ts | 44 ++++++++++++ .../input-suggestions.component.ts | 31 ++------ src/app/shared/shared.module.ts | 6 +- 17 files changed, 289 insertions(+), 37 deletions(-) create mode 100644 src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html create mode 100644 src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.spec.ts create mode 100644 src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.ts create mode 100644 src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html create mode 100644 src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.spec.ts create mode 100644 src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.ts diff --git a/src/app/+item-page/edit-item-page/edit-item-page.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.module.ts index de672c9ea7..a82c1976c8 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.module.ts @@ -40,7 +40,7 @@ import { EditItemPageRoutingModule } from './edit-item-page.routing.module'; ItemMetadataComponent, ItemBitstreamsComponent, EditInPlaceFieldComponent, - ItemMoveComponent + ItemMoveComponent, ] }) export class EditItemPageModule { diff --git a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts index c82025cf34..781b5ea933 100644 --- a/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts +++ b/src/app/+item-page/edit-item-page/edit-item-page.routing.module.ts @@ -111,6 +111,7 @@ export function getItemEditMovePath(id: string) { { path: ITEM_EDIT_MOVE_PATH, component: ItemMoveComponent, + data: {title: 'item.edit.move.title'}, resolve: { item: ItemPageResolver } diff --git a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html index e9c5de95ca..e8ffc28920 100644 --- a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html +++ b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html @@ -4,7 +4,7 @@ {{metadata?.key?.split('.').join('.​')}}
- + >
{{"item.edit.metadata.metadatafield.invalid" | translate}} diff --git a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts index 09363b9964..7182f90108 100644 --- a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.spec.ts @@ -11,12 +11,12 @@ import { By } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { SharedModule } from '../../../../shared/shared.module'; import { getTestScheduler } from 'jasmine-marbles'; -import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; import { TestScheduler } from 'rxjs/testing'; import { MetadataSchema } from '../../../../core/metadata/metadataschema.model'; import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { TranslateModule } from '@ngx-translate/core'; import { MetadatumViewModel } from '../../../../core/shared/metadata.models'; +import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; let comp: EditInPlaceFieldComponent; let fixture: ComponentFixture; diff --git a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts index 0b9bc62c55..facfd25008 100644 --- a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts +++ b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts @@ -5,12 +5,12 @@ import { cloneDeep } from 'lodash'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { map, take } from 'rxjs/operators'; import { MetadataField } from '../../../../core/metadata/metadatafield.model'; -import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { NgModel } from '@angular/forms'; import { MetadatumViewModel } from '../../../../core/shared/metadata.models'; +import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; @Component({ // tslint:disable-next-line:component-selector diff --git a/src/app/+search-page/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html b/src/app/+search-page/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html index 76cdc6c8f5..f2b2aad7aa 100644 --- a/src/app/+search-page/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html +++ b/src/app/+search-page/search-filters/search-filter/search-authority-filter/search-authority-filter.component.html @@ -15,7 +15,7 @@ | translate}}
- + ngDefaultControl>
diff --git a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts index 772240eb0b..6402d07f9b 100644 --- a/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts +++ b/src/app/+search-page/search-filters/search-filter/search-facet-filter/search-facet-filter.component.ts @@ -21,9 +21,9 @@ import { SearchService } from '../../../search-service/search.service'; import { FILTER_CONFIG, IN_PLACE_SEARCH, SearchFilterService } from '../search-filter.service'; import { SearchConfigurationService } from '../../../search-service/search-configuration.service'; import { getSucceededRemoteData } from '../../../../core/shared/operators'; -import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; import { SearchOptions } from '../../../search-options.model'; import { SEARCH_CONFIG_SERVICE } from '../../../../+my-dspace-page/my-dspace-page.component'; +import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model'; @Component({ selector: 'ds-search-facet-filter', diff --git a/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html b/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html index ac2a72f4b6..027f162a0a 100644 --- a/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html +++ b/src/app/+search-page/search-filters/search-filter/search-hierarchy-filter/search-hierarchy-filter.component.html @@ -15,7 +15,7 @@ | translate}}
- + >
diff --git a/src/app/+search-page/search-filters/search-filter/search-text-filter/search-text-filter.component.html b/src/app/+search-page/search-filters/search-filter/search-text-filter/search-text-filter.component.html index a4f4fb5ee8..5241c6c0bd 100644 --- a/src/app/+search-page/search-filters/search-filter/search-text-filter/search-text-filter.component.html +++ b/src/app/+search-page/search-filters/search-filter/search-text-filter/search-text-filter.component.html @@ -15,7 +15,7 @@ | translate}}
- + ngDefaultControl> diff --git a/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html new file mode 100644 index 0000000000..016ff8c06c --- /dev/null +++ b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html @@ -0,0 +1,23 @@ +
+ + + +
+ diff --git a/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.spec.ts b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.spec.ts new file mode 100644 index 0000000000..2e343a6834 --- /dev/null +++ b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.spec.ts @@ -0,0 +1,71 @@ +import { ChangeDetectionStrategy, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; + +import { TranslateModule } from '@ngx-translate/core'; +import { By } from '@angular/platform-browser'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { RouterTestingModule } from '@angular/router/testing'; +import { DsoInputSuggestionsComponent } from './dso-input-suggestions.component'; +import { DSpaceObject } from '../../../core/shared/dspace-object.model'; + +describe('DsoInputSuggestionsComponent', () => { + + let comp: DsoInputSuggestionsComponent; + let fixture: ComponentFixture; + let de: DebugElement; + let el: HTMLElement; + + const dso1 = { + uuid: 'test-uuid-1', + name: 'test-name-1' + } as DSpaceObject; + + const dso2 = { + uuid: 'test-uuid-2', + name: 'test-name-2' + } as DSpaceObject; + + const dso3 = { + uuid: 'test-uuid-3', + name: 'test-name-3' + } as DSpaceObject; + + const suggestions = [dso1, dso2, dso3]; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule, FormsModule], + declarations: [DsoInputSuggestionsComponent], + providers: [], + schemas: [NO_ERRORS_SCHEMA] + }).overrideComponent(DsoInputSuggestionsComponent, { + set: {changeDetection: ChangeDetectionStrategy.Default} + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DsoInputSuggestionsComponent); + + comp = fixture.componentInstance; // LoadingComponent test instance + comp.suggestions = suggestions; + // query for the message