Browse Source

Simplify schema builders and add missing field builders.

pull/768/head
Sebastian 4 years ago
parent
commit
e64619ea7c
  1. 21
      backend/extensions/Squidex.Extensions/Samples/Middleware/TemplateInstance.cs
  2. 21
      backend/extensions/Squidex.Extensions/Samples/Middleware/TemplateMiddleware.cs
  3. 84
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ArrayFieldBuilder.cs
  4. 37
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/AssetFieldBuilder.cs
  5. 17
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/BooleanFieldBuilder.cs
  6. 20
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ComponentFieldBuilder.cs
  7. 20
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ComponentsFieldBuilder.cs
  8. 17
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/DateTimeFieldBuilder.cs
  9. 51
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/FieldBuilder.cs
  10. 7
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/JsonFieldBuilder.cs
  11. 7
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/NumberFieldBuilder.cs
  12. 18
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ReferencesFieldBuilder.cs
  13. 76
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/SchemaBuilder.cs
  14. 73
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/StringFieldBuilder.cs
  15. 17
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/TagsFieldBuilder.cs
  16. 20
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/UIFieldBuilder.cs
  17. 21
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateBlog.cs
  18. 70
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateProfile.cs
  19. 88
      backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs

21
backend/extensions/Squidex.Extensions/Samples/Middleware/TemplateInstance.cs

@ -6,6 +6,7 @@
// ==========================================================================
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Apps.Templates;
using Squidex.Domain.Apps.Entities.Apps.Templates.Builders;
@ -20,16 +21,26 @@ namespace Squidex.Extensions.Samples.Middleware
var schema =
SchemaBuilder.Create("Blogs")
.AddString("Title", f => f
.Length(100)
.Properties(p => p with
{
MaxLength = 100
})
.Required())
.AddString("Slug", f => f
.Length(100)
.Properties(p => p with
{
MaxLength = 100
})
.Required()
.Disabled())
.AddString("Text", f => f
.Length(1000)
.Required()
.AsRichText())
.Properties(p => p with
{
Editor = StringFieldEditor.RichText,
MaxLength = 1000,
MinLength = 200
})
.Required())
.Build();
return publish(schema);

21
backend/extensions/Squidex.Extensions/Samples/Middleware/TemplateMiddleware.cs

@ -7,6 +7,7 @@
using System;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Domain.Apps.Entities.Apps.Templates.Builders;
@ -35,16 +36,26 @@ namespace Squidex.Extensions.Samples.Middleware
var schema =
SchemaBuilder.Create("Pages")
.AddString("Title", f => f
.Length(100)
.Properties(p => p with
{
MaxLength = 100
})
.Required())
.AddString("Slug", f => f
.Length(100)
.Properties(p => p with
{
MaxLength = 100
})
.Required()
.Disabled())
.AddString("Text", f => f
.Length(1000)
.Required()
.AsRichText())
.Properties(p => p with
{
Editor = StringFieldEditor.RichText,
MaxLength = 1000,
MinLength = 200
})
.Required())
.Build();
await publish(schema);

84
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ArrayFieldBuilder.cs

