From 816e77af3ae840d4dad6ddb027be6cd9a41658ab Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Tue, 11 May 2021 19:12:54 +0200 Subject: [PATCH] Refactoring/schema type (#696) * Introduce schema-type. * Make tests more stable. * Metadata provider. * Fix stackoverflow. --- .../src/Migrations/OldEvents/SchemaCreated.cs | 2 +- .../Rules/RuleAction.cs | 1 - .../Rules/RuleTrigger.cs | 2 - .../Schemas/ArrayField.cs | 1 - .../Schemas/FieldBase.cs | 30 +++ .../Schemas/Json/SchemaSurrogate.cs | 27 ++- .../Schemas/Schema.cs | 154 ++++++--------- .../Schemas/SchemaExtensions.cs | 5 + .../Schemas/SchemaProperties.cs | 2 + .../Schemas/SchemaType.cs | 15 ++ .../SchemaSynchronizer.cs | 2 +- .../Apps/Templates/Builders/SchemaBuilder.cs | 2 +- .../DomainObject/ContentDomainObject.cs | 3 +- .../Guards/SingletonExtensions.cs | 7 +- .../DomainObject/Guards/WorkflowExtensions.cs | 5 +- .../Queries/Steps/EnrichWithSchema.cs | 2 +- .../Contents/SingletonCommandMiddleware.cs | 3 +- .../Schemas/Commands/ConfigurePreviewUrls.cs | 4 +- .../Schemas/Commands/CreateSchema.cs | 12 +- .../Schemas/Commands/IUpsertCommand.cs | 8 +- .../Schemas/Commands/SynchronizeSchema.cs | 8 +- .../DomainObject/SchemaDomainObject.cs | 6 +- .../Schemas/SchemasSearchSource.cs | 4 +- .../Schemas/SchemaPreviewUrlsConfigured.cs | 4 +- .../Api/Controllers/Apps/Models/AppDto.cs | 2 +- .../Api/Controllers/Assets/Models/AssetDto.cs | 6 +- .../Areas/Api/Controllers/BulkResultDto.cs | 2 +- .../Contents/ContentsController.cs | 4 +- .../Contents/Models/BulkUpdateContentsDto.cs | 2 +- .../Contents/Models/CreateContentDto.cs | 2 +- .../Contents/Models/ImportContentsDto.cs | 2 +- .../Contents/Models/UpsertContentDto.cs | 2 +- .../Schemas/Models/ConfigurePreviewUrlsDto.cs | 3 +- .../Schemas/Models/ConfigureUIFieldsDto.cs | 20 +- .../Schemas/Models/CreateSchemaDto.cs | 20 +- .../Models/Fields/AssetsFieldPropertiesDto.cs | 2 +- .../Schemas/Models/SchemaDetailsDto.cs | 102 ---------- .../Controllers/Schemas/Models/SchemaDto.cs | 93 +++++++-- .../Schemas/Models/UpsertSchemaDto.cs | 17 +- .../Schemas/SchemaFieldsController.cs | 44 ++--- .../Controllers/Schemas/SchemasController.cs | 28 +-- .../Model/Schemas/SchemaTests.cs | 28 ++- .../SchemaSynchronizerTests.cs | 3 +- .../Operations/GenerateEdmSchema/EdmTests.cs | 4 +- .../TestHelpers/TestUtils.cs | 4 +- .../DefaultWorkflowsValidatorTests.cs | 1 - .../DomainObject/Guards/GuardContentTests.cs | 2 +- .../SingletonCommandMiddlewareTests.cs | 7 +- .../DomainObject/Guards/GuardSchemaTests.cs | 4 +- .../DomainObject/SchemaDomainObjectTests.cs | 10 +- .../Schemas/SchemaCommandsTests.cs | 7 +- .../Schemas/SchemasSearchSourceTests.cs | 14 +- .../Collections/ImmutableListTests.cs | 1 - .../state/event-consumers.state.spec.ts | 4 +- .../administration/state/users.state.spec.ts | 6 +- .../pages/content/content-page.component.ts | 4 +- .../editor/content-editor.component.ts | 4 +- .../pages/contents/contents-page.component.ts | 4 +- .../shared/preview-button.component.ts | 4 +- .../references/content-creator.component.ts | 4 +- .../content-selector-item.component.ts | 4 +- .../references/content-selector.component.ts | 4 +- .../common/schema-edit-form.component.ts | 4 +- .../export/schema-export-form.component.ts | 4 +- .../schema/fields/field-wizard.component.ts | 4 +- .../pages/schema/fields/field.component.ts | 4 +- .../schema/fields/schema-fields.component.ts | 4 +- .../schema-preview-urls-form.component.ts | 4 +- .../schema-field-rules-form.component.ts | 4 +- .../pages/schema/schema-page.component.ts | 4 +- .../scripts/schema-scripts-form.component.ts | 4 +- .../pages/schema/ui/field-list.component.ts | 4 +- .../schema/ui/schema-ui-form.component.ts | 4 +- .../pages/schemas/schema-form.component.html | 8 +- .../pages/schemas/schema-form.component.ts | 2 +- .../schema-must-exist-published.guard.spec.ts | 6 +- .../guards/schema-must-exist.guard.spec.ts | 4 +- ...schema-must-not-be-singleton.guard.spec.ts | 8 +- .../app/shared/services/apps.service.spec.ts | 16 +- frontend/app/shared/services/apps.service.ts | 18 +- .../shared/services/assets.service.spec.ts | 4 +- .../app/shared/services/assets.service.ts | 8 +- .../shared/services/contents.service.spec.ts | 8 +- .../app/shared/services/contents.service.ts | 20 +- .../shared/services/schemas.service.spec.ts | 176 +++++++----------- .../app/shared/services/schemas.service.ts | 169 ++++++++--------- frontend/app/shared/services/schemas.spec.ts | 9 +- .../services/users-provider.service.spec.ts | 5 +- frontend/app/shared/state/_test-helpers.ts | 14 +- frontend/app/shared/state/apps.state.spec.ts | 5 +- .../shared/state/asset-uploader.state.spec.ts | 4 +- .../app/shared/state/assets.state.spec.ts | 4 +- .../app/shared/state/backups.state.spec.ts | 6 +- .../app/shared/state/clients.state.spec.ts | 2 +- frontend/app/shared/state/contents.forms.ts | 4 +- .../state/contents.forms.visitors.spec.ts | 109 +---------- .../shared/state/contributors.state.spec.ts | 2 +- .../app/shared/state/languages.state.spec.ts | 2 +- frontend/app/shared/state/plans.state.spec.ts | 2 +- frontend/app/shared/state/query.ts | 4 +- frontend/app/shared/state/roles.state.spec.ts | 2 +- .../shared/state/rule-events.state.spec.ts | 2 +- .../shared/state/rule-simulator.state.spec.ts | 5 +- frontend/app/shared/state/rules.state.spec.ts | 2 +- frontend/app/shared/state/schemas.forms.ts | 28 +-- .../app/shared/state/schemas.state.spec.ts | 136 +++++++------- frontend/app/shared/state/schemas.state.ts | 49 +++-- .../app/shared/state/table-fields.spec.ts | 12 +- frontend/app/shared/state/table-fields.ts | 4 +- .../app/shared/state/workflows.state.spec.ts | 2 +- 110 files changed, 772 insertions(+), 916 deletions(-) create mode 100644 backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaType.cs delete mode 100644 backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs diff --git a/backend/src/Migrations/OldEvents/SchemaCreated.cs b/backend/src/Migrations/OldEvents/SchemaCreated.cs index 1c6be72a9..3d0b0dadc 100644 --- a/backend/src/Migrations/OldEvents/SchemaCreated.cs +++ b/backend/src/Migrations/OldEvents/SchemaCreated.cs @@ -33,7 +33,7 @@ namespace Migrations.OldEvents public IEvent Migrate() { - var schema = new Schema(Name, Properties, Singleton); + var schema = new Schema(Name, Properties, Singleton ? SchemaType.Singleton : SchemaType.Default); if (Publish) { diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs index a1501bcea..620bb8b93 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs @@ -8,7 +8,6 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; -using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; namespace Squidex.Domain.Apps.Core.Rules diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs index 019e304f6..260d15172 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs @@ -5,8 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure.Reflection; - namespace Squidex.Domain.Apps.Core.Rules { public abstract record RuleTrigger diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayField.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayField.cs index 8b9cea229..1e11d9d9f 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayField.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayField.cs @@ -8,7 +8,6 @@ using System; using System.Collections.Generic; using System.Diagnostics.Contracts; -using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Core.Schemas { diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldBase.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldBase.cs index 13b8da28b..9c143aa53 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldBase.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldBase.cs @@ -5,16 +5,25 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; +using System.Collections.Generic; using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Core.Schemas { public abstract class FieldBase { + private Dictionary metadata; + public long Id { get; } public string Name { get; } + public IDictionary Metadata + { + get => metadata ??= new Dictionary(); + } + protected FieldBase(long id, string name) { Guard.NotNullOrEmpty(name, nameof(name)); @@ -24,5 +33,26 @@ namespace Squidex.Domain.Apps.Core.Schemas Name = name; } + + public T? GetMetadata(string key, T? defaultValue = default) + { + var local = metadata; + + return local != null && local.TryGetValue(key, out var item) ? (T)item : defaultValue; + } + + public T GetMetadata(string key, Func defaultValueFactory) + { + var local = metadata; + + return local != null && local.TryGetValue(key, out var item) ? (T)item : defaultValueFactory(); + } + + public bool HasMetadata(string key) + { + var local = metadata; + + return local?.ContainsKey(key) == true; + } } } diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaSurrogate.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaSurrogate.cs index 769e2634a..589b35dd2 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaSurrogate.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaSurrogate.cs @@ -1,4 +1,4 @@ -// ========================================================================== +// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) @@ -6,9 +6,9 @@ // ========================================================================== using System; -using System.Collections.Generic; using System.Linq; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; namespace Squidex.Domain.Apps.Core.Schemas.Json @@ -19,10 +19,10 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json public string Category { get; set; } - public bool IsSingleton { get; set; } - public bool IsPublished { get; set; } + public SchemaType Type { get; set; } + public SchemaProperties Properties { get; set; } public SchemaScripts? Scripts { get; set; } @@ -35,7 +35,18 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json public FieldSurrogate[] Fields { get; set; } - public Dictionary? PreviewUrls { get; set; } + public ImmutableDictionary? PreviewUrls { get; set; } + + public bool IsSingleton + { + set + { + if (value) + { + Type = SchemaType.Singleton; + } + } + } public void FromSource(Schema source) { @@ -54,8 +65,6 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json Partitioning = x.Partitioning.Key, Properties = x.RawProperties }).ToArray(); - - PreviewUrls = source.PreviewUrls.ToDictionary(x => x.Key, x => x.Value); } private static FieldSurrogate[]? CreateChildren(IField field) @@ -81,7 +90,7 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json { var fields = Fields?.Select(f => f.ToField()).ToArray() ?? Array.Empty(); - var schema = new Schema(Name, fields, Properties, IsPublished, IsSingleton); + var schema = new Schema(Name, fields, Properties, IsPublished, Type); if (!string.IsNullOrWhiteSpace(Category)) { @@ -116,4 +125,4 @@ namespace Squidex.Domain.Apps.Core.Schemas.Json return schema; } } -} \ No newline at end of file +} diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Schema.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Schema.cs index 578222821..36bc96303 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Schema.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Schema.cs @@ -10,113 +10,71 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; namespace Squidex.Domain.Apps.Core.Schemas { public sealed class Schema { - private static readonly Dictionary EmptyPreviewUrls = new Dictionary(); - private readonly string name; - private readonly bool isSingleton; - private string category; - private FieldNames fieldsInLists = FieldNames.Empty; - private FieldNames fieldsInReferences = FieldNames.Empty; - private FieldRules fieldRules = FieldRules.Empty; - private FieldCollection fields = FieldCollection.Empty; - private IReadOnlyDictionary previewUrls = EmptyPreviewUrls; - private SchemaScripts scripts = SchemaScripts.Empty; - private SchemaProperties properties; - private bool isPublished; - - public string Name - { - get => name; - } + public SchemaType Type { get; } - public string Category - { - get => category; - } + public string Name { get; } - public bool IsPublished - { - get => isPublished; - } + public string Category { get; private set; } - public bool IsSingleton - { - get => isSingleton; - } + public bool IsPublished { get; private set; } - public IReadOnlyList Fields - { - get => fields.Ordered; - } + public FieldCollection FieldCollection { get; private set; } = FieldCollection.Empty; - public IReadOnlyDictionary FieldsById - { - get => fields.ById; - } + public FieldRules FieldRules { get; private set; } = FieldRules.Empty; - public IReadOnlyDictionary FieldsByName - { - get => fields.ByName; - } + public FieldNames FieldsInLists { get; private set; } = FieldNames.Empty; - public IReadOnlyDictionary PreviewUrls - { - get => previewUrls; - } + public FieldNames FieldsInReferences { get; private set; } = FieldNames.Empty; - public FieldCollection FieldCollection - { - get => fields; - } + public SchemaScripts Scripts { get; private set; } = SchemaScripts.Empty; - public FieldRules FieldRules - { - get => fieldRules; - } + public SchemaProperties Properties { get; private set; } = new SchemaProperties(); - public FieldNames FieldsInLists - { - get => fieldsInLists; - } + public ImmutableDictionary PreviewUrls { get; private set; } = ImmutableDictionary.Empty(); - public FieldNames FieldsInReferences + public IReadOnlyList Fields { - get => fieldsInReferences; + get => FieldCollection.Ordered; } - public SchemaScripts Scripts + public IReadOnlyDictionary FieldsById { - get => scripts; + get => FieldCollection.ById; } - public SchemaProperties Properties + public IReadOnlyDictionary FieldsByName { - get => properties; + get => FieldCollection.ByName; } - public Schema(string name, SchemaProperties? properties = null, bool isSingleton = false) + public Schema(string name, SchemaProperties? properties = null, SchemaType type = SchemaType.Default) { Guard.NotNullOrEmpty(name, nameof(name)); - this.name = name; + Name = name; - this.properties = properties ?? new SchemaProperties(); + if (properties != null) + { + Properties = properties; + } - this.isSingleton = isSingleton; + Type = type; } - public Schema(string name, RootField[] fields, SchemaProperties properties, bool isPublished, bool isSingleton = false) - : this(name, properties, isSingleton) + public Schema(string name, RootField[] fields, SchemaProperties? properties, bool isPublished = false, SchemaType type = SchemaType.Default) + : this(name, properties, type) { Guard.NotNull(fields, nameof(fields)); - this.fields = new FieldCollection(fields); + FieldCollection = new FieldCollection(fields); - this.isPublished = isPublished; + IsPublished = isPublished; } [Pure] @@ -124,14 +82,14 @@ namespace Squidex.Domain.Apps.Core.Schemas { newProperties ??= new SchemaProperties(); - if (properties.Equals(newProperties)) + if (Properties.Equals(newProperties)) { return this; } return Clone(clone => { - clone.properties = newProperties; + clone.Properties = newProperties; }); } @@ -140,14 +98,14 @@ namespace Squidex.Domain.Apps.Core.Schemas { newScripts ??= new SchemaScripts(); - if (scripts.Equals(newScripts)) + if (Scripts.Equals(newScripts)) { return this; } return Clone(clone => { - clone.scripts = newScripts; + clone.Scripts = newScripts; }); } @@ -156,14 +114,14 @@ namespace Squidex.Domain.Apps.Core.Schemas { names ??= FieldNames.Empty; - if (fieldsInLists.SequenceEqual(names)) + if (FieldsInLists.SequenceEqual(names)) { return this; } return Clone(clone => { - clone.fieldsInLists = names; + clone.FieldsInLists = names; }); } @@ -178,14 +136,14 @@ namespace Squidex.Domain.Apps.Core.Schemas { names ??= FieldNames.Empty; - if (fieldsInReferences.SequenceEqual(names)) + if (FieldsInReferences.SequenceEqual(names)) { return this; } return Clone(clone => { - clone.fieldsInReferences = names; + clone.FieldsInReferences = names; }); } @@ -200,14 +158,14 @@ namespace Squidex.Domain.Apps.Core.Schemas { rules ??= FieldRules.Empty; - if (fieldRules.Equals(rules)) + if (FieldRules.Equals(rules)) { return this; } return Clone(clone => { - clone.fieldRules = rules; + clone.FieldRules = rules; }); } @@ -220,58 +178,58 @@ namespace Squidex.Domain.Apps.Core.Schemas [Pure] public Schema Publish() { - if (isPublished) + if (IsPublished) { return this; } return Clone(clone => { - clone.isPublished = true; + clone.IsPublished = true; }); } [Pure] public Schema Unpublish() { - if (!isPublished) + if (!IsPublished) { return this; } return Clone(clone => { - clone.isPublished = false; + clone.IsPublished = false; }); } [Pure] - public Schema ChangeCategory(string newCategory) + public Schema ChangeCategory(string category) { - if (string.Equals(category, newCategory)) + if (string.Equals(Category, category)) { return this; } return Clone(clone => { - clone.category = newCategory; + clone.Category = category; }); } [Pure] - public Schema SetPreviewUrls(IReadOnlyDictionary newPreviewUrls) + public Schema SetPreviewUrls(ImmutableDictionary previewUrls) { - previewUrls ??= EmptyPreviewUrls; + previewUrls ??= ImmutableDictionary.Empty(); - if (previewUrls.EqualsDictionary(newPreviewUrls)) + if (PreviewUrls.Equals(previewUrls)) { return this; } return Clone(clone => { - clone.previewUrls = newPreviewUrls; + clone.PreviewUrls = previewUrls; }); } @@ -285,9 +243,9 @@ namespace Squidex.Domain.Apps.Core.Schemas return Clone(clone => { - clone.fields = fields.Remove(fieldId); - clone.fieldsInLists = fieldsInLists.Remove(field.Name); - clone.fieldsInReferences = fieldsInReferences.Remove(field.Name); + clone.FieldCollection = FieldCollection.Remove(fieldId); + clone.FieldsInLists = FieldsInLists.Remove(field.Name); + clone.FieldsInReferences = FieldsInReferences.Remove(field.Name); }); } @@ -311,16 +269,16 @@ namespace Squidex.Domain.Apps.Core.Schemas private Schema UpdateFields(Func, FieldCollection> updater) { - var newFields = updater(fields); + var newFields = updater(FieldCollection); - if (ReferenceEquals(newFields, fields)) + if (ReferenceEquals(newFields, FieldCollection)) { return this; } return Clone(clone => { - clone.fields = newFields; + clone.FieldCollection = newFields; }); } diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaExtensions.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaExtensions.cs index f8df53eb1..c125478cd 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaExtensions.cs @@ -45,6 +45,11 @@ namespace Squidex.Domain.Apps.Core.Schemas return field.RawProperties.Label.Or(field.TypeName()); } + public static bool IsSingleton(this Schema schema) + { + return schema.Type == SchemaType.Singleton; + } + public static string TypeName(this Schema schema) { return schema.Name.ToPascalCase(); diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaProperties.cs index 95a93534d..bb5955577 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaProperties.cs @@ -11,6 +11,8 @@ namespace Squidex.Domain.Apps.Core.Schemas { public sealed record SchemaProperties : NamedElementPropertiesBase { + public static readonly SchemaProperties Empty = new SchemaProperties(); + public ImmutableList? Tags { get; init; } public string? ContentsSidebarUrl { get; init; } diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaType.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaType.cs new file mode 100644 index 000000000..8ba4671c4 --- /dev/null +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/SchemaType.cs @@ -0,0 +1,15 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Domain.Apps.Core.Schemas +{ + public enum SchemaType + { + Default, + Singleton + } +} diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/EventSynchronization/SchemaSynchronizer.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/EventSynchronization/SchemaSynchronizer.cs index 03efdd554..6c7122668 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/EventSynchronization/SchemaSynchronizer.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/EventSynchronization/SchemaSynchronizer.cs @@ -48,7 +48,7 @@ namespace Squidex.Domain.Apps.Core.EventSynchronization if (!source.PreviewUrls.EqualsDictionary(target.PreviewUrls)) { - yield return new SchemaPreviewUrlsConfigured { PreviewUrls = target.PreviewUrls.ToDictionary() }; + yield return new SchemaPreviewUrlsConfigured { PreviewUrls = target.PreviewUrls }; } if (source.IsPublished != target.IsPublished) diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/SchemaBuilder.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/SchemaBuilder.cs index 177717e5e..91d3dcdce 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/SchemaBuilder.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/SchemaBuilder.cs @@ -62,7 +62,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders public SchemaBuilder Singleton() { - command.IsSingleton = true; + command.Type = SchemaType.Singleton; return this; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs index c21a1599b..df72ac17e 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/ContentDomainObject.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading.Tasks; using NodaTime; using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards; using Squidex.Domain.Apps.Events; @@ -95,7 +96,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject await CreateCore(c, operation); - if (operation.Schema.SchemaDef.IsSingleton) + if (operation.Schema.SchemaDef.IsSingleton()) { ChangeStatus(c.AsChange(Status.Published)); } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/SingletonExtensions.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/SingletonExtensions.cs index f27b51f2c..c12803834 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/SingletonExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/SingletonExtensions.cs @@ -6,6 +6,7 @@ // ========================================================================== using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.Translations; @@ -15,7 +16,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards { public static void MustNotCreateSingleton(this OperationContext context) { - if (context.SchemaDef.IsSingleton && context.ContentId != context.Schema.Id) + if (context.SchemaDef.IsSingleton() && context.ContentId != context.Schema.Id) { throw new DomainException(T.Get("contents.singletonNotCreatable")); } @@ -23,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards public static void MustNotChangeSingleton(this OperationContext context, Status status) { - if (context.SchemaDef.IsSingleton && (context.Content.NewStatus == null || status != Status.Published)) + if (context.SchemaDef.IsSingleton() && (context.Content.NewStatus == null || status != Status.Published)) { throw new DomainException(T.Get("contents.singletonNotChangeable")); } @@ -31,7 +32,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards public static void MustNotDeleteSingleton(this OperationContext context) { - if (context.SchemaDef.IsSingleton) + if (context.SchemaDef.IsSingleton()) { throw new DomainException(T.Get("contents.singletonNotDeletable")); } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/WorkflowExtensions.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/WorkflowExtensions.cs index 4ef0a74b8..fa601f256 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/WorkflowExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/WorkflowExtensions.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.Translations; @@ -23,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards public static async Task CheckTransitionAsync(this OperationContext context, Status status) { - if (!context.SchemaDef.IsSingleton) + if (!context.SchemaDef.IsSingleton()) { var workflow = GetWorkflow(context); @@ -41,7 +42,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards public static async Task CheckStatusAsync(this OperationContext context, Status status) { - if (!context.SchemaDef.IsSingleton) + if (!context.SchemaDef.IsSingleton()) { var workflow = GetWorkflow(context); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/EnrichWithSchema.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/EnrichWithSchema.cs index db1e7eee2..7a39c9690 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/EnrichWithSchema.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/EnrichWithSchema.cs @@ -25,7 +25,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries.Steps foreach (var content in group) { - content.IsSingleton = schema.SchemaDef.IsSingleton; + content.IsSingleton = schema.SchemaDef.IsSingleton(); content.SchemaName = schemaName; content.SchemaDisplayName = schemaDisplayName; diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/SingletonCommandMiddleware.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/SingletonCommandMiddleware.cs index 9a6d026b6..e128efd88 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/SingletonCommandMiddleware.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/SingletonCommandMiddleware.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure; @@ -21,7 +22,7 @@ namespace Squidex.Domain.Apps.Entities.Contents { await next(context); - if (context.IsCompleted && context.Command is CreateSchema { IsSingleton: true } createSchema) + if (context.IsCompleted && context.Command is CreateSchema { Type: SchemaType.Singleton } createSchema) { var schemaId = NamedId.Of(createSchema.SchemaId, createSchema.Name); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/ConfigurePreviewUrls.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/ConfigurePreviewUrls.cs index b83ea0f1e..09069d885 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/ConfigurePreviewUrls.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/ConfigurePreviewUrls.cs @@ -5,12 +5,12 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; +using Squidex.Infrastructure.Collections; namespace Squidex.Domain.Apps.Entities.Schemas.Commands { public sealed class ConfigurePreviewUrls : SchemaUpdateCommand { - public Dictionary PreviewUrls { get; set; } + public ImmutableDictionary PreviewUrls { get; set; } } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchema.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchema.cs index 41077678f..c417ef396 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchema.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/CreateSchema.cs @@ -1,14 +1,14 @@ -// ========================================================================== +// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; using System.Runtime.Serialization; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Commands; using SchemaField = Squidex.Domain.Apps.Entities.Schemas.Commands.UpsertSchemaField; @@ -24,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Commands public bool IsPublished { get; set; } - public bool IsSingleton { get; set; } + public SchemaType Type { get; set; } public SchemaField[]? Fields { get; set; } @@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Commands public SchemaProperties Properties { get; set; } - public Dictionary? PreviewUrls { get; set; } + public ImmutableDictionary? PreviewUrls { get; set; } [IgnoreDataMember] public override DomainId AggregateId @@ -55,7 +55,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Commands { IUpsertCommand self = this; - return self.ToSchema(Name, IsSingleton); + return self.ToSchema(Name, Type); } } -} \ No newline at end of file +} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/IUpsertCommand.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/IUpsertCommand.cs index 5e730bf89..d515dd5ff 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/IUpsertCommand.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/IUpsertCommand.cs @@ -5,10 +5,10 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; using System.Linq; using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Collections; using SchemaField = Squidex.Domain.Apps.Entities.Schemas.Commands.UpsertSchemaField; namespace Squidex.Domain.Apps.Entities.Schemas.Commands @@ -31,11 +31,11 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Commands FieldRuleCommand[]? FieldRules { get; set; } - Dictionary? PreviewUrls { get; set; } + ImmutableDictionary? PreviewUrls { get; set; } - Schema ToSchema(string name, bool isSingleton) + Schema ToSchema(string name, SchemaType type) { - var schema = new Schema(name, Properties, isSingleton); + var schema = new Schema(name, Properties, type); if (IsPublished) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/SynchronizeSchema.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/SynchronizeSchema.cs index 24c9789d1..c3808e4e3 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/SynchronizeSchema.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/Commands/SynchronizeSchema.cs @@ -5,8 +5,8 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Commands; using SchemaField = Squidex.Domain.Apps.Entities.Schemas.Commands.UpsertSchemaField; @@ -34,13 +34,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Commands public SchemaProperties Properties { get; set; } - public Dictionary? PreviewUrls { get; set; } + public ImmutableDictionary? PreviewUrls { get; set; } - public Schema BuildSchema(string name, bool isSingleton) + public Schema BuildSchema(string name, SchemaType type) { IUpsertCommand self = this; - return self.ToSchema(name, isSingleton); + return self.ToSchema(name, type); } } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/DomainObject/SchemaDomainObject.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/DomainObject/SchemaDomainObject.cs index 0ecb13bbb..32c2a4f8d 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/DomainObject/SchemaDomainObject.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/DomainObject/SchemaDomainObject.cs @@ -1,4 +1,4 @@ -// ========================================================================== +// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) @@ -251,7 +251,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject }; var schemaSource = Snapshot.SchemaDef; - var schemaTarget = command.BuildSchema(schemaSource.Name, schemaSource.IsSingleton); + var schemaTarget = command.BuildSchema(schemaSource.Name, schemaSource.Type); var events = schemaSource.Synchronize(schemaTarget, () => Snapshot.SchemaFieldsTotal + 1, options); @@ -411,4 +411,4 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject return J.AsTask(Snapshot); } } -} \ No newline at end of file +} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemasSearchSource.cs b/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemasSearchSource.cs index 1e47176c3..68fff4e43 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemasSearchSource.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Schemas/SchemasSearchSource.cs @@ -1,4 +1,4 @@ -// ========================================================================== +// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) @@ -71,7 +71,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas private void AddContentsUrl(SearchResults result, NamedId appId, ISchemaEntity schema, NamedId schemaId, string name) { - if (schema.SchemaDef.IsSingleton) + if (schema.SchemaDef.IsSingleton()) { var contentUrl = urlGenerator.ContentUI(appId, schemaId, schemaId.Id); diff --git a/backend/src/Squidex.Domain.Apps.Events/Schemas/SchemaPreviewUrlsConfigured.cs b/backend/src/Squidex.Domain.Apps.Events/Schemas/SchemaPreviewUrlsConfigured.cs index 3983af224..3520d49c9 100644 --- a/backend/src/Squidex.Domain.Apps.Events/Schemas/SchemaPreviewUrlsConfigured.cs +++ b/backend/src/Squidex.Domain.Apps.Events/Schemas/SchemaPreviewUrlsConfigured.cs @@ -5,7 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.EventSourcing; namespace Squidex.Domain.Apps.Events.Schemas @@ -13,6 +13,6 @@ namespace Squidex.Domain.Apps.Events.Schemas [EventType(nameof(SchemaPreviewUrlsConfigured))] public sealed class SchemaPreviewUrlsConfigured : SchemaEvent { - public Dictionary PreviewUrls { get; set; } + public ImmutableDictionary PreviewUrls { get; set; } } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs index b867dcfac..b5bf15267 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs @@ -76,7 +76,7 @@ namespace Squidex.Areas.Api.Controllers.Apps.Models /// /// Indicates if the user can access the api. /// - [Obsolete("Usage role properties")] + [Obsolete("Use 'roleProperties' field now.")] public bool CanAccessApi { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs index 2a746cdc6..4cefeee41 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs @@ -133,7 +133,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models /// /// Determines of the created file is an image. /// - [Obsolete("Use Type instead")] + [Obsolete("Use 'type' field now.")] public bool IsImage { get => Type == AssetType.Image; @@ -142,7 +142,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models /// /// The width of the image in pixels if the asset is an image. /// - [Obsolete("Use Metdata instead")] + [Obsolete("Use 'metdata' field now.")] public int? PixelWidth { get => Metadata.GetPixelWidth(); @@ -151,7 +151,7 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models /// /// The height of the image in pixels if the asset is an image. /// - [Obsolete("Use Metdata instead")] + [Obsolete("Use 'metdata' field now.")] public int? PixelHeight { get => Metadata.GetPixelHeight(); diff --git a/backend/src/Squidex/Areas/Api/Controllers/BulkResultDto.cs b/backend/src/Squidex/Areas/Api/Controllers/BulkResultDto.cs index cc204e766..bd0ade02b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/BulkResultDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/BulkResultDto.cs @@ -34,7 +34,7 @@ namespace Squidex.Areas.Api.Controllers /// /// The id of the entity that has been handled successfully or not. /// - [Obsolete("Use Id instead.")] + [Obsolete("Use 'id' field now.")] public DomainId? ContentId => Id; public static BulkResultDto FromBulkResult(BulkUpdateResultItem result, HttpContext httpContext) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs index 346c9437b..386e9d47b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs @@ -1,4 +1,4 @@ -// ========================================================================== +// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) @@ -386,7 +386,7 @@ namespace Squidex.Areas.Api.Controllers.Contents [ProducesResponseType(typeof(BulkResultDto[]), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppContentsCreate)] [ApiCosts(5)] - [Obsolete("Use bulk endpoint")] + [Obsolete("Use bulk endpoint now.")] public async Task PostContents(string app, string name, [FromBody] ImportContentsDto request) { var command = request.ToCommand(); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs index 6eb548f83..e1edfffdb 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/BulkUpdateContentsDto.cs @@ -27,7 +27,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models /// /// True to automatically publish the content. /// - [Obsolete("Use Jobs.Status")] + [Obsolete("Use 'jobs.status' fields now.")] public bool Publish { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs index e85055eb2..e3824e8fe 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs @@ -40,7 +40,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models /// True to automatically publish the content. /// [FromQuery] - [Obsolete("Use status query string.")] + [Obsolete("Use 'status' query string now.")] public bool Publish { get; set; } public CreateContent ToCommand() diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs index 36b488e76..a92cb3a05 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ImportContentsDto.cs @@ -28,7 +28,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models /// /// True to automatically publish the content. /// - [Obsolete("Use Bulk endpoint")] + [Obsolete("Use bulk endpoint now.")] public bool Publish { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs index d1686994f..83bd2e932 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs @@ -34,7 +34,7 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models /// True to automatically publish the content. /// [FromQuery] - [Obsolete("Use status query string.")] + [Obsolete("Use 'status' query string now.")] public bool Publish { get; set; } public UpsertContent ToCommand(DomainId id) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs index 5016e0c3e..1d69f5107 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Infrastructure.Collections; namespace Squidex.Areas.Api.Controllers.Schemas.Models { @@ -16,7 +17,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models { return new ConfigurePreviewUrls { - PreviewUrls = new Dictionary(this) + PreviewUrls = new Dictionary(this).ToImmutableDictionary() }; } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs index 32fd97b54..2fd9bf8f2 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs @@ -5,9 +5,9 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Infrastructure.Reflection; namespace Squidex.Areas.Api.Controllers.Schemas.Models { @@ -16,28 +16,16 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models /// /// The name of fields that are used in content lists. /// - public List? FieldsInLists { get; set; } + public FieldNames? FieldsInLists { get; set; } /// /// The name of fields that are used in content references. /// - public List? FieldsInReferences { get; set; } + public FieldNames? FieldsInReferences { get; set; } public ConfigureUIFields ToCommand() { - var command = new ConfigureUIFields(); - - if (FieldsInLists != null) - { - command.FieldsInLists = new FieldNames(FieldsInLists); - } - - if (FieldsInReferences != null) - { - command.FieldsInReferences = new FieldNames(FieldsInReferences); - } - - return command; + return SimpleMapper.Map(this, new ConfigureUIFields()); } } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs index f8b0208bf..c154beb65 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs @@ -5,6 +5,8 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Validation; @@ -19,10 +21,26 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models [LocalizedRegularExpression("^[a-z0-9]+(\\-[a-z0-9]+)*$")] public string Name { get; set; } + /// + /// The type of the schema. + /// + public SchemaType Type { get; set; } + /// /// Set to true to allow a single content item only. /// - public bool IsSingleton { get; set; } + [Obsolete("Use 'type' field now.")] + public bool IsSingleton + { + get => Type == SchemaType.Singleton; + set + { + if (value) + { + Type = SchemaType.Singleton; + } + } + } public CreateSchema ToCommand() { diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs index 7f969a907..a0be64a82 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs @@ -97,7 +97,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields /// /// True to resolve first image in the content list. /// - [Obsolete("Use ResolveFirst now")] + [Obsolete("Use 'resolveFirst' field now")] public bool ResolveImage { get => ResolveFirst; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs deleted file mode 100644 index e80c77d9c..000000000 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs +++ /dev/null @@ -1,102 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using System.Collections.Generic; -using System.Linq; -using Squidex.Domain.Apps.Entities.Schemas; -using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; -using Squidex.Web; - -namespace Squidex.Areas.Api.Controllers.Schemas.Models -{ - public sealed class SchemaDetailsDto : SchemaDto - { - private static readonly Dictionary EmptyPreviewUrls = new Dictionary(); - - /// - /// The scripts. - /// - [LocalizedRequired] - public SchemaScriptsDto Scripts { get; set; } = new SchemaScriptsDto(); - - /// - /// The preview Urls. - /// - [LocalizedRequired] - public Dictionary PreviewUrls { get; set; } = EmptyPreviewUrls; - - /// - /// The name of fields that are used in content lists. - /// - [LocalizedRequired] - public List FieldsInLists { get; set; } - - /// - /// The name of fields that are used in content references. - /// - [LocalizedRequired] - public List FieldsInReferences { get; set; } - - /// - /// The field rules. - /// - public List FieldRules { get; set; } - - /// - /// The list of fields. - /// - [LocalizedRequired] - public List Fields { get; set; } - - public static SchemaDetailsDto FromSchemaWithDetails(ISchemaEntity schema, Resources resources) - { - var result = new SchemaDetailsDto(); - - SimpleMapper.Map(schema, result); - SimpleMapper.Map(schema.SchemaDef, result); - SimpleMapper.Map(schema.SchemaDef.Scripts, result.Scripts); - SimpleMapper.Map(schema.SchemaDef.Properties, result.Properties); - - result.FieldsInLists = schema.SchemaDef.FieldsInLists.ToList(); - result.FieldsInReferences = schema.SchemaDef.FieldsInReferences.ToList(); - - result.FieldRules = schema.SchemaDef.FieldRules.Select(FieldRuleDto.FromFieldRule).ToList(); - - if (schema.SchemaDef.PreviewUrls.Count > 0) - { - result.PreviewUrls = new Dictionary(schema.SchemaDef.PreviewUrls); - } - - result.Fields = new List(); - - foreach (var field in schema.SchemaDef.Fields) - { - result.Fields.Add(FieldDto.FromField(field)); - } - - result.CreateLinks(resources); - - return result; - } - - protected override void CreateLinks(Resources resources) - { - base.CreateLinks(resources); - - var allowUpdate = resources.CanUpdateSchema(Name); - - if (Fields != null) - { - foreach (var nested in Fields) - { - nested.CreateLinks(resources, Name, allowUpdate); - } - } - } - } -} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs index f82ab6ba5..c463ba750 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDto.cs @@ -5,10 +5,15 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; +using System.Collections.Generic; +using System.Linq; using NodaTime; using Squidex.Areas.Api.Controllers.Contents; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; using Squidex.Web; @@ -22,6 +27,18 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models /// public DomainId Id { get; set; } + /// + /// The user that has created the schema. + /// + [LocalizedRequired] + public RefToken CreatedBy { get; set; } + + /// + /// The user that has updated the schema. + /// + [LocalizedRequired] + public RefToken LastModifiedBy { get; set; } + /// /// The name of the schema. Unique within the app. /// @@ -29,6 +46,11 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models [LocalizedRegularExpression("^[a-z0-9]+(\\-[a-z0-9]+)*$")] public string Name { get; set; } + /// + /// The type of the schema. + /// + public SchemaType Type { get; set; } + /// /// The name of the category. /// @@ -43,7 +65,11 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models /// /// Indicates if the schema is a singleton. /// - public bool IsSingleton { get; set; } + [Obsolete("Use 'type' field now.")] + public bool IsSingleton + { + get => Type == SchemaType.Singleton; + } /// /// Indicates if the schema is published. @@ -51,41 +77,74 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models public bool IsPublished { get; set; } /// - /// The user that has created the schema. + /// The date and time when the schema has been created. + /// + public Instant Created { get; set; } + + /// + /// The date and time when the schema has been modified last. + /// + public Instant LastModified { get; set; } + + /// + /// The version of the schema. + /// + public long Version { get; set; } + + /// + /// The scripts. /// [LocalizedRequired] - public RefToken CreatedBy { get; set; } + public SchemaScriptsDto Scripts { get; set; } = new SchemaScriptsDto(); /// - /// The user that has updated the schema. + /// The preview Urls. /// [LocalizedRequired] - public RefToken LastModifiedBy { get; set; } + public ImmutableDictionary PreviewUrls { get; set; } /// - /// The date and time when the schema has been created. + /// The name of fields that are used in content lists. /// - public Instant Created { get; set; } + [LocalizedRequired] + public FieldNames FieldsInLists { get; set; } /// - /// The date and time when the schema has been modified last. + /// The name of fields that are used in content references. /// - public Instant LastModified { get; set; } + [LocalizedRequired] + public FieldNames FieldsInReferences { get; set; } /// - /// The version of the schema. + /// The field rules. /// - public long Version { get; set; } + public List FieldRules { get; set; } - public static SchemaDto FromSchema(ISchemaEntity schema, Resources controller) + /// + /// The list of fields. + /// + [LocalizedRequired] + public List Fields { get; set; } + + public static SchemaDto FromSchema(ISchemaEntity schema, Resources resources) { var result = new SchemaDto(); SimpleMapper.Map(schema, result); SimpleMapper.Map(schema.SchemaDef, result); + SimpleMapper.Map(schema.SchemaDef.Scripts, result.Scripts); SimpleMapper.Map(schema.SchemaDef.Properties, result.Properties); - result.CreateLinks(controller); + result.FieldRules = schema.SchemaDef.FieldRules.Select(FieldRuleDto.FromFieldRule).ToList(); + + result.Fields = new List(); + + foreach (var field in schema.SchemaDef.Fields) + { + result.Fields.Add(FieldDto.FromField(field)); + } + + result.CreateLinks(resources); return result; } @@ -144,6 +203,14 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models { AddDeleteLink("delete", resources.Url(x => nameof(x.DeleteSchema), values)); } + + if (Fields != null) + { + foreach (var nested in Fields) + { + nested.CreateLinks(resources, Name, allowUpdate); + } + } } } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs index 98a91acae..5ffa8078a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; namespace Squidex.Areas.Api.Controllers.Schemas.Models @@ -27,12 +28,12 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models /// /// The names of the fields that should be used in references. /// - public string[]? FieldsInReferences { get; set; } + public FieldNames? FieldsInReferences { get; set; } /// /// The names of the fields that should be shown in lists, including meta fields. /// - public string[]? FieldsInLists { get; set; } + public FieldNames? FieldsInLists { get; set; } /// /// Optional fields. @@ -42,7 +43,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models /// /// The optional preview urls. /// - public Dictionary? PreviewUrls { get; set; } + public ImmutableDictionary? PreviewUrls { get; set; } /// /// The category. @@ -72,16 +73,6 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models SimpleMapper.Map(dto.Scripts, command.Scripts); } - if (dto.FieldsInLists != null) - { - command.FieldsInLists = new FieldNames(dto.FieldsInLists); - } - - if (dto.FieldsInReferences != null) - { - command.FieldsInReferences = new FieldNames(dto.FieldsInReferences); - } - if (dto.Fields?.Length > 0) { var fields = new List(); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs index b395c282b..15f1592ec 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs @@ -42,7 +42,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPost] [Route("apps/{app}/schemas/{name}/fields/")] - [ProducesResponseType(typeof(SchemaDetailsDto), 201)] + [ProducesResponseType(typeof(SchemaDto), 201)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PostField(string app, string name, [FromBody] AddFieldDto request) @@ -69,7 +69,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPost] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/")] - [ProducesResponseType(typeof(SchemaDetailsDto), 201)] + [ProducesResponseType(typeof(SchemaDto), 201)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PostNestedField(string app, string name, long parentId, [FromBody] AddFieldDto request) @@ -94,7 +94,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/ui/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutSchemaUIFields(string app, string name, [FromBody] ConfigureUIFieldsDto request) @@ -119,7 +119,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/ordering/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutSchemaFieldOrdering(string app, string name, [FromBody] ReorderFieldsDto request) @@ -145,7 +145,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/ordering/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutNestedFieldOrdering(string app, string name, long parentId, [FromBody] ReorderFieldsDto request) @@ -171,7 +171,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutField(string app, string name, long id, [FromBody] UpdateFieldDto request) @@ -198,7 +198,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutNestedField(string app, string name, long parentId, long id, [FromBody] UpdateFieldDto request) @@ -226,7 +226,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/lock/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task LockField(string app, string name, long id) @@ -255,7 +255,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/lock/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task LockNestedField(string app, string name, long parentId, long id) @@ -283,7 +283,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/hide/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task HideField(string app, string name, long id) @@ -312,7 +312,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/hide/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task HideNestedField(string app, string name, long parentId, long id) @@ -340,7 +340,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/show/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task ShowField(string app, string name, long id) @@ -369,7 +369,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/show/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task ShowNestedField(string app, string name, long parentId, long id) @@ -397,7 +397,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/enable/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task EnableField(string app, string name, long id) @@ -426,7 +426,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/enable/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task EnableNestedField(string app, string name, long parentId, long id) @@ -454,7 +454,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{id:long}/disable/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DisableField(string app, string name, long id) @@ -483,7 +483,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/disable/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DisableNestedField(string app, string name, long parentId, long id) @@ -508,7 +508,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpDelete] [Route("apps/{app}/schemas/{name}/fields/{id:long}/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DeleteField(string app, string name, long id) @@ -534,7 +534,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpDelete] [Route("apps/{app}/schemas/{name}/fields/{parentId:long}/nested/{id:long}/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task DeleteNestedField(string app, string name, long parentId, long id) @@ -546,14 +546,14 @@ namespace Squidex.Areas.Api.Controllers.Schemas return Ok(response); } - private async Task InvokeCommandAsync(ICommand command) + private async Task InvokeCommandAsync(ICommand command) { var context = await CommandBus.PublishAsync(command); var result = context.Result(); - var response = SchemaDetailsDto.FromSchemaWithDetails(result, Resources); + var response = SchemaDto.FromSchema(result, Resources); return response; } } -} \ No newline at end of file +} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs index 0c72b8c50..21381f213 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs @@ -77,7 +77,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpGet] [Route("apps/{app}/schemas/{name}/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasRead)] [ApiCosts(0)] public async Task GetSchema(string app, string name) @@ -91,7 +91,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas var response = Deferred.Response(() => { - return SchemaDetailsDto.FromSchemaWithDetails(schema, Resources); + return SchemaDto.FromSchema(schema, Resources); }); Response.Headers[HeaderNames.ETag] = schema.ToEtag(); @@ -111,7 +111,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPost] [Route("apps/{app}/schemas/")] - [ProducesResponseType(typeof(SchemaDetailsDto), 201)] + [ProducesResponseType(typeof(SchemaDto), 201)] [ApiPermissionOrAnonymous(Permissions.AppSchemasCreate)] [ApiCosts(1)] public async Task PostSchema(string app, [FromBody] CreateSchemaDto request) @@ -136,7 +136,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutSchema(string app, string name, [FromBody] UpdateSchemaDto request) @@ -161,7 +161,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/sync")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutSchemaSync(string app, string name, [FromBody] SynchronizeSchemaDto request) @@ -186,7 +186,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/category")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutCategory(string app, string name, [FromBody] ChangeCategoryDto request) @@ -211,7 +211,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/preview-urls")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutPreviewUrls(string app, string name, [FromBody] ConfigurePreviewUrlsDto request) @@ -236,7 +236,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/scripts/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasScripts)] [ApiCosts(1)] public async Task PutScripts(string app, string name, [FromBody] SchemaScriptsDto request) @@ -261,7 +261,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/rules/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasUpdate)] [ApiCosts(1)] public async Task PutRules(string app, string name, [FromBody] ConfigureFieldRulesDto request) @@ -284,7 +284,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/publish/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasPublish)] [ApiCosts(1)] public async Task PublishSchema(string app, string name) @@ -307,7 +307,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/unpublish/")] - [ProducesResponseType(typeof(SchemaDetailsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(Permissions.AppSchemasPublish)] [ApiCosts(1)] public async Task UnpublishSchema(string app, string name) @@ -375,14 +375,14 @@ namespace Squidex.Areas.Api.Controllers.Schemas } } - private async Task InvokeCommandAsync(ICommand command) + private async Task InvokeCommandAsync(ICommand command) { var context = await CommandBus.PublishAsync(command); var result = context.Result(); - var response = SchemaDetailsDto.FromSchemaWithDetails(result, Resources); + var response = SchemaDto.FromSchema(result, Resources); return response; } } -} \ No newline at end of file +} diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs index 6abacd170..916c67ea3 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs @@ -11,6 +11,7 @@ using System.Linq; using FluentAssertions; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.TestHelpers; +using Squidex.Infrastructure.Collections; using Xunit; #pragma warning disable SA1310 // Field names must not contain underscore @@ -437,11 +438,11 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas var urls1 = new Dictionary { ["web"] = "Url" - }; + }.ToImmutableDictionary(); var urls2 = new Dictionary { ["web"] = "Url" - }; + }.ToImmutableDictionary(); var schema_1 = schema_0.SetPreviewUrls(urls1); var schema_2 = schema_1.SetPreviewUrls(urls2); @@ -457,7 +458,7 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas public void Should_serialize_and_deserialize_schema() { var schemaSource = - TestUtils.MixedSchema(true) + TestUtils.MixedSchema(SchemaType.Singleton) .ChangeCategory("Category") .SetFieldRules(FieldRule.Hide("2")) .SetFieldsInLists("field2") @@ -465,7 +466,7 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas .SetPreviewUrls(new Dictionary { ["web"] = "Url" - }) + }.ToImmutableDictionary()) .SetScripts(new SchemaScripts { Create = "" @@ -476,6 +477,25 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas schemaTarget.Should().BeEquivalentTo(schemaSource); } + [Fact] + public void Should_deserialize_obsolete_isSingleton_property() + { + var schemaSource = new + { + name = "my-schema", + isPublished = true, + isSingleton = true + }; + + var expected = + new Schema("my-schema", type: SchemaType.Singleton) + .Publish(); + + var schemaTarget = schemaSource.SerializeAndDeserialize(); + + schemaTarget.Should().BeEquivalentTo(expected); + } + private static RootField CreateField(int id) { return Fields.Number(id, $"my-field-{id}", Partitioning.Invariant); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/EventSynchronization/SchemaSynchronizerTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/EventSynchronization/SchemaSynchronizerTests.cs index e4f4a8fb3..88e2cfa61 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/EventSynchronization/SchemaSynchronizerTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/EventSynchronization/SchemaSynchronizerTests.cs @@ -11,6 +11,7 @@ using Squidex.Domain.Apps.Core.EventSynchronization; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Events.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.EventSynchronization @@ -88,7 +89,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EventSynchronization var previewUrls = new Dictionary { ["web"] = "Url" - }; + }.ToImmutableDictionary(); var sourceSchema = new Schema("source"); diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/GenerateEdmSchema/EdmTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/GenerateEdmSchema/EdmTests.cs index d23af251a..4e5693b70 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/GenerateEdmSchema/EdmTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/GenerateEdmSchema/EdmTests.cs @@ -38,7 +38,9 @@ namespace Squidex.Domain.Apps.Core.Operations.GenerateEdmSchema return (new EdmComplexType("Squidex", string.Join(".", names)), true); }); - var edmModel = TestUtils.MixedSchema().BuildEdmType(true, languagesConfig.ToResolver(), typeFactory); + var edmModel = + TestUtils.MixedSchema() + .BuildEdmType(true, languagesConfig.ToResolver(), typeFactory); Assert.NotNull(edmModel); } diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/TestHelpers/TestUtils.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/TestHelpers/TestUtils.cs index f8dc43189..61b0388cb 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/TestHelpers/TestUtils.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/TestHelpers/TestUtils.cs @@ -81,9 +81,9 @@ namespace Squidex.Domain.Apps.Core.TestHelpers return new NewtonsoftJsonSerializer(serializerSettings); } - public static Schema MixedSchema(bool isSingleton = false) + public static Schema MixedSchema(SchemaType type = SchemaType.Default) { - var schema = new Schema("user", isSingleton: isSingleton) + var schema = new Schema("user", type: type) .Publish() .AddArray(101, "root-array", Partitioning.Language, f => f .AddAssets(201, "nested-assets") diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultWorkflowsValidatorTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultWorkflowsValidatorTests.cs index 083d6b7a7..1a7fc28e7 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultWorkflowsValidatorTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultWorkflowsValidatorTests.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FakeItEasy; diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs index 94fefb75a..37f06700d 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs @@ -39,7 +39,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards Mocks.Schema(appId, schemaId, new Schema(schemaId.Name)); singletonSchema = - Mocks.Schema(appId, schemaId, new Schema(schemaId.Name, isSingleton: true)); + Mocks.Schema(appId, schemaId, new Schema(schemaId.Name, type: SchemaType.Singleton)); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/SingletonCommandMiddlewareTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/SingletonCommandMiddlewareTests.cs index 9bf833acb..c380c21b5 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/SingletonCommandMiddlewareTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/SingletonCommandMiddlewareTests.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using FakeItEasy; using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Commands; @@ -23,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Contents [Fact] public async Task Should_create_content_if_singleton_schema_is_created() { - var command = new CreateSchema { IsSingleton = true, Name = "my-schema" }; + var command = new CreateSchema { Type = SchemaType.Singleton, Name = "my-schema" }; var context = new CommandContext(command, commandBus) @@ -38,7 +39,7 @@ namespace Squidex.Domain.Apps.Entities.Contents [Fact] public async Task Should_not_create_content_if_non_singleton_schema_is_created() { - var command = new CreateSchema { IsSingleton = false }; + var command = new CreateSchema(); var context = new CommandContext(command, commandBus) @@ -53,7 +54,7 @@ namespace Squidex.Domain.Apps.Entities.Contents [Fact] public async Task Should_not_create_content_if_singleton_schema_not_created() { - var command = new CreateSchema { IsSingleton = true }; + var command = new CreateSchema { Type = SchemaType.Singleton }; var context = new CommandContext(command, commandBus); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/Guards/GuardSchemaTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/Guards/GuardSchemaTests.cs index dedcd782e..538a184e3 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/Guards/GuardSchemaTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/Guards/GuardSchemaTests.cs @@ -5,13 +5,13 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.TestHelpers; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Validation; using Xunit; @@ -657,7 +657,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards [Fact] public void CanConfigurePreviewUrls_should_not_throw_exception_if_valid() { - var command = new ConfigurePreviewUrls { PreviewUrls = new Dictionary() }; + var command = new ConfigurePreviewUrls { PreviewUrls = ImmutableDictionary.Empty() }; GuardSchema.CanConfigurePreviewUrls(command); } diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaDomainObjectTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaDomainObjectTests.cs index 5b14931f7..6b88f1726 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaDomainObjectTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaDomainObjectTests.cs @@ -15,6 +15,7 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Domain.Apps.Events.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Commands; using Squidex.Log; using Xunit; @@ -55,7 +56,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject { var properties = new SchemaProperties(); - var command = new CreateSchema { Name = SchemaName, SchemaId = SchemaId, Properties = properties, IsSingleton = true }; + var command = new CreateSchema { Name = SchemaName, SchemaId = SchemaId, Properties = properties, Type = SchemaType.Singleton }; var result = await PublishAsync(command); @@ -64,12 +65,11 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject Assert.Equal(AppId, sut.Snapshot.AppId.Id); Assert.Equal(SchemaName, sut.Snapshot.SchemaDef.Name); - Assert.Equal(SchemaName, sut.Snapshot.SchemaDef.Name); - Assert.True(sut.Snapshot.SchemaDef.IsSingleton); + Assert.Equal(SchemaType.Singleton, sut.Snapshot.SchemaDef.Type); LastEvents .ShouldHaveSameEvents( - CreateEvent(new SchemaCreated { Schema = new Schema(command.Name, command.Properties, command.IsSingleton) }) + CreateEvent(new SchemaCreated { Schema = new Schema(command.Name, command.Properties, SchemaType.Singleton) }) ); } @@ -291,7 +291,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject PreviewUrls = new Dictionary { ["Web"] = "web-url" - } + }.ToImmutableDictionary() }; await ExecuteCreateAsync(); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaCommandsTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaCommandsTests.cs index 6eb53ecab..defb9451a 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaCommandsTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaCommandsTests.cs @@ -10,6 +10,7 @@ using FluentAssertions; using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Infrastructure.Collections; using Xunit; namespace Squidex.Domain.Apps.Entities.Schemas @@ -47,7 +48,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas PreviewUrls = new Dictionary { ["mobile"] = "http://mobile" - }, + }.ToImmutableDictionary(), Category = "myCategory" }; @@ -69,10 +70,10 @@ namespace Squidex.Domain.Apps.Entities.Schemas .SetPreviewUrls(new Dictionary { ["mobile"] = "http://mobile" - }) + }.ToImmutableDictionary()) .Publish(); - var actual = command.BuildSchema("my-schema", false); + var actual = command.BuildSchema("my-schema", SchemaType.Default); actual.Should().BeEquivalentTo(expected); } diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemasSearchSourceTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemasSearchSourceTests.cs index 6421e1a76..eea43fa4c 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemasSearchSourceTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemasSearchSourceTests.cs @@ -39,7 +39,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas { var ctx = ContextWithPermission(); - var schema1 = CreateSchema("schemaA1", false); + var schema1 = CreateSchema("schemaA1"); A.CallTo(() => appProvider.GetSchemasAsync(appId.Id)) .Returns(new List { schema1 }); @@ -61,9 +61,9 @@ namespace Squidex.Domain.Apps.Entities.Schemas var ctx = ContextWithPermission(permission.Id); - var schema1 = CreateSchema("schemaA1", false); - var schema2 = CreateSchema("schemaA2", false); - var schema3 = CreateSchema("schemaB2", false); + var schema1 = CreateSchema("schemaA1"); + var schema2 = CreateSchema("schemaA2"); + var schema3 = CreateSchema("schemaB2"); A.CallTo(() => appProvider.GetSchemasAsync(appId.Id)) .Returns(new List { schema1, schema2, schema3 }); @@ -93,7 +93,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas var ctx = ContextWithPermission(permission.Id); - var schema1 = CreateSchema("schemaA1", true); + var schema1 = CreateSchema("schemaA1", SchemaType.Singleton); A.CallTo(() => appProvider.GetSchemasAsync(appId.Id)) .Returns(new List { schema1 }); @@ -112,9 +112,9 @@ namespace Squidex.Domain.Apps.Entities.Schemas .Add("schemaA1 Content", SearchResultType.Content, "schemaA1-content-url", "schemaA1")); } - private ISchemaEntity CreateSchema(string name, bool isSingleton) + private ISchemaEntity CreateSchema(string name, SchemaType type = SchemaType.Default) { - return Mocks.Schema(appId, NamedId.Of(DomainId.NewGuid(), name), new Schema(name, null, isSingleton)); + return Mocks.Schema(appId, NamedId.Of(DomainId.NewGuid(), name), new Schema(name, type: type)); } private Context ContextWithPermission(string? permission = null) diff --git a/backend/tests/Squidex.Infrastructure.Tests/Collections/ImmutableListTests.cs b/backend/tests/Squidex.Infrastructure.Tests/Collections/ImmutableListTests.cs index fba54285f..32c865f2f 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/Collections/ImmutableListTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/Collections/ImmutableListTests.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Collections.Generic; using System.Linq; using Xunit; diff --git a/frontend/app/features/administration/state/event-consumers.state.spec.ts b/frontend/app/features/administration/state/event-consumers.state.spec.ts index decaf28c7..edb7f17cb 100644 --- a/frontend/app/features/administration/state/event-consumers.state.spec.ts +++ b/frontend/app/features/administration/state/event-consumers.state.spec.ts @@ -48,7 +48,7 @@ describe('EventConsumersState', () => { it('should reset loading state if loading failed', () => { eventConsumersService.setup(x => x.getEventConsumers()) - .returns(() => throwError('error')); + .returns(() => throwError('Service Error')); eventConsumersState.load().pipe(onErrorResumeNext()).subscribe(); @@ -68,7 +68,7 @@ describe('EventConsumersState', () => { it('should show notification on load error if silent is false', () => { eventConsumersService.setup(x => x.getEventConsumers()) - .returns(() => throwError({})).verifiable(); + .returns(() => throwError('Service Error')).verifiable(); eventConsumersState.load(true, false).pipe(onErrorResumeNext()).subscribe(); diff --git a/frontend/app/features/administration/state/users.state.spec.ts b/frontend/app/features/administration/state/users.state.spec.ts index e0ea23ce3..1e0af9c99 100644 --- a/frontend/app/features/administration/state/users.state.spec.ts +++ b/frontend/app/features/administration/state/users.state.spec.ts @@ -53,7 +53,7 @@ describe('UsersState', () => { it('should reset loading state if loading failed', () => { usersService.setup(x => x.getUsers(10, 0, undefined)) - .returns(() => throwError('error')); + .returns(() => throwError('Service Error')); usersState.load().pipe(onErrorResumeNext()).subscribe(); @@ -136,11 +136,11 @@ describe('UsersState', () => { it('should return null on select if user is not found', () => { usersService.setup(x => x.getUser('unknown')) - .returns(() => throwError({})).verifiable(); + .returns(() => throwError('Service Error')).verifiable(); let userSelected: UserDto; - usersState.select('unknown').subscribe(x => { + usersState.select('unknown').pipe(onErrorResumeNext()).subscribe(x => { userSelected = x!; }).unsubscribe(); diff --git a/frontend/app/features/content/pages/content/content-page.component.ts b/frontend/app/features/content/pages/content/content-page.component.ts index cfde8ae58..b0266fbcd 100644 --- a/frontend/app/features/content/pages/content/content-page.component.ts +++ b/frontend/app/features/content/pages/content/content-page.component.ts @@ -9,7 +9,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ApiUrlConfig, AppLanguageDto, AppsState, AuthService, AutoSaveKey, AutoSaveService, CanComponentDeactivate, ContentDto, ContentsState, defined, DialogService, EditContentForm, fadeAnimation, LanguagesState, ModalModel, ResourceOwner, SchemaDetailsDto, SchemasState, TempService, Version } from '@app/shared'; +import { ApiUrlConfig, AppLanguageDto, AppsState, AuthService, AutoSaveKey, AutoSaveService, CanComponentDeactivate, ContentDto, ContentsState, defined, DialogService, EditContentForm, fadeAnimation, LanguagesState, ModalModel, ResourceOwner, SchemaDto, SchemasState, TempService, Version } from '@app/shared'; import { Observable, of } from 'rxjs'; import { filter, map, tap } from 'rxjs/operators'; import { ContentReferencesComponent } from './references/content-references.component'; @@ -29,7 +29,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD @ViewChild(ContentReferencesComponent) public references: ContentReferencesComponent; - public schema: SchemaDetailsDto; + public schema: SchemaDto; public formContext: any; diff --git a/frontend/app/features/content/pages/content/editor/content-editor.component.ts b/frontend/app/features/content/pages/content/editor/content-editor.component.ts index 4b71b4630..64b53d45e 100644 --- a/frontend/app/features/content/pages/content/editor/content-editor.component.ts +++ b/frontend/app/features/content/pages/content/editor/content-editor.component.ts @@ -6,7 +6,7 @@ */ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { AppLanguageDto, EditContentForm, FieldForm, FieldSection, RootFieldDto, SchemaDetailsDto, Version } from '@app/shared'; +import { AppLanguageDto, EditContentForm, FieldForm, FieldSection, RootFieldDto, SchemaDto, Version } from '@app/shared'; @Component({ selector: 'sqx-content-editor', @@ -30,7 +30,7 @@ export class ContentEditorComponent { public contentFormCompare?: EditContentForm | null; @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; @Input() public formContext: any; diff --git a/frontend/app/features/content/pages/contents/contents-page.component.ts b/frontend/app/features/content/pages/contents/contents-page.component.ts index 6175e984c..e79caa709 100644 --- a/frontend/app/features/content/pages/contents/contents-page.component.ts +++ b/frontend/app/features/content/pages/contents/contents-page.component.ts @@ -9,7 +9,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { AppLanguageDto, AppsState, ContentDto, ContentsState, ContributorsState, defined, fadeAnimation, LanguagesState, ModalModel, Queries, Query, queryModelFromSchema, QuerySynchronizer, ResourceOwner, Router2State, SchemaDetailsDto, SchemasState, switchSafe, TableFields, TempService, UIState } from '@app/shared'; +import { AppLanguageDto, AppsState, ContentDto, ContentsState, ContributorsState, defined, fadeAnimation, LanguagesState, ModalModel, Queries, Query, queryModelFromSchema, QuerySynchronizer, ResourceOwner, Router2State, SchemaDto, SchemasState, switchSafe, TableFields, TempService, UIState } from '@app/shared'; import { combineLatest } from 'rxjs'; import { distinctUntilChanged, map, switchMap, take, tap } from 'rxjs/operators'; import { DueTimeSelectorComponent } from './../../shared/due-time-selector.component'; @@ -29,7 +29,7 @@ export class ContentsPageComponent extends ResourceOwner implements OnInit { @ViewChild('dueTimeSelector', { static: false }) public dueTimeSelector: DueTimeSelectorComponent; - public schema: SchemaDetailsDto; + public schema: SchemaDto; public tableView: TableFields; public tableViewModal = new ModalModel(); diff --git a/frontend/app/features/content/shared/preview-button.component.ts b/frontend/app/features/content/shared/preview-button.component.ts index 261e625e9..eadd298b0 100644 --- a/frontend/app/features/content/shared/preview-button.component.ts +++ b/frontend/app/features/content/shared/preview-button.component.ts @@ -6,7 +6,7 @@ */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; -import { ContentDto, fadeAnimation, interpolate, LocalStoreService, ModalModel, SchemaDetailsDto, Settings, StatefulComponent } from '@app/shared'; +import { ContentDto, fadeAnimation, interpolate, LocalStoreService, ModalModel, SchemaDto, Settings, StatefulComponent } from '@app/shared'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; @@ -35,7 +35,7 @@ export class PreviewButtonComponent extends StatefulComponent implements public content: ContentDto; @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public dropdown = new ModalModel(); diff --git a/frontend/app/features/content/shared/references/content-creator.component.ts b/frontend/app/features/content/shared/references/content-creator.component.ts index 21ee0a7f6..a3e9094da 100644 --- a/frontend/app/features/content/shared/references/content-creator.component.ts +++ b/frontend/app/features/content/shared/references/content-creator.component.ts @@ -6,7 +6,7 @@ */ import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { AppLanguageDto, ComponentContentsState, ContentDto, EditContentForm, ResourceOwner, SchemaDetailsDto, SchemaDto, SchemasState, Types } from '@app/shared'; +import { AppLanguageDto, ComponentContentsState, ContentDto, EditContentForm, ResourceOwner, SchemaDto, SchemasState, Types } from '@app/shared'; @Component({ selector: 'sqx-content-creator', @@ -38,7 +38,7 @@ export class ContentCreatorComponent extends ResourceOwner implements OnInit { @Input() public formContext: any; - public schema: SchemaDetailsDto; + public schema: SchemaDto; public schemas: ReadonlyArray = []; public contentForm: EditContentForm; diff --git a/frontend/app/features/content/shared/references/content-selector-item.component.ts b/frontend/app/features/content/shared/references/content-selector-item.component.ts index 98a61e68e..7aa8104f3 100644 --- a/frontend/app/features/content/shared/references/content-selector-item.component.ts +++ b/frontend/app/features/content/shared/references/content-selector-item.component.ts @@ -8,7 +8,7 @@ /* tslint:disable: component-selector */ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; -import { ContentDto, LanguageDto, SchemaDetailsDto } from '@app/shared'; +import { ContentDto, LanguageDto, SchemaDto } from '@app/shared'; @Component({ selector: '[sqxContentSelectorItem]', @@ -30,7 +30,7 @@ export class ContentSelectorItemComponent { public language: LanguageDto; @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; @Input('sqxContentSelectorItem') public content: ContentDto; diff --git a/frontend/app/features/content/shared/references/content-selector.component.ts b/frontend/app/features/content/shared/references/content-selector.component.ts index 026b68745..47ac8e530 100644 --- a/frontend/app/features/content/shared/references/content-selector.component.ts +++ b/frontend/app/features/content/shared/references/content-selector.component.ts @@ -6,7 +6,7 @@ */ import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { ApiUrlConfig, AppsState, ComponentContentsState, ContentDto, LanguageDto, Query, QueryModel, queryModelFromSchema, ResourceOwner, SchemaDetailsDto, SchemaDto, SchemasState, Types } from '@app/shared'; +import { ApiUrlConfig, AppsState, ComponentContentsState, ContentDto, LanguageDto, Query, QueryModel, queryModelFromSchema, ResourceOwner, SchemaDto, SchemasState, Types } from '@app/shared'; @Component({ selector: 'sqx-content-selector', @@ -35,7 +35,7 @@ export class ContentSelectorComponent extends ResourceOwner implements OnInit { @Input() public alreadySelected: ReadonlyArray; - public schema: SchemaDetailsDto; + public schema: SchemaDto; public schemas: ReadonlyArray = []; public queryModel: QueryModel; diff --git a/frontend/app/features/schemas/pages/schema/common/schema-edit-form.component.ts b/frontend/app/features/schemas/pages/schema/common/schema-edit-form.component.ts index b0bb91caa..16ab01073 100644 --- a/frontend/app/features/schemas/pages/schema/common/schema-edit-form.component.ts +++ b/frontend/app/features/schemas/pages/schema/common/schema-edit-form.component.ts @@ -7,7 +7,7 @@ import { Component, Input, OnChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; -import { EditSchemaForm, SchemaDetailsDto, SchemasState } from '@app/shared'; +import { EditSchemaForm, SchemaDto, SchemasState } from '@app/shared'; @Component({ selector: 'sqx-schema-edit-form', @@ -16,7 +16,7 @@ import { EditSchemaForm, SchemaDetailsDto, SchemasState } from '@app/shared'; }) export class SchemaEditFormComponent implements OnChanges { @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public fieldForm = new EditSchemaForm(this.formBuilder); diff --git a/frontend/app/features/schemas/pages/schema/export/schema-export-form.component.ts b/frontend/app/features/schemas/pages/schema/export/schema-export-form.component.ts index fbc6f98ba..7e31e9ec0 100644 --- a/frontend/app/features/schemas/pages/schema/export/schema-export-form.component.ts +++ b/frontend/app/features/schemas/pages/schema/export/schema-export-form.component.ts @@ -7,7 +7,7 @@ import { Component, Input, OnChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; -import { SchemaDetailsDto, SchemasState, SynchronizeSchemaForm } from '@app/shared'; +import { SchemaDto, SchemasState, SynchronizeSchemaForm } from '@app/shared'; @Component({ selector: 'sqx-schema-export-form', @@ -16,7 +16,7 @@ import { SchemaDetailsDto, SchemasState, SynchronizeSchemaForm } from '@app/shar }) export class SchemaExportFormComponent implements OnChanges { @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public synchronizeForm = new SynchronizeSchemaForm(this.formBuilder); diff --git a/frontend/app/features/schemas/pages/schema/fields/field-wizard.component.ts b/frontend/app/features/schemas/pages/schema/fields/field-wizard.component.ts index 4adc8a317..2304a2730 100644 --- a/frontend/app/features/schemas/pages/schema/fields/field-wizard.component.ts +++ b/frontend/app/features/schemas/pages/schema/fields/field-wizard.component.ts @@ -7,7 +7,7 @@ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { FormBuilder } from '@angular/forms'; -import { AddFieldForm, AppSettingsDto, createProperties, EditFieldForm, FieldDto, fieldTypes, LanguagesState, RootFieldDto, SchemaDetailsDto, SchemasState, Types } from '@app/shared'; +import { AddFieldForm, AppSettingsDto, createProperties, EditFieldForm, FieldDto, fieldTypes, LanguagesState, RootFieldDto, SchemaDto, SchemasState, Types } from '@app/shared'; const DEFAULT_FIELD = { name: '', partitioning: 'invariant', properties: createProperties('String') }; @@ -21,7 +21,7 @@ export class FieldWizardComponent implements OnInit { public nameInput: ElementRef; @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; @Input() public settings: AppSettingsDto; diff --git a/frontend/app/features/schemas/pages/schema/fields/field.component.ts b/frontend/app/features/schemas/pages/schema/fields/field.component.ts index ac4bb479e..0681b9b28 100644 --- a/frontend/app/features/schemas/pages/schema/fields/field.component.ts +++ b/frontend/app/features/schemas/pages/schema/fields/field.component.ts @@ -8,7 +8,7 @@ import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; -import { AppSettingsDto, createProperties, DialogModel, EditFieldForm, fadeAnimation, LanguageDto, ModalModel, NestedFieldDto, RootFieldDto, SchemaDetailsDto, SchemasState, sorted } from '@app/shared'; +import { AppSettingsDto, createProperties, DialogModel, EditFieldForm, fadeAnimation, LanguageDto, ModalModel, NestedFieldDto, RootFieldDto, SchemaDto, SchemasState, sorted } from '@app/shared'; @Component({ selector: 'sqx-field', @@ -23,7 +23,7 @@ export class FieldComponent implements OnChanges { public field: NestedFieldDto | RootFieldDto; @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; @Input() public parent: RootFieldDto; diff --git a/frontend/app/features/schemas/pages/schema/fields/schema-fields.component.ts b/frontend/app/features/schemas/pages/schema/fields/schema-fields.component.ts index 978608b01..33fd252a1 100644 --- a/frontend/app/features/schemas/pages/schema/fields/schema-fields.component.ts +++ b/frontend/app/features/schemas/pages/schema/fields/schema-fields.component.ts @@ -7,7 +7,7 @@ import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { Component, Input, OnInit } from '@angular/core'; -import { AppsState, DialogModel, FieldDto, fieldTypes, LanguagesState, SchemaDetailsDto, SchemasState, sorted } from '@app/shared'; +import { AppsState, DialogModel, FieldDto, fieldTypes, LanguagesState, SchemaDto, SchemasState, sorted } from '@app/shared'; @Component({ selector: 'sqx-schema-fields', @@ -18,7 +18,7 @@ export class SchemaFieldsComponent implements OnInit { public fieldTypes = fieldTypes; @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public addFieldDialog = new DialogModel(); diff --git a/frontend/app/features/schemas/pages/schema/preview/schema-preview-urls-form.component.ts b/frontend/app/features/schemas/pages/schema/preview/schema-preview-urls-form.component.ts index 0576086dd..9b55c416b 100644 --- a/frontend/app/features/schemas/pages/schema/preview/schema-preview-urls-form.component.ts +++ b/frontend/app/features/schemas/pages/schema/preview/schema-preview-urls-form.component.ts @@ -7,7 +7,7 @@ import { Component, Input, OnChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; -import { ConfigurePreviewUrlsForm, SchemaDetailsDto, SchemasState } from '@app/shared'; +import { ConfigurePreviewUrlsForm, SchemaDto, SchemasState } from '@app/shared'; @Component({ selector: 'sqx-schema-preview-urls-form', @@ -16,7 +16,7 @@ import { ConfigurePreviewUrlsForm, SchemaDetailsDto, SchemasState } from '@app/s }) export class SchemaPreviewUrlsFormComponent implements OnChanges { @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public editForm = new ConfigurePreviewUrlsForm(this.formBuilder); diff --git a/frontend/app/features/schemas/pages/schema/rules/schema-field-rules-form.component.ts b/frontend/app/features/schemas/pages/schema/rules/schema-field-rules-form.component.ts index 67c34842b..c64307ccb 100644 --- a/frontend/app/features/schemas/pages/schema/rules/schema-field-rules-form.component.ts +++ b/frontend/app/features/schemas/pages/schema/rules/schema-field-rules-form.component.ts @@ -7,7 +7,7 @@ import { Component, Input, OnChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; -import { ConfigureFieldRulesForm, FIELD_RULE_ACTIONS, SchemaDetailsDto, SchemasState } from '@app/shared'; +import { ConfigureFieldRulesForm, FIELD_RULE_ACTIONS, SchemaDto, SchemasState } from '@app/shared'; @Component({ selector: 'sqx-schema-field-rules-form', @@ -16,7 +16,7 @@ import { ConfigureFieldRulesForm, FIELD_RULE_ACTIONS, SchemaDetailsDto, SchemasS }) export class SchemaFieldRulesFormComponent implements OnChanges { @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public editForm = new ConfigureFieldRulesForm(this.formBuilder); diff --git a/frontend/app/features/schemas/pages/schema/schema-page.component.ts b/frontend/app/features/schemas/pages/schema/schema-page.component.ts index 8e645960a..6c3af1512 100644 --- a/frontend/app/features/schemas/pages/schema/schema-page.component.ts +++ b/frontend/app/features/schemas/pages/schema/schema-page.component.ts @@ -7,7 +7,7 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { defined, fadeAnimation, MessageBus, ModalModel, ResourceOwner, SchemaDetailsDto, SchemasState } from '@app/shared'; +import { defined, fadeAnimation, MessageBus, ModalModel, ResourceOwner, SchemaDto, SchemasState } from '@app/shared'; import { map } from 'rxjs/operators'; import { SchemaCloning } from './../messages'; @@ -22,7 +22,7 @@ import { SchemaCloning } from './../messages'; export class SchemaPageComponent extends ResourceOwner implements OnInit { public readonly exact = { exact: true }; - public schema: SchemaDetailsDto; + public schema: SchemaDto; public schemaTab = this.route.queryParams.pipe(map(x => x['tab'] || 'fields')); public editOptionsDropdown = new ModalModel(); diff --git a/frontend/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts b/frontend/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts index 6faf97fce..aa36b3f1e 100644 --- a/frontend/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts +++ b/frontend/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts @@ -7,7 +7,7 @@ import { Component, Input, OnChanges } from '@angular/core'; import { FormBuilder } from '@angular/forms'; -import { AppsState, EditScriptsForm, SchemaCompletions, SchemaDetailsDto, SchemasService, SchemasState } from '@app/shared'; +import { AppsState, EditScriptsForm, SchemaCompletions, SchemaDto, SchemasService, SchemasState } from '@app/shared'; import { EMPTY, Observable } from 'rxjs'; @Component({ @@ -17,7 +17,7 @@ import { EMPTY, Observable } from 'rxjs'; }) export class SchemaScriptsFormComponent implements OnChanges { @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public schemaScript = 'query'; public schemaCompletions: Observable = EMPTY; diff --git a/frontend/app/features/schemas/pages/schema/ui/field-list.component.ts b/frontend/app/features/schemas/pages/schema/ui/field-list.component.ts index 687776a36..bd5f1d57b 100644 --- a/frontend/app/features/schemas/pages/schema/ui/field-list.component.ts +++ b/frontend/app/features/schemas/pages/schema/ui/field-list.component.ts @@ -9,7 +9,7 @@ import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop'; import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; -import { MetaFields, SchemaDetailsDto } from '@app/shared'; +import { MetaFields, SchemaDto } from '@app/shared'; const META_FIELD_NAMES = Object.values(MetaFields); @@ -24,7 +24,7 @@ export class FieldListComponent implements OnChanges { public emptyText = ''; @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; @Input() public fieldNames: ReadonlyArray; diff --git a/frontend/app/features/schemas/pages/schema/ui/schema-ui-form.component.ts b/frontend/app/features/schemas/pages/schema/ui/schema-ui-form.component.ts index eb31a2106..2f7a30be0 100644 --- a/frontend/app/features/schemas/pages/schema/ui/schema-ui-form.component.ts +++ b/frontend/app/features/schemas/pages/schema/ui/schema-ui-form.component.ts @@ -6,7 +6,7 @@ */ import { Component, Input, OnChanges } from '@angular/core'; -import { SchemaDetailsDto, SchemasState } from '@app/shared'; +import { SchemaDto, SchemasState } from '@app/shared'; type State = { fieldsInLists: ReadonlyArray, fieldsInReferences: ReadonlyArray }; @@ -17,7 +17,7 @@ type State = { fieldsInLists: ReadonlyArray, fieldsInReferences: Readonl }) export class SchemaUIFormComponent implements OnChanges { @Input() - public schema: SchemaDetailsDto; + public schema: SchemaDto; public selectedTab = 0; diff --git a/frontend/app/features/schemas/pages/schemas/schema-form.component.html b/frontend/app/features/schemas/pages/schemas/schema-form.component.html index 290fba757..320a4a755 100644 --- a/frontend/app/features/schemas/pages/schemas/schema-form.component.html +++ b/frontend/app/features/schemas/pages/schemas/schema-form.component.html @@ -29,11 +29,11 @@