Skip to content

Commit 88ac610

Browse files
[CST-15124] propagate error to child controllers, handle removal of field
1 parent a7cd709 commit 88ac610

5 files changed

Lines changed: 53 additions & 70 deletions

File tree

src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import {
33
Component,
44
ComponentFactoryResolver,
55
ContentChildren,
6-
EventEmitter,
7-
Inject,
6+
EventEmitter, Inject,
87
Input,
98
NgZone,
109
OnChanges,
@@ -59,9 +58,7 @@ import { TranslateService } from '@ngx-translate/core';
5958
import { ReorderableRelationship } from './existing-metadata-list-element/existing-metadata-list-element.component';
6059

6160
import { DYNAMIC_FORM_CONTROL_TYPE_ONEBOX } from './models/onebox/dynamic-onebox.model';
62-
import {
63-
DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN
64-
} from './models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
61+
import { DYNAMIC_FORM_CONTROL_TYPE_SCROLLABLE_DROPDOWN } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
6562
import { DYNAMIC_FORM_CONTROL_TYPE_TAG } from './models/tag/dynamic-tag.model';
6663
import { DYNAMIC_FORM_CONTROL_TYPE_DSDATEPICKER } from './models/date-picker/date-picker.model';
6764
import { DYNAMIC_FORM_CONTROL_TYPE_LOOKUP } from './models/lookup/dynamic-lookup.model';
@@ -73,9 +70,7 @@ import { DsDynamicTagComponent } from './models/tag/dynamic-tag.component';
7370
import { DsDatePickerComponent } from './models/date-picker/date-picker.component';
7471
import { DsDynamicListComponent } from './models/list/dynamic-list.component';
7572
import { DsDynamicOneboxComponent } from './models/onebox/dynamic-onebox.component';
76-
import {
77-
DsDynamicScrollableDropdownComponent
78-
} from './models/scrollable-dropdown/dynamic-scrollable-dropdown.component';
73+
import { DsDynamicScrollableDropdownComponent } from './models/scrollable-dropdown/dynamic-scrollable-dropdown.component';
7974
import { DsDynamicLookupComponent } from './models/lookup/dynamic-lookup.component';
8075
import { DsDynamicFormGroupComponent } from './models/form-group/dynamic-form-group.component';
8176
import { DsDynamicFormArrayComponent } from './models/array-group/dynamic-form-array.component';
@@ -87,9 +82,7 @@ import { CustomSwitchComponent } from './models/custom-switch/custom-switch.comp
8782
import { find, map, startWith, switchMap, take } from 'rxjs/operators';
8883
import { combineLatest as observableCombineLatest, Observable, Subscription } from 'rxjs';
8984
import { DsDynamicTypeBindRelationService } from './ds-dynamic-type-bind-relation.service';
90-
import {
91-
DsDynamicRelationInlineGroupComponent
92-
} from './models/relation-inline-group/dynamic-relation-inline-group.components';
85+
import { DsDynamicRelationInlineGroupComponent } from './models/relation-inline-group/dynamic-relation-inline-group.components';
9386
import { SearchResult } from '../../../search/models/search-result.model';
9487
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
9588
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
@@ -130,6 +123,9 @@ import { APP_CONFIG, AppConfig } from '../../../../../config/app-config.interfac
130123
import { itemLinksToFollow } from '../../../utils/relation-query.utils';
131124
import { DynamicConcatModel } from './models/ds-dynamic-concat.model';
132125
import { Metadata } from '../../../../core/shared/metadata.utils';
126+
import { DsDynamicMarkdownComponent } from './models/markdown/dynamic-markdown.component';
127+
import { DYNAMIC_FORM_CONTROL_TYPE_MARKDOWN } from './models/markdown/dynamic-markdown.model';
128+
import { DynamicLinkModel } from './models/ds-dynamic-link.model';
133129

134130
export function dsDynamicFormControlMapFn(model: DynamicFormControlModel): Type<DynamicFormControl> | null {
135131
switch (model.type) {
@@ -192,6 +188,9 @@ export function dsDynamicFormControlMapFn(model: DynamicFormControlModel): Type<
192188
case DYNAMIC_FORM_CONTROL_TYPE_CUSTOM_SWITCH:
193189
return CustomSwitchComponent;
194190

191+
case DYNAMIC_FORM_CONTROL_TYPE_MARKDOWN:
192+
return DsDynamicMarkdownComponent;
193+
195194
default:
196195
return null;
197196
}
@@ -504,7 +503,6 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
504503
* Unsubscribe from all subscriptions
505504
*/
506505
ngOnDestroy(): void {
507-
super.ngOnDestroy();
508506
this.subs
509507
.filter((sub) => hasValue(sub))
510508
.forEach((sub) => sub.unsubscribe());
@@ -555,13 +553,13 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
555553
addSecurityLevelToMetadata($event) {
556554
this.model.securityLevel = $event;
557555
this.securityLevel = $event;
558-
if (this.model.parent && this.model.parent instanceof DynamicConcatModel) {
556+
if (this.model.parent && (this.model.parent instanceof DynamicConcatModel || this.model.parent instanceof DynamicLinkModel)) {
559557
this.model.parent.securityLevel = $event;
560558
}
561559
if (this.model.value) {
562560
this.model.securityLevel = $event;
563561
this.securityLevel = $event;
564-
if (this.model.parent && this.model.parent instanceof DynamicConcatModel) {
562+
if (this.model.parent && (this.model.parent instanceof DynamicConcatModel || this.model.parent instanceof DynamicLinkModel)) {
565563
this.model.parent.securityLevel = $event;
566564
}
567565
this.change.emit(

src/app/shared/form/builder/ds-dynamic-form-ui/models/link/dynamic-link.model.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/app/shared/form/form.component.ts

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import { DynamicRowGroupModel } from './builder/ds-dynamic-form-ui/models/ds-dyn
2828
import {
2929
DynamicRelationGroupModel
3030
} from './builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.model';
31+
import { DynamicLinkModel } from './builder/ds-dynamic-form-ui/models/ds-dynamic-link.model';
32+
import { DynamicConcatModel } from './builder/ds-dynamic-form-ui/models/ds-dynamic-concat.model';
3133

3234
export interface MetadataFields {
3335
[key: string]: FormFieldMetadataValueObject[]
@@ -53,9 +55,9 @@ export class FormComponent implements OnDestroy, OnInit {
5355
@Input() displaySubmit = true;
5456

5557
/**
56-
* A boolean that indicate if to display form's reset button
58+
* A boolean that indicate if to display form's cancel button
5759
*/
58-
@Input() displayReset = true;
60+
@Input() displayCancel = true;
5961

6062
/**
6163
* A String that indicate the entity type of the item
@@ -78,9 +80,9 @@ export class FormComponent implements OnDestroy, OnInit {
7880
@Input() submitLabel = 'form.submit';
7981

8082
/**
81-
* i18n key for the reset button
83+
* i18n key for the cancel button
8284
*/
83-
@Input() resetLabel = 'form.reset';
85+
@Input() cancelLabel = 'form.cancel';
8486

8587
/**
8688
* An array of DynamicFormControlModel type
@@ -348,14 +350,20 @@ export class FormComponent implements OnDestroy, OnInit {
348350
removeItem($event, arrayContext: DynamicFormArrayModel, index: number): void {
349351
const formArrayControl = this.formGroup.get(this.formBuilderService.getPath(arrayContext)) as UntypedFormArray;
350352
const event = this.getEvent($event, arrayContext, index, 'remove');
353+
console.log(formArrayControl, event);
351354
if (this.formBuilderService.isQualdropGroup(event.model as DynamicFormControlModel) || this.isInlineGroupForm) {
352355
// In case of qualdrop value or inline-group remove event must be dispatched before removing the control from array
353356
this.removeArrayItem.emit(event);
354357
}
355358
if (index === 0 && formArrayControl.value?.length === 1) {
356359
event.model = cloneDeep(event.model);
357360
const fieldId = event.model.id;
358-
formArrayControl.at(0).get(fieldId).setValue(null);
361+
362+
if (event.model instanceof DynamicLinkModel || event.model instanceof DynamicConcatModel) {
363+
formArrayControl.at(0).get(fieldId).reset();
364+
} else {
365+
formArrayControl.at(0).get(fieldId).setValue(null);
366+
}
359367
} else {
360368
this.formBuilderService.removeFormArrayGroup(index, formArrayControl, arrayContext);
361369
}
@@ -424,29 +432,27 @@ export class FormComponent implements OnDestroy, OnInit {
424432

425433
private updateMetadataValue(metadataFields: MetadataFields): void {
426434
const metadataKeys = hasValue(metadataFields) ? Object.keys(metadataFields) : [];
427-
const formKeys = hasValue(this.formGroup.value) ? Object.keys(this.formGroup.value) : [];
428-
429-
formKeys
430-
.filter((key) => isNotEmpty(this.formGroup.value[key]))
431-
.forEach((key) => {
432-
const innerObjectKeys = (Object.keys(this.formGroup.value[key]) as any[]).map((oldKey) => oldKey.replaceAll('_', '.'));
433-
const filteredKeys = innerObjectKeys.filter(innerKey => metadataKeys.includes(innerKey));
434-
const oldValue = this.formGroup.value[key];
435-
436-
if (filteredKeys.length > 0) {
437-
filteredKeys.forEach((oldValueKey) => {
438-
const newValue = { ...oldValue };
439-
const formattedKey = (oldValueKey as any).replaceAll('.', '_');
440-
const patchValue = {};
441-
442-
newValue[formattedKey] = metadataFields[oldValueKey][0];
443-
patchValue[key] = newValue;
444-
445-
if (!isEqual(oldValue[oldValueKey], newValue[oldValueKey])) {
446-
this.formGroup.patchValue(patchValue);
447-
}
448-
});
449-
}
450-
});
435+
const formKeys = hasValue(this.formGroup.value) ? Object.keys(this.formGroup.value).map(key => key.replace('_array', '')) : [];
436+
437+
formKeys.forEach((key) => {
438+
const innerObjectKeys = (Object.keys(this.formGroup.value[key] ?? {} ) as any[]).map((oldKey) => oldKey.replaceAll('_', '.'));
439+
const filteredKeys = innerObjectKeys.filter(innerKey => metadataKeys.includes(innerKey));
440+
const oldValue = this.formGroup.value[key];
441+
442+
if (filteredKeys.length > 0) {
443+
filteredKeys.forEach((oldValueKey) => {
444+
const newValue = {...oldValue};
445+
const formattedKey = (oldValueKey as any).replaceAll('.', '_');
446+
const patchValue = {};
447+
448+
newValue[formattedKey] = metadataFields[oldValueKey][0];
449+
patchValue[key] = newValue;
450+
451+
if (!isEqual(oldValue[oldValueKey], newValue[oldValueKey])) {
452+
this.formGroup.patchValue(patchValue);
453+
}
454+
});
455+
}
456+
});
451457
}
452458
}

src/app/shared/form/form.service.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from './form.actions';
2222
import { FormEntry, FormError, FormTouchedState } from './form.reducer';
2323
import { environment } from '../../../environments/environment';
24+
import { DynamicLinkModel } from './builder/ds-dynamic-form-ui/models/ds-dynamic-link.model';
2425

2526
@Injectable()
2627
export class FormService {
@@ -137,6 +138,7 @@ export class FormService {
137138
}
138139

139140
public addErrorToField(field: AbstractControl, model: DynamicFormControlModel, message: string) {
141+
140142
const error = {}; // create the error object
141143
const errorKey = this.getValidatorNameFromMap(message);
142144
let errorMsg = message;
@@ -163,9 +165,9 @@ export class FormService {
163165
}
164166

165167
// if the field in question is a concat group, pass down the error to its fields
166-
if (field instanceof UntypedFormGroup && model instanceof DynamicFormGroupModel && this.formBuilderService.isConcatGroup(model)) {
168+
if ((field instanceof UntypedFormGroup && model instanceof DynamicFormGroupModel && this.formBuilderService.isConcatGroup(model)) || model instanceof DynamicLinkModel) {
167169
model.group.forEach((subModel) => {
168-
const subField = field.controls[subModel.id];
170+
const subField = (field as UntypedFormGroup).controls[subModel.id];
169171

170172
this.addErrorToField(subField, subModel, message);
171173
});

src/assets/i18n/en.json5

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2143,6 +2143,8 @@
21432143

21442144
"error.validation.groupExists": "This group already exists",
21452145

2146+
"error.validation.invalidProjectURL": "The URL of the project is invalid",
2147+
21462148
"error.validation.metadata.name.invalid-pattern": "This field cannot contain dots, commas or spaces. Please use the Element & Qualifier fields instead",
21472149

21482150
"error.validation.metadata.name.max-length": "This field may not contain more than 32 characters",

0 commit comments

Comments
 (0)