Fixed merge issues

This commit is contained in:
Giuseppe
2018-10-17 12:25:46 +02:00
parent 8bc7d31864
commit 7b483ce052
43 changed files with 295 additions and 209 deletions

View File

@@ -184,7 +184,7 @@ describe('BrowseService', () => {
scheduler.schedule(() => service.getBrowseItemsFor(browseDefinitions[1].id, mockAuthorName).subscribe()); scheduler.schedule(() => service.getBrowseItemsFor(browseDefinitions[1].id, mockAuthorName).subscribe());
scheduler.flush(); scheduler.flush();
expect(requestService.configure).toHaveBeenCalledWith(expected); expect(requestService.configure).toHaveBeenCalledWith(expected, undefined);
}); });
it('should call RemoteDataBuildService to create the RemoteData Observable', () => { it('should call RemoteDataBuildService to create the RemoteData Observable', () => {

View File

@@ -13,6 +13,10 @@ import { NormalizedEPerson } from '../../eperson/models/normalized-eperson.model
import { NormalizedGroup } from '../../eperson/models/normalized-group.model'; import { NormalizedGroup } from '../../eperson/models/normalized-group.model';
import { NormalizedWorkflowItem } from '../../submission/models/normalized-workflowitem.model'; import { NormalizedWorkflowItem } from '../../submission/models/normalized-workflowitem.model';
import { NormalizedBitstreamFormat } from './normalized-bitstream-format.model'; import { NormalizedBitstreamFormat } from './normalized-bitstream-format.model';
import { SubmissionResourceType } from '../../submission/submission-resource-type';
import { SubmissionDefinitionsModel } from '../../shared/config/config-submission-definitions.model';
import { SubmissionFormsModel } from '../../shared/config/config-submission-forms.model';
import { SubmissionSectionModel } from '../../shared/config/config-submission-section.model';
export class NormalizedObjectFactory { export class NormalizedObjectFactory {
public static getConstructor(type: ResourceType): GenericConstructor<NormalizedObject> { public static getConstructor(type: ResourceType): GenericConstructor<NormalizedObject> {
@@ -53,6 +57,18 @@ export class NormalizedObjectFactory {
case ResourceType.BitstreamFormat: { case ResourceType.BitstreamFormat: {
return NormalizedBitstreamFormat return NormalizedBitstreamFormat
} }
case ResourceType.SubmissionDefinition:
case ResourceType.SubmissionDefinitions: {
return SubmissionDefinitionsModel
}
case ResourceType.SubmissionForm:
case ResourceType.SubmissionForms: {
return SubmissionFormsModel
}
case ResourceType.SubmissionSection:
case ResourceType.SubmissionSections: {
return SubmissionSectionModel
}
default: { default: {
return undefined; return undefined;
} }

View File

@@ -28,9 +28,8 @@ export class NormalizedResourcePolicy extends NormalizedObject {
/** /**
* The uuid of the Group this Resource Policy applies to * The uuid of the Group this Resource Policy applies to
*/ */
@relationship(ResourceType.Group, false) @autoserialize
@autoserializeAs(String, 'groupUUID') groupUUID: string;
group: string;
/** /**
* Identifier for this Resource Policy * Identifier for this Resource Policy
@@ -46,4 +45,5 @@ export class NormalizedResourcePolicy extends NormalizedObject {
*/ */
@autoserializeAs(new IDToUUIDSerializer('resource-policy'), 'id') @autoserializeAs(new IDToUUIDSerializer('resource-policy'), 'id')
uuid: string; uuid: string;
} }

View File

@@ -11,6 +11,7 @@ import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafie
import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-response.model'; import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-response.model';
import { AuthStatus } from '../auth/models/auth-status.model'; import { AuthStatus } from '../auth/models/auth-status.model';
import { NormalizedObject } from './models/normalized-object.model'; import { NormalizedObject } from './models/normalized-object.model';
import { PaginatedList } from '../data/paginated-list';
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
export class RestResponse { export class RestResponse {
@@ -160,7 +161,7 @@ export class ErrorResponse extends RestResponse {
export class ConfigSuccessResponse extends RestResponse { export class ConfigSuccessResponse extends RestResponse {
constructor( constructor(
public configDefinition: ConfigObject[], public configDefinition: ConfigObject,
public statusCode: number, public statusCode: number,
public statusText: string, public statusText: string,
public pageInfo?: PageInfo public pageInfo?: PageInfo
@@ -183,7 +184,7 @@ export class AuthStatusResponse extends RestResponse {
export class IntegrationSuccessResponse extends RestResponse { export class IntegrationSuccessResponse extends RestResponse {
constructor( constructor(
public dataDefinition: IntegrationModel[], public dataDefinition: PaginatedList<IntegrationModel>,
public statusCode: number, public statusCode: number,
public statusText: string, public statusText: string,
public pageInfo?: PageInfo public pageInfo?: PageInfo
@@ -194,7 +195,7 @@ export class IntegrationSuccessResponse extends RestResponse {
export class PostPatchSuccessResponse extends RestResponse { export class PostPatchSuccessResponse extends RestResponse {
constructor( constructor(
public dataDefinition: any[], public dataDefinition: any,
public statusCode: number, public statusCode: number,
public statusText: string, public statusText: string,
public pageInfo?: PageInfo public pageInfo?: PageInfo

View File

@@ -7,7 +7,7 @@ import { ConfigObject } from '../shared/config/config.model';
export class ConfigData { export class ConfigData {
constructor( constructor(
public pageInfo: PageInfo, public pageInfo: PageInfo,
public payload: ConfigObject[] public payload: ConfigObject
) { ) {
} }
} }

View File

@@ -6,7 +6,6 @@ import { ObjectCacheService } from '../cache/object-cache.service';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
import { GenericConstructor } from '../shared/generic-constructor'; import { GenericConstructor } from '../shared/generic-constructor';
import { PaginatedList } from './paginated-list'; import { PaginatedList } from './paginated-list';
import { NormalizedObject } from '../cache/models/normalized-object.model';
import { ResourceType } from '../shared/resource-type'; import { ResourceType } from '../shared/resource-type';
import { RESTURLCombiner } from '../url-combiner/rest-url-combiner'; import { RESTURLCombiner } from '../url-combiner/rest-url-combiner';
@@ -15,7 +14,7 @@ function isObjectLevel(halObj: any) {
} }
function isPaginatedResponse(halObj: any) { function isPaginatedResponse(halObj: any) {
return isNotEmpty(halObj.page) && hasValue(halObj._embedded); return hasValue(halObj.page) && hasValue(halObj._embedded);
} }
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
@@ -47,11 +46,11 @@ export abstract class BaseResponseParsingService {
if (isNotEmpty(parsedObj)) { if (isNotEmpty(parsedObj)) {
if (isPaginatedResponse(data._embedded[property])) { if (isPaginatedResponse(data._embedded[property])) {
object[property] = parsedObj; object[property] = parsedObj;
object[property].page = parsedObj.page.map((obj) => obj.self); object[property].page = parsedObj.page.map((obj) => this.retrieveObjectOrUrl(obj));
} else if (isObjectLevel(data._embedded[property])) { } else if (isObjectLevel(data._embedded[property])) {
object[property] = parsedObj.self; object[property] = this.retrieveObjectOrUrl(parsedObj);
} else if (Array.isArray(parsedObj)) { } else if (Array.isArray(parsedObj)) {
object[property] = parsedObj.map((obj) => obj.self) object[property] = parsedObj.map((obj) => this.retrieveObjectOrUrl(obj))
} }
} }
}); });
@@ -65,8 +64,7 @@ export abstract class BaseResponseParsingService {
.filter((property) => data.hasOwnProperty(property)) .filter((property) => data.hasOwnProperty(property))
.filter((property) => hasValue(data[property])) .filter((property) => hasValue(data[property]))
.forEach((property) => { .forEach((property) => {
const obj = this.process(data[property], requestHref); result[property] = this.process(data[property], requestHref);
result[property] = obj;
}); });
return result; return result;
@@ -101,8 +99,7 @@ export abstract class BaseResponseParsingService {
if (hasValue(normObjConstructor)) { if (hasValue(normObjConstructor)) {
const serializer = new DSpaceRESTv2Serializer(normObjConstructor); const serializer = new DSpaceRESTv2Serializer(normObjConstructor);
const res = serializer.deserialize(obj); return serializer.deserialize(obj);
return res;
} else { } else {
// TODO: move check to Validator? // TODO: move check to Validator?
// throw new Error(`The server returned an object with an unknown a known type: ${type}`); // throw new Error(`The server returned an object with an unknown a known type: ${type}`);
@@ -150,6 +147,11 @@ export abstract class BaseResponseParsingService {
return obj[keys[0]]; return obj[keys[0]];
} }
protected retrieveObjectOrUrl(obj: any): any {
return this.toCache ? obj.self : obj;
// return obj.self;
}
// TODO Remove when https://jira.duraspace.org/browse/DS-4006 is fixed // TODO Remove when https://jira.duraspace.org/browse/DS-4006 is fixed
// See https://github.com/DSpace/dspace-angular/issues/292 // See https://github.com/DSpace/dspace-angular/issues/292
private fixBadEPersonRestResponse(obj: any): any { private fixBadEPersonRestResponse(obj: any): any {

View File

@@ -106,7 +106,8 @@ describe('BrowseItemsResponseParsingService', () => {
number: 0 number: 0
} }
}, },
statusCode: '200' statusCode: 200,
statusText: 'OK'
} as DSpaceRESTV2Response; } as DSpaceRESTV2Response;
const invalidResponseNotAList = { const invalidResponseNotAList = {
@@ -142,11 +143,12 @@ describe('BrowseItemsResponseParsingService', () => {
} }
} }
}, },
statusCode: '200' statusCode: 200,
statusText: 'OK'
} as DSpaceRESTV2Response; } as DSpaceRESTV2Response;
const invalidResponseStatusCode = { const invalidResponseStatusCode = {
payload: {}, statusCode: '500' payload: {}, statusCode: 500, statusText: 'Internal Server Error'
} as DSpaceRESTV2Response; } as DSpaceRESTV2Response;
it('should return a GenericSuccessResponse if data contains a valid browse items response', () => { it('should return a GenericSuccessResponse if data contains a valid browse items response', () => {

View File

@@ -44,12 +44,12 @@ export class BrowseItemsResponseParsingService extends BaseResponseParsingServic
&& Array.isArray(data.payload._embedded[Object.keys(data.payload._embedded)[0]])) { && Array.isArray(data.payload._embedded[Object.keys(data.payload._embedded)[0]])) {
const serializer = new DSpaceRESTv2Serializer(DSpaceObject); const serializer = new DSpaceRESTv2Serializer(DSpaceObject);
const items = serializer.deserializeArray(data.payload._embedded[Object.keys(data.payload._embedded)[0]]); const items = serializer.deserializeArray(data.payload._embedded[Object.keys(data.payload._embedded)[0]]);
return new GenericSuccessResponse(items, data.statusCode, this.processPageInfo(data.payload)); return new GenericSuccessResponse(items, data.statusCode, data.statusText, this.processPageInfo(data.payload));
} else { } else {
return new ErrorResponse( return new ErrorResponse(
Object.assign( Object.assign(
new Error('Unexpected response from browse endpoint'), new Error('Unexpected response from browse endpoint'),
{ statusText: data.statusCode } { statusCode: data.statusCode, statusText: data.statusText }
) )
); );
} }

View File

@@ -9,6 +9,7 @@ import { CoreState } from '../core.reducers';
import { SubmissionDefinitionsModel } from '../shared/config/config-submission-definitions.model'; import { SubmissionDefinitionsModel } from '../shared/config/config-submission-definitions.model';
import { PaginatedList } from './paginated-list'; import { PaginatedList } from './paginated-list';
import { PageInfo } from '../shared/page-info.model'; import { PageInfo } from '../shared/page-info.model';
import { SubmissionSectionModel } from '../shared/config/config-submission-section.model';
describe('ConfigResponseParsingService', () => { describe('ConfigResponseParsingService', () => {
let service: ConfigResponseParsingService; let service: ConfigResponseParsingService;
@@ -176,10 +177,65 @@ describe('ConfigResponseParsingService', () => {
}, },
self: 'https://rest.api/config/submissiondefinitions/traditional', self: 'https://rest.api/config/submissiondefinitions/traditional',
sections: new PaginatedList(pageinfo, [ sections: new PaginatedList(pageinfo, [
'https://rest.api/config/submissionsections/traditionalpageone', Object.assign(new SubmissionSectionModel(), {
'https://rest.api/config/submissionsections/traditionalpagetwo', header: 'submit.progressbar.describe.stepone',
'https://rest.api/config/submissionsections/upload', mandatory: true,
'https://rest.api/config/submissionsections/license' sectionType: 'submission-form',
visibility:{
main:null,
other:'READONLY'
},
type: 'submissionsection',
_links: {
self: 'https://rest.api/config/submissionsections/traditionalpageone',
config: 'https://rest.api/config/submissionforms/traditionalpageone'
},
self: 'https://rest.api/config/submissionsections/traditionalpageone',
}),
Object.assign(new SubmissionSectionModel(), {
header: 'submit.progressbar.describe.steptwo',
mandatory: true,
sectionType: 'submission-form',
visibility:{
main:null,
other:'READONLY'
},
type: 'submissionsection',
_links: {
self: 'https://rest.api/config/submissionsections/traditionalpagetwo',
config: 'https://rest.api/config/submissionforms/traditionalpagetwo'
},
self: 'https://rest.api/config/submissionsections/traditionalpagetwo',
}),
Object.assign(new SubmissionSectionModel(), {
header: 'submit.progressbar.upload',
mandatory: false,
sectionType: 'upload',
visibility:{
main:null,
other:'READONLY'
},
type: 'submissionsection',
_links: {
self: 'https://rest.api/config/submissionsections/upload',
config: 'https://rest.api/config/submissionuploads/upload'
},
self: 'https://rest.api/config/submissionsections/upload',
}),
Object.assign(new SubmissionSectionModel(), {
header: 'submit.progressbar.license',
mandatory: true,
sectionType: 'license',
visibility:{
main:null,
other:'READONLY'
},
type: 'submissionsection',
_links: {
self: 'https://rest.api/config/submissionsections/license'
},
self: 'https://rest.api/config/submissionsections/license',
})
]) ])
}); });

View File

@@ -7,6 +7,7 @@ import { CoreState } from '../core.reducers';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { FindAllOptions } from './request.models'; import { FindAllOptions } from './request.models';
import { SortOptions, SortDirection } from '../cache/models/sort-options.model'; import { SortOptions, SortDirection } from '../cache/models/sort-options.model';
@@ -17,6 +18,7 @@ class NormalizedTestObject extends NormalizedObject {
} }
class TestService extends DataService<NormalizedTestObject, any> { class TestService extends DataService<NormalizedTestObject, any> {
protected forceBypassCache = false;
constructor( constructor(
protected responseCache: ResponseCacheService, protected responseCache: ResponseCacheService,
protected requestService: RequestService, protected requestService: RequestService,

View File

@@ -57,7 +57,7 @@ describe('DSpaceObjectDataService', () => {
scheduler.schedule(() => service.findById(testObject.uuid)); scheduler.schedule(() => service.findById(testObject.uuid));
scheduler.flush(); scheduler.flush();
expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestURL, testObject.uuid)); expect(requestService.configure).toHaveBeenCalledWith(new FindByIDRequest(requestUUID, requestURL, testObject.uuid), false);
}); });
it('should return a RemoteData<DSpaceObject> for the object with the given ID', () => { it('should return a RemoteData<DSpaceObject> for the object with the given ID', () => {

View File

@@ -15,6 +15,7 @@ import { FindAllOptions } from './request.models';
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject> { class DataServiceImpl extends DataService<NormalizedDSpaceObject, DSpaceObject> {
protected linkPath = 'dso'; protected linkPath = 'dso';
protected forceBypassCache = false;
constructor( constructor(
protected responseCache: ResponseCacheService, protected responseCache: ResponseCacheService,

View File

@@ -1,7 +1,7 @@
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { ResponseCacheService } from '../cache/response-cache.service'; import { ResponseCacheService } from '../cache/response-cache.service';
import { EpersonRequest } from '../data/request.models'; import { EpersonRequest, FindAllOptions } from '../data/request.models';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { NormalizedObject } from '../cache/models/normalized-object.model'; import { NormalizedObject } from '../cache/models/normalized-object.model';
import { DataService } from '../data/data.service'; import { DataService } from '../data/data.service';
@@ -14,7 +14,7 @@ export abstract class EpersonService<TNormalized extends NormalizedObject, TDoma
protected abstract browseEndpoint: string; protected abstract browseEndpoint: string;
protected abstract halService: HALEndpointService; protected abstract halService: HALEndpointService;
public getScopedEndpoint(scopeID: string): Observable<string> { public getBrowseEndpoint(options: FindAllOptions): Observable<string> {
return this.halService.getEndpoint(this.linkPath); return this.halService.getEndpoint(this.linkPath);
} }
} }

View File

@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { filter, map, take } from 'rxjs/operators'; import { filter, map, take } from 'rxjs/operators';
@@ -8,10 +9,9 @@ import { ResponseCacheService } from '../cache/response-cache.service';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { FindAllOptions } from '../data/request.models'; import { FindAllOptions } from '../data/request.models';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { NormalizedGroupModel } from './models/NormalizedGroup.model'; import { NormalizedGroup } from './models/normalized-group.model';
import { Group } from './models/group.model'; import { Group } from './models/group.model';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers'; import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { SearchParam } from '../cache/models/search-param.model'; import { SearchParam } from '../cache/models/search-param.model';
@@ -19,7 +19,7 @@ import { RemoteData } from '../data/remote-data';
import { PaginatedList } from '../data/paginated-list'; import { PaginatedList } from '../data/paginated-list';
@Injectable() @Injectable()
export class GroupEpersonService extends EpersonService<NormalizedGroupModel, Group> { export class GroupEpersonService extends EpersonService<NormalizedGroup, Group> {
protected linkPath = 'groups'; protected linkPath = 'groups';
protected browseEndpoint = ''; protected browseEndpoint = '';
protected forceBypassCache = false; protected forceBypassCache = false;

View File

@@ -3,10 +3,9 @@ import { CacheableObject } from '../../cache/object-cache.reducer';
import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model';
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model'; import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
import { EPerson } from './eperson.model'; import { EPerson } from './eperson.model';
import { mapsTo, relationship } from '../../cache/builders/build-decorators'; import { mapsTo } from '../../cache/builders/build-decorators';
import { ResourceType } from '../../shared/resource-type';
import { Group } from './group.model'; import { Group } from './group.model';
import { NormalizedGroupModel } from './NormalizedGroup.model'; import { NormalizedGroup } from './normalized-group.model';
@mapsTo(EPerson) @mapsTo(EPerson)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
@@ -15,7 +14,7 @@ export class NormalizedEPerson extends NormalizedDSpaceObject implements Cacheab
@autoserialize @autoserialize
public handle: string; public handle: string;
@autoserializeAs(NormalizedGroupModel) @autoserializeAs(NormalizedGroup)
groups: Group[]; groups: Group[];
@autoserialize @autoserialize

View File

@@ -9,7 +9,7 @@ import { JsonPatchOperationPathObject } from './json-patch-operation-path-combin
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { isEmpty, isNotEmpty } from '../../../shared/empty.util'; import { isEmpty, isNotEmpty } from '../../../shared/empty.util';
import { dateToGMTString } from '../../../shared/date.util'; import { dateToGMTString } from '../../../shared/date.util';
import { AuthorityValueModel } from '../../integration/models/authority-value.model'; import { AuthorityValue } from '../../integration/models/authority.value';
import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model'; import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model';
@@ -77,7 +77,7 @@ export class JsonPatchOperationsBuilder {
operationValue = value; operationValue = value;
} else if (value instanceof Date) { } else if (value instanceof Date) {
operationValue = new FormFieldMetadataValueObject(dateToGMTString(value)); operationValue = new FormFieldMetadataValueObject(dateToGMTString(value));
} else if (value instanceof AuthorityValueModel) { } else if (value instanceof AuthorityValue) {
operationValue = this.prepareAuthorityValue(value); operationValue = this.prepareAuthorityValue(value);
} else if (value instanceof FormFieldLanguageValueObject) { } else if (value instanceof FormFieldLanguageValueObject) {
operationValue = new FormFieldMetadataValueObject(value.value, value.language); operationValue = new FormFieldMetadataValueObject(value.value, value.language);

View File

@@ -5,6 +5,7 @@ import { RemoteData } from '../data/remote-data';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { License } from './license.model'; import { License } from './license.model';
import { ResourcePolicy } from './resource-policy.model'; import { ResourcePolicy } from './resource-policy.model';
import { PaginatedList } from '../data/paginated-list';
export class Collection extends DSpaceObject { export class Collection extends DSpaceObject {
@@ -66,7 +67,7 @@ export class Collection extends DSpaceObject {
/** /**
* The default access conditions of this Collection * The default access conditions of this Collection
*/ */
defaultAccessConditions: Observable<RemoteData<ResourcePolicy[]>>; defaultAccessConditions: Observable<RemoteData<PaginatedList<ResourcePolicy>>>;
/** /**
* An array of Collections that are direct parents of this Collection * An array of Collections that are direct parents of this Collection

View File

@@ -10,7 +10,7 @@ export class SubmissionUploadsModel extends ConfigObject {
accessConditionOptions: AccessConditionOption[]; accessConditionOptions: AccessConditionOption[];
@autoserializeAs(SubmissionFormsModel) @autoserializeAs(SubmissionFormsModel)
metadata: SubmissionFormsModel[]; metadata: SubmissionFormsModel;
@autoserialize @autoserialize
required: boolean; required: boolean;

View File

@@ -1,12 +1,13 @@
import { autoserialize, autoserializeAs } from 'cerialize'; import { autoserialize, autoserializeAs } from 'cerialize';
import { NormalizedObject } from '../../cache/models/normalized-object.model';
export abstract class ConfigObject { export abstract class ConfigObject extends NormalizedObject{
@autoserialize @autoserialize
public name: string; public name: string;
@autoserialize @autoserialize
public type: string; public type: any;
@autoserialize @autoserialize
public _links: { public _links: {

View File

@@ -18,9 +18,9 @@ export class ResourcePolicy implements CacheableObject {
name: string; name: string;
/** /**
* The Group this Resource Policy applies to * The uuid of the Group this Resource Policy applies to
*/ */
group: Group; groupUUID: string;
/** /**
* The link to the rest endpoint where this Resource Policy can be found * The link to the rest endpoint where this Resource Policy can be found

View File

@@ -12,4 +12,10 @@ export enum ResourceType {
License = 'license', License = 'license',
Workflowitem = 'workflowitem', Workflowitem = 'workflowitem',
Workspaceitem = 'workspaceitem', Workspaceitem = 'workspaceitem',
SubmissionDefinitions = 'submissiondefinitions',
SubmissionDefinition = 'submissiondefinition',
SubmissionForm = 'submissionform',
SubmissionForms = 'submissionforms',
SubmissionSections = 'submissionsections',
SubmissionSection = 'submissionsection',
} }

View File

@@ -1,47 +1,10 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; import { inheritSerialization } from 'cerialize';
import { mapsTo, relationship } from '../../cache/builders/build-decorators'; import { mapsTo } from '../../cache/builders/build-decorators';
import { NormalizedWorkspaceItem } from './normalized-workspaceitem.model';
import { NormalizedSubmissionObject } from './normalized-submission-object.model'; import { NormalizedSubmissionObject } from './normalized-submission-object.model';
import { ResourceType } from '../../shared/resource-type';
import { SubmissionDefinitionsModel } from '../../shared/config/config-submission-definitions.model';
import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model';
import { SubmissionObjectError } from './submission-object.model';
import { EditItem } from './edititem.model'; import { EditItem } from './edititem.model';
@mapsTo(EditItem) @mapsTo(EditItem)
@inheritSerialization(NormalizedWorkspaceItem) @inheritSerialization(NormalizedSubmissionObject)
export class NormalizedEditItem extends NormalizedSubmissionObject { export class NormalizedEditItem extends NormalizedSubmissionObject {
/**
* The item identifier
*/
@autoserialize
id: string;
/**
* The item last modified date
*/
@autoserialize
lastModified: Date;
@autoserialize
@relationship(ResourceType.Collection, true)
collection: string[];
@autoserialize
@relationship(ResourceType.Item, true)
item: string[];
@autoserialize
sections: WorkspaceitemSectionsObject;
@autoserializeAs(SubmissionDefinitionsModel)
submissionDefinition: SubmissionDefinitionsModel;
@autoserialize
@relationship(ResourceType.Eperson, true)
submitter: string[];
@autoserialize
errors: SubmissionObjectError[]
} }

View File

@@ -1,8 +1,35 @@
import { autoserialize, inheritSerialization } from 'cerialize';
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model'; import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model';
import { SubmissionObjectError } from './submission-object.model';
/** /**
* An abstract model class for a DSpaceObject. * An abstract model class for a NormalizedSubmissionObject.
*/ */
export abstract class NormalizedSubmissionObject extends NormalizedDSpaceObject { @inheritSerialization(NormalizedDSpaceObject)
export class NormalizedSubmissionObject extends NormalizedDSpaceObject {
/**
* The workspaceitem/workflowitem identifier
*/
@autoserialize
id: string;
/**
* The workspaceitem/workflowitem last modified date
*/
@autoserialize
lastModified: Date;
/**
* The workspaceitem/workflowitem last sections data
*/
@autoserialize
sections: WorkspaceitemSectionsObject;
/**
* The workspaceitem/workflowitem last sections errors
*/
@autoserialize
errors: SubmissionObjectError[];
} }

View File

@@ -1,47 +1,28 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; import { autoserialize, inheritSerialization } from 'cerialize';
import { mapsTo, relationship } from '../../cache/builders/build-decorators'; import { mapsTo, relationship } from '../../cache/builders/build-decorators';
import { Workflowitem } from './workflowitem.model'; import { Workflowitem } from './workflowitem.model';
import { NormalizedWorkspaceItem } from './normalized-workspaceitem.model';
import { NormalizedSubmissionObject } from './normalized-submission-object.model'; import { NormalizedSubmissionObject } from './normalized-submission-object.model';
import { ResourceType } from '../../shared/resource-type'; import { ResourceType } from '../../shared/resource-type';
import { SubmissionDefinitionsModel } from '../../shared/config/config-submission-definitions.model';
import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model';
import { SubmissionObjectError } from './submission-object.model';
@mapsTo(Workflowitem) @mapsTo(Workflowitem)
@inheritSerialization(NormalizedWorkspaceItem) @inheritSerialization(NormalizedSubmissionObject)
export class NormalizedWorkflowItem extends NormalizedSubmissionObject { export class NormalizedWorkflowItem extends NormalizedSubmissionObject {
/**
* The workspaceitem identifier
*/
@autoserialize @autoserialize
id: string; @relationship(ResourceType.Collection, false)
collection: string;
/**
* The workspaceitem last modified date
*/
@autoserialize
lastModified: Date;
@autoserialize @autoserialize
@relationship(ResourceType.Collection, true) @relationship(ResourceType.Item, false)
collection: string[]; item: string;
@autoserialize @autoserialize
@relationship(ResourceType.Item, true) @relationship(ResourceType.SubmissionDefinition, false)
item: string[]; submissionDefinition: string;
@autoserialize @autoserialize
sections: WorkspaceitemSectionsObject; @relationship(ResourceType.EPerson, false)
submitter: string;
@autoserializeAs(SubmissionDefinitionsModel)
submissionDefinition: SubmissionDefinitionsModel;
@autoserialize
@relationship(ResourceType.Eperson, true)
submitter: string[];
@autoserialize
errors: SubmissionObjectError[]
} }

View File

@@ -1,51 +1,29 @@
import { autoserialize, autoserializeAs, inheritSerialization } from 'cerialize'; import { autoserialize, inheritSerialization } from 'cerialize';
import { Workspaceitem } from './workspaceitem.model'; import { Workspaceitem } from './workspaceitem.model';
import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model';
import { NormalizedSubmissionObject } from './normalized-submission-object.model'; import { NormalizedSubmissionObject } from './normalized-submission-object.model';
import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
import { mapsTo, relationship } from '../../cache/builders/build-decorators'; import { mapsTo, relationship } from '../../cache/builders/build-decorators';
import { NormalizedCollection } from '../../cache/models/normalized-collection.model'; import { NormalizedDSpaceObject } from '../../cache/models/normalized-dspace-object.model';
import { ResourceType } from '../../shared/resource-type'; import { ResourceType } from '../../shared/resource-type';
import { SubmissionDefinitionsModel } from '../../shared/config/config-submission-definitions.model';
import { Eperson } from '../../eperson/models/eperson.model';
import { SubmissionObjectError } from './submission-object.model';
@mapsTo(Workspaceitem) @mapsTo(Workspaceitem)
@inheritSerialization(NormalizedDSpaceObject) @inheritSerialization(NormalizedDSpaceObject)
@inheritSerialization(NormalizedSubmissionObject)
export class NormalizedWorkspaceItem extends NormalizedSubmissionObject { export class NormalizedWorkspaceItem extends NormalizedSubmissionObject {
/**
* The workspaceitem identifier
*/
@autoserialize @autoserialize
id: string; @relationship(ResourceType.Collection, false)
collection: string;
/**
* The workspaceitem last modified date
*/
@autoserialize
lastModified: Date;
@autoserialize @autoserialize
@relationship(ResourceType.Collection, true) @relationship(ResourceType.Item, false)
collection: string[]; item: string;
@autoserialize @autoserialize
@relationship(ResourceType.Item, true) @relationship(ResourceType.SubmissionDefinition, false)
item: string[]; submissionDefinition: string;
@autoserialize @autoserialize
sections: WorkspaceitemSectionsObject; @relationship(ResourceType.EPerson, false)
submitter: string;
@autoserializeAs(SubmissionDefinitionsModel)
submissionDefinition: SubmissionDefinitionsModel;
@autoserialize
@relationship(ResourceType.Eperson, true)
submitter: string[];
@autoserialize
errors: SubmissionObjectError[]
} }

View File

@@ -1,12 +1,13 @@
import { Observable } from 'rxjs/Observable';
import { CacheableObject } from '../../cache/object-cache.reducer'; import { CacheableObject } from '../../cache/object-cache.reducer';
import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model'; import { ListableObject } from '../../../shared/object-collection/shared/listable-object.model';
import { DSpaceObject } from '../../shared/dspace-object.model'; import { DSpaceObject } from '../../shared/dspace-object.model';
import { Eperson } from '../../eperson/models/eperson.model'; import { EPerson } from '../../eperson/models/eperson.model';
import { RemoteData } from '../../data/remote-data'; import { RemoteData } from '../../data/remote-data';
import { Collection } from '../../shared/collection.model'; import { Collection } from '../../shared/collection.model';
import { Item } from '../../shared/item.model'; import { Item } from '../../shared/item.model';
import { SubmissionDefinitionsModel } from '../../shared/config/config-submission-definitions.model'; import { SubmissionDefinitionsModel } from '../../shared/config/config-submission-definitions.model';
import { Observable } from 'rxjs/Observable';
import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model'; import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model';
export interface SubmissionObjectError { export interface SubmissionObjectError {
@@ -15,29 +16,47 @@ export interface SubmissionObjectError {
} }
/** /**
* An abstract model class for a DSpaceObject. * An abstract model class for a SubmissionObject.
*/ */
export abstract class SubmissionObject extends DSpaceObject implements CacheableObject, ListableObject { export abstract class SubmissionObject extends DSpaceObject implements CacheableObject, ListableObject {
/** /**
* The workspaceitem identifier * The workspaceitem/workflowitem identifier
*/ */
id: string; id: string;
/** /**
* The workspaceitem last modified date * The workspaceitem/workflowitem last modified date
*/ */
lastModified: Date; lastModified: Date;
collection: Observable<RemoteData<Collection[]>> | Collection[]; /**
* The collection this submission applies to
*/
collection: Observable<RemoteData<Collection>> | Collection;
item: Observable<RemoteData<Item[]>> | Item[]; /**
* The submission item
*/
item: Observable<RemoteData<Item>> | Item;
/**
* The workspaceitem/workflowitem last sections data
*/
sections: WorkspaceitemSectionsObject; sections: WorkspaceitemSectionsObject;
/**
* The submission config definition
*/
submissionDefinition: SubmissionDefinitionsModel; submissionDefinition: SubmissionDefinitionsModel;
submitter: Observable<RemoteData<Eperson[]>> | Eperson[]; /**
* The workspaceitem submitter
*/
submitter: Observable<RemoteData<EPerson>> | EPerson;
/**
* The workspaceitem/workflowitem last sections errors
*/
errors: SubmissionObjectError[]; errors: SubmissionObjectError[];
} }

View File

@@ -15,6 +15,9 @@ import { SubmissionResourceType } from './submission-resource-type';
import { NormalizedResourcePolicy } from '../cache/models/normalized-resource-policy.model'; import { NormalizedResourcePolicy } from '../cache/models/normalized-resource-policy.model';
import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model'; import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model';
import { NormalizedEditItem } from './models/normalized-edititem.model'; import { NormalizedEditItem } from './models/normalized-edititem.model';
import { ResourceType } from '../shared/resource-type';
import { NormalizedEPerson } from '../eperson/models/normalized-eperson.model';
import { NormalizedGroup } from '../eperson/models/normalized-group.model';
export class NormalizedSubmissionObjectFactory { export class NormalizedSubmissionObjectFactory {
public static getConstructor(type: SubmissionResourceType): GenericConstructor<NormalizedObject | ConfigObject> { public static getConstructor(type: SubmissionResourceType): GenericConstructor<NormalizedObject | ConfigObject> {
@@ -40,6 +43,12 @@ export class NormalizedSubmissionObjectFactory {
case SubmissionResourceType.License: { case SubmissionResourceType.License: {
return NormalizedLicense return NormalizedLicense
} }
case SubmissionResourceType.EPerson: {
return NormalizedEPerson
}
case SubmissionResourceType.Group: {
return NormalizedGroup
}
case SubmissionResourceType.WorkspaceItem: { case SubmissionResourceType.WorkspaceItem: {
return NormalizedWorkspaceItem return NormalizedWorkspaceItem
} }

View File

@@ -9,8 +9,10 @@ export enum SubmissionResourceType {
Item = 'item', Item = 'item',
Collection = 'collection', Collection = 'collection',
Community = 'community', Community = 'community',
ResourcePolicy = 'resourcePolicies', ResourcePolicy = 'resourcePolicy',
License = 'license', License = 'license',
EPerson = 'eperson',
Group = 'group',
WorkspaceItem = 'workspaceitem', WorkspaceItem = 'workspaceitem',
WorkflowItem = 'workflowitem', WorkflowItem = 'workflowitem',
EditItem = 'edititem', EditItem = 'edititem',

View File

@@ -7,7 +7,7 @@ import { ErrorResponse, RestResponse, SubmissionSuccessResponse } from '../cache
import { isEmpty, isNotEmpty, isNotNull } from '../../shared/empty.util'; import { isEmpty, isNotEmpty, isNotNull } from '../../shared/empty.util';
import { ConfigObject } from '../shared/config/config.model'; import { ConfigObject } from '../shared/config/config.model';
import { BaseResponseParsingService, ProcessRequestDTO } from '../data/base-response-parsing.service'; import { BaseResponseParsingService } from '../data/base-response-parsing.service';
import { GLOBAL_CONFIG } from '../../../config'; import { GLOBAL_CONFIG } from '../../../config';
import { GlobalConfig } from '../../../config/global-config.interface'; import { GlobalConfig } from '../../../config/global-config.interface';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
@@ -18,6 +18,9 @@ import { NormalizedWorkspaceItem } from './models/normalized-workspaceitem.model
import { normalizeSectionData } from './models/workspaceitem-sections.model'; import { normalizeSectionData } from './models/workspaceitem-sections.model';
import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model'; import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model';
import { NormalizedEditItem } from './models/normalized-edititem.model'; import { NormalizedEditItem } from './models/normalized-edititem.model';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { NormalizedSubmissionObject } from './models/normalized-submission-object.model';
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
@Injectable() @Injectable()
export class SubmissionResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { export class SubmissionResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
@@ -26,7 +29,7 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
protected toCache = false; protected toCache = false;
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig, constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
protected objectCache: ObjectCacheService,) { protected objectCache: ObjectCacheService) {
super(); super();
} }
@@ -35,7 +38,7 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
&& isNotEmpty(data.payload._links) && isNotEmpty(data.payload._links)
&& (data.statusCode === 201 || data.statusCode === 200)) { && (data.statusCode === 201 || data.statusCode === 200)) {
const dataDefinition = this.processResponse<NormalizedObject | ConfigObject, SubmissionResourceType>(data.payload, request.href); const dataDefinition = this.processResponse<NormalizedObject | ConfigObject, SubmissionResourceType>(data.payload, request.href);
return new SubmissionSuccessResponse(dataDefinition[Object.keys(dataDefinition)[0]], data.statusCode, data.statusText, this.processPageInfo(data.payload)); return new SubmissionSuccessResponse(dataDefinition, data.statusCode, data.statusText, this.processPageInfo(data.payload));
} else if (isEmpty(data.payload) && data.statusCode === 204) { } else if (isEmpty(data.payload) && data.statusCode === 204) {
// Response from a DELETE request // Response from a DELETE request
return new SubmissionSuccessResponse(null, data.statusCode, data.statusText); return new SubmissionSuccessResponse(null, data.statusCode, data.statusText);
@@ -49,11 +52,13 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
} }
} }
protected processResponse<ObjectDomain, ObjectType>(data: any, requestHref: string): ProcessRequestDTO<ObjectDomain> { protected processResponse<ObjectDomain, ObjectType>(data: any, requestHref: string): any[] {
const dataDefinition = this.process<NormalizedObject | ConfigObject, SubmissionResourceType>(data, requestHref); const dataDefinition = this.process<NormalizedObject | ConfigObject, SubmissionResourceType>(data, requestHref);
const normalizedDefinition = Object.create({}); const normalizedDefinition = Array.of();
normalizedDefinition[Object.keys(dataDefinition)[0]] = []; const processedList = Array.isArray(dataDefinition) ? dataDefinition : Array.of(dataDefinition);
dataDefinition[Object.keys(dataDefinition)[0]].forEach((item, index) => {
processedList.forEach((item, index) => {
let normalizedItem = Object.assign({}, item); let normalizedItem = Object.assign({}, item);
// In case data is an Instance of NormalizedWorkspaceItem normalize field value of all the section of type form // In case data is an Instance of NormalizedWorkspaceItem normalize field value of all the section of type form
if (item instanceof NormalizedWorkspaceItem if (item instanceof NormalizedWorkspaceItem
@@ -90,10 +95,10 @@ export class SubmissionResponseParsingService extends BaseResponseParsingService
normalizedItem = Object.assign({}, item, {sections: precessedSection}); normalizedItem = Object.assign({}, item, {sections: precessedSection});
} }
} }
normalizedDefinition[Object.keys(dataDefinition)[0]][index] = normalizedItem; normalizedDefinition.push( normalizedItem);
}); });
return normalizedDefinition as ProcessRequestDTO<ObjectDomain>; return normalizedDefinition;
} }
} }

View File

@@ -12,6 +12,7 @@ import { RequestService } from '../data/request.service';
import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model'; import { NormalizedWorkflowItem } from './models/normalized-workflowitem.model';
import { Workflowitem } from './models/workflowitem.model'; import { Workflowitem } from './models/workflowitem.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { FindAllOptions } from '../data/request.models';
@Injectable() @Injectable()
export class WorkflowitemDataService extends DataService<NormalizedWorkflowItem, Workflowitem> { export class WorkflowitemDataService extends DataService<NormalizedWorkflowItem, Workflowitem> {
@@ -28,7 +29,7 @@ export class WorkflowitemDataService extends DataService<NormalizedWorkflowItem,
super(); super();
} }
public getScopedEndpoint(scopeID: string): Observable<string> { public getBrowseEndpoint(options: FindAllOptions) {
return this.halService.getEndpoint(this.linkPath); return this.halService.getEndpoint(this.linkPath);
} }

View File

@@ -12,6 +12,7 @@ import { RequestService } from '../data/request.service';
import { Workspaceitem } from './models/workspaceitem.model'; import { Workspaceitem } from './models/workspaceitem.model';
import { NormalizedWorkspaceItem } from './models/normalized-workspaceitem.model'; import { NormalizedWorkspaceItem } from './models/normalized-workspaceitem.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { FindAllOptions } from '../data/request.models';
@Injectable() @Injectable()
export class WorkspaceitemDataService extends DataService<NormalizedWorkspaceItem, Workspaceitem> { export class WorkspaceitemDataService extends DataService<NormalizedWorkspaceItem, Workspaceitem> {
@@ -28,7 +29,7 @@ export class WorkspaceitemDataService extends DataService<NormalizedWorkspaceIte
super(); super();
} }
public getScopedEndpoint(scopeID: string): Observable<string> { public getBrowseEndpoint(options: FindAllOptions) {
return this.halService.getEndpoint(this.linkPath); return this.halService.getEndpoint(this.linkPath);
} }

View File

@@ -1,4 +1,4 @@
<div *ngIf="!dismissed" class="alert {{type}} alert-dismissible fade show" role="alert" [@enterLeave]="animate"> <div *ngIf="!dismissed" class="alert {{type}} alert-dismissible fade show w-100" role="alert" [@enterLeave]="animate">
<span *ngIf="content" [innerHTML]="content | translate"></span> <span *ngIf="content" [innerHTML]="content | translate"></span>
<ng-content></ng-content> <ng-content></ng-content>

View File

@@ -10,6 +10,7 @@ import { SubmissionService } from '../submission.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { SubmissionObject } from '../../core/submission/models/submission-object.model'; import { SubmissionObject } from '../../core/submission/models/submission-object.model';
import { Collection } from '../../core/shared/collection.model';
@Component({ @Component({
selector: 'ds-submission-edit', selector: 'ds-submission-edit',
@@ -51,10 +52,10 @@ export class SubmissionEditComponent implements OnDestroy, OnInit {
this.notificationsService.info(null, this.translate.get('submission.general.cannot_submit')); this.notificationsService.info(null, this.translate.get('submission.general.cannot_submit'));
this.router.navigate(['/mydspace']); this.router.navigate(['/mydspace']);
} else { } else {
this.collectionId = submissionObject.collection[0].id; this.collectionId = (submissionObject.collection as Collection).id;
this.selfUrl = submissionObject.self; this.selfUrl = submissionObject.self;
this.sections = submissionObject.sections; this.sections = submissionObject.sections;
this.submissionDefinition = submissionObject.submissionDefinition[0]; this.submissionDefinition = (submissionObject.submissionDefinition as SubmissionDefinitionsModel);
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
} }
} }

View File

@@ -93,9 +93,9 @@ export class SubmissionFormCollectionComponent implements OnChanges, OnInit {
.subscribe((communityData: Community) => { .subscribe((communityData: Community) => {
this.subs.push(communityData.collections this.subs.push(communityData.collections
.filter((collections: RemoteData<Collection[]>) => !collections.isResponsePending && collections.hasSucceeded) .filter((collections: RemoteData<PaginatedList<Collection>>) => !collections.isResponsePending && collections.hasSucceeded)
.first() .first()
.switchMap((collections: RemoteData<Collection[]>) => collections.payload) .switchMap((collections: RemoteData<PaginatedList<Collection>>) => collections.payload.page)
.filter((collectionData: Collection) => isNotEmpty(collectionData)) .filter((collectionData: Collection) => isNotEmpty(collectionData))
.subscribe((collectionData: Collection) => { .subscribe((collectionData: Collection) => {
if (collectionData.id === this.selectedCollectionId) { if (collectionData.id === this.selectedCollectionId) {

View File

@@ -11,6 +11,8 @@ import { Observable } from 'rxjs/Observable';
import { SectionDataObject } from '../sections/models/section-data.model'; import { SectionDataObject } from '../sections/models/section-data.model';
import { UploaderOptions } from '../../shared/uploader/uploader-options.model'; import { UploaderOptions } from '../../shared/uploader/uploader-options.model';
import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service';
import { Collection } from '../../core/shared/collection.model';
import { SubmissionObject } from '../../core/submission/models/submission-object.model';
@Component({ @Component({
selector: 'ds-submission-submit-form', selector: 'ds-submission-submit-form',
@@ -99,16 +101,16 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
.forEach((subscription) => subscription.unsubscribe()); .forEach((subscription) => subscription.unsubscribe());
} }
onCollectionChange(workspaceItemObject: Workspaceitem) { onCollectionChange(submissionObject: SubmissionObject) {
this.collectionId = workspaceItemObject.collection[0].id; this.collectionId = (submissionObject.collection as Collection).id;
if (this.definitionId !== workspaceItemObject.submissionDefinition[0].name) { if (this.definitionId !== submissionObject.submissionDefinition.name) {
this.sections = workspaceItemObject.sections; this.sections = submissionObject.sections;
this.submissionDefinition = workspaceItemObject.submissionDefinition[0]; this.submissionDefinition = submissionObject.submissionDefinition;
this.definitionId = this.submissionDefinition.name; this.definitionId = this.submissionDefinition.name;
this.submissionService.resetSubmissionObject( this.submissionService.resetSubmissionObject(
this.collectionId, this.collectionId,
this.submissionId, this.submissionId,
workspaceItemObject.self, submissionObject.self,
this.submissionDefinition, this.submissionDefinition,
this.sections); this.sections);
} else { } else {
@@ -117,7 +119,6 @@ export class SubmissionFormComponent implements OnChanges, OnDestroy {
} }
isLoading(): Observable<boolean> { isLoading(): Observable<boolean> {
// return isUndefined(this.loading) || this.loading === true;
return this.loading; return this.loading;
} }

View File

@@ -54,7 +54,7 @@ export class SubmissionObjectEffects {
.map((action: InitSubmissionFormAction) => { .map((action: InitSubmissionFormAction) => {
const definition = action.payload.submissionDefinition; const definition = action.payload.submissionDefinition;
const mappedActions = []; const mappedActions = [];
definition.sections.forEach((sectionDefinition: SubmissionSectionModel, index: number) => { definition.sections.page.forEach((sectionDefinition: SubmissionSectionModel, index: number) => {
const sectionId = sectionDefinition._links.self.substr(sectionDefinition._links.self.lastIndexOf('/') + 1); const sectionId = sectionDefinition._links.self.substr(sectionDefinition._links.self.lastIndexOf('/') + 1);
const config = sectionDefinition._links.config || ''; const config = sectionDefinition._links.config || '';
const enabled = (sectionDefinition.mandatory && sectionDefinition.sectionType !== SectionsType.DetectDuplicate) || (isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId)); const enabled = (sectionDefinition.mandatory && sectionDefinition.sectionType !== SectionsType.DetectDuplicate) || (isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId));

View File

@@ -8,3 +8,10 @@
border-radius: $border-radius; border-radius: $border-radius;
box-shadow: $btn-focus-box-shadow; box-shadow: $btn-focus-box-shadow;
} }
// TODO to remove the following when upgrading @ng-bootstrap
:host /deep/ .card:first-of-type {
border-bottom: $card-border-width solid $card-border-color !important;
border-bottom-left-radius: $card-border-radius !important;
border-bottom-right-radius: $card-border-radius !important;
}

View File

@@ -1,7 +1,7 @@
<ds-item-list-preview <!--<ds-item-list-preview
[item]="item" [item]="item"
[object]="object" [object]="object"
></ds-item-list-preview> ></ds-item-list-preview>-->
<div *ngIf="isWorkFlow" class="mt-2"> <div *ngIf="isWorkFlow" class="mt-2">
<form> <form>

View File

@@ -71,7 +71,7 @@ export class FormSectionComponent extends SectionModelComponent implements OnDes
this.formId = this.formService.getUniqueId(this.sectionData.id); this.formId = this.formService.getUniqueId(this.sectionData.id);
this.formConfigService.getConfigByHref(this.sectionData.config) this.formConfigService.getConfigByHref(this.sectionData.config)
.flatMap((config: ConfigData) => config.payload) .map((config: ConfigData) => config.payload)
.subscribe((config: SubmissionFormsModel) => { .subscribe((config: SubmissionFormsModel) => {
this.formConfig = config; this.formConfig = config;
this.sectionService.getSectionData(this.submissionId, this.sectionData.id) this.sectionService.getSectionData(this.submissionId, this.sectionData.id)

View File

@@ -19,6 +19,10 @@ import { RemoteData } from '../../../core/data/remote-data';
import { Group } from '../../../core/eperson/models/group.model'; import { Group } from '../../../core/eperson/models/group.model';
import { SectionsService } from '../sections.service'; import { SectionsService } from '../sections.service';
import { SubmissionService } from '../../submission.service'; import { SubmissionService } from '../../submission.service';
import { Collection } from '../../../core/shared/collection.model';
import { PaginatedList } from '../../../core/data/paginated-list';
import { ResourcePolicy } from '../../../core/shared/resource-policy.model';
import { AccessConditionOption } from '../../../core/shared/config/config-access-condition-option.model';
export const POLICY_DEFAULT_NO_LIST = 1; // Banner1 export const POLICY_DEFAULT_NO_LIST = 1; // Banner1
export const POLICY_DEFAULT_WITH_LIST = 2; // Banner2 export const POLICY_DEFAULT_WITH_LIST = 2; // Banner2
@@ -53,7 +57,7 @@ export class UploadSectionComponent extends SectionModelComponent implements OnD
/* /*
* List of available access conditions that could be setted to files * List of available access conditions that could be setted to files
*/ */
public availableAccessConditionOptions: any[]; // List of accessConditions that an user can select public availableAccessConditionOptions: AccessConditionOption[]; // List of accessConditions that an user can select
/* /*
* List of Groups available for every access condition * List of Groups available for every access condition
@@ -76,11 +80,11 @@ export class UploadSectionComponent extends SectionModelComponent implements OnD
onSectionInit() { onSectionInit() {
const config$ = this.uploadsConfigService.getConfigByHref(this.sectionData.config) const config$ = this.uploadsConfigService.getConfigByHref(this.sectionData.config)
.flatMap((config) => config.payload); .map((config) => config.payload);
this.configMetadataForm$ = config$ this.configMetadataForm$ = config$
.take(1) .take(1)
.map((config: SubmissionUploadsModel) => config.metadata[0]); .map((config: SubmissionUploadsModel) => config.metadata);
this.subs.push( this.subs.push(
this.submissionService.getSubmissionObject(this.submissionId) this.submissionService.getSubmissionObject(this.submissionId)
@@ -89,26 +93,28 @@ export class UploadSectionComponent extends SectionModelComponent implements OnD
.subscribe((submissionObject: SubmissionObjectEntry) => { .subscribe((submissionObject: SubmissionObjectEntry) => {
this.collectionId = submissionObject.collection; this.collectionId = submissionObject.collection;
this.collectionDataService.findById(this.collectionId) this.collectionDataService.findById(this.collectionId)
.filter((collectionData) => isNotUndefined((collectionData.payload))) .filter((rd: RemoteData<Collection>) => isNotUndefined((rd.payload)))
.take(1) .take(1)
.subscribe((collectionData) => { .subscribe((collectionRemoteData: RemoteData<Collection>) => {
this.collectionName = collectionData.payload.name; this.collectionName = collectionRemoteData.payload.name;
// Default Access Conditions // Default Access Conditions
this.subs.push(collectionData.payload.defaultAccessConditions this.subs.push(collectionRemoteData.payload.defaultAccessConditions
.filter((accessConditions) => isNotUndefined((accessConditions.payload))) .filter((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) =>
defaultAccessConditionsRemoteData.hasSucceeded)
.take(1) .take(1)
.subscribe((defaultAccessConditions) => { .subscribe((defaultAccessConditionsRemoteData: RemoteData<PaginatedList<ResourcePolicy>>) => {
if (isNotEmpty(defaultAccessConditions.payload)) { if (isNotEmpty(defaultAccessConditionsRemoteData.payload)) {
this.collectionDefaultAccessConditions = Array.isArray(defaultAccessConditions.payload) this.collectionDefaultAccessConditions = Array.isArray(defaultAccessConditionsRemoteData.payload.page)
? defaultAccessConditions.payload : [defaultAccessConditions.payload]; ? defaultAccessConditionsRemoteData.payload.page : [defaultAccessConditionsRemoteData.payload.page];
} }
// Edit Form Configuration, access policy list // Edit Form Configuration, access policy list
this.subs.push(config$ this.subs.push(config$
.take(1) .take(1)
.subscribe((config: SubmissionUploadsModel) => { .subscribe((config: SubmissionUploadsModel) => {
this.availableAccessConditionOptions = isNotEmpty(config.accessConditionOptions) ? config.accessConditionOptions : []; this.availableAccessConditionOptions = isNotEmpty(config.accessConditionOptions) ? config.accessConditionOptions : [];
this.collectionPolicyType = this.availableAccessConditionOptions.length > 0 this.collectionPolicyType = this.availableAccessConditionOptions.length > 0
@@ -118,7 +124,7 @@ export class UploadSectionComponent extends SectionModelComponent implements OnD
this.availableGroups = new Map(); this.availableGroups = new Map();
const groupsObs = []; const groupsObs = [];
// Retrieve Groups for accessConditionPolicies // Retrieve Groups for accessConditionPolicies
this.availableAccessConditionOptions.forEach((accessCondition) => { this.availableAccessConditionOptions.forEach((accessCondition: AccessConditionOption) => {
if (accessCondition.hasEndDate === true || accessCondition.hasStartDate === true) { if (accessCondition.hasEndDate === true || accessCondition.hasStartDate === true) {
groupsObs.push( groupsObs.push(
this.groupService.findById(accessCondition.groupUUID) this.groupService.findById(accessCondition.groupUUID)

View File

@@ -5,12 +5,7 @@ import { Store } from '@ngrx/store';
import { ResponseCacheService } from '../core/cache/response-cache.service'; import { ResponseCacheService } from '../core/cache/response-cache.service';
import { RequestService } from '../core/data/request.service'; import { RequestService } from '../core/data/request.service';
import { ResponseCacheEntry } from '../core/cache/response-cache.reducer'; import { ResponseCacheEntry } from '../core/cache/response-cache.reducer';
import { import { ErrorResponse, RestResponse, SubmissionSuccessResponse } from '../core/cache/response-cache.models';
ErrorResponse,
PostPatchSuccessResponse,
RestResponse,
SubmissionSuccessResponse
} from '../core/cache/response-cache.models';
import { isNotEmpty } from '../shared/empty.util'; import { isNotEmpty } from '../shared/empty.util';
import { import {
ConfigRequest, ConfigRequest,
@@ -26,12 +21,14 @@ import { SubmitDataResponseDefinitionObject } from '../core/shared/submit-data-r
import { CoreState } from '../core/core.reducers'; import { CoreState } from '../core/core.reducers';
import { HttpOptions } from '../core/dspace-rest-v2/dspace-rest-v2.service'; import { HttpOptions } from '../core/dspace-rest-v2/dspace-rest-v2.service';
import { HALEndpointService } from '../core/shared/hal-endpoint.service'; import { HALEndpointService } from '../core/shared/hal-endpoint.service';
import { RemoteDataBuildService } from '../core/cache/builders/remote-data-build.service';
@Injectable() @Injectable()
export class SubmissionRestService { export class SubmissionRestService {
protected linkPath = 'workspaceitems'; protected linkPath = 'workspaceitems';
constructor( constructor(
protected rdbService: RemoteDataBuildService,
protected responseCache: ResponseCacheService, protected responseCache: ResponseCacheService,
protected requestService: RequestService, protected requestService: RequestService,
protected store: Store<CoreState>, protected store: Store<CoreState>,
@@ -46,8 +43,8 @@ export class SubmissionRestService {
errorResponse.flatMap((response: ErrorResponse) => errorResponse.flatMap((response: ErrorResponse) =>
Observable.throw(new Error(`Couldn't send data to server`))), Observable.throw(new Error(`Couldn't send data to server`))),
successResponse successResponse
.filter((response: PostPatchSuccessResponse) => isNotEmpty(response)) .filter((response: SubmissionSuccessResponse) => isNotEmpty(response))
.map((response: PostPatchSuccessResponse) => response.dataDefinition) .map((response: SubmissionSuccessResponse) => response.dataDefinition)
.distinctUntilChanged()); .distinctUntilChanged());
} }

View File

@@ -60,7 +60,7 @@ export class SubmissionService {
createSubmission(): Observable<SubmissionObject> { createSubmission(): Observable<SubmissionObject> {
return this.restService.postToEndpoint('workspaceitems', {}) return this.restService.postToEndpoint('workspaceitems', {})
.map((workspaceitems) => workspaceitems[0]) .map((workspaceitem: SubmissionObject) => workspaceitem[0])
.catch(() => Observable.of({})) .catch(() => Observable.of({}))
} }

View File

@@ -9,6 +9,7 @@ import { TranslateService } from '@ngx-translate/core';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { SubmissionService } from '../submission.service'; import { SubmissionService } from '../submission.service';
import { SubmissionObject } from '../../core/submission/models/submission-object.model'; import { SubmissionObject } from '../../core/submission/models/submission-object.model';
import { Collection } from '../../core/shared/collection.model';
@Component({ @Component({
selector: 'ds-submit-page', selector: 'ds-submit-page',
@@ -44,9 +45,9 @@ export class SubmissionSubmitComponent implements OnDestroy, OnInit {
this.notificationsService.info(null, this.translate.get('submission.general.cannot_submit')); this.notificationsService.info(null, this.translate.get('submission.general.cannot_submit'));
this.router.navigate(['/mydspace']); this.router.navigate(['/mydspace']);
} else { } else {
this.collectionId = submissionObject.collection[0].id; this.collectionId = (submissionObject.collection as Collection).id;
this.selfUrl = submissionObject.self; this.selfUrl = submissionObject.self;
this.submissionDefinition = submissionObject.submissionDefinition[0]; this.submissionDefinition = (submissionObject.submissionDefinition as SubmissionDefinitionsModel);
this.submissionId = submissionObject.id; this.submissionId = submissionObject.id;
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
} }