@ -13,96 +13,134 @@ using Squidex.Text;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class ArrayFieldBuilder : FieldBuilder<ArrayFieldBuilder>
public sealed class ArrayFieldBuilder : FieldBuilder<ArrayFieldBuilder, ArrayFieldProperties>
{
private UpsertSchemaField TypedField
{
get => (UpsertSchemaField)Field;
}
public ArrayFieldBuilder(UpsertSchemaField field, CreateSchema schema)
: base(field, schema)
public ArrayFieldBuilder(UpsertSchemaField field, ArrayFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
public ArrayFieldBuilder AddAssets(string name, Action<AssetFieldBuilder> configure)
{
var field = AddField<AssetsFieldProperties>(name);
var (field, properties) = AddField<AssetsFieldProperties>(name);
configure(new AssetFieldBuilder(field, Schema));
configure(new AssetFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddBoolean(string name, Action<BooleanFieldBuilder> configure)
{
var field = AddField<BooleanFieldProperties>(name);
var (field, properties) = AddField<BooleanFieldProperties>(name);
configure(new BooleanFieldBuilder(field, Schema));
configure(new BooleanFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddDateTime(string name, Action<DateTimeFieldBuilder> configure)
{
var field = AddField<DateTimeFieldProperties>(name);
var (field, properties) = AddField<DateTimeFieldProperties>(name);
configure(new DateTimeFieldBuilder(field, Schema));
configure(new DateTimeFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddComponent(string name, Action<ComponentFieldBuilder> configure)
{
var (field, properties) = AddField<ComponentFieldProperties>(name);
configure(new ComponentFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddComponents(string name, Action<ComponentsFieldBuilder> configure)
{
var (field, properties) = AddField<ComponentsFieldProperties>(name);
configure(new ComponentsFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddJson(string name, Action<JsonFieldBuilder> configure)
{
var field = AddField<JsonFieldProperties>(name);
var (field, properties) = AddField<JsonFieldProperties>(name);
configure(new JsonFieldBuilder(field, Schema));
configure(new JsonFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddNumber(string name, Action<NumberFieldBuilder> configure)
{
var field = AddField<NumberFieldProperties>(name);
var (field, properties) = AddField<NumberFieldProperties>(name);
configure(new NumberFieldBuilder(field, Schema));
configure(new NumberFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddReferences(string name, Action<ReferencesFieldBuilder> configure)
{
var field = AddField<ReferencesFieldProperties>(name);
var (field, properties) = AddField<ReferencesFieldProperties>(name);
configure(new ReferencesFieldBuilder(field, Schema));
configure(new ReferencesFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddString(string name, Action<StringFieldBuilder> configure)
{
var field = AddField<StringFieldProperties>(name);
var (field, properties) = AddField<StringFieldProperties>(name);
configure(new StringFieldBuilder(field, Schema));
configure(new StringFieldBuilder(field, properties, Schema));
return this;
}
private UpsertSchemaNestedField AddField<T>(string name) where T : FieldProperties, new()
public ArrayFieldBuilder AddTags(string name, Action<TagsFieldBuilder> configure)
{
var (field, properties) = AddField<TagsFieldProperties>(name);
configure(new TagsFieldBuilder(field, properties, Schema));
return this;
}
public ArrayFieldBuilder AddUI(string name, Action<UIFieldBuilder> configure)
{
var (field, properties) = AddField<UIFieldProperties>(name);
configure(new UIFieldBuilder(field, properties, Schema));
return this;
}
private (UpsertSchemaNestedField, T) AddField<T>(string name) where T : FieldProperties, new()
{
var properties = new T
{
Label = name
};
var nestedField = new UpsertSchemaNestedField
{
Name = name.ToCamelCase(),
Properties = new T
{
Label = name
}
Properties = properties
};
TypedField.Nested ??= Array.Empty<UpsertSchemaNestedField>();
TypedField.Nested = TypedField.Nested.Union(new[] { nestedField }).ToArray();
return nestedField;
return (nestedField, properties);
}
}
}

37
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/AssetFieldBuilder.cs

@ -5,47 +5,16 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class AssetFieldBuilder : FieldBuilder<AssetFieldBuilder>
public sealed class AssetFieldBuilder : FieldBuilder<AssetFieldBuilder, AssetsFieldProperties>
{
public AssetFieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
: base(field, schema)
public AssetFieldBuilder(UpsertSchemaFieldBase field, AssetsFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
public AssetFieldBuilder MustBeImage()
{
Properties<AssetsFieldProperties>(p => p with
{
ExpectedType = AssetType.Image
});
return this;
}
public AssetFieldBuilder MustBe(AssetType type)
{
Properties<AssetsFieldProperties>(p => p with
{
ExpectedType = type
});
return this;
}
public AssetFieldBuilder RequireSingle()
{
Properties<AssetsFieldProperties>(p => p with
{
MaxItems = 1
});
return this;
}
}
}

17
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/BooleanFieldBuilder.cs

@ -10,22 +10,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class BooleanFieldBuilder : FieldBuilder<BooleanFieldBuilder>
public sealed class BooleanFieldBuilder : FieldBuilder<BooleanFieldBuilder, BooleanFieldProperties>
{
public BooleanFieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
: base(field, schema)
public BooleanFieldBuilder(UpsertSchemaFieldBase field, BooleanFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
public BooleanFieldBuilder AsToggle()
{
Properties<BooleanFieldProperties>(p => p with
{
Editor = BooleanFieldEditor.Toggle,
EditorUrl = null
});
return this;
}
}
}

20
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ComponentFieldBuilder.cs

@ -0,0 +1,20 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public sealed class ComponentFieldBuilder : FieldBuilder<ComponentFieldBuilder, ComponentFieldProperties>
{
public ComponentFieldBuilder(UpsertSchemaFieldBase field, ComponentFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
}
}

20
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ComponentsFieldBuilder.cs

@ -0,0 +1,20 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public sealed class ComponentsFieldBuilder : FieldBuilder<ComponentsFieldBuilder, ComponentsFieldProperties>
{
public ComponentsFieldBuilder(UpsertSchemaFieldBase field, ComponentsFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
}
}

17
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/DateTimeFieldBuilder.cs

@ -10,22 +10,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class DateTimeFieldBuilder : FieldBuilder<DateTimeFieldBuilder>
public sealed class DateTimeFieldBuilder : FieldBuilder<DateTimeFieldBuilder, DateTimeFieldProperties>
{
public DateTimeFieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
: base(field, schema)
public DateTimeFieldBuilder(UpsertSchemaFieldBase field, DateTimeFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
public DateTimeFieldBuilder AsDateTime()
{
Properties<DateTimeFieldProperties>(p => p with
{
Editor = DateTimeFieldEditor.DateTime,
EditorUrl = null
});
return this;
}
}
}

51
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/FieldBuilder.cs

@ -15,59 +15,68 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
public abstract class FieldBuilder
{
protected UpsertSchemaFieldBase Field { get; init; }
protected CreateSchema Schema { get; init; }
}
public abstract class FieldBuilder<T> : FieldBuilder
where T : FieldBuilder
public abstract class FieldBuilder<T, TProperties> : FieldBuilder where T : FieldBuilder where TProperties : FieldProperties
{
protected FieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
private TProperties properties;
protected FieldBuilder(UpsertSchemaFieldBase field, TProperties properties, CreateSchema schema)
{
this.properties = properties;
Field = field;
Schema = schema;
}
public T Label(string? label)
public T Localizable()
{
Field.Properties = Field.Properties with { Label = label };
if (Field is UpsertSchemaField localizableField)
{
localizableField.Partitioning = Partitioning.Language.Key;
}
return (T)(object)this;
}
public T Hints(string? hints)
public T Disabled(bool isDisabled = true)
{
Field.Properties = Field.Properties with { Hints = hints };
Field.IsDisabled = isDisabled;
return (T)(object)this;
}
public T Localizable()
public T Hidden(bool isHidden = true)
{
if (Field is UpsertSchemaField localizableField)
{
localizableField.Partitioning = Partitioning.Language.Key;
}
Field.IsHidden = isHidden;
return (T)(object)this;
}
public T Disabled()
public T Label(string? label)
{
Field.IsDisabled = true;
return (T)(object)this;
return Properties(x => x with { Label = label });
}
public T Required()
public T Hints(string? hints)
{
Field.Properties = Field.Properties with { IsRequired = true };
return Properties(x => x with { Hints = hints });
}
return (T)(object)this;
public T Required(bool isRequired = true)
{
return Properties(x => x with { IsRequired = isRequired });
}
protected void Properties<TProperties>(Func<TProperties, TProperties> updater) where TProperties : FieldProperties
public T Properties(Func<TProperties, TProperties> updater)
{
Field.Properties = updater((TProperties)Field.Properties);
properties = updater(properties);
Field.Properties = properties;
return (T)(object)this;
}
public T ShowInList()

7
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/JsonFieldBuilder.cs

@ -5,14 +5,15 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class JsonFieldBuilder : FieldBuilder<JsonFieldBuilder>
public sealed class JsonFieldBuilder : FieldBuilder<JsonFieldBuilder, JsonFieldProperties>
{
public JsonFieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
: base(field, schema)
public JsonFieldBuilder(UpsertSchemaFieldBase field, JsonFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
}

7
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/NumberFieldBuilder.cs

@ -5,14 +5,15 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class NumberFieldBuilder : FieldBuilder<NumberFieldBuilder>
public sealed class NumberFieldBuilder : FieldBuilder<NumberFieldBuilder, NumberFieldProperties>
{
public NumberFieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
: base(field, schema)
public NumberFieldBuilder(UpsertSchemaFieldBase field, NumberFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
}

18
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/ReferencesFieldBuilder.cs

@ -7,26 +7,14 @@
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Collections;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class ReferencesFieldBuilder : FieldBuilder<ReferencesFieldBuilder>
public sealed class ReferencesFieldBuilder : FieldBuilder<ReferencesFieldBuilder, ReferencesFieldProperties>
{
public ReferencesFieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
: base(field, schema)
public ReferencesFieldBuilder(UpsertSchemaFieldBase field, ReferencesFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
public ReferencesFieldBuilder WithSchemaId(DomainId id)
{
Properties<ReferencesFieldProperties>(p => p with
{
SchemaIds = ImmutableList.Create(id)
});
return this;
}
}
}

76
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/SchemaBuilder.cs

@ -67,96 +67,122 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
return this;
}
public SchemaBuilder AddArray(string name, Action<ArrayFieldBuilder> configure)
{
var (field, properties) = AddField<ArrayFieldProperties>(name);
configure(new ArrayFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddAssets(string name, Action<AssetFieldBuilder> configure)
{
var field = AddField<AssetsFieldProperties>(name);
var (field, properties) = AddField<AssetsFieldProperties>(name);
configure(new AssetFieldBuilder(field, command));
configure(new AssetFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddBoolean(string name, Action<BooleanFieldBuilder> configure)
{
var field = AddField<BooleanFieldProperties>(name);
var (field, properties) = AddField<BooleanFieldProperties>(name);
configure(new BooleanFieldBuilder(field, command));
configure(new BooleanFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddComponent(string name, Action<ComponentFieldBuilder> configure)
{
var (field, properties) = AddField<ComponentFieldProperties>(name);
configure(new ComponentFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddComponents(string name, Action<ComponentsFieldBuilder> configure)
{
var (field, properties) = AddField<ComponentsFieldProperties>(name);
configure(new ComponentsFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddDateTime(string name, Action<DateTimeFieldBuilder> configure)
{
var field = AddField<DateTimeFieldProperties>(name);
var (field, properties) = AddField<DateTimeFieldProperties>(name);
configure(new DateTimeFieldBuilder(field, command));
configure(new DateTimeFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddJson(string name, Action<JsonFieldBuilder> configure)
{
var field = AddField<JsonFieldProperties>(name);
var (field, properties) = AddField<JsonFieldProperties>(name);
configure(new JsonFieldBuilder(field, command));
configure(new JsonFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddNumber(string name, Action<NumberFieldBuilder> configure)
{
var field = AddField<NumberFieldProperties>(name);
var (field, properties) = AddField<NumberFieldProperties>(name);
configure(new NumberFieldBuilder(field, command));
configure(new NumberFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddReferences(string name, Action<ReferencesFieldBuilder> configure)
{
var field = AddField<ReferencesFieldProperties>(name);
var (field, properties) = AddField<ReferencesFieldProperties>(name);
configure(new ReferencesFieldBuilder(field, command));
configure(new ReferencesFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddString(string name, Action<StringFieldBuilder> configure)
{
var field = AddField<StringFieldProperties>(name);
var (field, properties) = AddField<StringFieldProperties>(name);
configure(new StringFieldBuilder(field, command));
configure(new StringFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddTags(string name, Action<TagsFieldBuilder> configure)
{
var field = AddField<TagsFieldProperties>(name);
var (field, properties) = AddField<TagsFieldProperties>(name);
configure(new TagsFieldBuilder(field, command));
configure(new TagsFieldBuilder(field, properties, command));
return this;
}
public SchemaBuilder AddArray(string name, Action<ArrayFieldBuilder> configure)
public SchemaBuilder AddUI(string name, Action<UIFieldBuilder> configure)
{
var field = AddField<ArrayFieldProperties>(name);
var (field, properties) = AddField<UIFieldProperties>(name);
configure(new ArrayFieldBuilder(field, command));
configure(new UIFieldBuilder(field, properties, command));
return this;
}
private UpsertSchemaField AddField<T>(string name) where T : FieldProperties, new()
private (UpsertSchemaField, T) AddField<T>(string name) where T : FieldProperties, new()
{
var properties = new T { Label = name };
var field = new UpsertSchemaField
{
Name = name.ToCamelCase(),
Properties = new T
{
Label = name
}
Properties = properties,
};
if (command.Fields == null)
@ -168,7 +194,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
command.Fields = command.Fields.Union(Enumerable.Repeat(field, 1)).ToArray();
}
return field;
return (field, properties);
}
public CreateSchema Build()

73
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/StringFieldBuilder.cs

@ -7,81 +7,14 @@
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure.Collections;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class StringFieldBuilder : FieldBuilder<StringFieldBuilder>
public sealed class StringFieldBuilder : FieldBuilder<StringFieldBuilder, StringFieldProperties>
{
public StringFieldBuilder(UpsertSchemaFieldBase field, CreateSchema schema)
: base(field, schema)
public StringFieldBuilder(UpsertSchemaFieldBase field, StringFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
public StringFieldBuilder AsTextArea()
{
Properties<StringFieldProperties>(p => p with
{
EditorUrl = null,
Editor = StringFieldEditor.TextArea
});
return this;
}
public StringFieldBuilder AsRichText()
{
Properties<StringFieldProperties>(p => p with
{
EditorUrl = null,
Editor = StringFieldEditor.RichText
});
return this;
}
public StringFieldBuilder AsDropDown(params string[] values)
{
Properties<StringFieldProperties>(p => p with
{
AllowedValues = ImmutableList.Create(values),
EditorUrl = null,
Editor = StringFieldEditor.Dropdown
});
return this;
}
public StringFieldBuilder Unique()
{
Properties<StringFieldProperties>(p => p with
{
IsUnique = true
});
return this;
}
public StringFieldBuilder Pattern(string pattern, string? message = null)
{
Properties<StringFieldProperties>(p => p with
{
Pattern = pattern,
PatternMessage = message
});
return this;
}
public StringFieldBuilder Length(int maxLength, int minLength = 0)
{
Properties<StringFieldProperties>(p => p with
{
MaxLength = maxLength,
MinLength = minLength
});
return this;
}
}
}

17
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/TagsFieldBuilder.cs

@ -7,25 +7,14 @@
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
using Squidex.Infrastructure.Collections;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public class TagsFieldBuilder : FieldBuilder<TagsFieldBuilder>
public sealed class TagsFieldBuilder : FieldBuilder<TagsFieldBuilder, TagsFieldProperties>
{
public TagsFieldBuilder(UpsertSchemaField field, CreateSchema schema)
: base(field, schema)
public TagsFieldBuilder(UpsertSchemaFieldBase field, TagsFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
public TagsFieldBuilder WithAllowedValues(params string[] values)
{
Properties<TagsFieldProperties>(p => p with
{
AllowedValues = ImmutableList.Create(values)
});
return this;
}
}
}

20
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/Builders/UIFieldBuilder.cs

@ -0,0 +1,20 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Schemas.Commands;
namespace Squidex.Domain.Apps.Entities.Apps.Templates.Builders
{
public sealed class UIFieldBuilder : FieldBuilder<UIFieldBuilder, UIFieldProperties>
{
public UIFieldBuilder(UpsertSchemaFieldBase field, UIFieldProperties properties, CreateSchema schema)
: base(field, properties, schema)
{
}
}
}

21
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateBlog.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.Apps.Templates.Builders;
using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Infrastructure;
@ -67,12 +68,18 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
var schema =
SchemaBuilder.Create("Posts")
.AddString("Title", f => f
.Length(100)
.Properties(p => p with
{
MaxLength = 100
})
.Required()
.ShowInList()
.Hints("The title of the post."))
.AddString("Text", f => f
.AsRichText()
.Properties(p => p with
{
Editor = StringFieldEditor.RichText
})
.Required()
.Hints("The text of the post."))
.AddString("Slug", f => f
@ -92,12 +99,18 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
var schema =
SchemaBuilder.Create("Pages")
.AddString("Title", f => f
.Length(100)
.Properties(p => p with
{
MaxLength = 100
})
.Required()
.ShowInList()
.Hints("The title of the page."))
.AddString("Text", f => f
.AsRichText()
.Properties(p => p with
{
Editor = StringFieldEditor.RichText
})
.Required()
.Hints("The text of the page."))
.AddString("Slug", f => f

70
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/CreateProfile.cs

@ -6,10 +6,13 @@
// ==========================================================================
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Assets;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Entities.Apps.Templates.Builders;
using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Collections;
namespace Squidex.Domain.Apps.Entities.Apps.Templates
{
@ -64,17 +67,31 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
.ShowInList()
.Hints("Your last name."))
.AddAssets("Image", f => f
.MustBeImage()
.Properties(p => p with
{
ExpectedType = AssetType.Image,
MaxItems = 1,
MinItems = 1
})
.Hints("Your profile image."))
.AddString("Profession", f => f
.AsTextArea()
.Properties(p => p with
{
Editor = StringFieldEditor.TextArea
})
.Required()
.Hints("Describe your profession."))
.AddString("Summary", f => f
.AsTextArea()
.Properties(p => p with
{
Editor = StringFieldEditor.TextArea
})
.Hints("Write a short summary about yourself."))
.AddString("Legal Terms", f => f
.AsTextArea()
.Properties(p => p with
{
Editor = StringFieldEditor.TextArea
})
.Hints("The terms to fulfill legal requirements."))
.AddString("Github Link", f => f
.Hints("An optional link to your Github account."))
@ -102,15 +119,23 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
.ShowInList()
.Hints("The name of your project."))
.AddString("Description", f => f
.AsTextArea()
.Properties(p => p with
{
Editor = StringFieldEditor.TextArea
})
.Required()
.Hints("Describe your project."))
.AddAssets("Image", f => f
.MustBeImage()
.Properties(p => p with
{
ExpectedType = AssetType.Image,
MaxItems = 1,
MinItems = 1
})
.Required()
.Hints("An image or screenshot for your project."))
.AddString("Label", f => f
.AsTextArea()
.Properties(p => p with { Editor = StringFieldEditor.TextArea })
.Hints("An optional label to categorize your project, e.g. 'Open Source'."))
.AddString("Link", f => f
.Hints("An optional link to your project."))
@ -136,7 +161,12 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
.ShowInList()
.Hints("The company or organization you worked for."))
.AddAssets("Logo", f => f
.MustBeImage()
.Properties(p => p with
{
ExpectedType = AssetType.Image,
MaxItems = 1,
MinItems = 1
})
.Hints("The logo of the company or organization you worked for."))
.AddDateTime("From", f => f
.Required()
@ -163,7 +193,12 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
.ShowInList()
.Hints("The school or university."))
.AddAssets("Logo", f => f
.MustBeImage()
.Properties(p => p with
{
ExpectedType = AssetType.Image,
MaxItems = 1,
MinItems = 1
})
.Hints("The logo of the school or university."))
.AddDateTime("From", f => f
.Required()
@ -186,7 +221,12 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
.ShowInList()
.Hints("The name or title of your publication."))
.AddAssets("Cover", f => f
.MustBeImage()
.Properties(p => p with
{
ExpectedType = AssetType.Image,
MaxItems = 1,
MinItems = 1
})
.Hints("The cover of your publication."))
.AddString("Description", f => f
.Hints("Describe the content of your publication."))
@ -208,7 +248,15 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
.ShowInList()
.Hints("The name of the skill."))
.AddString("Experience", f => f
.AsDropDown("Beginner", "Advanced", "Professional", "Expert")
.Properties(p => p with
{
AllowedValues = ImmutableList.Create(
"Beginner",
"Advanced",
"Professional",
"Expert"),
Editor = StringFieldEditor.Dropdown,
})
.Required()
.ShowInList()
.Hints("The level of experience."))

88
backend/src/Squidex.Domain.Apps.Entities/History/NotifoService.cs

@ -24,6 +24,8 @@ using Squidex.Log;
using Squidex.Shared.Identity;
using Squidex.Shared.Users;
#pragma warning disable MA0073 // Avoid comparison with bool constant
namespace Squidex.Domain.Apps.Entities.History
{
public class NotifoService : IUserEvents
@ -167,32 +169,16 @@ namespace Squidex.Domain.Apps.Entities.History
var maxAge = now - MaxAge;
var batches = events
.Where(x => !x.AppEvent.Headers.Restored())
.Where(x => IsNewer(x.AppEvent.Headers, maxAge))
.Where(x => IsComment(x.AppEvent.Payload) || x.HistoryEvent != null)
.Where(x => x.AppEvent.Headers.Restored() == false)
.Where(x => x.AppEvent.Headers.Timestamp() > maxAge)
.SelectMany(x => CreateRequests(x.AppEvent, x.HistoryEvent))
.Batch(50);
foreach (var batch in batches)
{
var requests = new List<PublishDto>();
foreach (var @event in batch)
{
var payload = @event.AppEvent.Payload;
if (payload is CommentCreated comment && IsComment(payload))
{
AddMentions(requests, comment);
}
else if (@event.HistoryEvent != null)
{
AddHistoryEvent(requests, @event.HistoryEvent, payload);
}
}
var request = new PublishManyDto
{
Requests = requests
Requests = batch.ToList()
};
await client.Events.PostEventsAsync(options.AppId, request);
@ -269,7 +255,22 @@ namespace Squidex.Domain.Apps.Entities.History
}
}
private void AddHistoryEvent(List<PublishDto> requests, HistoryEvent historyEvent, AppEvent payload)
private IEnumerable<PublishDto> CreateRequests(Envelope<AppEvent> appEvent, HistoryEvent? historyEvent)
{
if (appEvent.Payload is CommentCreated comment && comment.Mentions?.Length > 0)
{
foreach (var userId in comment.Mentions)
{
yield return CreateMentionRequest(comment, userId);
}
}
else if (historyEvent != null)
{
yield return CreateHistoryRequest(historyEvent, appEvent.Payload);
}
}
private PublishDto CreateHistoryRequest(HistoryEvent historyEvent, AppEvent payload)
{
var publishRequest = new PublishDto
{
@ -295,47 +296,34 @@ namespace Squidex.Domain.Apps.Entities.History
SetUser(payload, publishRequest);
SetTopic(payload, publishRequest, historyEvent);
requests.Add(publishRequest);
return publishRequest;
}
private static void AddMentions(List<PublishDto> requests, CommentCreated comment)
private static PublishDto CreateMentionRequest(CommentCreated comment, string userId)
{
foreach (var userId in comment.Mentions!)
var publishRequest = new PublishDto
{
var publishRequest = new PublishDto
{
Topic = $"users/{userId}"
};
publishRequest.Properties["SquidexApp"] = comment.AppId.Name;
Topic = $"users/{userId}"
};
publishRequest.Preformatted = new NotificationFormattingDto
{
Subject =
{
["en"] = comment.Text
}
};
publishRequest.Properties["SquidexApp"] = comment.AppId.Name;
if (comment.Url?.IsAbsoluteUri == true)
publishRequest.Preformatted = new NotificationFormattingDto
{
Subject =
{
publishRequest.Preformatted.LinkUrl["en"] = comment.Url.ToString();
["en"] = comment.Text
}
};
SetUser(comment, publishRequest);
requests.Add(publishRequest);
if (comment.Url?.IsAbsoluteUri == true)
{
publishRequest.Preformatted.LinkUrl["en"] = comment.Url.ToString();
}
}
private static bool IsNewer(EnvelopeHeaders headers, Instant maxAge)
{
return headers.Timestamp() > maxAge;
}
SetUser(comment, publishRequest);
private static bool IsComment(AppEvent appEvent)
{
return appEvent is CommentCreated comment && comment.Mentions?.Length > 0;
return publishRequest;
}
private static void SetUser(AppEvent appEvent, PublishDto publishRequest)

Loading…
Cancel
Save