mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
71894: confirm edit metadata button disabled if invalid &
removed unneeded service
This commit is contained in:
@@ -6,6 +6,8 @@
|
||||
<div *ngIf="(editable | async)" class="field-container">
|
||||
<ds-filter-input-suggestions [suggestions]="(metadataFieldSuggestions | async)"
|
||||
[(ngModel)]="metadata.key"
|
||||
[url]="this.url"
|
||||
[metadata]="this.metadata"
|
||||
(submitSuggestion)="update(suggestionControl)"
|
||||
(clickSuggestion)="update(suggestionControl)"
|
||||
(typeSuggestion)="update(suggestionControl)"
|
||||
@@ -50,7 +52,7 @@
|
||||
title="{{'item.edit.metadata.edit.buttons.edit' | translate}}">
|
||||
<i class="fas fa-edit fa-fw"></i>
|
||||
</button>
|
||||
<button [disabled]="!(canSetUneditable() | async)" *ngIf="(editable | async)"
|
||||
<button [disabled]="!(canSetUneditable() | async) || (valid | async) === false" *ngIf="(editable | async)"
|
||||
(click)="setEditable(false)" class="btn btn-outline-success btn-sm"
|
||||
title="{{'item.edit.metadata.edit.buttons.unedit' | translate}}">
|
||||
<i class="fas fa-check fa-fw"></i>
|
||||
|
@@ -36,7 +36,7 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
||||
/**
|
||||
* The metadatum of this field
|
||||
*/
|
||||
metadata: MetadatumViewModel;
|
||||
@Input() metadata: MetadatumViewModel;
|
||||
|
||||
/**
|
||||
* Emits whether or not this field is currently editable
|
||||
|
@@ -68,7 +68,6 @@ import { ItemDataService } from './data/item-data.service';
|
||||
import { LicenseDataService } from './data/license-data.service';
|
||||
import { LookupRelationService } from './data/lookup-relation.service';
|
||||
import { MappedCollectionsReponseParsingService } from './data/mapped-collections-reponse-parsing.service';
|
||||
import { MetadatafieldParsingService } from './data/metadatafield-response-parsing.service';
|
||||
import { MyDSpaceResponseParsingService } from './data/mydspace-response-parsing.service';
|
||||
import { ObjectUpdatesService } from './data/object-updates/object-updates.service';
|
||||
import { RelationshipTypeService } from './data/relationship-type.service';
|
||||
@@ -196,7 +195,7 @@ const PROVIDERS = [
|
||||
SiteDataService,
|
||||
DSOResponseParsingService,
|
||||
{ provide: MOCK_RESPONSE_MAP, useValue: mockResponseMap },
|
||||
{ provide: DSpaceRESTv2Service, useFactory: restServiceFactory, deps: [MOCK_RESPONSE_MAP, HttpClient]},
|
||||
{ provide: DSpaceRESTv2Service, useFactory: restServiceFactory, deps: [MOCK_RESPONSE_MAP, HttpClient] },
|
||||
DynamicFormLayoutService,
|
||||
DynamicFormService,
|
||||
DynamicFormValidationService,
|
||||
@@ -290,7 +289,6 @@ const PROVIDERS = [
|
||||
MetadataSchemaDataService,
|
||||
MetadataFieldDataService,
|
||||
TokenResponseParsingService,
|
||||
MetadatafieldParsingService,
|
||||
// register AuthInterceptor as HttpInterceptor
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
|
@@ -1,19 +0,0 @@
|
||||
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 { RestRequest } from './request.models';
|
||||
import { ResponseParsingService } from './parsing.service';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { MetadatafieldSuccessResponse, RestResponse } from '../cache/response.models';
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
@@ -2,7 +2,6 @@ import { SortOptions } from '../cache/models/sort-options.model';
|
||||
import { GenericConstructor } from '../shared/generic-constructor';
|
||||
import { BrowseEntriesResponseParsingService } from './browse-entries-response-parsing.service';
|
||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
||||
import { MetadatafieldParsingService } from './metadatafield-response-parsing.service';
|
||||
import { ResponseParsingService } from './parsing.service';
|
||||
import { EndpointMapResponseParsingService } from './endpoint-map-response-parsing.service';
|
||||
import { BrowseResponseParsingService } from './browse-response-parsing.service';
|
||||
@@ -430,14 +429,4 @@ export class RequestError extends Error {
|
||||
statusCode: number;
|
||||
statusText: string;
|
||||
}
|
||||
|
||||
export class GetMetadataFieldRequest extends GetRequest {
|
||||
constructor(uuid: string, href: string, public options?: HttpOptions) {
|
||||
super(uuid, href, null, options);
|
||||
}
|
||||
|
||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
||||
return MetadatafieldParsingService;
|
||||
}
|
||||
}
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
@@ -2,7 +2,7 @@
|
||||
[action]="action" (keydown)="onKeydown($event)"
|
||||
(keydown.arrowdown)="shiftFocusDown($event)"
|
||||
(keydown.arrowup)="shiftFocusUp($event)" (keydown.esc)="close()"
|
||||
(dsClickOutside)="close();">
|
||||
(dsClickOutside)="checkIfValidInput(form);close();">
|
||||
<input #inputField type="text" formControlName="metadataNameField" [(ngModel)]="value" id="name" [name]="name"
|
||||
class="form-control suggestion_input"
|
||||
[ngClass]="{'is-invalid': !valid}"
|
||||
@@ -11,10 +11,6 @@
|
||||
ng-model-options="{standalone: true}"
|
||||
autocomplete="off">
|
||||
<input type="submit" class="d-none"/>
|
||||
<small class="text-danger"
|
||||
*ngIf="form.get('metadataNameField').status === 'INVALID' && (form.get('metadataNameField').dirty || form.get('metadataNameField').touched)">
|
||||
{{"item.edit.metadata.metadatafield.invalid" | translate}}
|
||||
</small>
|
||||
<div class="autocomplete dropdown-menu" [ngClass]="{'show': (show | async) && isNotEmpty(suggestions)}">
|
||||
<div class="dropdown-list">
|
||||
<div *ngFor="let suggestionOption of suggestions">
|
||||
|
@@ -7,6 +7,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { MetadataFieldDataService } from '../../../core/data/metadata-field-data.service';
|
||||
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
|
||||
import { FilterInputSuggestionsComponent } from './filter-input-suggestions.component';
|
||||
|
||||
describe('FilterInputSuggestionsComponent', () => {
|
||||
@@ -26,7 +27,9 @@ describe('FilterInputSuggestionsComponent', () => {
|
||||
declarations: [FilterInputSuggestionsComponent],
|
||||
providers: [FormsModule,
|
||||
ReactiveFormsModule,
|
||||
{ provide: MetadataFieldDataService, useValue: {} }],
|
||||
{ provide: MetadataFieldDataService, useValue: {} },
|
||||
{ provide: ObjectUpdatesService, useValue: {} },
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(FilterInputSuggestionsComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { Component, forwardRef, Input, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
|
||||
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
|
||||
import { MetadatumViewModel } from '../../../core/shared/metadata.models';
|
||||
import { MetadataFieldValidator } from '../../utils/metadatafield-validator.directive';
|
||||
import { InputSuggestionsComponent } from '../input-suggestions.component';
|
||||
import { InputSuggestion } from '../input-suggestions.model';
|
||||
@@ -26,12 +28,23 @@ export class FilterInputSuggestionsComponent extends InputSuggestionsComponent i
|
||||
|
||||
form: FormGroup;
|
||||
|
||||
/**
|
||||
* The current url of this page
|
||||
*/
|
||||
@Input() url: string;
|
||||
|
||||
/**
|
||||
* The metadatum of this field
|
||||
*/
|
||||
@Input() metadata: MetadatumViewModel;
|
||||
|
||||
/**
|
||||
* The suggestions that should be shown
|
||||
*/
|
||||
@Input() suggestions: InputSuggestion[] = [];
|
||||
|
||||
constructor(private metadataFieldValidator: MetadataFieldValidator) {
|
||||
constructor(private metadataFieldValidator: MetadataFieldValidator,
|
||||
private objectUpdatesService: ObjectUpdatesService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -58,4 +71,14 @@ export class FilterInputSuggestionsComponent extends InputSuggestionsComponent i
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the input is valid according to validator and send (in)valid state to store
|
||||
* @param form Form with input
|
||||
*/
|
||||
checkIfValidInput(form) {
|
||||
this.valid = !(form.get('metadataNameField').status === 'INVALID' && (form.get('metadataNameField').dirty || form.get('metadataNameField').touched));
|
||||
this.objectUpdatesService.setValidFieldUpdate(this.url, this.metadata.uuid, this.valid);
|
||||
return this.valid;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user