mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
move schema on metadatafields to an observable remotedata
This commit is contained in:
@@ -157,19 +157,17 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
||||
this.registryService.getActiveMetadataField().pipe(take(1)).subscribe(
|
||||
(field) => {
|
||||
const values = {
|
||||
schema: this.metadataSchema,
|
||||
element: this.element.value,
|
||||
qualifier: this.qualifier.value,
|
||||
scopeNote: this.scopeNote.value
|
||||
};
|
||||
if (field == null) {
|
||||
this.registryService.createOrUpdateMetadataField(Object.assign(new MetadataField(), values)).subscribe((newField) => {
|
||||
this.registryService.createMetadataField(Object.assign(new MetadataField(), values), this.metadataSchema).subscribe((newField) => {
|
||||
this.submitForm.emit(newField);
|
||||
});
|
||||
} else {
|
||||
this.registryService.createOrUpdateMetadataField(Object.assign(new MetadataField(), field, {
|
||||
this.registryService.updateMetadataField(Object.assign(new MetadataField(), field, {
|
||||
id: field.id,
|
||||
schema: this.metadataSchema,
|
||||
element: (values.element ? values.element : field.element),
|
||||
qualifier: (values.qualifier ? values.qualifier : field.qualifier),
|
||||
scopeNote: (values.scopeNote ? values.scopeNote : field.scopeNote)
|
||||
|
@@ -61,7 +61,7 @@ describe('MetadataSchemaComponent', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'advisor',
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[0]
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[0])
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
@@ -73,7 +73,7 @@ describe('MetadataSchemaComponent', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'author',
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[0]
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[0])
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
@@ -85,7 +85,7 @@ describe('MetadataSchemaComponent', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'editor',
|
||||
scopeNote: 'test scope note',
|
||||
schema: mockSchemasList[1]
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[1])
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
@@ -97,15 +97,15 @@ describe('MetadataSchemaComponent', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'illustrator',
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[1]
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[1])
|
||||
}
|
||||
];
|
||||
const mockSchemas = createSuccessfulRemoteDataObject$(new PaginatedList(null, mockSchemasList));
|
||||
/* tslint:disable:no-empty */
|
||||
const registryServiceStub = {
|
||||
getMetadataSchemas: () => mockSchemas,
|
||||
getMetadataFieldsBySchema: (schema: MetadataSchema) => createSuccessfulRemoteDataObject$(new PaginatedList(null, mockFieldsList.filter((value) => value.schema === schema))),
|
||||
getMetadataSchemaByName: (schemaName: string) => createSuccessfulRemoteDataObject$(mockSchemasList.filter((value) => value.prefix === schemaName)[0]),
|
||||
getMetadataFieldsBySchema: (schema: MetadataSchema) => createSuccessfulRemoteDataObject$(new PaginatedList(null, mockFieldsList)),
|
||||
getMetadataSchemaByPrefix: (schemaName: string) => createSuccessfulRemoteDataObject$(mockSchemasList.filter((value) => value.prefix === schemaName)[0]),
|
||||
getActiveMetadataField: () => observableOf(undefined),
|
||||
getSelectedMetadataFields: () => observableOf([]),
|
||||
editMetadataField: (schema) => {},
|
||||
|
@@ -17,6 +17,7 @@ import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operato
|
||||
import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
|
||||
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
|
||||
import { followLink } from '../../../shared/utils/follow-link-config.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-schema',
|
||||
@@ -71,7 +72,7 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
* @param params
|
||||
*/
|
||||
initialize(params) {
|
||||
this.metadataSchema$ = this.registryService.getMetadataSchemaByName(params.schemaName).pipe(getFirstSucceededRemoteDataPayload());
|
||||
this.metadataSchema$ = this.registryService.getMetadataSchemaByPrefix(params.schemaName).pipe(getFirstSucceededRemoteDataPayload());
|
||||
this.updateFields();
|
||||
}
|
||||
|
||||
@@ -91,7 +92,7 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
this.metadataFields$ = combineLatest(this.metadataSchema$, this.needsUpdate$).pipe(
|
||||
switchMap(([schema, update]: [MetadataSchema, boolean]) => {
|
||||
if (update) {
|
||||
return this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config));
|
||||
return this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config), followLink('schema'));
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@@ -67,4 +67,4 @@
|
||||
<i class="fas fa-undo-alt fa-fw"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</td>
|
||||
|
@@ -58,7 +58,7 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
||||
metadataFieldSuggestions: BehaviorSubject<InputSuggestion[]> = new BehaviorSubject([]);
|
||||
|
||||
constructor(
|
||||
private metadataFieldService: RegistryService,
|
||||
private registryService: RegistryService,
|
||||
private objectUpdatesService: ObjectUpdatesService,
|
||||
) {
|
||||
}
|
||||
@@ -128,13 +128,13 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
||||
*/
|
||||
findMetadataFieldSuggestions(query: string): void {
|
||||
if (isNotEmpty(query)) {
|
||||
this.metadataFieldService.queryMetadataFields(query).pipe(
|
||||
this.registryService.queryMetadataFields(query).pipe(
|
||||
// getSucceededRemoteData(),
|
||||
take(1),
|
||||
map((data) => data.payload.page)
|
||||
).subscribe(
|
||||
(fields: MetadataField[]) => this.metadataFieldSuggestions.next(
|
||||
fields.filter((field: MetadataField) => field.schema.prefix !== 'relation' && field.schema.prefix !== 'relationship').map((field: MetadataField) => {
|
||||
fields.map((field: MetadataField) => {
|
||||
return {
|
||||
displayValue: field.toString().split('.').join('.​'),
|
||||
value: field.toString()
|
||||
|
@@ -64,45 +64,6 @@ describe('MetadataFieldDataService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('createOrUpdateMetadataField', () => {
|
||||
let field: MetadataField;
|
||||
|
||||
beforeEach(() => {
|
||||
field = Object.assign(new MetadataField(), {
|
||||
element: 'identifier',
|
||||
qualifier: undefined,
|
||||
schema: schema,
|
||||
_links: {
|
||||
self: { href: 'selflink' }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('called with a new metadata field', () => {
|
||||
it('should send a CreateRequest', (done) => {
|
||||
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
||||
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(CreateRequest));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('called with an existing metadata field', () => {
|
||||
beforeEach(() => {
|
||||
field = Object.assign(field, {
|
||||
id: 'id-of-existing-field'
|
||||
});
|
||||
});
|
||||
|
||||
it('should send a PutRequest', (done) => {
|
||||
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
||||
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(PutRequest));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('clearRequests', () => {
|
||||
it('should remove requests on the data service\'s endpoint', (done) => {
|
||||
metadataFieldService.clearRequests().subscribe(() => {
|
||||
|
@@ -21,6 +21,7 @@ import { find, skipWhile, switchMap, tap } from 'rxjs/operators';
|
||||
import { RemoteData } from './remote-data';
|
||||
import { RequestParam } from '../cache/models/request-param.model';
|
||||
import { PaginatedList } from './paginated-list';
|
||||
import { getFirstSucceededRemoteDataPayload } from '../shared/operators';
|
||||
|
||||
/**
|
||||
* A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint
|
||||
@@ -56,24 +57,6 @@ export class MetadataFieldDataService extends DataService<MetadataField> {
|
||||
return this.searchBy(this.searchBySchemaLinkPath, optionsWithSchema, ...linksToFollow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or Update a MetadataField
|
||||
* 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):
|
||||
* - On creation, a CreateRequest is used
|
||||
* - On update, a PutRequest is used
|
||||
* @param field The MetadataField to create or update
|
||||
*/
|
||||
createOrUpdateMetadataField(field: MetadataField): Observable<RemoteData<MetadataField>> {
|
||||
const isUpdate = hasValue(field.id);
|
||||
|
||||
if (isUpdate) {
|
||||
return this.put(field);
|
||||
} else {
|
||||
return this.create(field, new RequestParam('schemaId', field.schema.id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all metadata field requests
|
||||
* Used for refreshing lists after adding/updating/removing a metadata field from a metadata schema
|
||||
|
@@ -9,6 +9,9 @@ import { ResourceType } from '../shared/resource-type';
|
||||
import { excludeFromEquals } from '../utilities/equals.decorators';
|
||||
import { METADATA_FIELD } from './metadata-field.resource-type';
|
||||
import { MetadataSchema } from './metadata-schema.model';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { Observable } from 'rxjs';
|
||||
import { METADATA_SCHEMA } from './metadata-schema.resource-type';
|
||||
|
||||
/**
|
||||
* Class the represents a metadata field
|
||||
@@ -61,16 +64,15 @@ export class MetadataField extends ListableObject implements HALResource {
|
||||
* The MetadataSchema for this MetadataField
|
||||
* Will be undefined unless the schema {@link HALLink} has been resolved.
|
||||
*/
|
||||
// TODO the responseparsingservice assumes schemas are always embedded. This should use remotedata, and be a link instead.
|
||||
// @link(METADATA_SCHEMA)
|
||||
schema?: MetadataSchema;
|
||||
@link(METADATA_SCHEMA)
|
||||
schema?: Observable<RemoteData<MetadataSchema>>;
|
||||
|
||||
/**
|
||||
* Method to print this metadata field as a string
|
||||
* @param separator The separator between the schema, element and qualifier in the string
|
||||
*/
|
||||
toString(separator: string = '.'): string {
|
||||
let key = this.schema.prefix + separator + this.element;
|
||||
let key = this.element;
|
||||
if (isNotEmpty(this.qualifier)) {
|
||||
key += separator + this.qualifier;
|
||||
}
|
||||
|
@@ -82,7 +82,7 @@ describe('RegistryService', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'advisor',
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[0],
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]),
|
||||
type: MetadataField.type
|
||||
}),
|
||||
Object.assign(new MetadataField(),
|
||||
@@ -94,7 +94,7 @@ describe('RegistryService', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'author',
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[0],
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]),
|
||||
type: MetadataField.type
|
||||
}),
|
||||
Object.assign(new MetadataField(),
|
||||
@@ -106,7 +106,7 @@ describe('RegistryService', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'editor',
|
||||
scopeNote: 'test scope note',
|
||||
schema: mockSchemasList[1],
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]),
|
||||
type: MetadataField.type
|
||||
}),
|
||||
Object.assign(new MetadataField(),
|
||||
@@ -118,7 +118,7 @@ describe('RegistryService', () => {
|
||||
element: 'contributor',
|
||||
qualifier: 'illustrator',
|
||||
scopeNote: null,
|
||||
schema: mockSchemasList[1],
|
||||
schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]),
|
||||
type: MetadataField.type
|
||||
})
|
||||
];
|
||||
@@ -134,7 +134,8 @@ describe('RegistryService', () => {
|
||||
metadataFieldService = jasmine.createSpyObj('metadataFieldService', {
|
||||
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockFieldsList)),
|
||||
findById: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||
createOrUpdateMetadataField: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||
create: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||
put: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||
deleteAndReturnResponse: observableOf(new RestResponse(true, 200, 'OK')),
|
||||
clearRequests: observableOf('href')
|
||||
});
|
||||
@@ -178,7 +179,7 @@ describe('RegistryService', () => {
|
||||
let result;
|
||||
|
||||
beforeEach(() => {
|
||||
result = registryService.getMetadataSchemaByName(mockSchemasList[0].prefix);
|
||||
result = registryService.getMetadataSchemaByPrefix(mockSchemasList[0].prefix);
|
||||
});
|
||||
|
||||
it('should call metadataSchemaService.findById with the correct ID', (done) => {
|
||||
@@ -325,14 +326,29 @@ describe('RegistryService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when createOrUpdateMetadataField is called', () => {
|
||||
describe('when createMetadataField is called', () => {
|
||||
let result: Observable<MetadataField>;
|
||||
|
||||
beforeEach(() => {
|
||||
result = registryService.createOrUpdateMetadataField(mockFieldsList[0]);
|
||||
result = registryService.createMetadataField(mockFieldsList[0], mockSchemasList[0]);
|
||||
});
|
||||
|
||||
it('should return the created/updated metadata field', (done) => {
|
||||
it('should return the created metadata field', (done) => {
|
||||
result.subscribe((field: MetadataField) => {
|
||||
expect(field).toEqual(mockFieldsList[0]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateMetadataField is called', () => {
|
||||
let result: Observable<MetadataField>;
|
||||
|
||||
beforeEach(() => {
|
||||
result = registryService.updateMetadataField(mockFieldsList[0]);
|
||||
});
|
||||
|
||||
it('should return the updated metadata field', (done) => {
|
||||
result.subscribe((field: MetadataField) => {
|
||||
expect(field).toEqual(mockFieldsList[0]);
|
||||
done();
|
||||
|
@@ -36,7 +36,8 @@ import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||
import { MetadataField } from '../metadata/metadata-field.model';
|
||||
import { MetadataSchemaDataService } from '../data/metadata-schema-data.service';
|
||||
import { MetadataFieldDataService } from '../data/metadata-field-data.service';
|
||||
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||
import { FollowLinkConfig, followLink } from '../../shared/utils/follow-link-config.model';
|
||||
import { RequestParam } from '../cache/models/request-param.model';
|
||||
|
||||
const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry;
|
||||
const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema);
|
||||
@@ -68,11 +69,11 @@ export class RegistryService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a metadata schema by its name
|
||||
* @param schemaName The name of the schema to find
|
||||
* Retrieves a metadata schema by its prefix
|
||||
* @param prefix The prefux of the schema to find
|
||||
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||
*/
|
||||
public getMetadataSchemaByName(schemaName: string, ...linksToFollow: Array<FollowLinkConfig<MetadataSchema>>): Observable<RemoteData<MetadataSchema>> {
|
||||
public getMetadataSchemaByPrefix(prefix: string, ...linksToFollow: Array<FollowLinkConfig<MetadataSchema>>): Observable<RemoteData<MetadataSchema>> {
|
||||
// Temporary options to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema
|
||||
const options: FindListOptions = Object.assign(new FindListOptions(), {
|
||||
elementsPerPage: 10000
|
||||
@@ -81,7 +82,7 @@ export class RegistryService {
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
map((schemas: PaginatedList<MetadataSchema>) => schemas.page),
|
||||
isNotEmptyOperator(),
|
||||
map((schemas: MetadataSchema[]) => schemas.filter((schema) => schema.prefix === schemaName)[0]),
|
||||
map((schemas: MetadataSchema[]) => schemas.filter((schema) => schema.prefix === prefix)[0]),
|
||||
flatMap((schema: MetadataSchema) => this.metadataSchemaService.findById(`${schema.id}`, ...linksToFollow))
|
||||
);
|
||||
}
|
||||
@@ -240,25 +241,37 @@ export class RegistryService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or Update a MetadataField
|
||||
* 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):
|
||||
* - On creation, a CreateRequest is used
|
||||
* - On update, a PutRequest is used
|
||||
* @param field The MetadataField to create or update
|
||||
* Create a MetadataField
|
||||
*
|
||||
* @param field The MetadataField to create
|
||||
* @param schema The MetadataSchema to create the field in
|
||||
*/
|
||||
public createOrUpdateMetadataField(field: MetadataField): Observable<MetadataField> {
|
||||
const isUpdate = hasValue(field.id);
|
||||
return this.metadataFieldService.createOrUpdateMetadataField(field).pipe(
|
||||
public createMetadataField(field: MetadataField, schema: MetadataSchema): Observable<MetadataField> {
|
||||
return this.metadataFieldService.create(field, new RequestParam('schemaId', schema.id)).pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
hasValueOperator(),
|
||||
tap(() => {
|
||||
const fieldString = `${field.schema.prefix}.${field.element}${field.qualifier ? `.${field.qualifier}` : ''}`;
|
||||
this.showNotifications(true, isUpdate, true, {field: fieldString});
|
||||
this.showNotifications(true, false, true, {field: field.toString()});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a MetadataField
|
||||
*
|
||||
* @param field The MetadataField to update
|
||||
*/
|
||||
public updateMetadataField(field: MetadataField): Observable<MetadataField> {
|
||||
return this.metadataFieldService.put(field).pipe(
|
||||
getFirstSucceededRemoteDataPayload(),
|
||||
hasValueOperator(),
|
||||
tap(() => {
|
||||
this.showNotifications(true, true, true, {field: field.toString()});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to delete a metadata field
|
||||
* @param id The id of the metadata field to delete
|
||||
@@ -296,12 +309,12 @@ export class RegistryService {
|
||||
* @returns an observable that emits a remote data object with a page of metadata fields that match the query
|
||||
*/
|
||||
queryMetadataFields(query: string): Observable<RemoteData<PaginatedList<MetadataField>>> {
|
||||
return this.getAllMetadataFields().pipe(
|
||||
return this.getAllMetadataFields(undefined, followLink('schema')).pipe(
|
||||
map((rd: RemoteData<PaginatedList<MetadataField>>) => {
|
||||
const filteredFields: MetadataField[] = rd.payload.page.filter(
|
||||
(field: MetadataField) => field.toString().indexOf(query) >= 0
|
||||
);
|
||||
const page: PaginatedList<MetadataField> = new PaginatedList<MetadataField>(new PageInfo(), filteredFields)
|
||||
const page: PaginatedList<MetadataField> = new PaginatedList<MetadataField>(new PageInfo(), filteredFields);
|
||||
return Object.assign({}, rd, { payload: page });
|
||||
})
|
||||
);
|
||||
|
Reference in New Issue
Block a user