diff --git a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html
index 80c78941c8..9f409d11bd 100644
--- a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html
+++ b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.html
@@ -12,7 +12,6 @@
(dsClickOutside)="checkValidity(suggestionControl)"
(findSuggestions)="findMetadataFieldSuggestions($event)"
#suggestionControl="ngModel"
- [dsInListValidator]="metadataFields"
[valid]="(valid | async) !== false"
dsAutoFocus autoFocusSelector=".suggestion_input"
[ngModelOptions]="{standalone: true}"
diff --git a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts
index cff1310f22..1bd4ebf341 100644
--- a/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts
+++ b/src/app/+item-page/edit-item-page/item-metadata/edit-in-place-field/edit-in-place-field.component.ts
@@ -37,11 +37,6 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
*/
@Input() url: string;
- /**
- * List of strings with all metadata field keys available
- */
- @Input() metadataFields: string[];
-
/**
* The metadatum of this field
*/
@@ -65,7 +60,6 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
constructor(
private registryService: RegistryService,
private objectUpdatesService: ObjectUpdatesService,
- private metadataSchemaService: MetadataSchemaDataService
) {
}
diff --git a/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.html b/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.html
index 366f6fffe2..042ed2d339 100644
--- a/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.html
+++ b/src/app/+item-page/edit-item-page/item-metadata/item-metadata.component.html
@@ -33,7 +33,6 @@
;
- /**
- * Observable with a list of strings with all existing metadata field keys
- */
- metadataFields$: Observable;
-
constructor(
public itemService: ItemDataService,
public objectUpdatesService: ObjectUpdatesService,
@@ -54,7 +49,6 @@ export class ItemMetadataComponent extends AbstractItemUpdateComponent {
public notificationsService: NotificationsService,
public translateService: TranslateService,
public route: ActivatedRoute,
- public metadataFieldService: RegistryService,
) {
super(itemService, objectUpdatesService, router, notificationsService, translateService, route);
}
@@ -64,7 +58,6 @@ export class ItemMetadataComponent extends AbstractItemUpdateComponent {
*/
ngOnInit(): void {
super.ngOnInit();
- this.metadataFields$ = this.findMetadataFields();
if (hasNoValue(this.updateService)) {
this.updateService = this.itemService;
}
@@ -130,16 +123,6 @@ export class ItemMetadataComponent extends AbstractItemUpdateComponent {
});
}
- /**
- * Method to request all metadata fields and convert them to a list of strings
- */
- findMetadataFields(): Observable {
- return this.metadataFieldService.getAllMetadataFields().pipe(
- getSucceededRemoteData(),
- take(1),
- map((remoteData$) => remoteData$.payload.page.map((field: MetadataField) => field.toString())));
- }
-
/**
* Check for empty metadata UUIDs and fix them (empty UUIDs would break the object-update service)
*/
diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts
index 726ae4613d..ec4b5f8a5a 100644
--- a/src/app/core/registry/registry.service.ts
+++ b/src/app/core/registry/registry.service.ts
@@ -90,20 +90,6 @@ export class RegistryService {
return this.metadataFieldService.findBySchema(schema, options, ...linksToFollow);
}
- /**
- * Retrieve all existing metadata fields as a paginated list
- * @param options Options to determine which page of metadata fields should be requested
- * When no options are provided, all metadata fields are requested in one large page
- * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
- * @returns an observable that emits a remote data object with a page of metadata fields
- */
- // TODO this is temporarily disabled. The performance is too bad.
- // It is used down the line for validation. That validation will have to be rewritten against a new rest endpoint.
- // Not by downloading the list of all fields.
- public getAllMetadataFields(options?: FindListOptions, ...linksToFollow: Array>): Observable>> {
- return createSuccessfulRemoteDataObject$(new PaginatedList(null, []));
- }
-
public editMetadataSchema(schema: MetadataSchema) {
this.store.dispatch(new MetadataRegistryEditSchemaAction(schema));
}
diff --git a/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html b/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html
index 49e4c0a1d5..2467dfb569 100644
--- a/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html
+++ b/src/app/shared/input-suggestions/filter-suggestions/filter-input-suggestions.component.html
@@ -8,7 +8,8 @@
[ngClass]="{'is-invalid': !valid}"
[dsDebounce]="debounceTime" (onDebounce)="find($event)"
[placeholder]="placeholder"
- [ngModelOptions]="{standalone: true}" autocomplete="off"/>
+ [ngModelOptions]="{standalone: true}" autocomplete="off"
+ dsMetadataFieldValidator />
@@ -19,4 +20,4 @@
-
\ No newline at end of file
+
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index 66bdea9217..bcdf8b2fd2 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -21,6 +21,7 @@ import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { EnumKeysPipe } from './utils/enum-keys-pipe';
import { FileSizePipe } from './utils/file-size-pipe';
+import { MetadataFieldValidator } from './utils/metadatafield-validator.directive';
import { SafeUrlPipe } from './utils/safe-url-pipe';
import { ConsolePipe } from './utils/console.pipe';
@@ -516,7 +517,8 @@ const DIRECTIVES = [
FileValueAccessorDirective,
FileValidator,
ClaimedTaskActionsDirective,
- NgForTrackByIdDirective
+ NgForTrackByIdDirective,
+ MetadataFieldValidator
];
@NgModule({
diff --git a/src/app/shared/utils/metadatafield-validator.directive.ts b/src/app/shared/utils/metadatafield-validator.directive.ts
new file mode 100644
index 0000000000..f4ee756fcb
--- /dev/null
+++ b/src/app/shared/utils/metadatafield-validator.directive.ts
@@ -0,0 +1,66 @@
+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 { MetadataFieldDataService } from '../../core/data/metadata-field-data.service';
+import { getSucceededRemoteData } from '../../core/shared/operators';
+
+/**
+ * Directive for validating if a ngModel value is a valid metadata field
+ */
+@Directive({
+ selector: '[ngModel][dsMetadataFieldValidator]',
+ // We add our directive to the list of existing validators
+ providers: [
+ { provide: NG_VALIDATORS, useExisting: MetadataFieldValidator, multi: true }
+ ]
+})
+@Injectable({ providedIn: 'root' })
+export class MetadataFieldValidator implements AsyncValidator {
+
+ constructor(private metadataFieldService: MetadataFieldDataService) {
+ }
+
+ /**
+ * The function that checks if the form control's value is currently valid
+ * @param control The FormControl
+ */
+ validate(control: AbstractControl): Observable {
+ const resTimer = observableTimer(500).pipe(
+ switchMap(() => {
+ console.log('control', control)
+ if (!control.value) {
+ return observableOf({ invalidMetadataField: { value: control.value } });
+ }
+ const mdFieldNameParts = control.value.split('.');
+ if (mdFieldNameParts.length < 2) {
+ console.log('not enough parts')
+ return observableOf({ invalidMetadataField: { value: control.value } });
+ }
+
+ const res = this.metadataFieldService.findByFieldName(mdFieldNameParts[0], mdFieldNameParts[1], mdFieldNameParts.length == 3 ? mdFieldNameParts[2] : '', '')
+ .pipe(
+ getSucceededRemoteData(),
+ map((results) => {
+ console.log('results', results)
+ // TODO: - Currently it’s valid if the search returns at least one matching mdField; but this does mean that if for example a mdField named schema.elementEx.qualifierEx exists, but you fill in schema. or schema.elementEx then there is at least one result, but this doesn’t mean this is the whole of the field (the suggestion does show the options); alternatively it is valid if exact one matching field but then dc.title isn’t valid because the search schema=dc & element=title also returns for example dc.title.alternative
+ // - So the endpoint / restcontract should probably be changed to accommodate and exact search? Or was that already what was wanted and did I interpret it wrong?
+ if (results.payload.totalElements > 0) {
+ console.log('VALID')
+ return null;
+ } else {
+ console.log('NOT VALID')
+ return { invalidMetadataField: { value: control.value } };
+ }
+ })
+ );
+
+ res.pipe(take(1)).subscribe();
+
+ return res;
+ })
+ );
+ resTimer.pipe(take(1)).subscribe();
+ return resTimer;
+ }
+}