Browse Source

UI fixes (#1142)

* Simplified editors.

* Primary ctor.

* Move inheritance to new line

* Formatting fixes.

* Fix registration.
pull/1144/head
Sebastian Stehle 2 years ago
committed by GitHub
parent
commit
920371bd9c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      backend/.editorconfig
  2. 9
      backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs
  3. 9
      backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs
  4. 12
      backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverExceptionHandler.cs
  5. 9
      backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverPlugin.cs
  6. 9
      backend/extensions/Squidex.Extensions/APM/Zipkin/ZipkinPlugin.cs
  7. 15
      backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs
  8. 10
      backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueActionHandler.cs
  9. 9
      backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs
  10. 13
      backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs
  11. 32
      backend/extensions/Squidex.Extensions/Actions/DeepDetect/DeepDetectActionHandler.cs
  12. 10
      backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs
  13. 15
      backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchActionHandler.cs
  14. 7
      backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs
  15. 10
      backend/extensions/Squidex.Extensions/Actions/Fastly/FastlyActionHandler.cs
  16. 9
      backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaActionHandler.cs
  17. 13
      backend/extensions/Squidex.Extensions/Actions/Medium/MediumActionHandler.cs
  18. 11
      backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs
  19. 15
      backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchActionHandler.cs
  20. 10
      backend/extensions/Squidex.Extensions/Actions/Prerender/PrerenderActionHandler.cs
  21. 10
      backend/extensions/Squidex.Extensions/Actions/Script/ScriptActionHandler.cs
  22. 10
      backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRActionHandler.cs
  23. 10
      backend/extensions/Squidex.Extensions/Actions/Slack/SlackActionHandler.cs
  24. 10
      backend/extensions/Squidex.Extensions/Actions/Twitter/TweetActionHandler.cs
  25. 14
      backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseActionHandler.cs
  26. 10
      backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs
  27. 7
      backend/extensions/Squidex.Extensions/Samples/Controllers/PluginController.cs
  28. 9
      backend/extensions/Squidex.Extensions/Samples/Middleware/DoubleLinkedContentMiddleware.cs
  29. 16
      backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj
  30. 14
      backend/extensions/Squidex.Extensions/Text/ElasticSearch/ElasticSearchTextIndex.cs
  31. 11
      backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidator.cs
  32. 8
      backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidatorFactory.cs
  33. 7
      backend/i18n/frontend_en.json
  34. 1
      backend/i18n/frontend_fr.json
  35. 1
      backend/i18n/frontend_it.json
  36. 1
      backend/i18n/frontend_nl.json
  37. 1
      backend/i18n/frontend_pt.json
  38. 1
      backend/i18n/frontend_zh.json
  39. 7
      backend/i18n/source/frontend_en.json
  40. 12
      backend/i18n/translator/Squidex.Translator/Processes/CheckBackend.cs
  41. 12
      backend/i18n/translator/Squidex.Translator/Processes/CheckFrontend.cs
  42. 12
      backend/i18n/translator/Squidex.Translator/Processes/GenerateBackendResources.cs
  43. 12
      backend/i18n/translator/Squidex.Translator/Processes/GenerateFrontendResources.cs
  44. 13
      backend/i18n/translator/Squidex.Translator/Processes/GenerateKeys.cs
  45. 12
      backend/i18n/translator/Squidex.Translator/Processes/TranslateBackend.cs
  46. 13
      backend/i18n/translator/Squidex.Translator/Processes/TranslateTemplates.cs
  47. 12
      backend/i18n/translator/Squidex.Translator/Processes/TranslateTypescript.cs
  48. 8
      backend/src/Migrations/MigrationPath.cs
  49. 2
      backend/src/Migrations/Migrations.csproj
  50. 2
      backend/src/Migrations/Migrations/Backup/BackupState.cs
  51. 16
      backend/src/Migrations/Migrations/Backup/ConvertBackup.cs
  52. 9
      backend/src/Migrations/Migrations/ClearRules.cs
  53. 9
      backend/src/Migrations/Migrations/ClearSchemas.cs
  54. 9
      backend/src/Migrations/Migrations/ConvertEventStore.cs
  55. 9
      backend/src/Migrations/Migrations/ConvertEventStoreAppId.cs
  56. 9
      backend/src/Migrations/Migrations/CreateAssetSlugs.cs
  57. 9
      backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs
  58. 10
      backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs
  59. 9
      backend/src/Migrations/Migrations/MongoDb/ConvertOldSnapshotStores.cs
  60. 9
      backend/src/Migrations/Migrations/MongoDb/ConvertRuleEventsJson.cs
  61. 11
      backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs
  62. 9
      backend/src/Migrations/Migrations/MongoDb/DeleteContentCollections.cs
  63. 9
      backend/src/Migrations/Migrations/MongoDb/RenameAssetMetadata.cs
  64. 9
      backend/src/Migrations/Migrations/MongoDb/RenameAssetSlugField.cs
  65. 9
      backend/src/Migrations/Migrations/MongoDb/RestructureContentCollection.cs
  66. 15
      backend/src/Migrations/Migrations/RebuildApps.cs
  67. 15
      backend/src/Migrations/Migrations/RebuildAssetFolders.cs
  68. 15
      backend/src/Migrations/Migrations/RebuildAssets.cs
  69. 15
      backend/src/Migrations/Migrations/RebuildContents.cs
  70. 15
      backend/src/Migrations/Migrations/RebuildRules.cs
  71. 15
      backend/src/Migrations/Migrations/RebuildSchemas.cs
  72. 15
      backend/src/Migrations/Migrations/RebuildSnapshots.cs
  73. 2
      backend/src/Migrations/OldEvents/AppClientUpdated.cs
  74. 19
      backend/src/Migrations/RebuildRunner.cs
  75. 9
      backend/src/Squidex.Domain.Apps.Core.Model/Contents/Status.cs
  76. 9
      backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptionAttribute.cs
  77. 2
      backend/src/Squidex.Domain.Apps.Core.Model/Rules/EnrichedEvents/EnrichedAssetEventType.cs
  78. 2
      backend/src/Squidex.Domain.Apps.Core.Model/Rules/EnrichedEvents/EnrichedSchemaEventType.cs
  79. 2
      backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldRuleAction.cs
  80. 2
      backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Fields.cs
  81. 4
      backend/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj
  82. 12
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddDefaultValues.cs
  83. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddSchemaNames.cs
  84. 10
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs
  85. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ExcludeChangedTypes.cs
  86. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveFromPreviousPartitioning.cs
  87. 12
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/UpdateValues.cs
  88. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs
  89. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EditorAttribute.cs
  90. 10
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EventEnricher.cs
  91. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventFluidExtensions.cs
  92. 8
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventJintExtension.cs
  93. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleEventFormatter.cs
  94. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs
  95. 14
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs
  96. 38
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
  97. 9
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentDataObject.cs
  98. 10
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs
  99. 8
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/HttpJintExtension.cs
  100. 10
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/StringAsyncJintExtension.cs

3
backend/.editorconfig

@ -21,9 +21,6 @@ dotnet_diagnostic.RECS0117.severity = none
dotnet_diagnostic.SA0001.severity = none
dotnet_diagnostic.SA1649.severity = none
# IDE0290: Use primary constructor
dotnet_diagnostic.IDE0290.severity = none
# IDE0305: Simplify collection initialization
dotnet_diagnostic.IDE0305.severity = none

9
backend/extensions/Squidex.Extensions/APM/ApplicationInsights/ApplicationInsightsPlugin.cs

@ -16,15 +16,8 @@ namespace Squidex.Extensions.APM.ApplicationInsights;
public sealed class ApplicationInsightsPlugin : IPlugin
{
private sealed class Configurator : ITelemetryConfigurator
private sealed class Configurator(IConfiguration config) : ITelemetryConfigurator
{
private readonly IConfiguration config;
public Configurator(IConfiguration config)
{
this.config = config;
}
public void Configure(TracerProviderBuilder builder)
{
builder.AddAzureMonitorTraceExporter(options =>

9
backend/extensions/Squidex.Extensions/APM/Otlp/OtlpPlugin.cs

@ -17,15 +17,8 @@ namespace Squidex.Extensions.APM.Otlp;
public sealed class OtlpPlugin : IPlugin
{
private sealed class Configurator : ITelemetryConfigurator
private sealed class Configurator(IConfiguration config) : ITelemetryConfigurator
{
private readonly IConfiguration config;
public Configurator(IConfiguration config)
{
this.config = config;
}
public void Configure(TracerProviderBuilder builder)
{
builder.AddOtlpExporter(options =>

12
backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverExceptionHandler.cs

@ -13,10 +13,9 @@ using Squidex.Log;
namespace Squidex.Extensions.APM.Stackdriver;
internal sealed class StackdriverExceptionHandler : ILogAppender
internal sealed class StackdriverExceptionHandler(IContextExceptionLogger logger, IHttpContextAccessor httpContextAccessor) : ILogAppender
{
private readonly IContextExceptionLogger logger;
private readonly HttpContextWrapper httpContextWrapper;
private readonly HttpContextWrapper httpContextWrapper = new HttpContextWrapper(httpContextAccessor);
public sealed class HttpContextWrapper : IContextWrapper
{
@ -43,13 +42,6 @@ internal sealed class StackdriverExceptionHandler : ILogAppender
}
}
public StackdriverExceptionHandler(IContextExceptionLogger logger, IHttpContextAccessor httpContextAccessor)
{
this.logger = logger;
httpContextWrapper = new HttpContextWrapper(httpContextAccessor);
}
public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception? exception)
{
try

9
backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverPlugin.cs

@ -18,15 +18,8 @@ namespace Squidex.Extensions.APM.Stackdriver;
public sealed class StackdriverPlugin : IPlugin
{
private sealed class Configurator : ITelemetryConfigurator
private sealed class Configurator(string projectId) : ITelemetryConfigurator
{
private readonly string projectId;
public Configurator(string projectId)
{
this.projectId = projectId;
}
public void Configure(TracerProviderBuilder builder)
{
builder.UseStackdriverExporter(projectId);

9
backend/extensions/Squidex.Extensions/APM/Zipkin/ZipkinPlugin.cs

@ -15,15 +15,8 @@ namespace Squidex.Extensions.APM.Zipkin;
public sealed class ZipkinPlugin : IPlugin
{
private sealed class Configurator : ITelemetryConfigurator
private sealed class Configurator(IConfiguration config) : ITelemetryConfigurator
{
private readonly IConfiguration config;
public Configurator(IConfiguration config)
{
this.config = config;
}
public void Configure(TracerProviderBuilder builder)
{
builder.AddZipkinExporter(options =>

15
backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs

@ -18,26 +18,15 @@ using Squidex.Infrastructure.Json;
namespace Squidex.Extensions.Actions.Algolia;
public sealed class AlgoliaActionHandler : RuleActionHandler<AlgoliaAction, AlgoliaJob>
public sealed class AlgoliaActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine, IJsonSerializer serializer) : RuleActionHandler<AlgoliaAction, AlgoliaJob>(formatter)
{
private readonly ClientPool<(string AppId, string ApiKey, string IndexName), ISearchIndex> clients;
private readonly IScriptEngine scriptEngine;
private readonly IJsonSerializer serializer;
public AlgoliaActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine, IJsonSerializer serializer)
: base(formatter)
{
clients = new ClientPool<(string AppId, string ApiKey, string IndexName), ISearchIndex>(key =>
private readonly ClientPool<(string AppId, string ApiKey, string IndexName), ISearchIndex> clients = new ClientPool<(string AppId, string ApiKey, string IndexName), ISearchIndex>(key =>
{
var client = new SearchClient(key.AppId, key.ApiKey);
return client.InitIndex(key.IndexName);
});
this.scriptEngine = scriptEngine;
this.serializer = serializer;
}
protected override async Task<(string Description, AlgoliaJob Data)> CreateJobAsync(EnrichedEvent @event, AlgoliaAction action)
{
if (@event is not IEnrichedEntityEvent entityEvent)

10
backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueActionHandler.cs

@ -14,14 +14,9 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.AzureQueue;
public sealed class AzureQueueActionHandler : RuleActionHandler<AzureQueueAction, AzureQueueJob>
public sealed class AzureQueueActionHandler(RuleEventFormatter formatter) : RuleActionHandler<AzureQueueAction, AzureQueueJob>(formatter)
{
private readonly ClientPool<(string ConnectionString, string QueueName), CloudQueue> clients;
public AzureQueueActionHandler(RuleEventFormatter formatter)
: base(formatter)
{
clients = new ClientPool<(string ConnectionString, string QueueName), CloudQueue>(key =>
private readonly ClientPool<(string ConnectionString, string QueueName), CloudQueue> clients = new ClientPool<(string ConnectionString, string QueueName), CloudQueue>(key =>
{
var storageAccount = CloudStorageAccount.Parse(key.ConnectionString);
@ -30,7 +25,6 @@ public sealed class AzureQueueActionHandler : RuleActionHandler<AzureQueueAction
return queueRef;
});
}
protected override async Task<(string Description, AzureQueueJob Data)> CreateJobAsync(EnrichedEvent @event, AzureQueueAction action)
{

9
backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs

@ -13,16 +13,9 @@ using Squidex.Infrastructure;
namespace Squidex.Extensions.Actions.Comment;
public sealed class CommentActionHandler : RuleActionHandler<CommentAction, CommentCreated>
public sealed class CommentActionHandler(RuleEventFormatter formatter, ICollaborationService collaboration) : RuleActionHandler<CommentAction, CommentCreated>(formatter)
{
private const string Description = "Send a Comment";
private readonly ICollaborationService collaboration;
public CommentActionHandler(RuleEventFormatter formatter, ICollaborationService collaboration)
: base(formatter)
{
this.collaboration = collaboration;
}
protected override async Task<(string Description, CommentCreated Data)> CreateJobAsync(EnrichedEvent @event, CommentAction action)
{

13
backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs

@ -17,20 +17,9 @@ using Command = Squidex.Domain.Apps.Entities.Contents.Commands.CreateContent;
namespace Squidex.Extensions.Actions.CreateContent;
public sealed class CreateContentActionHandler : RuleActionHandler<CreateContentAction, Command>
public sealed class CreateContentActionHandler(RuleEventFormatter formatter, IAppProvider appProvider, ICommandBus commandBus, IJsonSerializer jsonSerializer) : RuleActionHandler<CreateContentAction, Command>(formatter)
{
private const string Description = "Create a content";
private readonly ICommandBus commandBus;
private readonly IAppProvider appProvider;
private readonly IJsonSerializer jsonSerializer;
public CreateContentActionHandler(RuleEventFormatter formatter, IAppProvider appProvider, ICommandBus commandBus, IJsonSerializer jsonSerializer)
: base(formatter)
{
this.appProvider = appProvider;
this.commandBus = commandBus;
this.jsonSerializer = jsonSerializer;
}
protected override async Task<(string Description, Command Data)> CreateJobAsync(EnrichedEvent @event, CreateContentAction action)
{

32
backend/extensions/Squidex.Extensions/Actions/DeepDetect/DeepDetectActionHandler.cs

@ -23,31 +23,17 @@ namespace Squidex.Extensions.Actions.DeepDetect;
#pragma warning disable MA0048 // File name must match type name
internal sealed partial class DeepDetectActionHandler : RuleActionHandler<DeepDetectAction, DeepDetectJob>
internal sealed partial class DeepDetectActionHandler(
RuleEventFormatter formatter,
IHttpClientFactory httpClientFactory,
IJsonSerializer jsonSerializer,
IAppProvider appProvider,
IAssetQueryService assetQuery,
ICommandBus commandBus,
IUrlGenerator urlGenerator)
: RuleActionHandler<DeepDetectAction, DeepDetectJob>(formatter)
{
private const string Description = "Analyze Image";
private readonly IHttpClientFactory httpClientFactory;
private readonly IJsonSerializer jsonSerializer;
private readonly IAppProvider appProvider;
private readonly IAssetQueryService assetQuery;
private readonly ICommandBus commandBus;
private readonly IUrlGenerator urlGenerator;
public DeepDetectActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory,
IJsonSerializer jsonSerializer,
IAppProvider appProvider,
IAssetQueryService assetQuery,
ICommandBus commandBus,
IUrlGenerator urlGenerator)
: base(formatter)
{
this.httpClientFactory = httpClientFactory;
this.jsonSerializer = jsonSerializer;
this.appProvider = appProvider;
this.assetQuery = assetQuery;
this.commandBus = commandBus;
this.urlGenerator = urlGenerator;
}
protected override Task<(string Description, DeepDetectJob Data)> CreateJobAsync(EnrichedEvent @event, DeepDetectAction action)
{

10
backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs

@ -13,19 +13,11 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.Discourse;
public sealed class DiscourseActionHandler : RuleActionHandler<DiscourseAction, DiscourseJob>
public sealed class DiscourseActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory) : RuleActionHandler<DiscourseAction, DiscourseJob>(formatter)
{
private const string DescriptionCreatePost = "Create discourse Post";
private const string DescriptionCreateTopic = "Create discourse Topic";
private readonly IHttpClientFactory httpClientFactory;
public DiscourseActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory)
: base(formatter)
{
this.httpClientFactory = httpClientFactory;
}
protected override async Task<(string Description, DiscourseJob Data)> CreateJobAsync(EnrichedEvent @event, DiscourseAction action)
{
var url = $"{action.Url.ToString().TrimEnd('/')}/posts.json?api_key={action.ApiKey}&api_username={action.ApiUsername}";

15
backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchActionHandler.cs

@ -18,16 +18,9 @@ using Squidex.Infrastructure.Json;
namespace Squidex.Extensions.Actions.ElasticSearch;
public sealed class ElasticSearchActionHandler : RuleActionHandler<ElasticSearchAction, ElasticSearchJob>
public sealed class ElasticSearchActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine, IJsonSerializer serializer) : RuleActionHandler<ElasticSearchAction, ElasticSearchJob>(formatter)
{
private readonly ClientPool<(Uri Host, string? Username, string? Password), ElasticLowLevelClient> clients;
private readonly IScriptEngine scriptEngine;
private readonly IJsonSerializer serializer;
public ElasticSearchActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine, IJsonSerializer serializer)
: base(formatter)
{
clients = new ClientPool<(Uri Host, string? Username, string? Password), ElasticLowLevelClient>(key =>
private readonly ClientPool<(Uri Host, string? Username, string? Password), ElasticLowLevelClient> clients = new ClientPool<(Uri Host, string? Username, string? Password), ElasticLowLevelClient>(key =>
{
var config = new ConnectionConfiguration(key.Host);
@ -39,10 +32,6 @@ public sealed class ElasticSearchActionHandler : RuleActionHandler<ElasticSearch
return new ElasticLowLevelClient(config);
});
this.scriptEngine = scriptEngine;
this.serializer = serializer;
}
protected override async Task<(string Description, ElasticSearchJob Data)> CreateJobAsync(EnrichedEvent @event, ElasticSearchAction action)
{
var delete = @event.ShouldDelete(scriptEngine, action.Delete);

7
backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs

@ -15,13 +15,8 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.Email;
public sealed class EmailActionHandler : RuleActionHandler<EmailAction, EmailJob>
public sealed class EmailActionHandler(RuleEventFormatter formatter) : RuleActionHandler<EmailAction, EmailJob>(formatter)
{
public EmailActionHandler(RuleEventFormatter formatter)
: base(formatter)
{
}
protected override async Task<(string Description, EmailJob Data)> CreateJobAsync(EnrichedEvent @event, EmailAction action)
{
var ruleJob = new EmailJob

10
backend/extensions/Squidex.Extensions/Actions/Fastly/FastlyActionHandler.cs

@ -13,18 +13,10 @@ using Squidex.Infrastructure;
namespace Squidex.Extensions.Actions.Fastly;
public sealed class FastlyActionHandler : RuleActionHandler<FastlyAction, FastlyJob>
public sealed class FastlyActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory) : RuleActionHandler<FastlyAction, FastlyJob>(formatter)
{
private const string Description = "Purge key in fastly";
private readonly IHttpClientFactory httpClientFactory;
public FastlyActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory)
: base(formatter)
{
this.httpClientFactory = httpClientFactory;
}
protected override (string Description, FastlyJob Data) CreateJob(EnrichedEvent @event, FastlyAction action)
{
var id = string.Empty;

9
backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaActionHandler.cs

@ -12,16 +12,9 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.Kafka;
public sealed class KafkaActionHandler : RuleActionHandler<KafkaAction, KafkaJob>
public sealed class KafkaActionHandler(RuleEventFormatter formatter, KafkaProducer kafkaProducer) : RuleActionHandler<KafkaAction, KafkaJob>(formatter)
{
private const string Description = "Push to Kafka";
private readonly KafkaProducer kafkaProducer;
public KafkaActionHandler(RuleEventFormatter formatter, KafkaProducer kafkaProducer)
: base(formatter)
{
this.kafkaProducer = kafkaProducer;
}
protected override async Task<(string Description, KafkaJob Data)> CreateJobAsync(EnrichedEvent @event, KafkaAction action)
{

13
backend/extensions/Squidex.Extensions/Actions/Medium/MediumActionHandler.cs

@ -15,13 +15,10 @@ using Squidex.Infrastructure.Json;
namespace Squidex.Extensions.Actions.Medium;
public sealed class MediumActionHandler : RuleActionHandler<MediumAction, MediumJob>
public sealed class MediumActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory, IJsonSerializer serializer) : RuleActionHandler<MediumAction, MediumJob>(formatter)
{
private const string Description = "Post to medium";
private readonly IHttpClientFactory httpClientFactory;
private readonly IJsonSerializer serializer;
private sealed class UserResponse
{
public UserResponseData Data { get; set; }
@ -32,14 +29,6 @@ public sealed class MediumActionHandler : RuleActionHandler<MediumAction, Medium
public string Id { get; set; }
}
public MediumActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory, IJsonSerializer serializer)
: base(formatter)
{
this.httpClientFactory = httpClientFactory;
this.serializer = serializer;
}
protected override async Task<(string Description, MediumJob Data)> CreateJobAsync(EnrichedEvent @event, MediumAction action)
{
var ruleJob = new MediumJob { AccessToken = action.AccessToken, PublicationId = action.PublicationId };

11
backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs

@ -14,18 +14,9 @@ using Squidex.Shared.Users;
namespace Squidex.Extensions.Actions.Notification;
public sealed class NotificationActionHandler : RuleActionHandler<NotificationAction, CommentCreated>
public sealed class NotificationActionHandler(RuleEventFormatter formatter, ICollaborationService collaboration, IUserResolver userResolver) : RuleActionHandler<NotificationAction, CommentCreated>(formatter)
{
private const string Description = "Send a Notification";
private readonly ICollaborationService collaboration;
private readonly IUserResolver userResolver;
public NotificationActionHandler(RuleEventFormatter formatter, ICollaborationService collaboration, IUserResolver userResolver)
: base(formatter)
{
this.collaboration = collaboration;
this.userResolver = userResolver;
}
protected override async Task<(string Description, CommentCreated Data)> CreateJobAsync(EnrichedEvent @event, NotificationAction action)
{

15
backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchActionHandler.cs

@ -18,16 +18,9 @@ using Squidex.Infrastructure.Json;
namespace Squidex.Extensions.Actions.OpenSearch;
public sealed class OpenSearchActionHandler : RuleActionHandler<OpenSearchAction, OpenSearchJob>
public sealed class OpenSearchActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine, IJsonSerializer serializer) : RuleActionHandler<OpenSearchAction, OpenSearchJob>(formatter)
{
private readonly ClientPool<(Uri Host, string? Username, string? Password), OpenSearchLowLevelClient> clients;
private readonly IScriptEngine scriptEngine;
private readonly IJsonSerializer serializer;
public OpenSearchActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine, IJsonSerializer serializer)
: base(formatter)
{
clients = new ClientPool<(Uri Host, string? Username, string? Password), OpenSearchLowLevelClient>(key =>
private readonly ClientPool<(Uri Host, string? Username, string? Password), OpenSearchLowLevelClient> clients = new ClientPool<(Uri Host, string? Username, string? Password), OpenSearchLowLevelClient>(key =>
{
var config = new ConnectionConfiguration(key.Host);
@ -39,10 +32,6 @@ public sealed class OpenSearchActionHandler : RuleActionHandler<OpenSearchAction
return new OpenSearchLowLevelClient(config);
});
this.scriptEngine = scriptEngine;
this.serializer = serializer;
}
protected override async Task<(string Description, OpenSearchJob Data)> CreateJobAsync(EnrichedEvent @event, OpenSearchAction action)
{
var delete = @event.ShouldDelete(scriptEngine, action.Delete);

10
backend/extensions/Squidex.Extensions/Actions/Prerender/PrerenderActionHandler.cs

@ -13,16 +13,8 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.Prerender;
public sealed class PrerenderActionHandler : RuleActionHandler<PrerenderAction, PrerenderJob>
public sealed class PrerenderActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory) : RuleActionHandler<PrerenderAction, PrerenderJob>(formatter)
{
private readonly IHttpClientFactory httpClientFactory;
public PrerenderActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory)
: base(formatter)
{
this.httpClientFactory = httpClientFactory;
}
protected override async Task<(string Description, PrerenderJob Data)> CreateJobAsync(EnrichedEvent @event, PrerenderAction action)
{
var url = await FormatAsync(action.Url, @event);

10
backend/extensions/Squidex.Extensions/Actions/Script/ScriptActionHandler.cs

@ -16,16 +16,8 @@ using Squidex.Shared.Identity;
namespace Squidex.Extensions.Actions.Script;
public sealed class ScriptActionHandler : RuleActionHandler<ScriptAction, ScriptJob>
public sealed class ScriptActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine) : RuleActionHandler<ScriptAction, ScriptJob>(formatter)
{
private readonly IScriptEngine scriptEngine;
public ScriptActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEngine)
: base(formatter)
{
this.scriptEngine = scriptEngine;
}
protected override Task<(string Description, ScriptJob Data)> CreateJobAsync(EnrichedEvent @event, ScriptAction action)
{
var job = new ScriptJob { Script = action.Script, Event = @event };

10
backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRActionHandler.cs

@ -14,14 +14,9 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.SignalR;
public sealed class SignalRActionHandler : RuleActionHandler<SignalRAction, SignalRJob>
public sealed class SignalRActionHandler(RuleEventFormatter formatter) : RuleActionHandler<SignalRAction, SignalRJob>(formatter)
{
private readonly ClientPool<(string ConnectionString, string HubName), ServiceManager> clients;
public SignalRActionHandler(RuleEventFormatter formatter)
: base(formatter)
{
clients = new ClientPool<(string ConnectionString, string HubName), ServiceManager>(key =>
private readonly ClientPool<(string ConnectionString, string HubName), ServiceManager> clients = new ClientPool<(string ConnectionString, string HubName), ServiceManager>(key =>
{
var serviceManager = new ServiceManagerBuilder()
.WithOptions(option =>
@ -33,7 +28,6 @@ public sealed class SignalRActionHandler : RuleActionHandler<SignalRAction, Sign
return serviceManager;
});
}
protected override async Task<(string Description, SignalRJob Data)> CreateJobAsync(EnrichedEvent @event, SignalRAction action)
{

10
backend/extensions/Squidex.Extensions/Actions/Slack/SlackActionHandler.cs

@ -13,18 +13,10 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.Slack;
public sealed class SlackActionHandler : RuleActionHandler<SlackAction, SlackJob>
public sealed class SlackActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory) : RuleActionHandler<SlackAction, SlackJob>(formatter)
{
private const string Description = "Send message to slack";
private readonly IHttpClientFactory httpClientFactory;
public SlackActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory)
: base(formatter)
{
this.httpClientFactory = httpClientFactory;
}
protected override async Task<(string Description, SlackJob Data)> CreateJobAsync(EnrichedEvent @event, SlackAction action)
{
var body = new { text = await FormatAsync(action.Text, @event) };

10
backend/extensions/Squidex.Extensions/Actions/Twitter/TweetActionHandler.cs

@ -14,17 +14,11 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Extensions.Actions.Twitter;
public sealed class TweetActionHandler : RuleActionHandler<TweetAction, TweetJob>
public sealed class TweetActionHandler(RuleEventFormatter formatter, IOptions<TwitterOptions> twitterOptions) : RuleActionHandler<TweetAction, TweetJob>(formatter)
{
private const string Description = "Send a tweet";
private readonly TwitterOptions twitterOptions;
public TweetActionHandler(RuleEventFormatter formatter, IOptions<TwitterOptions> twitterOptions)
: base(formatter)
{
this.twitterOptions = twitterOptions.Value;
}
private readonly TwitterOptions twitterOptions = twitterOptions.Value;
protected override async Task<(string Description, TweetJob Data)> CreateJobAsync(EnrichedEvent @event, TweetAction action)
{

14
backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseActionHandler.cs

@ -18,20 +18,8 @@ using Squidex.Infrastructure.Json;
namespace Squidex.Extensions.Actions.Typesense;
public sealed class TypesenseActionHandler : RuleActionHandler<TypesenseAction, TypesenseJob>
public sealed class TypesenseActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory, IScriptEngine scriptEngine, IJsonSerializer serializer) : RuleActionHandler<TypesenseAction, TypesenseJob>(formatter)
{
private readonly IScriptEngine scriptEngine;
private readonly IHttpClientFactory httpClientFactory;
private readonly IJsonSerializer serializer;
public TypesenseActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory, IScriptEngine scriptEngine, IJsonSerializer serializer)
: base(formatter)
{
this.scriptEngine = scriptEngine;
this.httpClientFactory = httpClientFactory;
this.serializer = serializer;
}
protected override async Task<(string Description, TypesenseJob Data)> CreateJobAsync(EnrichedEvent @event, TypesenseAction action)
{
var delete = @event.ShouldDelete(scriptEngine, action.Delete);

10
backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs

@ -14,16 +14,8 @@ using Squidex.Infrastructure;
namespace Squidex.Extensions.Actions.Webhook;
public sealed class WebhookActionHandler : RuleActionHandler<WebhookAction, WebhookJob>
public sealed class WebhookActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory) : RuleActionHandler<WebhookAction, WebhookJob>(formatter)
{
private readonly IHttpClientFactory httpClientFactory;
public WebhookActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory)
: base(formatter)
{
this.httpClientFactory = httpClientFactory;
}
protected override async Task<(string Description, WebhookJob Data)> CreateJobAsync(EnrichedEvent @event, WebhookAction action)
{
var requestUrl = await FormatAsync(action.Url, @event);

7
backend/extensions/Squidex.Extensions/Samples/Controllers/PluginController.cs

@ -11,13 +11,8 @@ using Squidex.Web;
namespace Squidex.Extensions.Samples.Controllers;
public sealed class PluginController : ApiController
public sealed class PluginController(ICommandBus commandBus) : ApiController(commandBus)
{
public PluginController(ICommandBus commandBus)
: base(commandBus)
{
}
[Route("plugins/sample")]
public IActionResult Test()
{

9
backend/extensions/Squidex.Extensions/Samples/Middleware/DoubleLinkedContentMiddleware.cs

@ -14,15 +14,8 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Extensions.Samples.Middleware;
public sealed class DoubleLinkedContentMiddleware : ICustomCommandMiddleware
public sealed class DoubleLinkedContentMiddleware(IContentLoader contentLoader) : ICustomCommandMiddleware
{
private readonly IContentLoader contentLoader;
public DoubleLinkedContentMiddleware(IContentLoader contentLoader)
{
this.contentLoader = contentLoader;
}
public async Task HandleAsync(CommandContext context, NextDelegate next,
CancellationToken ct)
{

16
backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj

@ -13,23 +13,23 @@
<PackageReference Include="Algolia.Search" Version="6.17.0" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.3.0" />
<PackageReference Include="Azure.Search.Documents" Version="11.6.0" />
<PackageReference Include="Confluent.SchemaRegistry.Serdes.Avro" Version="2.5.2" />
<PackageReference Include="Confluent.SchemaRegistry.Serdes.Avro" Version="2.6.0" />
<PackageReference Include="CoreTweet" Version="1.0.0.483" />
<PackageReference Include="Elasticsearch.Net" Version="7.17.5" />
<PackageReference Include="Google.Cloud.Diagnostics.Common" Version="5.2.0" />
<PackageReference Include="Google.Cloud.Logging.V2" Version="4.4.0" />
<PackageReference Include="Google.Cloud.Monitoring.V3" Version="3.11.0" />
<PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Azure.CognitiveServices.Vision.ComputerVision" Version="7.0.1" />
<PackageReference Include="Microsoft.Azure.SignalR.Management" Version="1.27.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.OData.Core" Version="8.0.1" />
<PackageReference Include="NodaTime" Version="3.1.11" />
<PackageReference Include="OpenSearch.Net" Version="1.7.1" />
<PackageReference Include="Microsoft.Azure.SignalR.Management" Version="1.28.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageReference Include="Microsoft.OData.Core" Version="8.2.1" />
<PackageReference Include="NodaTime" Version="3.2.0" />
<PackageReference Include="OpenSearch.Net" Version="1.8.0" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.9.0" />

14
backend/extensions/Squidex.Extensions/Text/ElasticSearch/ElasticSearchTextIndex.cs

@ -15,21 +15,11 @@ using Squidex.Infrastructure.Json;
namespace Squidex.Extensions.Text.ElasticSearch;
public sealed partial class ElasticSearchTextIndex : ITextIndex, IInitializable
public sealed partial class ElasticSearchTextIndex(IElasticSearchClient elasticClient, string indexName, IJsonSerializer jsonSerializer) : ITextIndex, IInitializable
{
private static readonly Regex RegexLanguageNormal = BuildLanguageRegexNormal();
private static readonly Regex RegexLanguageStart = BuildLanguageRegexStart();
private readonly IJsonSerializer jsonSerializer;
private readonly IElasticSearchClient elasticClient;
private readonly QueryParser queryParser = new QueryParser(ElasticSearchIndexDefinition.GetFieldPath);
private readonly string indexName;
public ElasticSearchTextIndex(IElasticSearchClient elasticClient, string indexName, IJsonSerializer jsonSerializer)
{
this.elasticClient = elasticClient;
this.indexName = indexName;
this.jsonSerializer = jsonSerializer;
}
public Task InitializeAsync(
CancellationToken ct)
@ -217,7 +207,7 @@ public sealed partial class ElasticSearchTextIndex : ITextIndex, IInitializable
foreach (var item in hits)
{
ids.Add(DomainId.Create(item["_source"]["contentId"]));
ids.Add(DomainId.Create(item["_source"]["contentId"]));
}
return ids;

11
backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidator.cs

@ -16,17 +16,8 @@ using Squidex.Infrastructure.Queries;
namespace Squidex.Extensions.Validation;
internal sealed class CompositeUniqueValidator : IValidator
internal sealed class CompositeUniqueValidator(string contentTag, IContentRepository contentRepository) : IValidator
{
private readonly string contentTag;
private readonly IContentRepository contentRepository;
public CompositeUniqueValidator(string contentTag, IContentRepository contentRepository)
{
this.contentTag = contentTag;
this.contentRepository = contentRepository;
}
public void Validate(object? value, ValidationContext context)
{
if (value is ContentData data)

8
backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidatorFactory.cs

@ -10,15 +10,9 @@ using Squidex.Domain.Apps.Entities.Contents.Repositories;
namespace Squidex.Extensions.Validation;
public sealed class CompositeUniqueValidatorFactory : IValidatorsFactory
public sealed class CompositeUniqueValidatorFactory(IContentRepository contentRepository) : IValidatorsFactory
{
private const string Prefix = "unique:";
private readonly IContentRepository contentRepository;
public CompositeUniqueValidatorFactory(IContentRepository contentRepository)
{
this.contentRepository = contentRepository;
}
public IEnumerable<IValidator> CreateContentValidators(ValidationContext context, ValidatorFactory createFieldValidator)
{

7
backend/i18n/frontend_en.json

@ -422,7 +422,8 @@
"contents.arrayMoveTop": "Move this item to top",
"contents.arrayMoveUp": "Move this item up",
"contents.arrayNoFields": "Add a nested field first to add items.",
"contents.assetsUpload": "Drop files or click",
"contents.assetsSelect": "Select existing Asset",
"contents.assetsUpload": "Upload new Asset",
"contents.autotranslate": "Autotranslate from master language",
"contents.bulkFailed": "Failed to delete or update content. Please reload.",
"contents.calendar": "Scheduled Contents",
@ -479,11 +480,11 @@
"contents.pendingChangesTextToPreview": "You have unsaved changes.\n\nYou will not see them on preview.\n\n**Do you want to continue anyway?**",
"contents.pendingChangesTitle": "Unsaved changes",
"contents.publishAll": "Publish All",
"contents.referencesCreateNew": "Add New",
"contents.referencesCreateNew": "Add new Content",
"contents.referencesCreatePublish": "Create and Publish",
"contents.referencesLink": "Link selected contents ({count})",
"contents.referencesNoSchema": "No Schema",
"contents.referencesSelectExisting": "Select Existing",
"contents.referencesSelectExisting": "Select existing Content",
"contents.referencesSelectSchema": "Select {schema}",
"contents.refreshTooltip": "Refresh Contents",
"contents.reloaded": "Contents reloaded.",

1
backend/i18n/frontend_fr.json

@ -422,6 +422,7 @@
"contents.arrayMoveTop": "Déplacer cet élément vers le haut",
"contents.arrayMoveUp": "Déplacez cet élément vers le haut",
"contents.arrayNoFields": "Ajoutez d'abord un champ imbriqué pour ajouter des éléments.",
"contents.assetsSelect": "Select existing Asset",
"contents.assetsUpload": "Déposez des fichiers ou cliquez sur",
"contents.autotranslate": "Traduire automatiquement à partir de la langue principale",
"contents.bulkFailed": "Échec de la suppression ou de la mise à jour du contenu. Veuillez recharger.",

1
backend/i18n/frontend_it.json

@ -422,6 +422,7 @@
"contents.arrayMoveTop": "Sposta in cima questo elemento",
"contents.arrayMoveUp": "Sposta su questo elemento",
"contents.arrayNoFields": "Aggiungi un primo campo annidato agli elementi.",
"contents.assetsSelect": "Select existing Asset",
"contents.assetsUpload": "Trascina i file o clicca",
"contents.autotranslate": "Traduci in automatico dalla lingua principale",
"contents.bulkFailed": "Non è stato possibile eliminare il contenuto. Per favore ricarica.",

1
backend/i18n/frontend_nl.json

@ -422,6 +422,7 @@
"contents.arrayMoveTop": "Verplaats dit item naar boven",
"contents.arrayMoveUp": "Verplaats dit item omhoog",
"contents.arrayNoFields": "Voeg eerst een genest veld toe om items toe te voegen.",
"contents.assetsSelect": "Select existing Asset",
"contents.assetsUpload": "Zet bestanden neer of klik",
"contents.autotranslate": "Automatisch vertalen vanuit de hoofdtaal",
"contents.bulkFailed": "Verwijderen van inhoud is mislukt. Laad opnieuw.",

1
backend/i18n/frontend_pt.json

@ -422,6 +422,7 @@
"contents.arrayMoveTop": "Mova este item para cima",
"contents.arrayMoveUp": "Mova este item para cima",
"contents.arrayNoFields": "Adicione primeiro um campo aninhado para adicionar itens.",
"contents.assetsSelect": "Select existing Asset",
"contents.assetsUpload": "Deixe cair ficheiros ou clique",
"contents.autotranslate": "Transtração automática da linguagem mestra",
"contents.bulkFailed": "Falhou em eliminar ou atualizar o conteúdo. Por favor, recarregue.",

1
backend/i18n/frontend_zh.json

@ -422,6 +422,7 @@
"contents.arrayMoveTop": "将此项移至顶部",
"contents.arrayMoveUp": "将此项向上移动",
"contents.arrayNoFields": "先添加一个嵌套字段来添加项目。",
"contents.assetsSelect": "Select existing Asset",
"contents.assetsUpload": "删除文件或点击",
"contents.autotranslate": "从母语自动翻译",
"contents.bulkFailed": "删除或更新内容失败。请重新加载。",

7
backend/i18n/source/frontend_en.json

@ -422,7 +422,8 @@
"contents.arrayMoveTop": "Move this item to top",
"contents.arrayMoveUp": "Move this item up",
"contents.arrayNoFields": "Add a nested field first to add items.",
"contents.assetsUpload": "Drop files or click",
"contents.assetsSelect": "Select existing Asset",
"contents.assetsUpload": "Upload new Asset",
"contents.autotranslate": "Autotranslate from master language",
"contents.bulkFailed": "Failed to delete or update content. Please reload.",
"contents.calendar": "Scheduled Contents",
@ -479,11 +480,11 @@
"contents.pendingChangesTextToPreview": "You have unsaved changes.\n\nYou will not see them on preview.\n\n**Do you want to continue anyway?**",
"contents.pendingChangesTitle": "Unsaved changes",
"contents.publishAll": "Publish All",
"contents.referencesCreateNew": "Add New",
"contents.referencesCreateNew": "Add new Content",
"contents.referencesCreatePublish": "Create and Publish",
"contents.referencesLink": "Link selected contents ({count})",
"contents.referencesNoSchema": "No Schema",
"contents.referencesSelectExisting": "Select Existing",
"contents.referencesSelectExisting": "Select existing Content",
"contents.referencesSelectSchema": "Select {schema}",
"contents.refreshTooltip": "Refresh Contents",
"contents.reloaded": "Contents reloaded.",

12
backend/i18n/translator/Squidex.Translator/Processes/CheckBackend.cs

@ -10,17 +10,9 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public class CheckBackend
public class CheckBackend(DirectoryInfo folder, TranslationService service)
{
private readonly TranslationService service;
private readonly DirectoryInfo folder;
public CheckBackend(DirectoryInfo folder, TranslationService service)
{
this.folder = Backend.GetFolder(folder);
this.service = service;
}
private readonly DirectoryInfo folder = Backend.GetFolder(folder);
public void Run()
{

12
backend/i18n/translator/Squidex.Translator/Processes/CheckFrontend.cs

@ -10,17 +10,9 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public class CheckFrontend
public class CheckFrontend(DirectoryInfo folder, TranslationService service)
{
private readonly TranslationService service;
private readonly DirectoryInfo folder;
public CheckFrontend(DirectoryInfo folder, TranslationService service)
{
this.folder = Frontend.GetFolder(folder);
this.service = service;
}
private readonly DirectoryInfo folder = Frontend.GetFolder(folder);
public void Run(bool fix)
{

12
backend/i18n/translator/Squidex.Translator/Processes/GenerateBackendResources.cs

@ -11,17 +11,9 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public sealed class GenerateBackendResources
public sealed class GenerateBackendResources(DirectoryInfo folder, TranslationService service)
{
private readonly TranslationService service;
private readonly DirectoryInfo folder;
public GenerateBackendResources(DirectoryInfo folder, TranslationService service)
{
this.folder = new DirectoryInfo(Path.Combine(folder.FullName, "backend", "src", "Squidex.Shared"));
this.service = service;
}
private readonly DirectoryInfo folder = new DirectoryInfo(Path.Combine(folder.FullName, "backend", "src", "Squidex.Shared"));
public void Run()
{

12
backend/i18n/translator/Squidex.Translator/Processes/GenerateFrontendResources.cs

@ -9,17 +9,9 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public sealed class GenerateFrontendResources
public sealed class GenerateFrontendResources(DirectoryInfo folder, TranslationService service)
{
private readonly TranslationService service;
private readonly DirectoryInfo folder;
public GenerateFrontendResources(DirectoryInfo folder, TranslationService service)
{
this.folder = new DirectoryInfo(Path.Combine(folder.FullName, "backend", "i18n"));
this.service = service;
}
private readonly DirectoryInfo folder = new DirectoryInfo(Path.Combine(folder.FullName, "backend", "i18n"));
public void Run()
{

13
backend/i18n/translator/Squidex.Translator/Processes/GenerateKeys.cs

@ -9,19 +9,8 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public sealed class GenerateKeys
public sealed class GenerateKeys(DirectoryInfo folder, TranslationService service, string fileName)
{
private readonly TranslationService service;
private readonly string fileName;
private readonly DirectoryInfo folder;
public GenerateKeys(DirectoryInfo folder, TranslationService service, string fileName)
{
this.folder = folder;
this.service = service;
this.fileName = fileName;
}
public void Run()
{
var keys = new TranslatedTexts();

12
backend/i18n/translator/Squidex.Translator/Processes/TranslateBackend.cs

@ -10,17 +10,9 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public class TranslateBackend
public class TranslateBackend(DirectoryInfo folder, TranslationService service)
{
private readonly TranslationService service;
private readonly DirectoryInfo folder;
public TranslateBackend(DirectoryInfo folder, TranslationService service)
{
this.folder = Backend.GetFolder(folder);
this.service = service;
}
private readonly DirectoryInfo folder = Backend.GetFolder(folder);
public void Run()
{

13
backend/i18n/translator/Squidex.Translator/Processes/TranslateTemplates.cs

@ -11,7 +11,7 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public partial class TranslateTemplates
public partial class TranslateTemplates(DirectoryInfo folder, TranslationService service)
{
private static readonly HashSet<string> TagsToIgnore =
[
@ -29,20 +29,11 @@ public partial class TranslateTemplates
"confirmText", // Confirm Click
"message", // Title Component
};
private readonly TranslationService service;
private readonly DirectoryInfo folder;
private readonly DirectoryInfo folder = Frontend.GetFolder(folder);
private bool isReplaced;
private bool isSilent;
private int total;
public TranslateTemplates(DirectoryInfo folder, TranslationService service)
{
this.folder = Frontend.GetFolder(folder);
this.service = service;
}
public void Run(bool reportMissing)
{
isSilent = reportMissing;

12
backend/i18n/translator/Squidex.Translator/Processes/TranslateTypescript.cs

@ -10,17 +10,9 @@ using Squidex.Translator.State;
namespace Squidex.Translator.Processes;
public partial class TranslateTypescript
public partial class TranslateTypescript(DirectoryInfo folder, TranslationService service)
{
private readonly TranslationService service;
private readonly DirectoryInfo folder;
public TranslateTypescript(DirectoryInfo folder, TranslationService service)
{
this.folder = Frontend.GetFolder(folder);
this.service = service;
}
private readonly DirectoryInfo folder = Frontend.GetFolder(folder);
public void Run()
{

8
backend/src/Migrations/MigrationPath.cs

@ -14,15 +14,9 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations;
public sealed class MigrationPath : IMigrationPath
public sealed class MigrationPath(IServiceProvider serviceProvider) : IMigrationPath
{
private const int CurrentVersion = 27;
private readonly IServiceProvider serviceProvider;
public MigrationPath(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public (int Version, IEnumerable<IMigration>? Migrations) GetNext(int version)
{

2
backend/src/Migrations/Migrations.csproj

@ -6,7 +6,7 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

2
backend/src/Migrations/Migrations/Backup/BackupState.cs

@ -11,7 +11,7 @@ namespace Migrations.Migrations.Backup;
public sealed class BackupState
{
public List<BackupJob> Jobs { get; set; } = [];
public List<BackupJob> Jobs { get; set; } = [];
public JobsState ToJob()
{

16
backend/src/Migrations/Migrations/Backup/ConvertBackup.cs

@ -11,19 +11,11 @@ using Squidex.Infrastructure.States;
namespace Migrations.Migrations.Backup;
public sealed class ConvertBackup : IMigration
public sealed class ConvertBackup(
ISnapshotStore<BackupState> stateBackups,
ISnapshotStore<JobsState> stateJobs)
: IMigration
{
private readonly ISnapshotStore<BackupState> stateBackups;
private readonly ISnapshotStore<JobsState> stateJobs;
public ConvertBackup(
ISnapshotStore<BackupState> stateBackups,
ISnapshotStore<JobsState> stateJobs)
{
this.stateBackups = stateBackups;
this.stateJobs = stateJobs;
}
public async Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/ClearRules.cs

@ -11,15 +11,8 @@ using Squidex.Infrastructure.States;
namespace Migrations.Migrations;
public sealed class ClearRules : IMigration
public sealed class ClearRules(IStore<Rule> store) : IMigration
{
private readonly IStore<Rule> store;
public ClearRules(IStore<Rule> store)
{
this.store = store;
}
public Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/ClearSchemas.cs

@ -11,15 +11,8 @@ using Squidex.Infrastructure.States;
namespace Migrations.Migrations;
public sealed class ClearSchemas : IMigration
public sealed class ClearSchemas(IStore<Schema> store) : IMigration
{
private readonly IStore<Schema> store;
public ClearSchemas(IStore<Schema> store)
{
this.store = store;
}
public Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/ConvertEventStore.cs

@ -13,15 +13,8 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations;
public sealed class ConvertEventStore : MongoBase<BsonDocument>, IMigration
public sealed class ConvertEventStore(IEventStore eventStore) : MongoBase<BsonDocument>, IMigration
{
private readonly IEventStore eventStore;
public ConvertEventStore(IEventStore eventStore)
{
this.eventStore = eventStore;
}
public async Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/ConvertEventStoreAppId.cs

@ -14,15 +14,8 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations;
public sealed class ConvertEventStoreAppId : MongoBase<BsonDocument>, IMigration
public sealed class ConvertEventStoreAppId(IEventStore eventStore) : MongoBase<BsonDocument>, IMigration
{
private readonly IEventStore eventStore;
public ConvertEventStoreAppId(IEventStore eventStore)
{
this.eventStore = eventStore;
}
public async Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/CreateAssetSlugs.cs

@ -12,15 +12,8 @@ using Squidex.Infrastructure.States;
namespace Migrations.Migrations;
public sealed class CreateAssetSlugs : IMigration
public sealed class CreateAssetSlugs(ISnapshotStore<Asset> stateForAssets) : IMigration
{
private readonly ISnapshotStore<Asset> stateForAssets;
public CreateAssetSlugs(ISnapshotStore<Asset> stateForAssets)
{
this.stateForAssets = stateForAssets;
}
public async Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/MongoDb/AddAppIdToEventStream.cs

@ -15,15 +15,8 @@ using Squidex.Infrastructure.Tasks;
namespace Migrations.Migrations.MongoDb;
public sealed class AddAppIdToEventStream : MongoBase<BsonDocument>, IMigration
public sealed class AddAppIdToEventStream(IMongoDatabase database) : MongoBase<BsonDocument>, IMigration
{
private readonly IMongoDatabase database;
public AddAppIdToEventStream(IMongoDatabase database)
{
this.database = database;
}
public async Task UpdateAsync(
CancellationToken ct)
{

10
backend/src/Migrations/Migrations/MongoDb/ConvertDocumentIds.cs

@ -14,10 +14,8 @@ using Squidex.Infrastructure.Tasks;
namespace Migrations.Migrations.MongoDb;
public sealed class ConvertDocumentIds : MongoBase<BsonDocument>, IMigration
public sealed class ConvertDocumentIds(IMongoDatabase databaseDefault, IMongoDatabase databaseContent) : MongoBase<BsonDocument>, IMigration
{
private readonly IMongoDatabase databaseDefault;
private readonly IMongoDatabase databaseContent;
private Scope scope;
private enum Scope
@ -27,12 +25,6 @@ public sealed class ConvertDocumentIds : MongoBase<BsonDocument>, IMigration
Contents
}
public ConvertDocumentIds(IMongoDatabase databaseDefault, IMongoDatabase databaseContent)
{
this.databaseDefault = databaseDefault;
this.databaseContent = databaseContent;
}
public override string ToString()
{
return $"{base.ToString()}({scope})";

9
backend/src/Migrations/Migrations/MongoDb/ConvertOldSnapshotStores.cs

@ -12,15 +12,8 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
public sealed class ConvertOldSnapshotStores : MongoBase<BsonDocument>, IMigration
public sealed class ConvertOldSnapshotStores(IMongoDatabase database) : MongoBase<BsonDocument>, IMigration
{
private readonly IMongoDatabase database;
public ConvertOldSnapshotStores(IMongoDatabase database)
{
this.database = database;
}
public Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/MongoDb/ConvertRuleEventsJson.cs

@ -12,14 +12,9 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
public sealed class ConvertRuleEventsJson : MongoBase<BsonDocument>, IMigration
public sealed class ConvertRuleEventsJson(IMongoDatabase database) : MongoBase<BsonDocument>, IMigration
{
private readonly IMongoCollection<BsonDocument> collection;
public ConvertRuleEventsJson(IMongoDatabase database)
{
collection = database.GetCollection<BsonDocument>("RuleEvents");
}
private readonly IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("RuleEvents");
public async Task UpdateAsync(
CancellationToken ct)

11
backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs

@ -15,11 +15,8 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
public sealed class CopyRuleStatistics : IMigration
public sealed class CopyRuleStatistics(IMongoDatabase database, IRuleUsageTracker ruleUsageTracker) : IMigration
{
private readonly IMongoDatabase database;
private readonly IRuleUsageTracker ruleUsageTracker;
[BsonIgnoreExtraElements]
public class Document
{
@ -32,12 +29,6 @@ public sealed class CopyRuleStatistics : IMigration
public int NumSucceeded { get; private set; }
}
public CopyRuleStatistics(IMongoDatabase database, IRuleUsageTracker ruleUsageTracker)
{
this.database = database;
this.ruleUsageTracker = ruleUsageTracker;
}
public async Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/MongoDb/DeleteContentCollections.cs

@ -10,15 +10,8 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations.MongoDb;
public sealed class DeleteContentCollections : IMigration
public sealed class DeleteContentCollections(IMongoDatabase database) : IMigration
{
private readonly IMongoDatabase database;
public DeleteContentCollections(IMongoDatabase database)
{
this.database = database;
}
public async Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/MongoDb/RenameAssetMetadata.cs

@ -12,15 +12,8 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
public sealed class RenameAssetMetadata : MongoBase<BsonDocument>, IMigration
public sealed class RenameAssetMetadata(IMongoDatabase database) : MongoBase<BsonDocument>, IMigration
{
private readonly IMongoDatabase database;
public RenameAssetMetadata(IMongoDatabase database)
{
this.database = database;
}
public async Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/MongoDb/RenameAssetSlugField.cs

@ -12,15 +12,8 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
public sealed class RenameAssetSlugField : MongoBase<BsonDocument>, IMigration
public sealed class RenameAssetSlugField(IMongoDatabase database) : MongoBase<BsonDocument>, IMigration
{
private readonly IMongoDatabase database;
public RenameAssetSlugField(IMongoDatabase database)
{
this.database = database;
}
public Task UpdateAsync(
CancellationToken ct)
{

9
backend/src/Migrations/Migrations/MongoDb/RestructureContentCollection.cs

@ -12,15 +12,8 @@ using Squidex.Infrastructure.MongoDb;
namespace Migrations.Migrations.MongoDb;
public sealed class RestructureContentCollection : MongoBase<BsonDocument>, IMigration
public sealed class RestructureContentCollection(IMongoDatabase contentDatabase) : MongoBase<BsonDocument>, IMigration
{
private readonly IMongoDatabase contentDatabase;
public RestructureContentCollection(IMongoDatabase contentDatabase)
{
this.contentDatabase = contentDatabase;
}
public async Task UpdateAsync(
CancellationToken ct)
{

15
backend/src/Migrations/Migrations/RebuildApps.cs

@ -11,17 +11,12 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations;
public sealed class RebuildApps : IMigration
public sealed class RebuildApps(
Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
: IMigration
{
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildApps(Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
{
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public Task UpdateAsync(
CancellationToken ct)

15
backend/src/Migrations/Migrations/RebuildAssetFolders.cs

@ -11,17 +11,12 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations;
public sealed class RebuildAssetFolders : IMigration
public sealed class RebuildAssetFolders(
Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
: IMigration
{
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildAssetFolders(Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
{
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public Task UpdateAsync(
CancellationToken ct)

15
backend/src/Migrations/Migrations/RebuildAssets.cs

@ -11,17 +11,12 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations;
public sealed class RebuildAssets : IMigration
public sealed class RebuildAssets(
Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
: IMigration
{
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildAssets(Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
{
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public Task UpdateAsync(
CancellationToken ct)

15
backend/src/Migrations/Migrations/RebuildContents.cs

@ -11,17 +11,12 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations;
public sealed class RebuildContents : IMigration
public sealed class RebuildContents(
Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
: IMigration
{
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildContents(Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
{
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public Task UpdateAsync(
CancellationToken ct)

15
backend/src/Migrations/Migrations/RebuildRules.cs

@ -11,17 +11,12 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations;
public sealed class RebuildRules : IMigration
public sealed class RebuildRules(
Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
: IMigration
{
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildRules(Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
{
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public Task UpdateAsync(
CancellationToken ct)

15
backend/src/Migrations/Migrations/RebuildSchemas.cs

@ -11,17 +11,12 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations;
public sealed class RebuildSchemas : IMigration
public sealed class RebuildSchemas(
Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
: IMigration
{
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildSchemas(Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
{
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public Task UpdateAsync(
CancellationToken ct)

15
backend/src/Migrations/Migrations/RebuildSnapshots.cs

@ -11,17 +11,12 @@ using Squidex.Infrastructure.Migrations;
namespace Migrations.Migrations;
public sealed class RebuildSnapshots : IMigration
public sealed class RebuildSnapshots(
Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
: IMigration
{
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildSnapshots(Rebuilder rebuilder,
IOptions<RebuildOptions> rebuildOptions)
{
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public async Task UpdateAsync(
CancellationToken ct)

2
backend/src/Migrations/OldEvents/AppClientUpdated.cs

@ -41,4 +41,4 @@ public sealed class AppClientUpdated : AppEvent, IMigrated<IEvent>
return result;
}
}
}

19
backend/src/Migrations/RebuildRunner.cs

@ -11,21 +11,12 @@ using Squidex.Infrastructure.Commands;
namespace Migrations;
public sealed class RebuildRunner
public sealed class RebuildRunner(
IOptions<RebuildOptions> rebuildOptions,
Rebuilder rebuilder,
RebuildFiles rebuildFiles)
{
private readonly RebuildFiles rebuildFiles;
private readonly Rebuilder rebuilder;
private readonly RebuildOptions rebuildOptions;
public RebuildRunner(
IOptions<RebuildOptions> rebuildOptions,
Rebuilder rebuilder,
RebuildFiles rebuildFiles)
{
this.rebuildFiles = rebuildFiles;
this.rebuilder = rebuilder;
this.rebuildOptions = rebuildOptions.Value;
}
private readonly RebuildOptions rebuildOptions = rebuildOptions.Value;
public async Task RunAsync(
CancellationToken ct)

9
backend/src/Squidex.Domain.Apps.Core.Model/Contents/Status.cs

@ -10,24 +10,17 @@ using System.ComponentModel;
namespace Squidex.Domain.Apps.Core.Contents;
[TypeConverter(typeof(StatusTypeConverter))]
public readonly struct Status : IEquatable<Status>, IComparable<Status>
public readonly struct Status(string? name) : IEquatable<Status>, IComparable<Status>
{
public static readonly Status Archived = new Status("Archived");
public static readonly Status Draft = new Status("Draft");
public static readonly Status Published = new Status("Published");
private readonly string? name;
public string Name
{
get => name ?? "Unknown";
}
public Status(string? name)
{
this.name = name;
}
public override bool Equals(object? obj)
{
return obj is Status status && Equals(status);

9
backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptionAttribute.cs

@ -8,12 +8,7 @@
namespace Squidex.Domain.Apps.Core;
[AttributeUsage(AttributeTargets.Property)]
public sealed class FieldDescriptionAttribute : Attribute
public sealed class FieldDescriptionAttribute(string name) : Attribute
{
public string Name { get; }
public FieldDescriptionAttribute(string name)
{
Name = name;
}
public string Name { get; } = name;
}

2
backend/src/Squidex.Domain.Apps.Core.Model/Rules/EnrichedEvents/EnrichedAssetEventType.cs

@ -13,4 +13,4 @@ public enum EnrichedAssetEventType
Deleted,
Annotated,
Updated
}
}

2
backend/src/Squidex.Domain.Apps.Core.Model/Rules/EnrichedEvents/EnrichedSchemaEventType.cs

@ -14,4 +14,4 @@ public enum EnrichedSchemaEventType
Published,
Unpublished,
Updated
}
}

2
backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldRuleAction.cs

@ -12,4 +12,4 @@ public enum FieldRuleAction
Disable,
Hide,
Require
}
}

2
backend/src/Squidex.Domain.Apps.Core.Model/Schemas/Fields.cs

@ -20,7 +20,7 @@ public static class Fields
public static RootField<AssetsFieldProperties> Assets(long id, string name, Partitioning partitioning,
AssetsFieldProperties? properties = null)
{
return new RootField<AssetsFieldProperties> { Id = id, Name = name, Partitioning = partitioning, Properties = properties ?? new () };
return new RootField<AssetsFieldProperties> { Id = id, Name = name, Partitioning = partitioning, Properties = properties ?? new() };
}
public static RootField<BooleanFieldProperties> Boolean(long id, string name, Partitioning partitioning,

4
backend/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj

@ -12,11 +12,11 @@
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="2.0.163">
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
<PackageReference Include="NetTopologySuite" Version="2.5.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />

12
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddDefaultValues.cs

@ -12,10 +12,9 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent;
public sealed class AddDefaultValues : IContentDataConverter, IContentItemConverter, IContentFieldConverter
public sealed class AddDefaultValues(PartitionResolver partitionResolver, IClock? clock = null) : IContentDataConverter, IContentItemConverter, IContentFieldConverter
{
private readonly PartitionResolver partitionResolver;
private readonly IClock clock;
private readonly IClock clock = clock ?? SystemClock.Instance;
private Instant now;
public bool IgnoreRequiredFields { get; init; }
@ -24,13 +23,6 @@ public sealed class AddDefaultValues : IContentDataConverter, IContentItemConver
public HashSet<string>? FieldNames { get; init; }
public AddDefaultValues(PartitionResolver partitionResolver, IClock? clock = null)
{
this.partitionResolver = partitionResolver;
this.clock = clock ?? SystemClock.Instance;
}
public void ConvertDataBefore(Schema schema, ContentData data)
{
foreach (var field in schema.Fields)

9
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/AddSchemaNames.cs

@ -12,15 +12,8 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent;
public sealed class AddSchemaNames : IContentItemConverter
public sealed class AddSchemaNames(ResolvedComponents components) : IContentItemConverter
{
private readonly ResolvedComponents components;
public AddSchemaNames(ResolvedComponents components)
{
this.components = components;
}
public JsonObject ConvertItemAfter(IField parentField, JsonObject source, IEnumerable<IField> schema)
{
if (parentField is IArrayField)

10
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs

@ -14,20 +14,12 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent;
public sealed class ContentConverter
public sealed class ContentConverter(ResolvedComponents components, Schema schema)
{
private readonly List<IContentDataConverter> dataConverters = [];
private readonly List<IContentItemConverter> itemConverters = [];
private readonly List<IContentFieldConverter> fieldConverters = [];
private readonly List<IContentValueConverter> valueConverters = [];
private readonly ResolvedComponents components;
private readonly Schema schema;
public ContentConverter(ResolvedComponents components, Schema schema)
{
this.components = components;
this.schema = schema;
}
public ContentConverter Add(IConverter converter)
{

9
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ExcludeChangedTypes.cs

@ -13,15 +13,8 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent;
public sealed class ExcludeChangedTypes : IContentFieldConverter, IContentValueConverter
public sealed class ExcludeChangedTypes(IJsonSerializer serializer) : IContentFieldConverter, IContentValueConverter
{
private readonly IJsonSerializer serializer;
public ExcludeChangedTypes(IJsonSerializer serializer)
{
this.serializer = serializer;
}
public ContentFieldData? ConvertFieldBefore(IRootField field, ContentFieldData source)
{
foreach (var (_, value) in source)

9
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ResolveFromPreviousPartitioning.cs

@ -11,15 +11,8 @@ using Squidex.Domain.Apps.Core.Schemas;
namespace Squidex.Domain.Apps.Core.ConvertContent;
public sealed class ResolveFromPreviousPartitioning : IContentFieldConverter
public sealed class ResolveFromPreviousPartitioning(LanguagesConfig languages) : IContentFieldConverter
{
private readonly LanguagesConfig languages;
public ResolveFromPreviousPartitioning(LanguagesConfig languages)
{
this.languages = languages;
}
public ContentFieldData? ConvertFieldAfter(IRootField field, ContentFieldData source)
{
if (field.Partitioning.Equals(Partitioning.Invariant))

12
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/UpdateValues.cs

@ -12,20 +12,10 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent;
public sealed class UpdateValues : IContentValueConverter, IContentDataConverter
public sealed class UpdateValues(ContentData existingData, IScriptEngine scriptEngine, bool canUnset) : IContentValueConverter, IContentDataConverter
{
private readonly ContentData existingData;
private readonly IScriptEngine scriptEngine;
private readonly bool canUnset;
private ScriptVars? vars;
public UpdateValues(ContentData existingData, IScriptEngine scriptEngine, bool canUnset)
{
this.existingData = existingData;
this.scriptEngine = scriptEngine;
this.canUnset = canUnset;
}
public void ConvertDataBefore(Schema schema, ContentData source)
{
// Avoid unnecessary allocations if nothing has been changed, which is the default.

9
backend/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs

@ -12,15 +12,8 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds;
public sealed class ValueReferencesConverter : IContentValueConverter
public sealed class ValueReferencesConverter(HashSet<DomainId>? validIds = null) : IContentValueConverter
{
private readonly HashSet<DomainId>? validIds;
public ValueReferencesConverter(HashSet<DomainId>? validIds = null)
{
this.validIds = validIds;
}
public (bool Remove, JsonValue) ConvertValue(IField field, JsonValue source, IField? parent)
{
if (validIds == null || source == default)

9
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EditorAttribute.cs

@ -8,12 +8,7 @@
namespace Squidex.Domain.Apps.Core.HandleRules;
[AttributeUsage(AttributeTargets.Property)]
public sealed class EditorAttribute : Attribute
public sealed class EditorAttribute(RuleFieldEditor editor) : Attribute
{
public RuleFieldEditor Editor { get; }
public EditorAttribute(RuleFieldEditor editor)
{
Editor = editor;
}
public RuleFieldEditor Editor { get; } = editor;
}

10
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EventEnricher.cs

@ -14,17 +14,9 @@ using Squidex.Shared.Users;
namespace Squidex.Domain.Apps.Core.HandleRules;
public sealed class EventEnricher : IEventEnricher
public sealed class EventEnricher(IMemoryCache userCache, IUserResolver userResolver) : IEventEnricher
{
private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(10);
private readonly IMemoryCache userCache;
private readonly IUserResolver userResolver;
public EventEnricher(IMemoryCache userCache, IUserResolver userResolver)
{
this.userCache = userCache;
this.userResolver = userResolver;
}
public async Task EnrichAsync(EnrichedEvent enrichedEvent, Envelope<AppEvent>? @event)
{

9
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventFluidExtensions.cs

@ -14,15 +14,8 @@ using Squidex.Text;
namespace Squidex.Domain.Apps.Core.HandleRules.Extensions;
public sealed class EventFluidExtensions : IFluidExtension
public sealed class EventFluidExtensions(IUrlGenerator urlGenerator) : IFluidExtension
{
private readonly IUrlGenerator urlGenerator;
public EventFluidExtensions(IUrlGenerator urlGenerator)
{
this.urlGenerator = urlGenerator;
}
public void RegisterLanguageExtensions(CustomFluidParser parser, TemplateOptions options)
{
options.Filters.AddFilter("contentUrl", ContentUrl);

8
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Extensions/EventJintExtension.cs

@ -13,15 +13,9 @@ using Squidex.Text;
namespace Squidex.Domain.Apps.Core.HandleRules.Extensions;
public sealed class EventJintExtension : IJintExtension, IScriptDescriptor
public sealed class EventJintExtension(IUrlGenerator urlGenerator) : IJintExtension, IScriptDescriptor
{
private delegate JsValue EventDelegate();
private readonly IUrlGenerator urlGenerator;
public EventJintExtension(IUrlGenerator urlGenerator)
{
this.urlGenerator = urlGenerator;
}
public void Extend(ScriptExecutionContext context)
{

2
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleEventFormatter.cs

@ -20,4 +20,4 @@ public interface IRuleEventFormatter
{
return default;
}
}
}

9
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs

@ -12,10 +12,8 @@ using Squidex.Domain.Apps.Core.Rules.EnrichedEvents;
namespace Squidex.Domain.Apps.Core.HandleRules;
public abstract class RuleActionHandler<TAction, TData> : IRuleActionHandler where TAction : RuleAction
public abstract class RuleActionHandler<TAction, TData>(RuleEventFormatter formatter) : IRuleActionHandler where TAction : RuleAction
{
private readonly RuleEventFormatter formatter;
Type IRuleActionHandler.ActionType
{
get => typeof(TAction);
@ -26,11 +24,6 @@ public abstract class RuleActionHandler<TAction, TData> : IRuleActionHandler whe
get => typeof(TData);
}
protected RuleActionHandler(RuleEventFormatter formatter)
{
this.formatter = formatter;
}
protected virtual string ToJson<T>(T @event) where T : notnull
{
return formatter.ToPayload(@event);

14
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs

@ -23,15 +23,11 @@ using ValueTaskSupplement;
namespace Squidex.Domain.Apps.Core.HandleRules;
public partial class RuleEventFormatter
public partial class RuleEventFormatter(IJsonSerializer serializer, IEnumerable<IRuleEventFormatter> formatters, ITemplateEngine templateEngine, IScriptEngine scriptEngine)
{
private const string GlobalFallback = "null";
private static readonly Regex RegexPatternOld = RegexPatternOldFactory();
private static readonly Regex RegexPatternNew = RegexPatternNewFactory();
private readonly IJsonSerializer serializer;
private readonly IEnumerable<IRuleEventFormatter> formatters;
private readonly ITemplateEngine templateEngine;
private readonly IScriptEngine scriptEngine;
private struct TextPart
{
@ -70,14 +66,6 @@ public partial class RuleEventFormatter
}
}
public RuleEventFormatter(IJsonSerializer serializer, IEnumerable<IRuleEventFormatter> formatters, ITemplateEngine templateEngine, IScriptEngine scriptEngine)
{
this.serializer = serializer;
this.formatters = formatters;
this.templateEngine = templateEngine;
this.scriptEngine = scriptEngine;
}
public virtual string ToPayload<T>(T @event) where T : notnull
{
// Just serialize the payload.

38
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs

@ -22,15 +22,19 @@ using Squidex.Infrastructure.Tasks;
namespace Squidex.Domain.Apps.Core.HandleRules;
public sealed class RuleService : IRuleService
public sealed class RuleService(
IOptions<RuleOptions> ruleOptions,
IEnumerable<IRuleTriggerHandler> ruleTriggerHandlers,
IEnumerable<IRuleActionHandler> ruleActionHandlers,
IEventEnricher eventEnricher,
IJsonSerializer serializer,
ILogger<RuleService> log,
TypeRegistry typeRegistry)
: IRuleService
{
private readonly Dictionary<Type, IRuleActionHandler> ruleActionHandlers;
private readonly Dictionary<Type, IRuleTriggerHandler> ruleTriggerHandlers;
private readonly TypeRegistry typeRegistry;
private readonly RuleOptions ruleOptions;
private readonly IEventEnricher eventEnricher;
private readonly IJsonSerializer serializer;
private readonly ILogger<RuleService> log;
private readonly Dictionary<Type, IRuleActionHandler> ruleActionHandlers = ruleActionHandlers.ToDictionary(x => x.ActionType);
private readonly Dictionary<Type, IRuleTriggerHandler> ruleTriggerHandlers = ruleTriggerHandlers.ToDictionary(x => x.TriggerType);
private readonly RuleOptions ruleOptions = ruleOptions.Value;
private sealed class RuleState
{
@ -43,24 +47,6 @@ public sealed class RuleService : IRuleService
public IClock Clock { get; set; } = SystemClock.Instance;
public RuleService(
IOptions<RuleOptions> ruleOptions,
IEnumerable<IRuleTriggerHandler> ruleTriggerHandlers,
IEnumerable<IRuleActionHandler> ruleActionHandlers,
IEventEnricher eventEnricher,
IJsonSerializer serializer,
ILogger<RuleService> log,
TypeRegistry typeRegistry)
{
this.typeRegistry = typeRegistry;
this.eventEnricher = eventEnricher;
this.ruleOptions = ruleOptions.Value;
this.ruleTriggerHandlers = ruleTriggerHandlers.ToDictionary(x => x.TriggerType);
this.ruleActionHandlers = ruleActionHandlers.ToDictionary(x => x.ActionType);
this.serializer = serializer;
this.log = log;
}
public bool CanCreateSnapshotEvents(Rule rule)
{
if (!ruleTriggerHandlers.TryGetValue(rule.Trigger.GetType(), out var triggerHandler))

9
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentDataObject.cs

@ -15,21 +15,14 @@ using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper;
public sealed class ContentDataObject : ObjectInstance
public sealed class ContentDataObject(Engine engine, ContentData contentData) : ObjectInstance(engine)
{
private readonly ContentData contentData;
private HashSet<string> fieldsToDelete;
private Dictionary<string, PropertyDescriptor> fieldProperties;
private bool isChanged;
public override bool Extensible => true;
public ContentDataObject(Engine engine, ContentData contentData)
: base(engine)
{
this.contentData = contentData;
}
public void MarkChanged()
{
isChanged = true;

10
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs

@ -12,10 +12,8 @@ using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper;
public sealed class ContentFieldProperty : CustomProperty
public sealed class ContentFieldProperty(ContentFieldObject contentField, JsonValue contentValue = default) : CustomProperty
{
private readonly ContentFieldObject contentField;
private JsonValue contentValue;
private JsValue? value;
private bool isChanged;
@ -59,10 +57,4 @@ public sealed class ContentFieldProperty : CustomProperty
{
get => isChanged;
}
public ContentFieldProperty(ContentFieldObject contentField, JsonValue contentValue = default)
{
this.contentField = contentField;
this.contentValue = contentValue;
}
}

8
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/HttpJintExtension.cs

@ -16,16 +16,10 @@ using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Core.Scripting.Extensions;
public sealed class HttpJintExtension : IJintExtension, IScriptDescriptor
public sealed class HttpJintExtension(IHttpClientFactory httpClientFactory) : IJintExtension, IScriptDescriptor
{
private delegate void HttpJsonDelegate(string url, Action<JsValue> callback, JsValue? headers = null, bool ignoreError = false);
private delegate void HttpJsonWithBodyDelegate(string url, JsValue body, Action<JsValue> callback, JsValue? headers = null, bool ignoreError = false);
private readonly IHttpClientFactory httpClientFactory;
public HttpJintExtension(IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public void ExtendAsync(ScriptExecutionContext context)
{

10
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/StringAsyncJintExtension.cs

@ -15,18 +15,10 @@ using Squidex.Text.Translations;
namespace Squidex.Domain.Apps.Core.Scripting.Extensions;
public sealed class StringAsyncJintExtension : IJintExtension, IScriptDescriptor
public sealed class StringAsyncJintExtension(ITranslator translator, IChatAgent chatAgent) : IJintExtension, IScriptDescriptor
{
private delegate void TextGenerateDelegate(string prompt, Action<JsValue> callback);
private delegate void TextTranslateDelegate(string text, string language, Action<JsValue> callback, string sourceLanguage);
private readonly ITranslator translator;
private readonly IChatAgent chatAgent;
public StringAsyncJintExtension(ITranslator translator, IChatAgent chatAgent)
{
this.translator = translator;
this.chatAgent = chatAgent;
}
public void ExtendAsync(ScriptExecutionContext context)
{

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save