71894: Refactored exact FieldName search for validator after change endpoint

This commit is contained in:
Marie Verdonck
2020-09-01 14:33:36 +02:00
parent 10b314cf20
commit b602a736de
6 changed files with 33 additions and 44 deletions

View File

@@ -63,7 +63,7 @@ const fieldUpdate = {
};
let scheduler: TestScheduler;
fdescribe('EditInPlaceFieldComponent', () => {
describe('EditInPlaceFieldComponent', () => {
beforeEach(async(() => {
scheduler = getTestScheduler();

View File

@@ -1,10 +1,9 @@
import { Injectable } from '@angular/core';
import { hasValue, isNotEmptyOperator } from '../../shared/empty.util';
import { hasValue } from '../../shared/empty.util';
import { dataService } from '../cache/builders/build-decorators';
import { RestResponse } from '../cache/response.models';
import { configureRequest } from '../shared/operators';
import { DataService } from './data.service';
import { RequestEntry } from './request.reducer';
import { PaginatedList } from './paginated-list';
import { RemoteData } from './remote-data';
import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store';
@@ -17,14 +16,10 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { METADATA_FIELD } from '../metadata/metadata-field.resource-type';
import { MetadataField } from '../metadata/metadata-field.model';
import { MetadataSchema } from '../metadata/metadata-schema.model';
import {
FindListOptions,
GetMetadataFieldRequest,
RestRequest
} from './request.models';
import { FindListOptions } from './request.models';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { Observable } from 'rxjs/internal/Observable';
import { distinctUntilChanged, find, map, switchMap, tap } from 'rxjs/operators';
import { tap } from 'rxjs/operators';
import { RequestParam } from '../cache/models/request-param.model';
/**
@@ -70,43 +65,33 @@ export class MetadataFieldDataService extends DataService<MetadataField> {
* @param qualifier optional; an exact match of the field's qualifier (e.g. "author", "alternative")
* @param query optional (if any of schema, element or qualifier used) - part of the fully qualified field,
* should start with the start of the schema, element or qualifier (e.g. “dc.ti”, “contributor”, “auth”, “contributor.ot”)
* @param exactName optional; the exact fully qualified field, should use the syntax schema.element.qualifier or
* schema.element if no qualifier exists (e.g. "dc.title", "dc.contributor.author"). It will only return one value
* if there's an exact match
* @param options The options info used to retrieve the fields
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
searchByFieldNameParams(schema: string, element: string, qualifier: string, query: string, options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>) {
searchByFieldNameParams(schema: string, element: string, qualifier: string, query: string, exactName: string, options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>): Observable<RemoteData<PaginatedList<MetadataField>>> {
const optionParams = Object.assign(new FindListOptions(), options, {
searchParams: [
new RequestParam('schema', hasValue(schema) ? schema : ''),
new RequestParam('element', hasValue(element) ? element : ''),
new RequestParam('qualifier', hasValue(qualifier) ? qualifier : ''),
new RequestParam('query', hasValue(query) ? query : '')
new RequestParam('query', hasValue(query) ? query : ''),
new RequestParam('exactName', hasValue(exactName) ? exactName : '')
]
});
return this.searchBy(this.searchByFieldNameLinkPath, optionParams, ...linksToFollow);
}
/**
* Finds a specific metadata field by name. There's always at most one metadata field per name.
* If the metadata field can be found it is in the response, otherwise the response will have code 404
* @param exactFieldName Exact metadata field name (ex. dc.title, dc.contributor.other)
* Finds a specific metadata field by name.
* @param exactFieldName The exact fully qualified field, should use the syntax schema.element.qualifier or
* schema.element if no qualifier exists (e.g. "dc.title", "dc.contributor.author"). It will only return one value
* if there's an exact match, empty list if there is no exact match.
*/
findByExactFieldName(exactFieldName: string): Observable<RestResponse> {
const request$ = this.halService.getEndpoint(this.linkPath).pipe(
isNotEmptyOperator(),
distinctUntilChanged(),
map((endpoint: string) => `${endpoint}/name/${exactFieldName}`),
map((endpointURL: string) => new GetMetadataFieldRequest(this.requestService.generateRequestId(), endpointURL)),
configureRequest(this.requestService)
);
const requestEntry$ = request$.pipe(
switchMap((request: RestRequest) => this.requestService.getByHref(request.href))
);
return requestEntry$.pipe(
find((request: RequestEntry) => request.completed),
map((request: RequestEntry) => request.response)
);
findByExactFieldName(exactFieldName: string): Observable<RemoteData<PaginatedList<MetadataField>>> {
return this.searchByFieldNameParams(null, null, null, null, exactFieldName, null);
}
/**

View File

@@ -293,6 +293,6 @@ 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, options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>): Observable<RemoteData<PaginatedList<MetadataField>>> {
return this.metadataFieldService.searchByFieldNameParams(null, null, null, query, options, ...linksToFollow);
return this.metadataFieldService.searchByFieldNameParams(null, null, null, query, null, options, ...linksToFollow);
}
}

View File

@@ -1,6 +1,6 @@
import { Router, UrlTree } from '@angular/router';
import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
import { filter, find, flatMap, map, switchMap, take, tap } from 'rxjs/operators';
import { filter, find, flatMap, map, switchMap, tap } from 'rxjs/operators';
import { hasValue, hasValueOperator, isNotEmpty } from '../../shared/empty.util';
import { SearchResult } from '../../shared/search/search-result.model';
import { DSOSuccessResponse, RestResponse } from '../cache/response.models';
@@ -272,7 +272,7 @@ export const metadataFieldsToString = () =>
});
return observableCombineLatest(fieldSchemaArray);
}),
map((fieldSchemaArray: {field: MetadataField, schema: MetadataSchema}[]): string[] => {
map((fieldSchemaArray: Array<{ field: MetadataField, schema: MetadataSchema }>): string[] => {
return fieldSchemaArray.map((fieldSchema: { field: MetadataField, schema: MetadataSchema }) => fieldSchema.schema.prefix + '.' + fieldSchema.field.toString())
})
);

View File

@@ -2,8 +2,11 @@ import { Directive, Injectable } from '@angular/core';
import { AbstractControl, AsyncValidator, NG_VALIDATORS, ValidationErrors } from '@angular/forms';
import { map, switchMap, take } from 'rxjs/operators';
import { of as observableOf, timer as observableTimer, Observable } from 'rxjs';
import { RestResponse } from '../../core/cache/response.models';
import { MetadataFieldDataService } from '../../core/data/metadata-field-data.service';
import { PaginatedList } from '../../core/data/paginated-list';
import { RemoteData } from '../../core/data/remote-data';
import { MetadataField } from '../../core/metadata/metadata-field.model';
import { getSucceededRemoteData } from '../../core/shared/operators';
/**
* Directive for validating if a ngModel value is a valid metadata field
@@ -38,11 +41,12 @@ export class MetadataFieldValidator implements AsyncValidator {
const res = this.metadataFieldService.findByExactFieldName(control.value)
.pipe(
map((response: RestResponse) => {
if (response.isSuccessful) {
return null;
} else {
getSucceededRemoteData(),
map((matchingFieldRD: RemoteData<PaginatedList<MetadataField>>) => {
if (matchingFieldRD.payload.pageInfo.totalElements === 0) {
return { invalidMetadataField: { value: control.value } };
} else if (matchingFieldRD.payload.pageInfo.totalElements === 1) {
return null;
}
})
);