diff --git a/src/Squidex.Core/PartitioningExtensions.cs b/src/Squidex.Core/PartitioningExtensions.cs new file mode 100644 index 000000000..9d53cff0f --- /dev/null +++ b/src/Squidex.Core/PartitioningExtensions.cs @@ -0,0 +1,27 @@ +// ========================================================================== +// PartitioningExtensions.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Collections.Generic; + +namespace Squidex.Core +{ + public static class PartitioningExtensions + { + private static readonly HashSet AllowedPartitions = new HashSet(StringComparer.OrdinalIgnoreCase) + { + Partitioning.Language.Key, + Partitioning.Invariant.Key + }; + + public static bool IsValidPartitioning(this string value) + { + return value == null || AllowedPartitions.Contains(value); + } + } +} diff --git a/src/Squidex.Events/Schemas/SchemaCreated.cs b/src/Squidex.Events/Schemas/SchemaCreated.cs index c648517ce..b00b95511 100644 --- a/src/Squidex.Events/Schemas/SchemaCreated.cs +++ b/src/Squidex.Events/Schemas/SchemaCreated.cs @@ -9,6 +9,8 @@ using Squidex.Core.Schemas; using Squidex.Infrastructure; +using SchemaFields = System.Collections.Generic.List; + namespace Squidex.Events.Schemas { [TypeName("SchemaCreatedEvent")] @@ -16,6 +18,8 @@ namespace Squidex.Events.Schemas { public string Name { get; set; } + public SchemaFields Fields { get; set; } + public SchemaProperties Properties { get; set; } } } diff --git a/src/Squidex.Events/Schemas/SchemaCreatedField.cs b/src/Squidex.Events/Schemas/SchemaCreatedField.cs new file mode 100644 index 000000000..a2635758d --- /dev/null +++ b/src/Squidex.Events/Schemas/SchemaCreatedField.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// SchemaCreatedField.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using Squidex.Core.Schemas; + +namespace Squidex.Events.Schemas +{ + public sealed class SchemaCreatedField + { + public string Partitioning { get; set; } + + public string Name { get; set; } + + public bool IsHidden { get; set; } + + public bool IsDisabled { get; set; } + + public FieldProperties Properties { get; set; } + } +} diff --git a/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs b/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs index 2cee64c9e..c93f117e9 100644 --- a/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs +++ b/src/Squidex.Events/Schemas/Utils/SchemaEventDispatcher.cs @@ -10,27 +10,59 @@ using System; using Squidex.Core; using Squidex.Core.Schemas; +// ReSharper disable InvertIf // ReSharper disable UnusedParameter.Global namespace Squidex.Events.Schemas.Utils { public static class SchemaEventDispatcher { + public static Schema Dispatch(SchemaCreated @event, FieldRegistry registry) + { + var schema = Schema.Create(@event.Name, @event.Properties); + + if (@event.Fields != null) + { + var fieldId = 1; + + foreach (var eventField in @event.Fields) + { + var partitioning = + string.Equals(eventField.Partitioning, Partitioning.Language.Key, StringComparison.OrdinalIgnoreCase) ? + Partitioning.Language : + Partitioning.Invariant; + + var field = registry.CreateField(fieldId, eventField.Name, partitioning, eventField.Properties); + + if (eventField.IsHidden) + { + field = field.Hide(); + } + + if (eventField.IsDisabled) + { + field = field.Disable(); + } + + schema = schema.AddOrUpdateField(field); + + fieldId++; + } + } + + return schema; + } + public static Schema Dispatch(FieldAdded @event, Schema schema, FieldRegistry registry) { var partitioning = - string.Equals(@event.Partitioning, "language", StringComparison.OrdinalIgnoreCase) ? + string.Equals(@event.Partitioning, Partitioning.Language.Key, StringComparison.OrdinalIgnoreCase) ? Partitioning.Language : Partitioning.Invariant; return schema.AddOrUpdateField(registry.CreateField(@event.FieldId.Id, @event.Name, partitioning, @event.Properties)); } - public static Schema Dispatch(SchemaCreated @event) - { - return Schema.Create(@event.Name, @event.Properties); - } - public static Schema Dispatch(FieldUpdated @event, Schema schema) { return schema.UpdateField(@event.FieldId.Id, @event.Properties); diff --git a/src/Squidex.Write/Schemas/Commands/AddField.cs b/src/Squidex.Write/Schemas/Commands/AddField.cs index 2741f2b90..29a1aa885 100644 --- a/src/Squidex.Write/Schemas/Commands/AddField.cs +++ b/src/Squidex.Write/Schemas/Commands/AddField.cs @@ -6,23 +6,15 @@ // All rights reserved. // ========================================================================== -using System; using System.Collections.Generic; +using Squidex.Core; using Squidex.Core.Schemas; using Squidex.Infrastructure; -using PartitioningOption = Squidex.Core.Partitioning; - namespace Squidex.Write.Schemas.Commands { public class AddField : FieldCommand, IValidatable { - private static readonly HashSet AllowedPartitions = new HashSet(StringComparer.OrdinalIgnoreCase) - { - PartitioningOption.Language.Key, - PartitioningOption.Invariant.Key - }; - public string Name { get; set; } public string Partitioning { get; set; } @@ -31,9 +23,9 @@ namespace Squidex.Write.Schemas.Commands public void Validate(IList errors) { - if (Partitioning != null && !AllowedPartitions.Contains(Partitioning)) + if (!Partitioning.IsValidPartitioning()) { - errors.Add(new ValidationError($"Partitioning must be one of {string.Join(", ", AllowedPartitions)}.", nameof(Partitioning))); + errors.Add(new ValidationError($"Partitioning is not valid.", nameof(Partitioning))); } if (!Name.IsPropertyName()) diff --git a/src/Squidex.Write/Schemas/Commands/CreateSchema.cs b/src/Squidex.Write/Schemas/Commands/CreateSchema.cs index 971e94228..fa8d0cb15 100644 --- a/src/Squidex.Write/Schemas/Commands/CreateSchema.cs +++ b/src/Squidex.Write/Schemas/Commands/CreateSchema.cs @@ -12,27 +12,19 @@ using Squidex.Core.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS.Commands; +using SchemaFields = System.Collections.Generic.List; + namespace Squidex.Write.Schemas.Commands { public class CreateSchema : AppCommand, IValidatable, IAggregateCommand { - private SchemaProperties properties; - - public SchemaProperties Properties - { - get - { - return properties ?? (properties = new SchemaProperties()); - } - set - { - properties = value; - } - } + public Guid SchemaId { get; set; } public string Name { get; set; } - public Guid SchemaId { get; set; } + public SchemaFields Fields { get; set; } = new SchemaFields(); + + public SchemaProperties Properties { get; set; } Guid IAggregateCommand.AggregateId { @@ -50,6 +42,11 @@ namespace Squidex.Write.Schemas.Commands { errors.Add(new ValidationError("Name must be a valid slug", nameof(Name))); } + + if (Properties == null) + { + errors.Add(new ValidationError("Properties must be specified", nameof(Properties))); + } } } } \ No newline at end of file diff --git a/src/Squidex.Write/Schemas/Commands/CreateSchemaField.cs b/src/Squidex.Write/Schemas/Commands/CreateSchemaField.cs new file mode 100644 index 000000000..ca96226db --- /dev/null +++ b/src/Squidex.Write/Schemas/Commands/CreateSchemaField.cs @@ -0,0 +1,48 @@ +// ========================================================================== +// CreateSchemaField.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using Squidex.Core; +using Squidex.Core.Schemas; +using Squidex.Infrastructure; + +namespace Squidex.Write.Schemas.Commands +{ + public sealed class CreateSchemaField + { + public string Partitioning { get; set; } + + public string Name { get; set; } + + public bool IsHidden { get; set; } + + public bool IsDisabled { get; set; } + + public FieldProperties Properties { get; set; } + + public void Validate(int index, IList errors) + { + var prefix = $"Fields.{index}"; + + if (!Partitioning.IsValidPartitioning()) + { + errors.Add(new ValidationError("Partitioning is not valid.", $"{prefix}.{nameof(Partitioning)}")); + } + + if (!Name.IsPropertyName()) + { + errors.Add(new ValidationError("Name must be a valid property name", $"{prefix}.{nameof(Name)}")); + } + + if (Properties == null) + { + errors.Add(new ValidationError("Properties must be defined.", $"{prefix}.{nameof(Properties)}")); + } + } + } +} diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts index 75b97bc0f..ebb130d5a 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts @@ -50,9 +50,9 @@ export class SchemaPageComponent extends AppComponentBase implements OnInit { 'String' ]; - public schemaName: string; - public schemaFields = ImmutableArray.empty(); public schemaExport: any; + public schemaFields = ImmutableArray.empty(); + public schemaName: string; public schemaProperties: SchemaPropertiesDto; public schemaVersion = new Version('');