diff --git a/src/app/+admin/admin-sidebar/admin-sidebar.component.ts b/src/app/+admin/admin-sidebar/admin-sidebar.component.ts index 185d083764..72eb306bf1 100644 --- a/src/app/+admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/app/+admin/admin-sidebar/admin-sidebar.component.ts @@ -17,6 +17,7 @@ import { CreateCollectionParentSelectorComponent } from '../../shared/dso-select import { EditItemSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component'; import { EditCommunitySelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; import { EditCollectionSelectorComponent } from '../../shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component'; +import {CreateItemParentSelectorComponent} from '../../shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; /** * Component representing the admin sidebar @@ -137,18 +138,18 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit { parentID: 'new', active: false, visible: true, - // model: { - // type: MenuItemType.ONCLICK, - // text: 'menu.section.new_item', - // function: () => { - // this.modalService.open(CreateItemParentSelectorComponent); - // } - // } as OnClickMenuItemModel, model: { - type: MenuItemType.LINK, + type: MenuItemType.ONCLICK, text: 'menu.section.new_item', - link: '/submit' - } as LinkMenuItemModel, + function: () => { + this.modalService.open(CreateItemParentSelectorComponent); + } + } as OnClickMenuItemModel, + // model: { + // type: MenuItemType.LINK, + // text: 'menu.section.new_item', + // link: '/submit' + // } as LinkMenuItemModel, }, { id: 'new_item_version', diff --git a/src/app/core/submission/submission-rest.service.ts b/src/app/core/submission/submission-rest.service.ts index b4f8185767..32ba070002 100644 --- a/src/app/core/submission/submission-rest.service.ts +++ b/src/app/core/submission/submission-rest.service.ts @@ -20,6 +20,7 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ErrorResponse, RestResponse, SubmissionSuccessResponse } from '../cache/response.models'; import { getResponseFromEntry } from '../shared/operators'; +import {URLCombiner} from '../url-combiner/url-combiner'; /** * The service handling all submission REST requests @@ -65,9 +66,15 @@ export class SubmissionRestService { * The base endpoint for the type of object * @param resourceID * The identifier for the object + * @param collectionId + * The owning collection for the object */ - protected getEndpointByIDHref(endpoint, resourceID): string { - return isNotEmpty(resourceID) ? `${endpoint}/${resourceID}` : `${endpoint}`; + protected getEndpointByIDHref(endpoint, resourceID, collectionId?: string): string { + let url = isNotEmpty(resourceID) ? `${endpoint}/${resourceID}` : `${endpoint}`; + if (collectionId) { + url = new URLCombiner(url, `?owningCollection=${collectionId}`).toString(); + } + return url; } /** @@ -130,12 +137,14 @@ export class SubmissionRestService { * The [HttpOptions] object * @return Observable * server response + * @param collectionId + * The owning collection id */ - public postToEndpoint(linkName: string, body: any, scopeId?: string, options?: HttpOptions): Observable { + public postToEndpoint(linkName: string, body: any, scopeId?: string, options?: HttpOptions, collectionId?: string): Observable { const requestId = this.requestService.generateRequestId(); return this.halService.getEndpoint(linkName).pipe( filter((href: string) => isNotEmpty(href)), - map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId)), + map((endpointURL: string) => this.getEndpointByIDHref(endpointURL, scopeId, collectionId)), distinctUntilChanged(), map((endpointURL: string) => new SubmissionPostRequest(requestId, endpointURL, body, options)), tap((request: PostRequest) => this.requestService.configure(request)), diff --git a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.spec.ts b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.spec.ts index 2c9b2499ab..b3058ab879 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.spec.ts +++ b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.spec.ts @@ -59,9 +59,8 @@ describe('CreateItemParentSelectorComponent', () => { }); it('should call navigate on the router with the correct create path when navigate is called', () => { - /* TODO when there is a specific submission path */ - // component.navigate(item); - // expect(router.navigate).toHaveBeenCalledWith([createPath]); + component.navigate(collection); + expect(router.navigate).toHaveBeenCalledWith(['/submit'], { queryParams: { collection: collection.uuid } }); }); }); diff --git a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts index 29af9f624e..02a0bd79cd 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute, NavigationExtras, Router } from '@angular/router'; import { DSpaceObjectType } from '../../../../core/shared/dspace-object-type.model'; import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; @@ -28,6 +28,11 @@ export class CreateItemParentSelectorComponent extends DSOSelectorModalWrapperCo * Navigate to the item create page */ navigate(dso: DSpaceObject) { - // There's no submit path per collection yet... + const navigationExtras: NavigationExtras = { + queryParams: { + ['collection']: dso.uuid, + } + }; + this.router.navigate(['/submit'], navigationExtras); } } diff --git a/src/app/submission/submission.service.spec.ts b/src/app/submission/submission.service.spec.ts index 3a95b0747b..1b346a56eb 100644 --- a/src/app/submission/submission.service.spec.ts +++ b/src/app/submission/submission.service.spec.ts @@ -401,6 +401,14 @@ describe('SubmissionService test suite', () => { service.createSubmission(); expect((service as any).restService.postToEndpoint).toHaveBeenCalled(); + expect((service as any).restService.postToEndpoint).toHaveBeenCalledWith('workspaceitems', {}, null, null, undefined); + }); + + it('should create a new submission with collection', () => { + service.createSubmission(collectionId); + + expect((service as any).restService.postToEndpoint).toHaveBeenCalled(); + expect((service as any).restService.postToEndpoint).toHaveBeenCalledWith('workspaceitems', {}, null, null, collectionId); }); }); diff --git a/src/app/submission/submission.service.ts b/src/app/submission/submission.service.ts index 766aa518f3..ac0cd7bec8 100644 --- a/src/app/submission/submission.service.ts +++ b/src/app/submission/submission.service.ts @@ -103,11 +103,13 @@ export class SubmissionService { /** * Perform a REST call to create a new workspaceitem and return response * + * @param collectionId + * The owning collection id * @return Observable * observable of SubmissionObject */ - createSubmission(): Observable { - return this.restService.postToEndpoint(this.workspaceLinkPath, {}).pipe( + createSubmission(collectionId?: string): Observable { + return this.restService.postToEndpoint(this.workspaceLinkPath, {}, null, null, collectionId).pipe( map((workspaceitem: SubmissionObject[]) => workspaceitem[0] as SubmissionObject), catchError(() => observableOf({} as SubmissionObject))) } diff --git a/src/app/submission/submit/submission-submit.component.spec.ts b/src/app/submission/submit/submission-submit.component.spec.ts index 771171a2d1..ca3316669f 100644 --- a/src/app/submission/submit/submission-submit.component.spec.ts +++ b/src/app/submission/submit/submission-submit.component.spec.ts @@ -1,6 +1,6 @@ import { async, ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { NO_ERRORS_SCHEMA, ViewContainerRef } from '@angular/core'; import { of as observableOf } from 'rxjs'; @@ -14,6 +14,7 @@ import { getMockTranslateService } from '../../shared/mocks/mock-translate.servi import { RouterStub } from '../../shared/testing/router-stub'; import { mockSubmissionObject } from '../../shared/mocks/mock-submission'; import { SubmissionSubmitComponent } from './submission-submit.component'; +import { ActivatedRouteStub } from '../../shared/testing/active-router-stub'; describe('SubmissionSubmitComponent Component', () => { @@ -39,6 +40,7 @@ describe('SubmissionSubmitComponent Component', () => { { provide: SubmissionService, useClass: SubmissionServiceStub }, { provide: TranslateService, useValue: getMockTranslateService() }, { provide: Router, useValue: new RouterStub() }, + { provide: ActivatedRoute, useValue: new ActivatedRouteStub() }, ViewContainerRef ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/submission/submit/submission-submit.component.ts b/src/app/submission/submit/submission-submit.component.ts index 448ccf97e2..0aa0380a25 100644 --- a/src/app/submission/submit/submission-submit.component.ts +++ b/src/app/submission/submit/submission-submit.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectorRef, Component, OnDestroy, OnInit, ViewContainerRef } from '@angular/core'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { Subscription } from 'rxjs'; @@ -27,6 +27,12 @@ export class SubmissionSubmitComponent implements OnDestroy, OnInit { */ public collectionId: string; + /** + * The collection id input to create a new submission + * @type {string} + */ + public collectionParam: string; + /** * The submission self url * @type {string} @@ -60,13 +66,18 @@ export class SubmissionSubmitComponent implements OnDestroy, OnInit { * @param {Router} router * @param {TranslateService} translate * @param {ViewContainerRef} viewContainerRef + * @param {ActivatedRoute} route */ constructor(private changeDetectorRef: ChangeDetectorRef, private notificationsService: NotificationsService, private router: Router, private submissionService: SubmissionService, private translate: TranslateService, - private viewContainerRef: ViewContainerRef) { + private viewContainerRef: ViewContainerRef, + private route: ActivatedRoute) { + this.route + .queryParams + .subscribe((params) => { this.collectionParam = (params.collection); }); } /** @@ -75,7 +86,7 @@ export class SubmissionSubmitComponent implements OnDestroy, OnInit { ngOnInit() { // NOTE execute the code on the browser side only, otherwise it is executed twice this.subs.push( - this.submissionService.createSubmission() + this.submissionService.createSubmission(this.collectionParam) .subscribe((submissionObject: SubmissionObject) => { // NOTE new submission is created on the browser side only if (isNotNull(submissionObject)) {