mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
70834: refactor createOrUpdate methods to use existing data-service methods
This commit is contained in:
@@ -140,7 +140,7 @@ export class MetadataSchemaFormComponent implements OnInit, OnDestroy {
|
|||||||
this.submitForm.emit(newSchema);
|
this.submitForm.emit(newSchema);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.registryService.createOrUpdateMetadataSchema(Object.assign(new MetadataSchema(), {
|
this.registryService.createOrUpdateMetadataSchema(Object.assign(new MetadataSchema(), schema, {
|
||||||
id: schema.id,
|
id: schema.id,
|
||||||
prefix: (values.prefix ? values.prefix : schema.prefix),
|
prefix: (values.prefix ? values.prefix : schema.prefix),
|
||||||
namespace: (values.namespace ? values.namespace : schema.namespace)
|
namespace: (values.namespace ? values.namespace : schema.namespace)
|
||||||
|
@@ -167,7 +167,7 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
this.submitForm.emit(newField);
|
this.submitForm.emit(newField);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.registryService.createOrUpdateMetadataField(Object.assign(new MetadataField(), {
|
this.registryService.createOrUpdateMetadataField(Object.assign(new MetadataField(), field, {
|
||||||
id: field.id,
|
id: field.id,
|
||||||
schema: this.metadataSchema,
|
schema: this.metadataSchema,
|
||||||
element: (values.element ? values.element : field.element),
|
element: (values.element ? values.element : field.element),
|
||||||
|
@@ -69,8 +69,6 @@ import { ItemDataService } from './data/item-data.service';
|
|||||||
import { LicenseDataService } from './data/license-data.service';
|
import { LicenseDataService } from './data/license-data.service';
|
||||||
import { LookupRelationService } from './data/lookup-relation.service';
|
import { LookupRelationService } from './data/lookup-relation.service';
|
||||||
import { MappedCollectionsReponseParsingService } from './data/mapped-collections-reponse-parsing.service';
|
import { MappedCollectionsReponseParsingService } from './data/mapped-collections-reponse-parsing.service';
|
||||||
import { MetadatafieldParsingService } from './data/metadatafield-parsing.service';
|
|
||||||
import { MetadataschemaParsingService } from './data/metadataschema-parsing.service';
|
|
||||||
import { MyDSpaceResponseParsingService } from './data/mydspace-response-parsing.service';
|
import { MyDSpaceResponseParsingService } from './data/mydspace-response-parsing.service';
|
||||||
import { ObjectUpdatesService } from './data/object-updates/object-updates.service';
|
import { ObjectUpdatesService } from './data/object-updates/object-updates.service';
|
||||||
import { RelationshipTypeService } from './data/relationship-type.service';
|
import { RelationshipTypeService } from './data/relationship-type.service';
|
||||||
@@ -219,8 +217,6 @@ const PROVIDERS = [
|
|||||||
JsonPatchOperationsBuilder,
|
JsonPatchOperationsBuilder,
|
||||||
AuthorityService,
|
AuthorityService,
|
||||||
IntegrationResponseParsingService,
|
IntegrationResponseParsingService,
|
||||||
MetadataschemaParsingService,
|
|
||||||
MetadatafieldParsingService,
|
|
||||||
UploaderService,
|
UploaderService,
|
||||||
UUIDService,
|
UUIDService,
|
||||||
NotificationsService,
|
NotificationsService,
|
||||||
|
@@ -45,11 +45,12 @@ import {
|
|||||||
FindListOptions,
|
FindListOptions,
|
||||||
FindListRequest,
|
FindListRequest,
|
||||||
GetRequest,
|
GetRequest,
|
||||||
PatchRequest
|
PatchRequest, PutRequest
|
||||||
} from './request.models';
|
} from './request.models';
|
||||||
import { RequestEntry } from './request.reducer';
|
import { RequestEntry } from './request.reducer';
|
||||||
import { RequestService } from './request.service';
|
import { RequestService } from './request.service';
|
||||||
import { RestRequestMethod } from './rest-request-method';
|
import { RestRequestMethod } from './rest-request-method';
|
||||||
|
import { GenericConstructor } from '../shared/generic-constructor';
|
||||||
|
|
||||||
export abstract class DataService<T extends CacheableObject> {
|
export abstract class DataService<T extends CacheableObject> {
|
||||||
protected abstract requestService: RequestService;
|
protected abstract requestService: RequestService;
|
||||||
@@ -354,6 +355,28 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a PUT request for the specified object
|
||||||
|
*
|
||||||
|
* @param object The object to send a put request for.
|
||||||
|
*/
|
||||||
|
put(object: T): Observable<RemoteData<T>> {
|
||||||
|
const requestId = this.requestService.generateRequestId();
|
||||||
|
const serializedObject = new DSpaceSerializer(object.constructor as GenericConstructor<{}>).serialize(object);
|
||||||
|
const request = new PutRequest(requestId, object._links.self.href, serializedObject);
|
||||||
|
|
||||||
|
if (hasValue(this.responseMsToLive)) {
|
||||||
|
request.responseMsToLive = this.responseMsToLive;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.requestService.configure(request);
|
||||||
|
|
||||||
|
return this.requestService.getByUUID(requestId).pipe(
|
||||||
|
find((re: RequestEntry) => hasValue(re) && re.completed),
|
||||||
|
switchMap(() => this.findByHref(object._links.self.href))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new patch to the object cache
|
* Add a new patch to the object cache
|
||||||
* The patch is derived from the differences between the given object and its version in the object cache
|
* The patch is derived from the differences between the given object and its version in the object cache
|
||||||
@@ -374,6 +397,18 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the endpoint for creating a new object
|
||||||
|
* @param parentUUID The parent object's UUID
|
||||||
|
*/
|
||||||
|
getCreateHref(parentUUID: string): Observable<string> {
|
||||||
|
return this.halService.getEndpoint(this.linkPath).pipe(
|
||||||
|
isNotEmptyOperator(),
|
||||||
|
distinctUntilChanged(),
|
||||||
|
map((endpoint: string) => parentUUID ? `${endpoint}?parent=${parentUUID}` : endpoint)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new DSpaceObject on the server, and store the response
|
* Create a new DSpaceObject on the server, and store the response
|
||||||
* in the object cache
|
* in the object cache
|
||||||
@@ -385,11 +420,7 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
*/
|
*/
|
||||||
create(dso: T, parentUUID: string): Observable<RemoteData<T>> {
|
create(dso: T, parentUUID: string): Observable<RemoteData<T>> {
|
||||||
const requestId = this.requestService.generateRequestId();
|
const requestId = this.requestService.generateRequestId();
|
||||||
const endpoint$ = this.halService.getEndpoint(this.linkPath).pipe(
|
const endpoint$ = this.getCreateHref(parentUUID);
|
||||||
isNotEmptyOperator(),
|
|
||||||
distinctUntilChanged(),
|
|
||||||
map((endpoint: string) => parentUUID ? `${endpoint}?parent=${parentUUID}` : endpoint)
|
|
||||||
);
|
|
||||||
|
|
||||||
const serializedDso = new DSpaceSerializer(getClassForType((dso as any).type)).serialize(dso);
|
const serializedDso = new DSpaceSerializer(getClassForType((dso as any).type)).serialize(dso);
|
||||||
|
|
||||||
|
@@ -4,11 +4,13 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
|
|||||||
import { of as observableOf } from 'rxjs/internal/observable/of';
|
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||||
import { RestResponse } from '../cache/response.models';
|
import { RestResponse } from '../cache/response.models';
|
||||||
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
|
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
|
||||||
import { CreateMetadataFieldRequest, FindListOptions, UpdateMetadataFieldRequest } from './request.models';
|
import { CreateRequest, FindListOptions, PutRequest } from './request.models';
|
||||||
import { MetadataFieldDataService } from './metadata-field-data.service';
|
import { MetadataFieldDataService } from './metadata-field-data.service';
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
import { MetadataField } from '../metadata/metadata-field.model';
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
import { SearchParam } from '../cache/models/search-param.model';
|
import { SearchParam } from '../cache/models/search-param.model';
|
||||||
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||||
|
|
||||||
describe('MetadataFieldDataService', () => {
|
describe('MetadataFieldDataService', () => {
|
||||||
let metadataFieldService: MetadataFieldDataService;
|
let metadataFieldService: MetadataFieldDataService;
|
||||||
@@ -16,13 +18,17 @@ describe('MetadataFieldDataService', () => {
|
|||||||
let halService: HALEndpointService;
|
let halService: HALEndpointService;
|
||||||
let notificationsService: NotificationsService;
|
let notificationsService: NotificationsService;
|
||||||
let schema: MetadataSchema;
|
let schema: MetadataSchema;
|
||||||
|
let rdbService: RemoteDataBuildService;
|
||||||
|
|
||||||
const endpoint = 'api/metadatafield/endpoint';
|
const endpoint = 'api/metadatafield/endpoint';
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
schema = Object.assign(new MetadataSchema(), {
|
schema = Object.assign(new MetadataSchema(), {
|
||||||
prefix: 'dc',
|
prefix: 'dc',
|
||||||
namespace: 'namespace'
|
namespace: 'namespace',
|
||||||
|
_links: {
|
||||||
|
self: { href: 'selflink' }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
requestService = jasmine.createSpyObj('requestService', {
|
requestService = jasmine.createSpyObj('requestService', {
|
||||||
generateRequestId: '34cfed7c-f597-49ef-9cbe-ea351f0023c2',
|
generateRequestId: '34cfed7c-f597-49ef-9cbe-ea351f0023c2',
|
||||||
@@ -34,7 +40,10 @@ describe('MetadataFieldDataService', () => {
|
|||||||
notificationsService = jasmine.createSpyObj('notificationsService', {
|
notificationsService = jasmine.createSpyObj('notificationsService', {
|
||||||
error: {}
|
error: {}
|
||||||
});
|
});
|
||||||
metadataFieldService = new MetadataFieldDataService(requestService, undefined, undefined, halService, undefined, undefined, undefined, notificationsService);
|
rdbService = jasmine.createSpyObj('rdbService', {
|
||||||
|
buildSingle: createSuccessfulRemoteDataObject$(undefined)
|
||||||
|
});
|
||||||
|
metadataFieldService = new MetadataFieldDataService(requestService, rdbService, undefined, halService, undefined, undefined, undefined, notificationsService);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -62,14 +71,17 @@ describe('MetadataFieldDataService', () => {
|
|||||||
field = Object.assign(new MetadataField(), {
|
field = Object.assign(new MetadataField(), {
|
||||||
element: 'identifier',
|
element: 'identifier',
|
||||||
qualifier: undefined,
|
qualifier: undefined,
|
||||||
schema: schema
|
schema: schema,
|
||||||
|
_links: {
|
||||||
|
self: { href: 'selflink' }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('called with a new metadata field', () => {
|
describe('called with a new metadata field', () => {
|
||||||
it('should send a CreateMetadataFieldRequest', (done) => {
|
it('should send a CreateRequest', (done) => {
|
||||||
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
||||||
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(CreateMetadataFieldRequest));
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(CreateRequest));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -82,9 +94,9 @@ describe('MetadataFieldDataService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send a UpdateMetadataFieldRequest', (done) => {
|
it('should send a PutRequest', (done) => {
|
||||||
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
||||||
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(UpdateMetadataFieldRequest));
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(PutRequest));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -8,21 +8,18 @@ import { CoreState } from '../core.reducers';
|
|||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { METADATA_FIELD } from '../metadata/metadata-field.resource-type';
|
import { METADATA_FIELD } from '../metadata/metadata-field.resource-type';
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
import { MetadataField } from '../metadata/metadata-field.model';
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
import { CreateMetadataFieldRequest, FindListOptions, UpdateMetadataFieldRequest } from './request.models';
|
import { FindListOptions } from './request.models';
|
||||||
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
import { SearchParam } from '../cache/models/search-param.model';
|
import { SearchParam } from '../cache/models/search-param.model';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
|
import { hasValue, isNotEmptyOperator } from '../../shared/empty.util';
|
||||||
import { distinctUntilChanged, map, take, tap } from 'rxjs/operators';
|
import { distinctUntilChanged, map, tap } from 'rxjs/operators';
|
||||||
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
import { RemoteData } from './remote-data';
|
||||||
import { configureRequest, getResponseFromEntry } from '../shared/operators';
|
|
||||||
import { MetadatafieldSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { NotificationOptions } from '../../shared/notifications/models/notification-options.model';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint
|
* A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint
|
||||||
@@ -62,52 +59,29 @@ export class MetadataFieldDataService extends DataService<MetadataField> {
|
|||||||
* Create or Update a MetadataField
|
* Create or Update a MetadataField
|
||||||
* If the MetadataField contains an id, it is assumed the field already exists and is updated instead
|
* If the MetadataField contains an id, it is assumed the field already exists and is updated instead
|
||||||
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
* - On creation, a CreateMetadataFieldRequest is used
|
* - On creation, a CreateRequest is used
|
||||||
* - On update, a UpdateMetadataFieldRequest is used
|
* - On update, a PutRequest is used
|
||||||
* @param field The MetadataField to create or update
|
* @param field The MetadataField to create or update
|
||||||
*/
|
*/
|
||||||
createOrUpdateMetadataField(field: MetadataField): Observable<RestResponse> {
|
createOrUpdateMetadataField(field: MetadataField): Observable<RemoteData<MetadataField>> {
|
||||||
const isUpdate = hasValue(field.id);
|
const isUpdate = hasValue(field.id);
|
||||||
const requestId = this.requestService.generateRequestId();
|
|
||||||
const endpoint$ = this.getBrowseEndpoint().pipe(
|
if (isUpdate) {
|
||||||
|
return this.put(field);
|
||||||
|
} else {
|
||||||
|
return this.create(field, `${field.schema.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the endpoint for creating a new object
|
||||||
|
* @param parentUUID The parent object's UUID
|
||||||
|
*/
|
||||||
|
getCreateHref(parentUUID: string): Observable<string> {
|
||||||
|
return this.halService.getEndpoint(this.linkPath).pipe(
|
||||||
isNotEmptyOperator(),
|
isNotEmptyOperator(),
|
||||||
map((endpoint: string) => (isUpdate ? `${endpoint}/${field.id}` : `${endpoint}?schemaId=${field.schema.id}`)),
|
distinctUntilChanged(),
|
||||||
distinctUntilChanged()
|
map((endpoint: string) => parentUUID ? `${endpoint}?schemaId=${parentUUID}` : endpoint)
|
||||||
);
|
|
||||||
|
|
||||||
const request$ = endpoint$.pipe(
|
|
||||||
take(1),
|
|
||||||
map((endpoint: string) => {
|
|
||||||
if (isUpdate) {
|
|
||||||
const options: HttpOptions = Object.create({});
|
|
||||||
let headers = new HttpHeaders();
|
|
||||||
headers = headers.append('Content-Type', 'application/json');
|
|
||||||
options.headers = headers;
|
|
||||||
return new UpdateMetadataFieldRequest(requestId, endpoint, JSON.stringify(field), options);
|
|
||||||
} else {
|
|
||||||
return new CreateMetadataFieldRequest(requestId, endpoint, JSON.stringify(field));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Execute the post/put request
|
|
||||||
request$.pipe(
|
|
||||||
configureRequest(this.requestService)
|
|
||||||
).subscribe();
|
|
||||||
|
|
||||||
// Return response
|
|
||||||
return this.requestService.getByUUID(requestId).pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RestResponse) => {
|
|
||||||
if (!response.isSuccessful) {
|
|
||||||
if (hasValue((response as any).errorMessage)) {
|
|
||||||
this.notificationsService.error('Server Error:', (response as any).errorMessage, new NotificationOptions(-1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
isNotEmptyOperator()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,13 +6,16 @@ import { of as observableOf } from 'rxjs';
|
|||||||
import { RestResponse } from '../cache/response.models';
|
import { RestResponse } from '../cache/response.models';
|
||||||
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
|
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
import { CreateMetadataSchemaRequest, UpdateMetadataSchemaRequest } from './request.models';
|
import { CreateRequest, PutRequest } from './request.models';
|
||||||
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||||
|
|
||||||
describe('MetadataSchemaDataService', () => {
|
describe('MetadataSchemaDataService', () => {
|
||||||
let metadataSchemaService: MetadataSchemaDataService;
|
let metadataSchemaService: MetadataSchemaDataService;
|
||||||
let requestService: RequestService;
|
let requestService: RequestService;
|
||||||
let halService: HALEndpointService;
|
let halService: HALEndpointService;
|
||||||
let notificationsService: NotificationsService;
|
let notificationsService: NotificationsService;
|
||||||
|
let rdbService: RemoteDataBuildService;
|
||||||
|
|
||||||
const endpoint = 'api/metadataschema/endpoint';
|
const endpoint = 'api/metadataschema/endpoint';
|
||||||
|
|
||||||
@@ -27,7 +30,10 @@ describe('MetadataSchemaDataService', () => {
|
|||||||
notificationsService = jasmine.createSpyObj('notificationsService', {
|
notificationsService = jasmine.createSpyObj('notificationsService', {
|
||||||
error: {}
|
error: {}
|
||||||
});
|
});
|
||||||
metadataSchemaService = new MetadataSchemaDataService(requestService, undefined, undefined, halService, undefined, undefined, undefined, notificationsService);
|
rdbService = jasmine.createSpyObj('rdbService', {
|
||||||
|
buildSingle: createSuccessfulRemoteDataObject$(undefined)
|
||||||
|
});
|
||||||
|
metadataSchemaService = new MetadataSchemaDataService(requestService, rdbService, undefined, halService, undefined, undefined, undefined, notificationsService);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -40,14 +46,17 @@ describe('MetadataSchemaDataService', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
schema = Object.assign(new MetadataSchema(), {
|
schema = Object.assign(new MetadataSchema(), {
|
||||||
prefix: 'dc',
|
prefix: 'dc',
|
||||||
namespace: 'namespace'
|
namespace: 'namespace',
|
||||||
|
_links: {
|
||||||
|
self: { href: 'selflink' }
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('called with a new metadata schema', () => {
|
describe('called with a new metadata schema', () => {
|
||||||
it('should send a CreateMetadataSchemaRequest', (done) => {
|
it('should send a CreateRequest', (done) => {
|
||||||
metadataSchemaService.createOrUpdateMetadataSchema(schema).subscribe(() => {
|
metadataSchemaService.createOrUpdateMetadataSchema(schema).subscribe(() => {
|
||||||
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(CreateMetadataSchemaRequest));
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(CreateRequest));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -60,9 +69,9 @@ describe('MetadataSchemaDataService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send a UpdateMetadataSchemaRequest', (done) => {
|
it('should send a PutRequest', (done) => {
|
||||||
metadataSchemaService.createOrUpdateMetadataSchema(schema).subscribe(() => {
|
metadataSchemaService.createOrUpdateMetadataSchema(schema).subscribe(() => {
|
||||||
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(UpdateMetadataSchemaRequest));
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(PutRequest));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { dataService, getClassForType } from '../cache/builders/build-decorators';
|
import { dataService } from '../cache/builders/build-decorators';
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { CoreState } from '../core.reducers';
|
import { CoreState } from '../core.reducers';
|
||||||
@@ -13,14 +13,9 @@ import { DataService } from './data.service';
|
|||||||
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
||||||
import { RequestService } from './request.service';
|
import { RequestService } from './request.service';
|
||||||
import { Observable } from 'rxjs/internal/Observable';
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
import { hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
|
import { hasValue } from '../../shared/empty.util';
|
||||||
import { distinctUntilChanged, map, take, tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
import { RemoteData } from './remote-data';
|
||||||
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
|
||||||
import { CreateMetadataSchemaRequest, UpdateMetadataSchemaRequest } from './request.models';
|
|
||||||
import { configureRequest, getResponseFromEntry } from '../shared/operators';
|
|
||||||
import { MetadataschemaSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { NotificationOptions } from '../../shared/notifications/models/notification-options.model';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint
|
* A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint
|
||||||
@@ -46,55 +41,18 @@ export class MetadataSchemaDataService extends DataService<MetadataSchema> {
|
|||||||
* Create or Update a MetadataSchema
|
* Create or Update a MetadataSchema
|
||||||
* If the MetadataSchema contains an id, it is assumed the schema already exists and is updated instead
|
* If the MetadataSchema contains an id, it is assumed the schema already exists and is updated instead
|
||||||
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
* - On creation, a CreateMetadataSchemaRequest is used
|
* - On creation, a CreateRequest is used
|
||||||
* - On update, a UpdateMetadataSchemaRequest is used
|
* - On update, a PutRequest is used
|
||||||
* @param schema The MetadataSchema to create or update
|
* @param schema The MetadataSchema to create or update
|
||||||
*/
|
*/
|
||||||
createOrUpdateMetadataSchema(schema: MetadataSchema): Observable<RestResponse> {
|
createOrUpdateMetadataSchema(schema: MetadataSchema): Observable<RemoteData<MetadataSchema>> {
|
||||||
const isUpdate = hasValue(schema.id);
|
const isUpdate = hasValue(schema.id);
|
||||||
const requestId = this.requestService.generateRequestId();
|
|
||||||
const endpoint$ = this.getBrowseEndpoint().pipe(
|
|
||||||
isNotEmptyOperator(),
|
|
||||||
map((endpoint: string) => (isUpdate ? `${endpoint}/${schema.id}` : endpoint)),
|
|
||||||
distinctUntilChanged()
|
|
||||||
);
|
|
||||||
|
|
||||||
const serializedSchema = new DSpaceSerializer(getClassForType(MetadataSchema.type)).serialize(schema);
|
if (isUpdate) {
|
||||||
|
return this.put(schema);
|
||||||
const request$ = endpoint$.pipe(
|
} else {
|
||||||
take(1),
|
return this.create(schema, undefined);
|
||||||
map((endpoint: string) => {
|
}
|
||||||
if (isUpdate) {
|
|
||||||
const options: HttpOptions = Object.create({});
|
|
||||||
let headers = new HttpHeaders();
|
|
||||||
headers = headers.append('Content-Type', 'application/json');
|
|
||||||
options.headers = headers;
|
|
||||||
return new UpdateMetadataSchemaRequest(requestId, endpoint, JSON.stringify(serializedSchema), options);
|
|
||||||
} else {
|
|
||||||
return new CreateMetadataSchemaRequest(requestId, endpoint, JSON.stringify(serializedSchema));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Execute the post/put request
|
|
||||||
request$.pipe(
|
|
||||||
configureRequest(this.requestService)
|
|
||||||
).subscribe();
|
|
||||||
|
|
||||||
// Return created/updated schema
|
|
||||||
return this.requestService.getByUUID(requestId).pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RestResponse) => {
|
|
||||||
if (!response.isSuccessful) {
|
|
||||||
if (hasValue((response as any).errorMessage)) {
|
|
||||||
this.notificationsService.error('Server Error:', (response as any).errorMessage, new NotificationOptions(-1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
isNotEmptyOperator()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { MetadatafieldSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
|
||||||
import { RestRequest } from './request.models';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A service responsible for parsing DSpaceRESTV2Response data related to a single MetadataField to a valid RestResponse
|
|
||||||
*/
|
|
||||||
@Injectable()
|
|
||||||
export class MetadatafieldParsingService implements ResponseParsingService {
|
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
|
||||||
const payload = data.payload;
|
|
||||||
|
|
||||||
const deserialized = new DSpaceSerializer(MetadataField).deserialize(payload);
|
|
||||||
return new MetadatafieldSuccessResponse(deserialized, data.statusCode, data.statusText);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { MetadataschemaSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
|
||||||
import { RestRequest } from './request.models';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class MetadataschemaParsingService implements ResponseParsingService {
|
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
|
||||||
const payload = data.payload;
|
|
||||||
|
|
||||||
const deserialized = new DSpaceSerializer(MetadataSchema).deserialize(payload);
|
|
||||||
return new MetadataschemaSuccessResponse(deserialized, data.statusCode, data.statusText);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -14,8 +14,6 @@ import { RestRequestMethod } from './rest-request-method';
|
|||||||
import { SearchParam } from '../cache/models/search-param.model';
|
import { SearchParam } from '../cache/models/search-param.model';
|
||||||
import { EpersonResponseParsingService } from '../eperson/eperson-response-parsing.service';
|
import { EpersonResponseParsingService } from '../eperson/eperson-response-parsing.service';
|
||||||
import { BrowseItemsResponseParsingService } from './browse-items-response-parsing-service';
|
import { BrowseItemsResponseParsingService } from './browse-items-response-parsing-service';
|
||||||
import { MetadataschemaParsingService } from './metadataschema-parsing.service';
|
|
||||||
import { MetadatafieldParsingService } from './metadatafield-parsing.service';
|
|
||||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||||
import { TaskResponseParsingService } from '../tasks/task-response-parsing.service';
|
import { TaskResponseParsingService } from '../tasks/task-response-parsing.service';
|
||||||
import { ContentSourceResponseParsingService } from './content-source-response-parsing.service';
|
import { ContentSourceResponseParsingService } from './content-source-response-parsing.service';
|
||||||
@@ -251,58 +249,6 @@ export class IntegrationRequest extends GetRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to create a MetadataSchema
|
|
||||||
*/
|
|
||||||
export class CreateMetadataSchemaRequest extends PostRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadataschemaParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to update a MetadataSchema
|
|
||||||
*/
|
|
||||||
export class UpdateMetadataSchemaRequest extends PutRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadataschemaParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to create a MetadataField
|
|
||||||
*/
|
|
||||||
export class CreateMetadataFieldRequest extends PostRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadatafieldParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to update a MetadataField
|
|
||||||
*/
|
|
||||||
export class UpdateMetadataFieldRequest extends PutRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadatafieldParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing a submission HTTP GET request object
|
* Class representing a submission HTTP GET request object
|
||||||
*/
|
*/
|
||||||
|
@@ -20,7 +20,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
|
|||||||
import { StoreMock } from '../../shared/testing/store.mock';
|
import { StoreMock } from '../../shared/testing/store.mock';
|
||||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
||||||
|
|
||||||
import { MetadatafieldSuccessResponse, MetadataschemaSuccessResponse, RestResponse } from '../cache/response.models';
|
import { RestResponse } from '../cache/response.models';
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
import { MetadataField } from '../metadata/metadata-field.model';
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
import { RegistryService } from './registry.service';
|
import { RegistryService } from './registry.service';
|
||||||
@@ -126,7 +126,7 @@ describe('RegistryService', () => {
|
|||||||
metadataSchemaService = jasmine.createSpyObj('metadataSchemaService', {
|
metadataSchemaService = jasmine.createSpyObj('metadataSchemaService', {
|
||||||
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockSchemasList)),
|
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockSchemasList)),
|
||||||
findById: createSuccessfulRemoteDataObject$(mockSchemasList[0]),
|
findById: createSuccessfulRemoteDataObject$(mockSchemasList[0]),
|
||||||
createOrUpdateMetadataSchema: observableOf(new MetadataschemaSuccessResponse(mockSchemasList[0], 200, 'OK')),
|
createOrUpdateMetadataSchema: createSuccessfulRemoteDataObject$(mockSchemasList[0]),
|
||||||
deleteAndReturnResponse: observableOf(new RestResponse(true, 200, 'OK')),
|
deleteAndReturnResponse: observableOf(new RestResponse(true, 200, 'OK')),
|
||||||
clearRequests: observableOf('href')
|
clearRequests: observableOf('href')
|
||||||
});
|
});
|
||||||
@@ -134,7 +134,7 @@ describe('RegistryService', () => {
|
|||||||
metadataFieldService = jasmine.createSpyObj('metadataFieldService', {
|
metadataFieldService = jasmine.createSpyObj('metadataFieldService', {
|
||||||
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockFieldsList)),
|
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockFieldsList)),
|
||||||
findById: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
findById: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||||
createOrUpdateMetadataField: observableOf(new MetadatafieldSuccessResponse(mockFieldsList[0], 200, 'OK')),
|
createOrUpdateMetadataField: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||||
deleteAndReturnResponse: observableOf(new RestResponse(true, 200, 'OK')),
|
deleteAndReturnResponse: observableOf(new RestResponse(true, 200, 'OK')),
|
||||||
clearRequests: observableOf('href')
|
clearRequests: observableOf('href')
|
||||||
});
|
});
|
||||||
|
@@ -12,8 +12,8 @@ import {
|
|||||||
RestResponse
|
RestResponse
|
||||||
} from '../cache/response.models';
|
} from '../cache/response.models';
|
||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util';
|
import { hasNoValue, hasValue, hasValueOperator, isNotEmpty } from '../../shared/empty.util';
|
||||||
import { getFirstSucceededRemoteDataPayload } from '../shared/operators';
|
import { getAllSucceededRemoteDataPayload, getFirstSucceededRemoteDataPayload } from '../shared/operators';
|
||||||
import { createSelector, select, Store } from '@ngrx/store';
|
import { createSelector, select, Store } from '@ngrx/store';
|
||||||
import { AppState } from '../../app.reducer';
|
import { AppState } from '../../app.reducer';
|
||||||
import { MetadataRegistryState } from '../../+admin/admin-registries/metadata-registry/metadata-registry.reducers';
|
import { MetadataRegistryState } from '../../+admin/admin-registries/metadata-registry/metadata-registry.reducers';
|
||||||
@@ -207,18 +207,17 @@ export class RegistryService {
|
|||||||
* Create or Update a MetadataSchema
|
* Create or Update a MetadataSchema
|
||||||
* If the MetadataSchema contains an id, it is assumed the schema already exists and is updated instead
|
* If the MetadataSchema contains an id, it is assumed the schema already exists and is updated instead
|
||||||
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
* - On creation, a CreateMetadataSchemaRequest is used
|
* - On creation, a CreateRequest is used
|
||||||
* - On update, a UpdateMetadataSchemaRequest is used
|
* - On update, a PutRequest is used
|
||||||
* @param schema The MetadataSchema to create or update
|
* @param schema The MetadataSchema to create or update
|
||||||
*/
|
*/
|
||||||
public createOrUpdateMetadataSchema(schema: MetadataSchema): Observable<MetadataSchema> {
|
public createOrUpdateMetadataSchema(schema: MetadataSchema): Observable<MetadataSchema> {
|
||||||
const isUpdate = hasValue(schema.id);
|
const isUpdate = hasValue(schema.id);
|
||||||
return this.metadataSchemaService.createOrUpdateMetadataSchema(schema).pipe(
|
return this.metadataSchemaService.createOrUpdateMetadataSchema(schema).pipe(
|
||||||
map((response: MetadataschemaSuccessResponse) => {
|
getFirstSucceededRemoteDataPayload(),
|
||||||
if (isNotEmpty(response.metadataschema)) {
|
hasValueOperator(),
|
||||||
this.showNotifications(true, isUpdate, false, {prefix: schema.prefix});
|
tap(() => {
|
||||||
return response.metadataschema;
|
this.showNotifications(true, isUpdate, false, {prefix: schema.prefix});
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -242,19 +241,18 @@ export class RegistryService {
|
|||||||
* Create or Update a MetadataField
|
* Create or Update a MetadataField
|
||||||
* If the MetadataField contains an id, it is assumed the field already exists and is updated instead
|
* If the MetadataField contains an id, it is assumed the field already exists and is updated instead
|
||||||
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
* - On creation, a CreateMetadataFieldRequest is used
|
* - On creation, a CreateRequest is used
|
||||||
* - On update, a UpdateMetadataFieldRequest is used
|
* - On update, a PutRequest is used
|
||||||
* @param field The MetadataField to create or update
|
* @param field The MetadataField to create or update
|
||||||
*/
|
*/
|
||||||
public createOrUpdateMetadataField(field: MetadataField): Observable<MetadataField> {
|
public createOrUpdateMetadataField(field: MetadataField): Observable<MetadataField> {
|
||||||
const isUpdate = hasValue(field.id);
|
const isUpdate = hasValue(field.id);
|
||||||
return this.metadataFieldService.createOrUpdateMetadataField(field).pipe(
|
return this.metadataFieldService.createOrUpdateMetadataField(field).pipe(
|
||||||
map((response: MetadatafieldSuccessResponse) => {
|
getFirstSucceededRemoteDataPayload(),
|
||||||
if (isNotEmpty(response.metadatafield)) {
|
hasValueOperator(),
|
||||||
const fieldString = `${field.schema.prefix}.${field.element}${field.qualifier ? `.${field.qualifier}` : ''}`;
|
tap(() => {
|
||||||
this.showNotifications(true, isUpdate, true, {field: fieldString});
|
const fieldString = `${field.schema.prefix}.${field.element}${field.qualifier ? `.${field.qualifier}` : ''}`;
|
||||||
return response.metadatafield;
|
this.showNotifications(true, isUpdate, true, {field: fieldString});
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user