diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayCalculatedDefaultValue.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayCalculatedDefaultValue.cs new file mode 100644 index 000000000..c74a7a6b8 --- /dev/null +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayCalculatedDefaultValue.cs @@ -0,0 +1,14 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Domain.Apps.Core.Schemas; + +public enum ArrayCalculatedDefaultValue +{ + EmptyArray, + Null +} diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs index d5be61a81..3a6e74c40 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs @@ -15,6 +15,8 @@ public sealed record ArrayFieldProperties : FieldProperties public int? MaxItems { get; init; } + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; init; } + public ReadonlyList? UniqueFields { get; init; } public override T Accept(IFieldPropertiesVisitor visitor, TArgs args) diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs index 4cbff3585..09a7bf436 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs @@ -18,6 +18,8 @@ public sealed record ComponentsFieldProperties : FieldProperties public ReadonlyList? UniqueFields { get; init; } + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; init; } + public DomainId SchemaId { init diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs index e5e3be6bd..3a4c50dce 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs @@ -33,6 +33,21 @@ public sealed class DefaultValueFactory : IFieldPropertiesVisitor public int? MaxItems { get; set; } + /// + /// The calculated default value for the field value. + /// + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; set; } + /// /// The fields that must be unique. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs index f048b4f8a..7301f8ed0 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs @@ -26,6 +26,11 @@ public sealed class ComponentsFieldPropertiesDto : FieldPropertiesDto /// public int? MaxItems { get; set; } + /// + /// The calculated default value for the field value. + /// + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; set; } + /// /// The ID of the embedded schemas. /// diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs index c388fa6d3..f3b53bcef 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs @@ -19,6 +19,26 @@ public class DefaultValueFactoryTests private readonly Instant now = Instant.FromUtc(2017, 10, 12, 16, 30, 10); private readonly Language language = Language.DE; + [Fact] + public void Should_get_default_value_from_array_field() + { + var field = + Fields.Array(1, "1", Partitioning.Invariant, + new ArrayFieldProperties()); + + Assert.Equal(new JsonArray(), DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + + [Fact] + public void Should_get_default_value_from_array_field_if_set_to_null() + { + var field = + Fields.Array(1, "1", Partitioning.Invariant, + new ArrayFieldProperties { CalculatedDefaultValue = ArrayCalculatedDefaultValue.Null }); + + Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + [Fact] public void Should_get_default_value_from_assets_field() { @@ -83,6 +103,26 @@ public class DefaultValueFactoryTests Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); } + [Fact] + public void Should_get_default_value_from_components_field() + { + var field = + Fields.Components(1, "1", Partitioning.Invariant, + new ComponentsFieldProperties()); + + Assert.Equal(new JsonArray(), DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + + [Fact] + public void Should_get_default_value_from_components_field_if_set_to_null() + { + var field = + Fields.Components(1, "1", Partitioning.Invariant, + new ComponentsFieldProperties { CalculatedDefaultValue = ArrayCalculatedDefaultValue.Null }); + + Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + [Fact] public void Should_get_default_value_from_datetime_field() { diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json index 498ac7af4..2235e95eb 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json @@ -130,6 +130,7 @@ "isDisabled": false, "properties": { "$type": "ComponentsField", + "calculatedDefaultValue": "EmptyArray", "schemaId": "62a1d2a8-f08d-4870-8cb9-cb3ba286d56c", "schemaIds": [ "62a1d2a8-f08d-4870-8cb9-cb3ba286d56c" @@ -267,6 +268,7 @@ "isDisabled": false, "properties": { "$type": "ArrayField", + "calculatedDefaultValue": "EmptyArray", "isRequired": false, "isRequiredOnPublish": false, "isHalfWidth": false diff --git a/frontend/src/app/features/schemas/module.ts b/frontend/src/app/features/schemas/module.ts index ae1b30e23..861285a68 100644 --- a/frontend/src/app/features/schemas/module.ts +++ b/frontend/src/app/features/schemas/module.ts @@ -9,6 +9,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HelpComponent, HistoryComponent, LoadSchemasGuard, SchemaMustExistGuard, SqxFrameworkModule, SqxSharedModule } from '@app/shared'; import { ArrayValidationComponent, AssetsUIComponent, AssetsValidationComponent, BooleanUIComponent, BooleanValidationComponent, ComponentsUIComponent, ComponentsValidationComponent, ComponentUIComponent, ComponentValidationComponent, DateTimeUIComponent, DateTimeValidationComponent, FieldComponent, FieldFormCommonComponent, FieldFormComponent, FieldFormUIComponent, FieldFormValidationComponent, FieldGroupComponent, FieldListComponent, FieldWizardComponent, GeolocationUIComponent, GeolocationValidationComponent, JsonMoreComponent, JsonUIComponent, JsonValidationComponent, NumberUIComponent, NumberValidationComponent, ReferencesUIComponent, ReferencesValidationComponent, SchemaEditFormComponent, SchemaExportFormComponent, SchemaFieldRulesFormComponent, SchemaFieldsComponent, SchemaFormComponent, SchemaPageComponent, SchemaPreviewUrlsFormComponent, SchemaScriptsFormComponent, SchemasPageComponent, SchemaUIFormComponent, SortableFieldListComponent, StringUIComponent, StringValidationComponent, TagsUIComponent, TagsValidationComponent } from './declarations'; +import { ArrayUIComponent } from './pages/schema/fields/types/array-ui.component'; const routes: Routes = [ { @@ -51,6 +52,7 @@ const routes: Routes = [ SchemaMustExistGuard, ], declarations: [ + ArrayUIComponent, ArrayValidationComponent, AssetsUIComponent, AssetsValidationComponent, diff --git a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html index 300c95e8c..7416d0e45 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html @@ -13,6 +13,9 @@ + + + diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.html new file mode 100644 index 000000000..f3fbddf8d --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.html @@ -0,0 +1,11 @@ +
+
+ + +
+ +
+
+
\ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.scss b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.scss new file mode 100644 index 000000000..2742d895e --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.scss @@ -0,0 +1,2 @@ +@import 'mixins'; +@import 'vars'; \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.ts new file mode 100644 index 000000000..cd10bf685 --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.ts @@ -0,0 +1,30 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Component, Input } from '@angular/core'; +import { UntypedFormGroup } from '@angular/forms'; +import { ArrayFieldPropertiesDto, FieldDto } from '@app/shared'; + +const CALCULATED_DEFAULT_VALUES: ReadonlyArray = ['EmptyArray', 'Null']; + +@Component({ + selector: 'sqx-array-ui', + styleUrls: ['array-ui.component.scss'], + templateUrl: 'array-ui.component.html', +}) +export class ArrayUIComponent { + @Input({ required: true }) + public fieldForm!: UntypedFormGroup; + + @Input({ required: true }) + public field!: FieldDto; + + @Input({ required: true }) + public properties!: ArrayFieldPropertiesDto; + + public calculatedDefaultValues = CALCULATED_DEFAULT_VALUES; +} diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html index e69de29bb..f3fbddf8d 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html @@ -0,0 +1,11 @@ +
+
+ + +
+ +
+
+
\ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts index 671346161..508417b4d 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts @@ -9,6 +9,8 @@ import { Component, Input } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared'; +const CALCULATED_DEFAULT_VALUES: ReadonlyArray = ['EmptyArray', 'Null']; + @Component({ selector: 'sqx-components-ui', styleUrls: ['components-ui.component.scss'], @@ -23,4 +25,6 @@ export class ComponentsUIComponent { @Input({ required: true }) public properties!: ReferencesFieldPropertiesDto; + + public calculatedDefaultValues = CALCULATED_DEFAULT_VALUES; } diff --git a/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts b/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts index 4bac0f7af..6f8acca46 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts @@ -41,6 +41,18 @@ describe('UndefinableFormArray', () => { valueActual: [1], }]; + it('should initialize with undefined', () => { + const control = new UndefinableFormArray(); + + expect(control.value).toBeUndefined(); + }); + + it('should initialize with empty array', () => { + const control = new UndefinableFormArray([]); + + expect(control.value).toEqual([]); + }); + it('should provide value even if controls are disabled', () => { const control = new UndefinableFormArray([ new UntypedFormControl('1'), diff --git a/frontend/src/app/framework/angular/forms/extended-form-array.ts b/frontend/src/app/framework/angular/forms/extended-form-array.ts index 9913c1fef..ed024f902 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-array.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-array.ts @@ -25,8 +25,8 @@ export class ExtendedFormArray extends UntypedFormArray { export class UndefinableFormArray extends ExtendedFormArray { private isUndefined = false; - constructor(controls: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { - super(controls, validatorOrOpts, asyncValidator); + constructor(controls?: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { + super(controls || [], validatorOrOpts, asyncValidator); const reduce = (this as any)['_reduceValue']; @@ -37,6 +37,12 @@ export class UndefinableFormArray extends ExtendedFormArray { return reduce.apply(this); } }; + + if (Types.isUndefined(controls)) { + this.isUndefined = true; + + super.reset([], { emitEvent: false }); + } } public getRawValue() { diff --git a/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts b/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts index 9da6d9c3d..4bf25cfbb 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts @@ -8,7 +8,7 @@ import { UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { ExtendedFormGroup, UndefinableFormGroup } from './extended-form-group'; -describe('UndefinableFormGroup', () => { +describe('ExtendedFormGroup', () => { it('should provide value even if controls are disabled', () => { const control = new ExtendedFormGroup({ test1: new UntypedFormControl('1'), @@ -23,7 +23,7 @@ describe('UndefinableFormGroup', () => { }); }); -describe('ExtendedFormGroup', () => { +describe('UndefinableFormGroup', () => { const tests = [{ name: 'undefined (on)', undefinable: true, @@ -41,8 +41,20 @@ describe('ExtendedFormGroup', () => { valueActual: { field: 1 }, }]; + it('should initialize with undefined', () => { + const control = new UndefinableFormGroup(); + + expect(control.value).toBeUndefined(); + }); + + it('should initialize with empty array', () => { + const control = new UndefinableFormGroup({}); + + expect(control.value).toEqual({}); + }); + it('should provide value even if controls are disabled', () => { - const control = new ExtendedFormGroup({ + const control = new UndefinableFormGroup({ test1: new UntypedFormControl('1'), test2: new UntypedFormControl('2'), }); diff --git a/frontend/src/app/framework/angular/forms/extended-form-group.ts b/frontend/src/app/framework/angular/forms/extended-form-group.ts index ab65bcdd6..e08e7328f 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-group.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-group.ts @@ -31,8 +31,8 @@ export class ExtendedFormGroup extends UntypedFormGroup { export class UndefinableFormGroup extends ExtendedFormGroup { private isUndefined = false; - constructor(controls: { [key: string]: AbstractControl }, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { - super(controls, validatorOrOpts, asyncValidator); + constructor(controls?: { [key: string]: AbstractControl }, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { + super(controls || {}, validatorOrOpts, asyncValidator); const reduce = (this as any)['_reduceValue']; @@ -43,6 +43,12 @@ export class UndefinableFormGroup extends ExtendedFormGroup { return reduce.apply(this); } }; + + if (Types.isUndefined(controls)) { + this.isUndefined = true; + + super.reset({}, { emitEvent: false }); + } } public getRawValue() { diff --git a/frontend/src/app/framework/angular/forms/templated-form-array.ts b/frontend/src/app/framework/angular/forms/templated-form-array.ts index ebd70a7ee..079309965 100644 --- a/frontend/src/app/framework/angular/forms/templated-form-array.ts +++ b/frontend/src/app/framework/angular/forms/templated-form-array.ts @@ -21,7 +21,7 @@ export class TemplatedFormArray extends UndefinableFormArray { constructor(public readonly template: FormArrayTemplate, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null, ) { - super([], validatorOrOpts, asyncValidator); + super(undefined, validatorOrOpts, asyncValidator); } public setValue(value?: any[], options?: { onlySelf?: boolean; emitEvent?: boolean }) { diff --git a/frontend/src/app/framework/angular/forms/templated-form-group.ts b/frontend/src/app/framework/angular/forms/templated-form-group.ts index f2704bcea..a3fdaf7a5 100644 --- a/frontend/src/app/framework/angular/forms/templated-form-group.ts +++ b/frontend/src/app/framework/angular/forms/templated-form-group.ts @@ -19,7 +19,7 @@ export class TemplatedFormGroup extends UndefinableFormGroup { constructor(public readonly template: FormGroupTemplate, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null, ) { - super({}, validatorOrOpts, asyncValidator); + super(undefined, validatorOrOpts, asyncValidator); } public setValue(value?: {}, options?: { onlySelf?: boolean; emitEvent?: boolean }) { diff --git a/frontend/src/app/shared/services/schemas.types.ts b/frontend/src/app/shared/services/schemas.types.ts index 77cdd8a94..aa2722b0f 100644 --- a/frontend/src/app/shared/services/schemas.types.ts +++ b/frontend/src/app/shared/services/schemas.types.ts @@ -179,6 +179,7 @@ export abstract class FieldPropertiesDto { export class ArrayFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'Array'; + public readonly calculatedDefaultValue: 'EmptyArray' | 'Null' = 'EmptyArray'; public readonly maxItems?: number; public readonly minItems?: number; public readonly uniqueFields?: ReadonlyArray; @@ -269,6 +270,7 @@ export class ComponentFieldPropertiesDto extends FieldPropertiesDto { export class ComponentsFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'Components'; + public readonly calculatedDefaultValue: 'EmptyArray' | 'Null' = 'EmptyArray'; public readonly schemaIds?: ReadonlyArray; public readonly maxItems?: number; public readonly minItems?: number; @@ -293,7 +295,7 @@ export const DATETIME_FIELD_EDITORS: ReadonlyArray = [ export class DateTimeFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'DateTime'; - public readonly calculatedDefaultValue?: string; + public readonly calculatedDefaultValue?: 'Now' | 'Today'; public readonly defaultValue?: string; public readonly defaultValues?: DefaultValue; public readonly format?: string; diff --git a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts index e140448d9..a74b64e76 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts @@ -38,8 +38,14 @@ describe('ArrayField', () => { expect(FieldFormatter.format(field, 1)).toBe('0 Items'); }); - it('should return default value as null', () => { - expect(FieldDefaultValue.get(field, 'iv')).toBeNull(); + it('should return default value as empty array', () => { + expect(FieldDefaultValue.get(field, 'iv')).toEqual([]); + }); + + it('should return default value as null when configured', () => { + const field2 = createField({ properties: createProperties('Array', { calculatedDefaultValue: 'Null' }) }); + + expect(FieldDefaultValue.get(field2, 'iv')).toBeNull(); }); }); @@ -130,8 +136,14 @@ describe('ComponentsField', () => { expect(FieldFormatter.format(field, 1)).toBe('0 Components'); }); - it('should return default value as null', () => { - expect(FieldDefaultValue.get(field, 'iv')).toBeNull(); + it('should return default value as empty array', () => { + expect(FieldDefaultValue.get(field, 'iv')).toEqual([]); + }); + + it('should return default value as null when configured', () => { + const field2 = createField({ properties: createProperties('Components', { calculatedDefaultValue: 'Null' }) }); + + expect(FieldDefaultValue.get(field2, 'iv')).toBeNull(); }); }); diff --git a/frontend/src/app/shared/state/contents.forms.visitors.ts b/frontend/src/app/shared/state/contents.forms.visitors.ts index cf1c7b490..884bb3caa 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.ts @@ -417,8 +417,20 @@ export class FieldDefaultValue implements FieldPropertiesVisitor { } } - public visitArray(_: ArrayFieldPropertiesDto): any { - return null; + public visitArray(properties: ArrayFieldPropertiesDto): any { + if (properties.calculatedDefaultValue === 'Null') { + return null; + } + + return []; + } + + public visitComponents(properties: ComponentsFieldPropertiesDto): any { + if (properties.calculatedDefaultValue === 'Null') { + return null; + } + + return []; } public visitAssets(properties: AssetsFieldPropertiesDto): any { @@ -433,10 +445,6 @@ export class FieldDefaultValue implements FieldPropertiesVisitor { return null; } - public visitComponents(_: ComponentsFieldPropertiesDto): any { - return null; - } - public visitGeolocation(_: GeolocationFieldPropertiesDto): any { return null; } diff --git a/frontend/src/app/shared/state/schemas.forms.ts b/frontend/src/app/shared/state/schemas.forms.ts index e30b441d7..2ff127472 100644 --- a/frontend/src/app/shared/state/schemas.forms.ts +++ b/frontend/src/app/shared/state/schemas.forms.ts @@ -249,6 +249,7 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor { } public visitArray() { + this.config['calculatedDefaultValue'] = new UntypedFormControl('EmptyArray'); this.config['maxItems'] = new UntypedFormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined); this.config['uniqueFields'] = new UntypedFormControl(undefined); @@ -288,6 +289,7 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor { } public visitComponents() { + this.config['calculatedDefaultValue'] = new UntypedFormControl('EmptyArray'); this.config['schemaIds'] = new UntypedFormControl(undefined); this.config['maxItems'] = new UntypedFormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined);