mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-14 13:33:03 +00:00
CC License Submission Step 2 - Storing the results
This commit is contained in:
15
src/app/core/cache/response.models.ts
vendored
15
src/app/core/cache/response.models.ts
vendored
@@ -29,6 +29,21 @@ export class RestResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A response containing a string.
|
||||||
|
*/
|
||||||
|
export class StringResponse extends RestResponse {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public isSuccessful: boolean,
|
||||||
|
public statusCode: number,
|
||||||
|
public statusText: string,
|
||||||
|
public content: string,
|
||||||
|
) {
|
||||||
|
super(isSuccessful, statusCode, statusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class DSOSuccessResponse extends RestResponse {
|
export class DSOSuccessResponse extends RestResponse {
|
||||||
constructor(
|
constructor(
|
||||||
public resourceSelfLinks: string[],
|
public resourceSelfLinks: string[],
|
||||||
|
@@ -147,6 +147,7 @@ import { WorkflowActionDataService } from './data/workflow-action-data.service';
|
|||||||
import { WorkflowAction } from './tasks/models/workflow-action-object.model';
|
import { WorkflowAction } from './tasks/models/workflow-action-object.model';
|
||||||
import { SubmissionCcLicensesDataService } from './data/submission-cc-licenses-data.service';
|
import { SubmissionCcLicensesDataService } from './data/submission-cc-licenses-data.service';
|
||||||
import { SubmissionCcLicence } from './shared/submission-cc-license.model';
|
import { SubmissionCcLicence } from './shared/submission-cc-license.model';
|
||||||
|
import { StringResponseParsingService } from './data/string-response-parsing.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When not in production, endpoint responses can be mocked for testing purposes
|
* When not in production, endpoint responses can be mocked for testing purposes
|
||||||
@@ -214,6 +215,7 @@ const PROVIDERS = [
|
|||||||
BrowseResponseParsingService,
|
BrowseResponseParsingService,
|
||||||
BrowseEntriesResponseParsingService,
|
BrowseEntriesResponseParsingService,
|
||||||
BrowseItemsResponseParsingService,
|
BrowseItemsResponseParsingService,
|
||||||
|
StringResponseParsingService,
|
||||||
BrowseService,
|
BrowseService,
|
||||||
ConfigResponseParsingService,
|
ConfigResponseParsingService,
|
||||||
SubmissionCcLicensesDataService,
|
SubmissionCcLicensesDataService,
|
||||||
|
23
src/app/core/data/string-response-parsing.service.ts
Normal file
23
src/app/core/data/string-response-parsing.service.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import {RestResponse, StringResponse} from '../cache/response.models';
|
||||||
|
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
||||||
|
import { ResponseParsingService } from './parsing.service';
|
||||||
|
import { RestRequest } from './request.models';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A responseparser that will parse the response body to a string.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class StringResponseParsingService implements ResponseParsingService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the response to a string.
|
||||||
|
*
|
||||||
|
* @param request The request that was sent to the server
|
||||||
|
* @param data The response to parse
|
||||||
|
*/
|
||||||
|
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||||
|
const isSuccessful = data.statusCode >= 200 && data.statusCode < 300;
|
||||||
|
return new StringResponse(isSuccessful, data.statusCode, data.statusText, data.payload as undefined as string);
|
||||||
|
}
|
||||||
|
}
|
@@ -10,8 +10,14 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
|
|||||||
import { DataService } from './data.service';
|
import { DataService } from './data.service';
|
||||||
import { RequestService } from './request.service';
|
import { RequestService } from './request.service';
|
||||||
import { SUBMISSION_CC_LICENSE } from '../shared/submission-cc-licences.resource-type';
|
import { SUBMISSION_CC_LICENSE } from '../shared/submission-cc-licences.resource-type';
|
||||||
import { SubmissionCcLicence } from '../shared/submission-cc-license.model';
|
import { Field, Option, SubmissionCcLicence } from '../shared/submission-cc-license.model';
|
||||||
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
||||||
|
import { GetRequest } from './request.models';
|
||||||
|
import { configureRequest, getResponseFromEntry } from '../shared/operators';
|
||||||
|
import { map, switchMap, tap } from 'rxjs/operators';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { StringResponse } from '../cache/response.models';
|
||||||
|
import { StringResponseParsingService } from './string-response-parsing.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@dataService(SUBMISSION_CC_LICENSE)
|
@dataService(SUBMISSION_CC_LICENSE)
|
||||||
@@ -31,4 +37,45 @@ export class SubmissionCcLicensesDataService extends DataService<SubmissionCcLic
|
|||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the link to the Creative Commons license corresponding to the given type and options.
|
||||||
|
* @param ccLicense the Creative Commons license type
|
||||||
|
* @param options the selected options of the license fields
|
||||||
|
*/
|
||||||
|
getCcLicenseLink(ccLicense: SubmissionCcLicence, options: Map<Field, Option>): Observable<StringResponse> {
|
||||||
|
|
||||||
|
const requestId = this.requestService.generateRequestId();
|
||||||
|
|
||||||
|
return this.getSearchByHref(
|
||||||
|
'rightsByQuestions',{
|
||||||
|
searchParams: [
|
||||||
|
{
|
||||||
|
fieldName: 'license',
|
||||||
|
fieldValue: ccLicense.id
|
||||||
|
},
|
||||||
|
...ccLicense.fields.map(
|
||||||
|
(field) => {
|
||||||
|
return {
|
||||||
|
fieldName: `answer_${field.id}`,
|
||||||
|
fieldValue: options.get(field).id,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
).pipe(
|
||||||
|
map((endpoint) => new GetRequest(
|
||||||
|
requestId,
|
||||||
|
endpoint,
|
||||||
|
undefined, {
|
||||||
|
responseType: 'text',
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
tap((request) => request.getResponseParser = () => StringResponseParsingService),
|
||||||
|
configureRequest(this.requestService),
|
||||||
|
switchMap(() => this.requestService.getByUUID(requestId)),
|
||||||
|
getResponseFromEntry(),
|
||||||
|
map((response) => response as StringResponse),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,18 +18,25 @@ export class SubmissionCcLicence extends HALResource {
|
|||||||
@autoserialize
|
@autoserialize
|
||||||
type: ResourceType;
|
type: ResourceType;
|
||||||
|
|
||||||
|
@autoserialize
|
||||||
|
id: string;
|
||||||
|
|
||||||
@autoserialize
|
@autoserialize
|
||||||
name: string;
|
name: string;
|
||||||
|
|
||||||
@autoserialize
|
@autoserialize
|
||||||
fields: Array<{
|
fields: Field[];
|
||||||
id: string;
|
}
|
||||||
label: string;
|
|
||||||
description: string;
|
export interface Field {
|
||||||
enums: Array<{
|
id: string;
|
||||||
id: string;
|
label: string;
|
||||||
label: string;
|
description: string;
|
||||||
description: string;
|
enums: Option[];
|
||||||
}>;
|
}
|
||||||
}>;
|
|
||||||
|
export interface Option {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
|
import {Option} from '../../shared/submission-cc-license.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface to represent the submission's creative commons license section data.
|
* An interface to represent the submission's creative commons license section data.
|
||||||
*/
|
*/
|
||||||
export interface WorkspaceitemSectionCcLicenseObject {
|
export interface WorkspaceitemSectionCcLicenseObject {
|
||||||
ccLicense: {
|
ccLicense?: {
|
||||||
name: string;
|
id: string;
|
||||||
fields: {
|
fields: {
|
||||||
[field: string]: string;
|
[fieldId: string]: Option;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
uri?: string;
|
||||||
|
accepted?: boolean;
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,12 @@
|
|||||||
{{ getSelectedCcLicense().name }}
|
{{ getSelectedCcLicense().name }}
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="submissionCcLicenses && !getSelectedCcLicense()">
|
<span *ngIf="submissionCcLicenses && !getSelectedCcLicense()">
|
||||||
{{ 'submission.sections.ccLicense.select' | translate }}
|
<ng-container *ngIf="storedCcLicenseLink">
|
||||||
|
{{ 'submission.sections.ccLicense.change' | translate }}
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="!storedCcLicenseLink">
|
||||||
|
{{ 'submission.sections.ccLicense.select' | translate }}
|
||||||
|
</ng-container>
|
||||||
</span>
|
</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
@@ -22,7 +27,7 @@
|
|||||||
</button>
|
</button>
|
||||||
<button *ngFor="let license of submissionCcLicenses"
|
<button *ngFor="let license of submissionCcLicenses"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
(click)="select(license)">
|
(click)="selectCcLicense(license)">
|
||||||
{{ license.name }}
|
{{ license.name }}
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@@ -78,33 +83,32 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ds-select *ngIf="field.enums?.length > 5">
|
<ds-select *ngIf="field.enums?.length > 5">
|
||||||
<ng-container class="selection" *ngVar="getSelectedOption(getSelectedCcLicense(), field.id) as option">
|
<ng-container class="selection" *ngVar="getSelectedOption(getSelectedCcLicense(), field) as option">
|
||||||
<span *ngIf="option">
|
<span *ngIf="option">
|
||||||
{{ option }}
|
{{ option.label }}
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="!option">
|
<span *ngIf="!option">
|
||||||
{{ 'submission.sections.ccLicense.option.select' | translate }}
|
{{ 'submission.sections.ccLicense.option.select' | translate }}
|
||||||
</span>
|
</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container class="menu">
|
<ng-container class="menu">
|
||||||
<button *ngFor="let value of field.enums"
|
<button *ngFor="let option of field.enums"
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
(click)="selectOption(getSelectedCcLicense(), field.id, value.label)">
|
(click)="selectOption(getSelectedCcLicense(), field, option)">
|
||||||
{{ value.label }}
|
{{ option.label }}
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ds-select>
|
</ds-select>
|
||||||
|
|
||||||
<ng-container *ngIf="field.enums?.length <= 5">
|
<ng-container *ngIf="field.enums?.length <= 5">
|
||||||
<div *ngFor="let value of field.enums"
|
<div *ngFor="let option of field.enums"
|
||||||
class="d-flex flex-row m-2"
|
class="d-flex flex-row m-2">
|
||||||
(click)="selectOption(getSelectedCcLicense(), field.id, value.label)">
|
<div (click)="selectOption(getSelectedCcLicense(), field, option)">
|
||||||
<input type="radio"
|
<input type="radio"
|
||||||
title="{{ value.label }}"
|
title="{{ option.label }}"
|
||||||
class="mr-1"
|
class="mr-1"
|
||||||
[checked]="isSelectedOption(getSelectedCcLicense(), field.id, value.label)">
|
[checked]="isSelectedOption(getSelectedCcLicense(), field, option)">
|
||||||
<div class="label">
|
<span class="label">{{ option.label }}</span>
|
||||||
{{ value.label }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@@ -112,3 +116,27 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngIf="getCcLicenseLink$()">
|
||||||
|
<ng-container *ngVar="getCcLicenseLink$() | async as licenseLink">
|
||||||
|
<div *ngIf="!licenseLink">
|
||||||
|
<i class='fas fa-circle-notch fa-spin m-2'></i>
|
||||||
|
</div>
|
||||||
|
<ng-container *ngIf="licenseLink">
|
||||||
|
<div>
|
||||||
|
{{ 'submission.sections.ccLicense.link' | translate }}
|
||||||
|
</div>
|
||||||
|
<a class="license-link" href="{{ licenseLink }}?target=_blank">
|
||||||
|
{{ licenseLink }}
|
||||||
|
</a>
|
||||||
|
<div class="m-2">
|
||||||
|
<div (click)="setAccepted(!accepted)">
|
||||||
|
<input type="checkbox"
|
||||||
|
title="accepted"
|
||||||
|
[checked]="accepted">
|
||||||
|
<span>{{ 'submission.sections.ccLicense.confirmation' | translate }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
@@ -15,6 +15,8 @@ import { PageInfo } from '../../core/shared/page-info.model';
|
|||||||
import { PaginatedList } from '../../core/data/paginated-list';
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
import { SubmissionCcLicence } from '../../core/shared/submission-cc-license.model';
|
import { SubmissionCcLicence } from '../../core/shared/submission-cc-license.model';
|
||||||
import { cold } from 'jasmine-marbles';
|
import { cold } from 'jasmine-marbles';
|
||||||
|
import { JsonPatchOperationsBuilder } from '../../core/json-patch/builder/json-patch-operations-builder';
|
||||||
|
import { StringResponse } from '../../core/cache/response.models';
|
||||||
|
|
||||||
describe('SubmissionSectionCcLicensesComponent', () => {
|
describe('SubmissionSectionCcLicensesComponent', () => {
|
||||||
|
|
||||||
@@ -34,6 +36,7 @@ describe('SubmissionSectionCcLicensesComponent', () => {
|
|||||||
|
|
||||||
const submissionCcLicenses: SubmissionCcLicence[] = [
|
const submissionCcLicenses: SubmissionCcLicence[] = [
|
||||||
{
|
{
|
||||||
|
id: 'test license id 1',
|
||||||
type: SUBMISSION_CC_LICENSE,
|
type: SUBMISSION_CC_LICENSE,
|
||||||
name: 'test license name 1',
|
name: 'test license name 1',
|
||||||
fields: [
|
fields: [
|
||||||
@@ -79,6 +82,7 @@ describe('SubmissionSectionCcLicensesComponent', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 'test license id 2',
|
||||||
type: SUBMISSION_CC_LICENSE,
|
type: SUBMISSION_CC_LICENSE,
|
||||||
name: 'test license name 2',
|
name: 'test license name 2',
|
||||||
fields: [
|
fields: [
|
||||||
@@ -124,25 +128,31 @@ describe('SubmissionSectionCcLicensesComponent', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const submissionCcLicensesDataService = {
|
|
||||||
findAll: () => observableOf(new RemoteData(
|
const submissionCcLicensesDataService = jasmine.createSpyObj('submissionCcLicensesDataService', {
|
||||||
|
getCcLicenseLink: observableOf(new StringResponse(true, 200, '200', 'test cc license link')),
|
||||||
|
findAll: observableOf(new RemoteData(
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
undefined,
|
undefined,
|
||||||
new PaginatedList(new PageInfo(), submissionCcLicenses),
|
new PaginatedList(new PageInfo(), submissionCcLicenses),
|
||||||
)),
|
)),
|
||||||
};
|
});
|
||||||
|
|
||||||
const sectionService = {
|
const sectionService = {
|
||||||
getSectionState: () => observableOf(
|
getSectionState: () => observableOf({
|
||||||
{
|
data: {}
|
||||||
data: {},
|
}),
|
||||||
}
|
|
||||||
),
|
|
||||||
setSectionStatus: () => undefined,
|
setSectionStatus: () => undefined,
|
||||||
|
updateSectionData: () => undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const operationsBuilder = jasmine.createSpyObj('operationsBuilder', {
|
||||||
|
add: undefined,
|
||||||
|
remove: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -153,11 +163,12 @@ describe('SubmissionSectionCcLicensesComponent', () => {
|
|||||||
SubmissionSectionCcLicensesComponent,
|
SubmissionSectionCcLicensesComponent,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: SubmissionCcLicensesDataService, useValue: submissionCcLicensesDataService},
|
{ provide: SubmissionCcLicensesDataService, useValue: submissionCcLicensesDataService },
|
||||||
{provide: SectionsService, useValue: sectionService},
|
{ provide: SectionsService, useValue: sectionService },
|
||||||
{provide: 'collectionIdProvider', useValue: 'test collection id'},
|
{ provide: JsonPatchOperationsBuilder, useValue: operationsBuilder },
|
||||||
{provide: 'sectionDataProvider', useValue: sectionObject},
|
{ provide: 'collectionIdProvider', useValue: 'test collection id' },
|
||||||
{provide: 'submissionIdProvider', useValue: 'test submission id'},
|
{ provide: 'sectionDataProvider', useValue: sectionObject },
|
||||||
|
{ provide: 'submissionIdProvider', useValue: 'test submission id' },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
@@ -181,8 +192,10 @@ describe('SubmissionSectionCcLicensesComponent', () => {
|
|||||||
|
|
||||||
describe('when a license is selected', () => {
|
describe('when a license is selected', () => {
|
||||||
|
|
||||||
|
const ccLicence = submissionCcLicenses[1];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
component.select(submissionCcLicenses[1]);
|
component.selectCcLicense(ccLicence);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -199,6 +212,10 @@ describe('SubmissionSectionCcLicensesComponent', () => {
|
|||||||
expect(de.query(By.css('div.test-field-id-2b'))).toBeTruthy();
|
expect(de.query(By.css('div.test-field-id-2b'))).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not display a license link', () => {
|
||||||
|
expect(de.query(By.css('.license-link'))).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
it('should have section status incomplete', () => {
|
it('should have section status incomplete', () => {
|
||||||
expect(component.getSectionStatus()).toBeObservable(cold('(a|)', { a: false }));
|
expect(component.getSectionStatus()).toBeObservable(cold('(a|)', { a: false }));
|
||||||
});
|
});
|
||||||
@@ -206,14 +223,47 @@ describe('SubmissionSectionCcLicensesComponent', () => {
|
|||||||
describe('when all options have a value selected', () => {
|
describe('when all options have a value selected', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const ccLicence = submissionCcLicenses[1];
|
component.selectOption(ccLicence, ccLicence.fields[0], ccLicence.fields[0].enums[1]);
|
||||||
component.selectOption(ccLicence, ccLicence.fields[0].id, ccLicence.fields[0].enums[1].label);
|
component.selectOption(ccLicence, ccLicence.fields[1], ccLicence.fields[1].enums[0]);
|
||||||
component.selectOption(ccLicence, ccLicence.fields[1].id, ccLicence.fields[1].enums[0].label);
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have section status complete', () => {
|
it('should call the submission cc licenses data service getCcLicenseLink method', () => {
|
||||||
expect(component.getSectionStatus()).toBeObservable(cold('(a|)', { a: true }));
|
expect(submissionCcLicensesDataService.getCcLicenseLink).toHaveBeenCalledWith(
|
||||||
|
ccLicence,
|
||||||
|
new Map([
|
||||||
|
[ccLicence.fields[0], ccLicence.fields[0].enums[1]],
|
||||||
|
[ccLicence.fields[1], ccLicence.fields[1].enums[0]],
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display a cc license link', () => {
|
||||||
|
expect(de.query(By.css('.license-link'))).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not be accepted', () => {
|
||||||
|
expect(component.accepted).toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have section status incomplete', () => {
|
||||||
|
expect(component.getSectionStatus()).toBeObservable(cold('(a|)', { a: false }));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the cc license is accepted', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
component.setAccepted(true);
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the operations builder add method', () => {
|
||||||
|
expect(operationsBuilder.add).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have section status complete', () => {
|
||||||
|
expect(component.getSectionStatus()).toBeObservable(cold('(a|)', { a: true }));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Component, Inject } from '@angular/core';
|
import { Component, Inject } from '@angular/core';
|
||||||
import { Observable, of as observableOf, Subscription } from 'rxjs';
|
import { Observable, of as observableOf, Subscription } from 'rxjs';
|
||||||
import { SubmissionCcLicence } from '../../core/shared/submission-cc-license.model';
|
import { Field, Option, SubmissionCcLicence } from '../../core/shared/submission-cc-license.model';
|
||||||
import { getRemoteDataPayload, getSucceededRemoteData } from '../../core/shared/operators';
|
import { getRemoteDataPayload, getSucceededRemoteData } from '../../core/shared/operators';
|
||||||
import { distinctUntilChanged, filter, map } from 'rxjs/operators';
|
import { distinctUntilChanged, filter, map } from 'rxjs/operators';
|
||||||
import { SubmissionCcLicensesDataService } from '../../core/data/submission-cc-licenses-data.service';
|
import { SubmissionCcLicensesDataService } from '../../core/data/submission-cc-licenses-data.service';
|
||||||
@@ -13,6 +13,7 @@ import { SectionsService } from '../../submission/sections/sections.service';
|
|||||||
import { WorkspaceitemSectionCcLicenseObject } from '../../core/submission/models/workspaceitem-section-cc-license.model';
|
import { WorkspaceitemSectionCcLicenseObject } from '../../core/submission/models/workspaceitem-section-cc-license.model';
|
||||||
import { JsonPatchOperationPathCombiner } from '../../core/json-patch/builder/json-patch-operation-path-combiner';
|
import { JsonPatchOperationPathCombiner } from '../../core/json-patch/builder/json-patch-operation-path-combiner';
|
||||||
import { isNotEmpty } from '../empty.util';
|
import { isNotEmpty } from '../empty.util';
|
||||||
|
import { JsonPatchOperationsBuilder } from '../../core/json-patch/builder/json-patch-operations-builder';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This component represents the submission section to select the Creative Commons license.
|
* This component represents the submission section to select the Creative Commons license.
|
||||||
@@ -58,10 +59,28 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
*/
|
*/
|
||||||
protected modalRef: NgbModalRef;
|
protected modalRef: NgbModalRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Creative Commons link saved in the workspace item.
|
||||||
|
*/
|
||||||
|
get storedCcLicenseLink(): string {
|
||||||
|
return this.data.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The accepted state for the selected Creative Commons license.
|
||||||
|
*/
|
||||||
|
get accepted(): boolean {
|
||||||
|
if (this.data.accepted === undefined) {
|
||||||
|
return !!this.data.uri;
|
||||||
|
}
|
||||||
|
return this.data.accepted;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected modalService: NgbModal,
|
protected modalService: NgbModal,
|
||||||
protected sectionService: SectionsService,
|
protected sectionService: SectionsService,
|
||||||
protected submissionCcLicensesDataService: SubmissionCcLicensesDataService,
|
protected submissionCcLicensesDataService: SubmissionCcLicensesDataService,
|
||||||
|
protected operationsBuilder: JsonPatchOperationsBuilder,
|
||||||
@Inject('collectionIdProvider') public injectedCollectionId: string,
|
@Inject('collectionIdProvider') public injectedCollectionId: string,
|
||||||
@Inject('sectionDataProvider') public injectedSectionData: SectionDataObject,
|
@Inject('sectionDataProvider') public injectedSectionData: SectionDataObject,
|
||||||
@Inject('submissionIdProvider') public injectedSubmissionId: string
|
@Inject('submissionIdProvider') public injectedSubmissionId: string
|
||||||
@@ -84,15 +103,16 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
* Select a given Creative Commons license.
|
* Select a given Creative Commons license.
|
||||||
* @param ccLicense the Creative Commons license to select.
|
* @param ccLicense the Creative Commons license to select.
|
||||||
*/
|
*/
|
||||||
select(ccLicense: SubmissionCcLicence) {
|
selectCcLicense(ccLicense: SubmissionCcLicence) {
|
||||||
if (!!this.getSelectedCcLicense() && this.getSelectedCcLicense().name === ccLicense.name) {
|
if (!!this.getSelectedCcLicense() && this.getSelectedCcLicense().id === ccLicense.id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.data.ccLicense = {
|
this.data.ccLicense = {
|
||||||
name: ccLicense.name,
|
id: ccLicense.id,
|
||||||
fields: {},
|
fields: {},
|
||||||
};
|
};
|
||||||
this.updateSectionStatus();
|
this.data.uri = undefined;
|
||||||
|
this.setAccepted(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,38 +122,63 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
if (!this.submissionCcLicenses || !this.data.ccLicense) {
|
if (!this.submissionCcLicenses || !this.data.ccLicense) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return this.submissionCcLicenses.filter((ccLicense) => ccLicense.name === this.data.ccLicense.name)[0];
|
return this.submissionCcLicenses.filter((ccLicense) => ccLicense.id === this.data.ccLicense.id)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select an option for a given license field.
|
* Select an option for a given license field.
|
||||||
* @param ccLicense the related Creative Commons license.
|
* @param ccLicense the related Creative Commons license.
|
||||||
* @param field the field for which to select an option.
|
* @param field the field for which to select an option.
|
||||||
* @param value the value of the selected option,.
|
* @param option the option to select.
|
||||||
*/
|
*/
|
||||||
selectOption(ccLicense: SubmissionCcLicence, field: string, value: string) {
|
selectOption(ccLicense: SubmissionCcLicence, field: Field, option: Option) {
|
||||||
|
if (this.isSelectedOption(ccLicense, field, option)) {
|
||||||
this.data.ccLicense.fields[field] = value;
|
return;
|
||||||
this.updateSectionStatus();
|
}
|
||||||
|
this.data.ccLicense.fields[field.id] = option;
|
||||||
|
this.setAccepted(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the selected option value for a given license field.
|
* Get the selected option for a given license field.
|
||||||
* @param ccLicense the related Creative Commons license.
|
* @param ccLicense the related Creative Commons license.
|
||||||
* @param field the field for which to get the selected option value.
|
* @param field the field for which to get the selected option value.
|
||||||
*/
|
*/
|
||||||
getSelectedOption(ccLicense: SubmissionCcLicence, field: string): string {
|
getSelectedOption(ccLicense: SubmissionCcLicence, field: Field): Option {
|
||||||
return this.data.ccLicense.fields[field];
|
return this.data.ccLicense.fields[field.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether a given option value is selected for a given license field.
|
* Whether a given option is selected for a given Creative Commons license field.
|
||||||
* @param ccLicense the related Creative Commons license.
|
* @param ccLicense the related Creative Commons license.
|
||||||
* @param field the field for which to check whether the option is selected.
|
* @param field the field for which to check whether the option is selected.
|
||||||
* @param value the value for which to check whether it is selected.
|
* @param option the option for which to check whether it is selected.
|
||||||
*/
|
*/
|
||||||
isSelectedOption(ccLicense: SubmissionCcLicence, field: string, value: string): boolean {
|
isSelectedOption(ccLicense: SubmissionCcLicence, field: Field, option: Option): boolean {
|
||||||
return this.getSelectedOption(ccLicense, field) === value;
|
return this.getSelectedOption(ccLicense, field) && this.getSelectedOption(ccLicense, field).id === option.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the link to the Creative Commons license corresponding with the selected options.
|
||||||
|
*/
|
||||||
|
getCcLicenseLink$(): Observable<string> {
|
||||||
|
|
||||||
|
if (!!this.storedCcLicenseLink) {
|
||||||
|
return observableOf(this.storedCcLicenseLink);
|
||||||
|
}
|
||||||
|
if (!this.getSelectedCcLicense() || this.getSelectedCcLicense().fields.some(
|
||||||
|
(field) => !this.getSelectedOption(this.getSelectedCcLicense(), field))) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const selectedCcLicense = this.getSelectedCcLicense();
|
||||||
|
return this.submissionCcLicensesDataService.getCcLicenseLink(
|
||||||
|
selectedCcLicense,
|
||||||
|
new Map(selectedCcLicense.fields.map(
|
||||||
|
(field) => [field, this.getSelectedOption(selectedCcLicense, field)]
|
||||||
|
)),
|
||||||
|
).pipe(
|
||||||
|
map((response) => response.content),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -158,11 +203,7 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
* the section status
|
* the section status
|
||||||
*/
|
*/
|
||||||
getSectionStatus(): Observable<boolean> {
|
getSectionStatus(): Observable<boolean> {
|
||||||
return observableOf(
|
return observableOf(this.accepted);
|
||||||
!!this.getSelectedCcLicense() && this.getSelectedCcLicense().fields.every(
|
|
||||||
(field) => !!this.getSelectedOption(this.getSelectedCcLicense(), field.id)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,14 +217,16 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
* Initialize the section.
|
* Initialize the section.
|
||||||
*/
|
*/
|
||||||
onSectionInit(): void {
|
onSectionInit(): void {
|
||||||
|
this.pathCombiner = new JsonPatchOperationPathCombiner('sections', this.sectionData.id);
|
||||||
this.subscriptions.push(
|
this.subscriptions.push(
|
||||||
this.sectionService.getSectionState(this.submissionId, this.sectionData.id).pipe(
|
this.sectionService.getSectionState(this.submissionId, this.sectionData.id).pipe(
|
||||||
filter((sectionState) => {
|
filter((sectionState) => {
|
||||||
return isNotEmpty(sectionState) && (isNotEmpty(sectionState.data) || isNotEmpty(sectionState.errors))
|
return isNotEmpty(sectionState) && (isNotEmpty(sectionState.data) || isNotEmpty(sectionState.errors))
|
||||||
}),
|
}),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
).subscribe((sectionState) => {
|
map((sectionState) => sectionState.data as WorkspaceitemSectionCcLicenseObject),
|
||||||
this.sectionData.data = sectionState.data;
|
).subscribe((data) => {
|
||||||
|
this.sectionData.data = data;
|
||||||
}),
|
}),
|
||||||
this.submissionCcLicensesDataService.findAll({elementsPerPage: Number.MAX_SAFE_INTEGER}).pipe(
|
this.submissionCcLicensesDataService.findAll({elementsPerPage: Number.MAX_SAFE_INTEGER}).pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
@@ -194,4 +237,33 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the accepted state for the Creative Commons license.
|
||||||
|
* @param accepted the accepted state for the cc license.
|
||||||
|
*/
|
||||||
|
setAccepted(accepted: boolean) {
|
||||||
|
const path = this.pathCombiner.getPath('uri');
|
||||||
|
if (accepted) {
|
||||||
|
this.getCcLicenseLink$().subscribe((link) => {
|
||||||
|
this.operationsBuilder.add(path, link.toString(), false, true);
|
||||||
|
this.data.accepted = true;
|
||||||
|
this.updateSectionData();
|
||||||
|
this.updateSectionStatus();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.operationsBuilder.remove(path);
|
||||||
|
this.data.accepted = false;
|
||||||
|
this.updateSectionData();
|
||||||
|
this.updateSectionStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the section data for this section.
|
||||||
|
*/
|
||||||
|
updateSectionData() {
|
||||||
|
this.sectionService.updateSectionData(this.submissionId, this.sectionData.id, this.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2430,10 +2430,16 @@
|
|||||||
|
|
||||||
"submission.sections.ccLicense.select": "Select a license…",
|
"submission.sections.ccLicense.select": "Select a license…",
|
||||||
|
|
||||||
|
"submission.sections.ccLicense.change": "Change your license…",
|
||||||
|
|
||||||
"submission.sections.ccLicense.none": "No licenses available",
|
"submission.sections.ccLicense.none": "No licenses available",
|
||||||
|
|
||||||
"submission.sections.ccLicense.option.select": "Select an option…",
|
"submission.sections.ccLicense.option.select": "Select an option…",
|
||||||
|
|
||||||
|
"submission.sections.ccLicense.link": "You’ve selected the following license:",
|
||||||
|
|
||||||
|
"submission.sections.ccLicense.confirmation": "I grant the license above",
|
||||||
|
|
||||||
"submission.sections.general.add-more": "Add more",
|
"submission.sections.general.add-more": "Add more",
|
||||||
|
|
||||||
"submission.sections.general.collection": "Collection",
|
"submission.sections.general.collection": "Collection",
|
||||||
|
Reference in New Issue
Block a user