diff --git a/src/Squidex.Core/Schemas/BooleanFieldProperties.cs b/src/Squidex.Core/Schemas/BooleanFieldProperties.cs index b125e0602..f7ce8c23c 100644 --- a/src/Squidex.Core/Schemas/BooleanFieldProperties.cs +++ b/src/Squidex.Core/Schemas/BooleanFieldProperties.cs @@ -49,7 +49,7 @@ namespace Squidex.Core.Schemas { if (!Editor.IsEnumValue()) { - yield return new ValidationError("Editor ist not a valid value", nameof(Editor)); + yield return new ValidationError("Editor is not a valid value", nameof(Editor)); } } } diff --git a/src/Squidex.Core/Schemas/DateTimeCalculatedDefaultValue.cs b/src/Squidex.Core/Schemas/DateTimeCalculatedDefaultValue.cs new file mode 100644 index 000000000..090985be7 --- /dev/null +++ b/src/Squidex.Core/Schemas/DateTimeCalculatedDefaultValue.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// DateTimeCalculatedDefaultValue.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +namespace Squidex.Core.Schemas +{ + public enum DateTimeCalculatedDefaultValue + { + Now, + Today + } +} diff --git a/src/Squidex.Core/Schemas/DateTimeFieldProperties.cs b/src/Squidex.Core/Schemas/DateTimeFieldProperties.cs index 189911847..3bd74b467 100644 --- a/src/Squidex.Core/Schemas/DateTimeFieldProperties.cs +++ b/src/Squidex.Core/Schemas/DateTimeFieldProperties.cs @@ -6,17 +6,23 @@ // All rights reserved. // ========================================================================== +using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Infrastructure; +// ReSharper disable ConvertIfStatementToSwitchStatement +// ReSharper disable RedundantIfElseBlock +// ReSharper disable InvertIf + namespace Squidex.Core.Schemas { [TypeName("DateTime")] public sealed class DateTimeFieldProperties : FieldProperties { private DateTimeFieldEditor editor; + private DateTimeCalculatedDefaultValue? calculatedDefaultValue; private Instant? maxValue; private Instant? minValue; private Instant? defaultValue; @@ -54,6 +60,17 @@ namespace Squidex.Core.Schemas } } + public DateTimeCalculatedDefaultValue? CalculatedDefaultValue + { + get { return calculatedDefaultValue; } + set + { + ThrowIfFrozen(); + + calculatedDefaultValue = value; + } + } + public DateTimeFieldEditor Editor { get { return editor; } @@ -67,14 +84,25 @@ namespace Squidex.Core.Schemas public override JToken GetDefaultValue() { - return DefaultValue?.ToString(); + if (CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Now) + { + return DateTime.UtcNow.ToString("o"); + } + else if (CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Today) + { + return DateTime.UtcNow.Date.ToString("o"); + } + else + { + return DefaultValue?.ToString(); + } } protected override IEnumerable ValidateCore() { if (!Editor.IsEnumValue()) { - yield return new ValidationError("Editor ist not a valid value", nameof(Editor)); + yield return new ValidationError("Editor is not a valid value", nameof(Editor)); } if (MaxValue.HasValue && MinValue.HasValue && MinValue.Value >= MaxValue.Value) @@ -91,6 +119,19 @@ namespace Squidex.Core.Schemas { yield return new ValidationError("Default value must be less than max value", nameof(DefaultValue)); } + + if (CalculatedDefaultValue.HasValue) + { + if (!CalculatedDefaultValue.Value.IsEnumValue()) + { + yield return new ValidationError("Calculated default value is not valid", nameof(CalculatedDefaultValue)); + } + + if (DefaultValue.HasValue) + { + yield return new ValidationError("Calculated default value and default value cannot be used together", nameof(CalculatedDefaultValue), nameof(DefaultValue)); + } + } } } } diff --git a/src/Squidex.Core/Schemas/GeolocationFieldProperties.cs b/src/Squidex.Core/Schemas/GeolocationFieldProperties.cs index ffb4cbca4..324de2aa8 100644 --- a/src/Squidex.Core/Schemas/GeolocationFieldProperties.cs +++ b/src/Squidex.Core/Schemas/GeolocationFieldProperties.cs @@ -37,7 +37,7 @@ namespace Squidex.Core.Schemas { if (!Editor.IsEnumValue()) { - yield return new ValidationError("Editor ist not a valid value", nameof(Editor)); + yield return new ValidationError("Editor is not a valid value", nameof(Editor)); } } } diff --git a/src/Squidex.Core/Schemas/NumberFieldProperties.cs b/src/Squidex.Core/Schemas/NumberFieldProperties.cs index 9f2625c34..ea80ef7e3 100644 --- a/src/Squidex.Core/Schemas/NumberFieldProperties.cs +++ b/src/Squidex.Core/Schemas/NumberFieldProperties.cs @@ -86,7 +86,7 @@ namespace Squidex.Core.Schemas { if (!Editor.IsEnumValue()) { - yield return new ValidationError("Editor ist not a valid value", nameof(Editor)); + yield return new ValidationError("Editor is not a valid value", nameof(Editor)); } if ((Editor == NumberFieldEditor.Radio || Editor == NumberFieldEditor.Dropdown) && (AllowedValues == null || AllowedValues.Count == 0)) diff --git a/src/Squidex.Core/Schemas/StringFieldProperties.cs b/src/Squidex.Core/Schemas/StringFieldProperties.cs index 41f80867a..2345b3529 100644 --- a/src/Squidex.Core/Schemas/StringFieldProperties.cs +++ b/src/Squidex.Core/Schemas/StringFieldProperties.cs @@ -112,7 +112,7 @@ namespace Squidex.Core.Schemas { if (!Editor.IsEnumValue()) { - yield return new ValidationError("Editor ist not a valid value", nameof(Editor)); + yield return new ValidationError("Editor is not a valid value", nameof(Editor)); } if ((Editor == StringFieldEditor.Radio || Editor == StringFieldEditor.Dropdown) && (AllowedValues == null || AllowedValues.Count == 0)) diff --git a/src/Squidex/Controllers/Api/Schemas/Models/DateTimeFieldPropertiesDto.cs b/src/Squidex/Controllers/Api/Schemas/Models/DateTimeFieldPropertiesDto.cs index b327fa5e8..6a53e428d 100644 --- a/src/Squidex/Controllers/Api/Schemas/Models/DateTimeFieldPropertiesDto.cs +++ b/src/Squidex/Controllers/Api/Schemas/Models/DateTimeFieldPropertiesDto.cs @@ -39,6 +39,12 @@ namespace Squidex.Controllers.Api.Schemas.Models [JsonConverter(typeof(StringEnumConverter))] public DateTimeFieldEditor Editor { get; set; } + /// + /// The calculated default value for the field value. + /// + [JsonConverter(typeof(StringEnumConverter))] + public DateTimeCalculatedDefaultValue? CalculatedDefaultValue { get; set; } + public override FieldProperties ToProperties() { var result = SimpleMapper.Map(this, new DateTimeFieldProperties()); diff --git a/src/Squidex/app/features/content/pages/content/content-field.component.html b/src/Squidex/app/features/content/pages/content/content-field.component.html index 85f8f9781..815d5f232 100644 --- a/src/Squidex/app/features/content/pages/content/content-field.component.html +++ b/src/Squidex/app/features/content/pages/content/content-field.component.html @@ -26,7 +26,7 @@
@@ -48,7 +48,7 @@
diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html index eaf21d029..39847533f 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html @@ -51,7 +51,7 @@
diff --git a/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.html b/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.html index be0594485..e40bdf9ed 100644 --- a/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.html +++ b/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.html @@ -23,11 +23,24 @@
-
- +
+
+ -
- +
+ +
+
+ +
+ + +
+ +
\ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.ts b/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.ts index 3c0803105..1527b47ee 100644 --- a/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/types/date-time-validation.component.ts @@ -9,7 +9,7 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core import { FormControl, FormGroup } from '@angular/forms'; import { Observable } from 'rxjs'; -import { NumberFieldPropertiesDto, ValidatorsEx } from 'shared'; +import { DateTimeFieldPropertiesDto, ValidatorsEx } from 'shared'; @Component({ selector: 'sqx-date-time-validation', @@ -22,11 +22,17 @@ export class DateTimeValidationComponent implements OnInit { public editForm: FormGroup; @Input() - public properties: NumberFieldPropertiesDto; + public properties: DateTimeFieldPropertiesDto; + public hideDefaultValues: Observable; public hideDefaultValue: Observable; + public calculatedDefaultValues = ['Now', 'Today']; + public ngOnInit() { + this.editForm.addControl('calculatedDefaultValue', + new FormControl(this.properties.calculatedDefaultValue)); + this.editForm.addControl('maxValue', new FormControl(this.properties.maxValue, [ ValidatorsEx.validDateTime() @@ -42,9 +48,14 @@ export class DateTimeValidationComponent implements OnInit { ValidatorsEx.validDateTime() ])); - this.hideDefaultValue = + this.hideDefaultValues = this.editForm.get('isRequired').valueChanges .startWith(this.properties.isRequired) .map(x => !!x); + + this.hideDefaultValue = + this.editForm.get('calculatedDefaultValue').valueChanges + .startWith(this.properties.calculatedDefaultValue) + .map(x => !!x); } } \ No newline at end of file diff --git a/src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html b/src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html index de510b727..6ad89bc72 100644 --- a/src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html +++ b/src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html @@ -53,7 +53,7 @@ diff --git a/src/Squidex/app/shared/services/schemas.service.ts b/src/Squidex/app/shared/services/schemas.service.ts index d51561ee8..e41123bec 100644 --- a/src/Squidex/app/shared/services/schemas.service.ts +++ b/src/Squidex/app/shared/services/schemas.service.ts @@ -160,7 +160,8 @@ export class DateTimeFieldPropertiesDto extends FieldPropertiesDto { public readonly editor: string, public readonly defaultValue?: string, public readonly maxValue?: string, - public readonly minValue?: string + public readonly minValue?: string, + public readonly calculatedDefaultValue?: string ) { super('DateTime', label, hints, placeholder, isRequired, isListField, isLocalizable); } diff --git a/tests/Squidex.Core.Tests/Schemas/BooleanFieldPropertiesTests.cs b/tests/Squidex.Core.Tests/Schemas/BooleanFieldPropertiesTests.cs index 25371a717..80506d4ea 100644 --- a/tests/Squidex.Core.Tests/Schemas/BooleanFieldPropertiesTests.cs +++ b/tests/Squidex.Core.Tests/Schemas/BooleanFieldPropertiesTests.cs @@ -30,7 +30,7 @@ namespace Squidex.Core.Schemas errors.ShouldBeEquivalentTo( new List { - new ValidationError("Editor ist not a valid value", "Editor") + new ValidationError("Editor is not a valid value", "Editor") }); } diff --git a/tests/Squidex.Core.Tests/Schemas/DateTimeFieldPropertiesTests.cs b/tests/Squidex.Core.Tests/Schemas/DateTimeFieldPropertiesTests.cs index 365b65bb5..ab8c15b1a 100644 --- a/tests/Squidex.Core.Tests/Schemas/DateTimeFieldPropertiesTests.cs +++ b/tests/Squidex.Core.Tests/Schemas/DateTimeFieldPropertiesTests.cs @@ -88,10 +88,62 @@ namespace Squidex.Core.Schemas errors.ShouldBeEquivalentTo( new List { - new ValidationError("Editor ist not a valid value", "Editor") + new ValidationError("Editor is not a valid value", "Editor") }); } + [Fact] + public void Should_add_error_if_calculated_default_value_is_not_valid() + { + var sut = new DateTimeFieldProperties { CalculatedDefaultValue = (DateTimeCalculatedDefaultValue)123 }; + + sut.Validate(errors); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Calculated default value is not valid", "CalculatedDefaultValue") + }); + } + + [Fact] + public void Should_add_error_if_calculated_default_value_default_value_is_defined() + { + var sut = new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Now, DefaultValue = FutureDays(10) }; + + sut.Validate(errors); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Calculated default value and default value cannot be used together", "CalculatedDefaultValue", "DefaultValue") + }); + } + + [Fact] + public void Should_provide_today_default_value() + { + var sut = new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Today }; + + Assert.Equal(DateTime.UtcNow.Date.ToString("o"), sut.GetDefaultValue().ToString()); + } + + [Fact] + public void Should_provide_now_default_value() + { + var sut = new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Now }; + + Assert.Equal(DateTime.UtcNow.ToString("o").Substring(0, 16), sut.GetDefaultValue().ToString().Substring(0, 16)); + } + + [Fact] + public void Should_provide_specific_default_value() + { + var sut = new DateTimeFieldProperties { DefaultValue = FutureDays(15) }; + + Assert.Equal(FutureDays(15).ToString(), sut.GetDefaultValue()); + } + [Fact] public void Should_set_or_freeze_sut() { diff --git a/tests/Squidex.Core.Tests/Schemas/GeolocationPropertiesTests.cs b/tests/Squidex.Core.Tests/Schemas/GeolocationPropertiesTests.cs index d858f704e..a8c96ae83 100644 --- a/tests/Squidex.Core.Tests/Schemas/GeolocationPropertiesTests.cs +++ b/tests/Squidex.Core.Tests/Schemas/GeolocationPropertiesTests.cs @@ -30,7 +30,7 @@ namespace Squidex.Core.Schemas errors.ShouldBeEquivalentTo( new List { - new ValidationError("Editor ist not a valid value", "Editor") + new ValidationError("Editor is not a valid value", "Editor") }); } diff --git a/tests/Squidex.Core.Tests/Schemas/NumberFieldPropertiesTests.cs b/tests/Squidex.Core.Tests/Schemas/NumberFieldPropertiesTests.cs index e9199d4a3..bc56e3514 100644 --- a/tests/Squidex.Core.Tests/Schemas/NumberFieldPropertiesTests.cs +++ b/tests/Squidex.Core.Tests/Schemas/NumberFieldPropertiesTests.cs @@ -130,7 +130,7 @@ namespace Squidex.Core.Schemas errors.ShouldBeEquivalentTo( new List { - new ValidationError("Editor ist not a valid value", "Editor") + new ValidationError("Editor is not a valid value", "Editor") }); } diff --git a/tests/Squidex.Core.Tests/Schemas/StringFieldPropertiesTests.cs b/tests/Squidex.Core.Tests/Schemas/StringFieldPropertiesTests.cs index 4af87e959..fc1600ade 100644 --- a/tests/Squidex.Core.Tests/Schemas/StringFieldPropertiesTests.cs +++ b/tests/Squidex.Core.Tests/Schemas/StringFieldPropertiesTests.cs @@ -87,7 +87,7 @@ namespace Squidex.Core.Schemas errors.ShouldBeEquivalentTo( new List { - new ValidationError("Editor ist not a valid value", "Editor") + new ValidationError("Editor is not a valid value", "Editor") }); }