forked from DSpace/dspace-angular
-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UFAL/share submission by email #720
Open
milanmajchrak
wants to merge
8
commits into
dtq-dev
Choose a base branch
from
ufal/share-submission-by-email
base: dtq-dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
ba28b98
Added share submission button into workspaceitem actions page.
milanmajchrak 8480a36
Added notification about the success of the sharing the submission.
milanmajchrak 50f4b0b
Created share submission module, page with routing. That page could a…
milanmajchrak 255e13d
WIP - created a new page `change-submitter-page`.
milanmajchrak 5096570
Created page when the user could take the workspace item as its own.
milanmajchrak 63a0efb
Pretified the code and added some docs
milanmajchrak 98bbb5b
Updated tests following the new feature
milanmajchrak db8ce27
Pretified the code
milanmajchrak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/app/change-submitter-page/change-submitter-page.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<div class="container pt-2 pb-4" *ngVar="submitter | async as sub"> | ||
<h3>{{'share.submission.page.title' | translate}}</h3> | ||
<span>{{'change.submitter.page.message' | translate}}</span> | ||
<span>{{getSubmitterName(sub)}}</span> | ||
<span> ({{sub?.email}})</span> | ||
<div class="pt-4"> | ||
<button class="btn btn-info" (click)="changeSubmitter()"> | ||
<span *ngIf="changeSubmitterSpinner" | ||
class="spinner-border spinner-border-sm spinner-button mr-1" role="status" aria-hidden="true"> | ||
</span> | ||
<span>{{'change.submitter.page.button.take-it' | translate}}</span> | ||
</button> | ||
</div> | ||
</div> | ||
|
||
|
3 changes: 3 additions & 0 deletions
3
src/app/change-submitter-page/change-submitter-page.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/** | ||
The file for styling the ChangeSubmitterPageComponent. | ||
*/ |
72 changes: 72 additions & 0 deletions
72
src/app/change-submitter-page/change-submitter-page.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { ChangeSubmitterPageComponent } from './change-submitter-page.component'; | ||
import { WorkspaceitemDataService } from '../core/submission/workspaceitem-data.service'; | ||
import { ActivatedRoute, Router } from '@angular/router'; | ||
import { HALEndpointService } from '../core/shared/hal-endpoint.service'; | ||
import { RemoteDataBuildService } from '../core/cache/builders/remote-data-build.service'; | ||
import { RequestService } from '../core/data/request.service'; | ||
import { NotificationsService } from '../shared/notifications/notifications.service'; | ||
import { TranslateModule } from '@ngx-translate/core'; | ||
import { NotificationsServiceStub } from '../shared/testing/notifications-service.stub'; | ||
import { RouterStub } from '../shared/testing/router.stub'; | ||
import { of as observableOf } from 'rxjs'; | ||
import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; | ||
import { getMockRequestService } from '../shared/mocks/request.service.mock'; | ||
import { createPaginatedList } from '../shared/testing/utils.test'; | ||
import { HALEndpointServiceStub } from '../shared/testing/hal-endpoint-service.stub'; | ||
import { getMockRemoteDataBuildService } from '../shared/mocks/remote-data-build.service.mock'; | ||
import { DSONameService } from '../core/breadcrumbs/dso-name.service'; | ||
import { DSONameServiceMock } from '../shared/mocks/dso-name.service.mock'; | ||
|
||
describe('ChangeSubmitterPageComponent', () => { | ||
let component: ChangeSubmitterPageComponent; | ||
let fixture: ComponentFixture<ChangeSubmitterPageComponent>; | ||
|
||
let activatedRoute; | ||
let requestService: RequestService; | ||
let mockDataService: WorkspaceitemDataService; | ||
let halService: HALEndpointService; | ||
let rdbService: RemoteDataBuildService; | ||
|
||
beforeEach(async () => { | ||
activatedRoute = { | ||
snapshot: { | ||
queryParams: new Map([ | ||
['shareToken', 'fake-share-token'], | ||
]) | ||
} | ||
}; | ||
requestService = getMockRequestService(); | ||
mockDataService = jasmine.createSpyObj('WorkspaceitemDataService', { | ||
searchBy: observableOf(createSuccessfulRemoteDataObject$(createPaginatedList([]))), | ||
}); | ||
halService = Object.assign(new HALEndpointServiceStub('some-url')); | ||
rdbService = getMockRemoteDataBuildService(); | ||
|
||
await TestBed.configureTestingModule({ | ||
declarations: [ ChangeSubmitterPageComponent ], | ||
imports: [ | ||
TranslateModule.forRoot() | ||
], | ||
providers: [ | ||
{ provide: ActivatedRoute, useValue: activatedRoute }, | ||
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }, | ||
{ provide: Router, useValue: new RouterStub() }, | ||
{ provide: RequestService, useValue: requestService }, | ||
{ provide: WorkspaceitemDataService, useValue: mockDataService }, | ||
{ provide: HALEndpointService, useValue: halService }, | ||
{ provide: RemoteDataBuildService, useValue: rdbService }, | ||
{ provide: DSONameService, useValue: DSONameServiceMock }, | ||
] | ||
}) | ||
.compileComponents(); | ||
|
||
fixture = TestBed.createComponent(ChangeSubmitterPageComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
153 changes: 153 additions & 0 deletions
153
src/app/change-submitter-page/change-submitter-page.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import { Component, OnInit } from '@angular/core'; | ||
import { BehaviorSubject, Observable } from 'rxjs'; | ||
import { WorkspaceItem } from '../core/submission/models/workspaceitem.model'; | ||
import { RequestParam } from '../core/cache/models/request-param.model'; | ||
import { | ||
getFirstCompletedRemoteData, | ||
getFirstSucceededRemoteDataPayload, | ||
getFirstSucceededRemoteListPayload | ||
} from '../core/shared/operators'; | ||
import { map } from 'rxjs/operators'; | ||
import { WorkspaceitemDataService } from '../core/submission/workspaceitem-data.service'; | ||
import { ActivatedRoute } from '@angular/router'; | ||
import { followLink } from '../shared/utils/follow-link-config.model'; | ||
import { EPerson } from '../core/eperson/models/eperson.model'; | ||
import { DSONameService } from '../core/breadcrumbs/dso-name.service'; | ||
import { isNullOrUndef } from 'chart.js/helpers'; | ||
import { HALEndpointService } from '../core/shared/hal-endpoint.service'; | ||
import { RemoteDataBuildService } from '../core/cache/builders/remote-data-build.service'; | ||
import { RequestService } from '../core/data/request.service'; | ||
import { PostRequest } from '../core/data/request.models'; | ||
import { RemoteData } from '../core/data/remote-data'; | ||
import { NotificationsService } from '../shared/notifications/notifications.service'; | ||
import { TranslateService } from '@ngx-translate/core'; | ||
|
||
@Component({ | ||
selector: 'ds-change-submitter-page', | ||
templateUrl: './change-submitter-page.component.html', | ||
styleUrls: ['./change-submitter-page.component.scss'] | ||
}) | ||
export class ChangeSubmitterPageComponent implements OnInit { | ||
|
||
/** | ||
* Share token from the url. This token is used to retrieve the WorkspaceItem. | ||
*/ | ||
private shareToken = ''; | ||
|
||
/** | ||
* BehaviorSubject that contains the submitter of the WorkspaceItem. | ||
*/ | ||
submitter: BehaviorSubject<EPerson> = new BehaviorSubject(null); | ||
|
||
/** | ||
* BehaviorSubject that contains the WorkspaceItem. | ||
*/ | ||
workspaceItem: BehaviorSubject<WorkspaceItem> = new BehaviorSubject(null); | ||
|
||
/** | ||
* Boolean that indicates if the spinner should be shown when the submitter is being changed. | ||
*/ | ||
changeSubmitterSpinner = false; | ||
|
||
constructor(private workspaceItemService: WorkspaceitemDataService, | ||
private route: ActivatedRoute, | ||
public dsoNameService: DSONameService, | ||
protected halService: HALEndpointService, | ||
protected rdbService: RemoteDataBuildService, | ||
protected requestService: RequestService, | ||
protected notificationsService: NotificationsService, | ||
protected translate: TranslateService) {} | ||
|
||
ngOnInit(): void { | ||
// Load `share_token` param value from the url | ||
this.shareToken = this.route.snapshot.queryParams.share_token; | ||
this.loadWorkspaceItemAndAssignSubmitter(this.shareToken); | ||
} | ||
|
||
/** | ||
* Load the WorkspaceItem using the shareToken and assign the submitter from the retrieved WorkspaceItem. | ||
*/ | ||
loadWorkspaceItemAndAssignSubmitter(shareToken: string) { | ||
this.findWorkspaceItemByShareToken(shareToken)?.subscribe((workspaceItem: WorkspaceItem) => { | ||
this.workspaceItem.next(workspaceItem); | ||
this.loadAndAssignSubmitter(workspaceItem); | ||
}); | ||
} | ||
|
||
/** | ||
* Find a WorkspaceItem by its shareToken. | ||
*/ | ||
findWorkspaceItemByShareToken(shareToken: string): Observable<WorkspaceItem> { | ||
return this.workspaceItemService.searchBy('shareToken', { | ||
searchParams: [Object.assign(new RequestParam('shareToken', shareToken))] | ||
}, false, false, followLink('submitter')).pipe(getFirstSucceededRemoteListPayload(), | ||
map((workspaceItems: WorkspaceItem[]) => workspaceItems?.[0])); | ||
} | ||
|
||
/** | ||
* Load the submitter from the WorkspaceItem and assign it to the submitter BehaviorSubject. | ||
*/ | ||
loadAndAssignSubmitter(workspaceItem: WorkspaceItem) { | ||
if (isNullOrUndef(workspaceItem)) { | ||
console.error('Cannot load submitter because WorkspaceItem is null or undefined'); | ||
return; | ||
} | ||
|
||
if (workspaceItem.submitter instanceof Observable<EPerson>) { | ||
console.log('Loading submitter from observable', workspaceItem); | ||
workspaceItem.submitter | ||
.pipe(getFirstSucceededRemoteDataPayload()) | ||
.subscribe((submitter: any) => { | ||
this.assignSubmitter(submitter); | ||
}); | ||
} else { | ||
this.assignSubmitter(workspaceItem.submitter); | ||
} | ||
} | ||
|
||
/** | ||
* Assign a new submitter to the submitter BehaviorSubject. | ||
*/ | ||
assignSubmitter(eperson: EPerson) { | ||
this.submitter.next(eperson); | ||
} | ||
|
||
/** | ||
* Get the name of the submitter using the DSONameService. | ||
* @param submitter | ||
*/ | ||
getSubmitterName(submitter: EPerson): string { | ||
if (isNullOrUndef(submitter)) { | ||
return ''; | ||
} | ||
return this.dsoNameService.getName(submitter); | ||
} | ||
|
||
/** | ||
* Change the submitter of the WorkspaceItem using the shareToken. This will send a POST request to the backend when | ||
* the submitter of the Item is changed. | ||
*/ | ||
changeSubmitter() { | ||
const requestId = this.requestService.generateRequestId(); | ||
|
||
const url = this.halService.getRootHref() + '/submission/setOwner?shareToken=' + this.shareToken; | ||
const postRequest = new PostRequest(requestId, url); | ||
// Send GET request | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? |
||
this.requestService.send(postRequest); | ||
this.changeSubmitterSpinner = true; | ||
// Get response | ||
const response = this.rdbService.buildFromRequestUUID(requestId); | ||
response.pipe(getFirstCompletedRemoteData()).subscribe((rd: RemoteData<WorkspaceItem>) => { | ||
if (rd.hasSucceeded) { | ||
this.notificationsService.success( | ||
this.translate.instant('change.submitter.page.changed-successfully')); | ||
// Update the submitter | ||
this.loadWorkspaceItemAndAssignSubmitter(this.shareToken); | ||
} else { | ||
this.notificationsService.error( | ||
this.translate.instant('change.submitter.page.changed-error')); | ||
} | ||
this.changeSubmitterSpinner = false; | ||
}); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/app/share-submission/share-submission-page/share-submission-page.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<div class="container pt-2 pb-4"> | ||
<h3>{{'share.submission.page.title' | translate}}</h3> | ||
<span>{{'share.submission.page.share-link.message.start' | translate}}</span> | ||
<a [href]="changeSubmitterLink">{{changeSubmitterLink}}</a> | ||
<span>{{'share.submission.page.share-link.message.end' | translate}}</span> | ||
</div> |
3 changes: 3 additions & 0 deletions
3
src/app/share-submission/share-submission-page/share-submission-page.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/** | ||
The file for styling the ShareSubmissionPageComponent. | ||
*/ |
40 changes: 40 additions & 0 deletions
40
src/app/share-submission/share-submission-page/share-submission-page.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { ShareSubmissionPageComponent } from './share-submission-page.component'; | ||
import { ActivatedRoute } from '@angular/router'; | ||
import { TranslateModule } from '@ngx-translate/core'; | ||
|
||
describe('ShareSubmissionPageComponent', () => { | ||
let component: ShareSubmissionPageComponent; | ||
let fixture: ComponentFixture<ShareSubmissionPageComponent>; | ||
let activatedRoute; | ||
|
||
beforeEach(async () => { | ||
activatedRoute = { | ||
snapshot: { | ||
queryParams: new Map([ | ||
['shareToken', 'fake-share-token'], | ||
]) | ||
} | ||
}; | ||
|
||
await TestBed.configureTestingModule({ | ||
declarations: [ ShareSubmissionPageComponent ], | ||
imports: [ | ||
TranslateModule.forRoot() | ||
], | ||
providers: [ | ||
{ provide: ActivatedRoute, useValue: activatedRoute } | ||
] | ||
}) | ||
.compileComponents(); | ||
|
||
fixture = TestBed.createComponent(ShareSubmissionPageComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
23 changes: 23 additions & 0 deletions
23
src/app/share-submission/share-submission-page/share-submission-page.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Component } from '@angular/core'; | ||
import { ActivatedRoute } from '@angular/router'; | ||
|
||
@Component({ | ||
selector: 'ds-share-submission-page', | ||
templateUrl: './share-submission-page.component.html', | ||
styleUrls: ['./share-submission-page.component.scss'] | ||
}) | ||
export class ShareSubmissionPageComponent { | ||
|
||
/** | ||
* Share token from the url. This token is used to retrieve the WorkspaceItem. | ||
* With this link, the submitter can be changed. | ||
*/ | ||
changeSubmitterLink: string; | ||
|
||
constructor(private route: ActivatedRoute) {} | ||
|
||
ngOnInit(): void { | ||
// Load `share-token` param value from the url | ||
this.changeSubmitterLink = this.route.snapshot.queryParams.changeSubmitterLink; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/app/share-submission/share-submission-page/share-submission-routing.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { RouterModule, Routes } from '@angular/router'; | ||
import { NgModule } from '@angular/core'; | ||
import { ShareSubmissionPageComponent } from './share-submission-page.component'; | ||
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver'; | ||
import { ChangeSubmitterPageComponent } from '../../change-submitter-page/change-submitter-page.component'; | ||
|
||
const routes: Routes = [ | ||
{ path: '', | ||
component: ShareSubmissionPageComponent, | ||
resolve: { breadcrumb: I18nBreadcrumbResolver }, | ||
data: { | ||
breadcrumbKey: 'share.submission', | ||
}, | ||
}, | ||
{ path: 'change-submitter', | ||
component: ChangeSubmitterPageComponent, | ||
resolve: { breadcrumb: I18nBreadcrumbResolver }, | ||
data: { | ||
breadcrumbKey: 'change.submitter', | ||
}, | ||
}, | ||
]; | ||
|
||
@NgModule({ | ||
imports: [RouterModule.forChild(routes)], | ||
exports: [RouterModule] | ||
}) | ||
export class ShareSubmissionPageModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { CommonModule } from '@angular/common'; | ||
import { ShareSubmissionPageComponent } from './share-submission-page/share-submission-page.component'; | ||
import { SharedModule } from '../shared/shared.module'; | ||
import { ShareSubmissionPageModule } from './share-submission-page/share-submission-routing.module'; | ||
import { ChangeSubmitterPageComponent } from '../change-submitter-page/change-submitter-page.component'; | ||
|
||
@NgModule({ | ||
declarations: [ | ||
ShareSubmissionPageComponent, | ||
ChangeSubmitterPageComponent | ||
], | ||
imports: [ | ||
CommonModule, | ||
ShareSubmissionPageModule, | ||
SharedModule, | ||
] | ||
}) | ||
export class ShareSubmissionModule { } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?