From c3c72c076b55b5163cd64bcaeea369cd1456825e Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sat, 20 May 2023 19:04:59 +0200 Subject: [PATCH] Fixes (#993) * Exception handling for scheduler. * Image hover * Fix transfer. * Fixes * Flush write. * OpenApi fixes --- .../StackdriverExceptionHandler.cs | 2 +- .../StackdriverSeverityLogAppender.cs | 2 +- .../Actions/Algolia/AlgoliaAction.cs | 4 +- .../Actions/Algolia/AlgoliaActionHandler.cs | 8 +- .../Actions/AzureQueue/AzureQueueAction.cs | 2 +- .../AzureQueue/AzureQueueActionHandler.cs | 6 +- .../Squidex.Extensions/Actions/ClientPool.cs | 4 +- .../Actions/Comment/CommentAction.cs | 2 +- .../Actions/Comment/CommentActionHandler.cs | 2 +- .../CreateContentActionHandler.cs | 2 +- .../Actions/Discourse/DiscourseAction.cs | 2 +- .../Discourse/DiscourseActionHandler.cs | 4 +- .../ElasticSearch/ElasticSearchAction.cs | 8 +- .../ElasticSearchActionHandler.cs | 14 +-- .../Actions/Email/EmailActionHandler.cs | 10 +- .../Actions/Kafka/KafkaAction.cs | 10 +- .../Actions/Kafka/KafkaActionHandler.cs | 22 ++--- .../Actions/Kafka/KafkaProducer.cs | 28 +++--- .../Actions/Medium/MediumAction.cs | 6 +- .../Actions/Medium/MediumActionHandler.cs | 8 +- .../Notification/NotificationAction.cs | 4 +- .../Notification/NotificationActionHandler.cs | 2 +- .../Actions/OpenSearch/OpenSearchAction.cs | 8 +- .../OpenSearch/OpenSearchActionHandler.cs | 14 +-- .../Squidex.Extensions/Actions/RuleHelper.cs | 6 +- .../Actions/SignalR/SignalRAction.cs | 6 +- .../Actions/SignalR/SignalRActionHandler.cs | 9 +- .../Actions/Twitter/TweetActionHandler.cs | 2 +- .../Actions/Typesense/TypesenseAction.cs | 4 +- .../Typesense/TypesenseActionHandler.cs | 4 +- .../Actions/Webhook/WebhookAction.cs | 8 +- .../Actions/Webhook/WebhookActionHandler.cs | 12 +-- .../DoubleLinkedContentMiddleware.cs | 6 +- .../Squidex.Extensions.csproj | 1 + .../Text/Azure/AzureIndexDefinition.cs | 4 +- .../Text/Azure/AzureTextIndex.cs | 6 +- .../Text/Azure/CommandFactory.cs | 4 +- .../Text/ElasticSearch/CommandFactory.cs | 21 ++-- .../ElasticSearch/ElasticSearchTextIndex.cs | 6 +- .../Validation/CompositeUniqueValidator.cs | 6 +- .../CompositeUniqueValidatorFactory.cs | 2 +- backend/i18n/frontend_en.json | 28 ++++-- backend/i18n/frontend_it.json | 28 ++++-- backend/i18n/frontend_nl.json | 28 ++++-- backend/i18n/frontend_pt.json | 28 ++++-- backend/i18n/frontend_zh.json | 28 ++++-- backend/i18n/source/frontend_en.json | 28 ++++-- backend/i18n/source/frontend_it.json | 10 +- backend/i18n/source/frontend_nl.json | 10 +- backend/i18n/source/frontend_pt.json | 10 +- backend/i18n/source/frontend_zh.json | 10 +- .../src/Migrations/OldEvents/SchemaCreated.cs | 6 +- .../Schemas/AssetsFieldProperties.cs | 2 + .../ConvertContent/IConverter.cs | 1 - .../HandleRules/RuleActionHandler.cs | 2 +- .../HandleRules/RuleEventFormatter.cs | 2 +- .../Assets/Visitors/FindExtensions.cs | 3 +- .../Contents/Operations/QueryByQuery.cs | 9 +- .../Operations/QueryInDedicatedCollection.cs | 4 +- .../{AssetExtensions.cs => AssetHeaders.cs} | 4 +- .../Backup/RestoreProcessor.cs | 8 +- ...ContentExtensions.cs => ContentHeaders.cs} | 69 ++++++------- .../Contents/Queries/Steps/ConvertData.cs | 2 +- ...ContextExtensions.cs => ContextHeaders.cs} | 26 ++--- .../MongoDb/Queries/FilterBuilder.cs | 9 +- .../Queries/QueryExtensions.cs | 5 - .../Queries/SortNode.cs | 2 + .../src/Squidex.Web/ApiExceptionConverter.cs | 2 +- .../Config/OpenApi/AcceptHeaderAttribute.cs | 96 +++++++++++++++++++ .../Config/OpenApi/AcceptQueryAttribute.cs | 36 +++++++ .../Api/Config/OpenApi/OpenApiServices.cs | 2 - .../Config/OpenApi/QueryParamsProcessor.cs | 34 ------- .../Config/OpenApi/RequiredSchemaProcessor.cs | 40 +++++++- .../Api/Controllers/Apps/Models/AppDto.cs | 1 - .../Controllers/Apps/Models/AppLanguageDto.cs | 1 - .../Apps/Models/AppLanguagesDto.cs | 1 - .../Controllers/Apps/Models/AppSettingsDto.cs | 1 - .../Api/Controllers/Apps/Models/ClientsDto.cs | 1 - .../Api/Controllers/Apps/Models/EditorDto.cs | 1 - .../Api/Controllers/Apps/Models/PatternDto.cs | 1 - .../Apps/Models/UpdateAppSettingsDto.cs | 1 - .../Controllers/Apps/Models/WorkflowDto.cs | 2 - .../Apps/Models/WorkflowStepDto.cs | 1 - .../Controllers/Assets/AssetsController.cs | 6 ++ .../Api/Controllers/Assets/Models/AssetDto.cs | 1 - .../Assets/Models/AssetFolderDto.cs | 1 - .../Assets/Models/AssetFoldersDto.cs | 1 - .../Controllers/Assets/Models/AssetsDto.cs | 1 - .../Assets/Models/BulkUpdateAssetsDto.cs | 1 - .../Assets/Models/CreateAssetDto.cs | 7 +- .../Assets/Models/DeleteAssetDto.cs | 4 +- .../Assets/Models/UpsertAssetDto.cs | 5 +- .../Backups/Models/RestoreJobDto.cs | 2 - .../Contents/ContentsController.cs | 59 ++++++++++-- .../Contents/ContentsSharedController.cs | 12 +++ .../Contents/Models/AllContentsByGetDto.cs | 8 +- .../Controllers/Contents/Models/ContentDto.cs | 1 - .../Contents/Models/ContentsDto.cs | 1 - .../Contents/Models/CreateContentDto.cs | 6 +- .../Contents/Models/DeleteContentDto.cs | 4 +- .../Contents/Models/ScheduleJobDto.cs | 1 - .../Contents/Models/StatusInfoDto.cs | 1 - .../Contents/Models/UpsertContentDto.cs | 6 +- .../Areas/Api/Controllers/ContributorDto.cs | 1 - .../Areas/Api/Controllers/ContributorsDto.cs | 1 - .../History/Models/HistoryEventDto.cs | 1 - .../Areas/Api/Controllers/LanguageDto.cs | 1 - .../Api/Controllers/News/Models/FeatureDto.cs | 2 - .../Controllers/News/Models/FeaturesDto.cs | 2 - .../Api/Controllers/Plans/Models/PlanDto.cs | 1 - .../Api/Controllers/Plans/Models/PlansDto.cs | 1 - .../Api/Controllers/Rules/Models/RuleDto.cs | 1 - .../Rules/Models/RuleElementDto.cs | 1 - .../Rules/Models/RuleElementPropertyDto.cs | 1 - .../Controllers/Rules/Models/RuleEventDto.cs | 1 - .../Controllers/Rules/Models/RuleEventsDto.cs | 1 - .../Api/Controllers/Rules/Models/RulesDto.cs | 1 - .../Rules/Models/SimulatedRuleEventsDto.cs | 1 - .../Schemas/Models/ChangeCategoryDto.cs | 2 + .../Schemas/Models/ConfigureFieldRulesDto.cs | 2 + .../Schemas/Models/ConfigurePreviewUrlsDto.cs | 2 + .../Schemas/Models/ConfigureUIFieldsDto.cs | 2 + .../Schemas/Models/CreateSchemaDto.cs | 2 + .../Schemas/Models/FieldPropertiesDto.cs | 2 + .../Models/Fields/ArrayFieldPropertiesDto.cs | 2 + .../Models/Fields/AssetsFieldPropertiesDto.cs | 7 ++ .../Fields/BooleanFieldPropertiesDto.cs | 2 + .../Fields/ComponentFieldPropertiesDto.cs | 2 + .../Fields/ComponentsFieldPropertiesDto.cs | 2 + .../Fields/DateTimeFieldPropertiesDto.cs | 2 + .../Models/Fields/NumberFieldPropertiesDto.cs | 2 + .../Fields/ReferencesFieldPropertiesDto.cs | 2 + .../Models/Fields/StringFieldPropertiesDto.cs | 2 + .../Models/Fields/TagsFieldPropertiesDto.cs | 2 + .../Models/Fields/UIFieldPropertiesDto.cs | 2 + .../Schemas/Models/ReorderFieldsDto.cs | 2 + .../Schemas/Models/SynchronizeSchemaDto.cs | 2 + .../Schemas/Models/UpdateFieldDto.cs | 2 + .../Schemas/Models/UpdateSchemaDto.cs | 2 + .../Schemas/Models/UpsertSchemaDto.cs | 2 + .../Schemas/Models/UpsertSchemaFieldDto.cs | 4 +- .../Models/UpsertSchemaNestedFieldDto.cs | 4 +- .../Search/Models/SearchResultDto.cs | 1 - .../Statistics/Models/CallsUsageDtoDto.cs | 1 - .../Api/Controllers/Teams/Models/TeamDto.cs | 1 - .../Templates/Models/TemplateDetailsDto.cs | 1 - .../Templates/Models/TemplateDto.cs | 1 - .../Api/Controllers/Users/Models/UserDto.cs | 1 - .../Api/Controllers/Users/Models/UsersDto.cs | 1 - ...kenHandler.cs => AlwaysAddScopeHandler.cs} | 0 .../Controllers/Account/AccountController.cs | 1 - .../MongoDb/AssetsQueryIntegrationTests.cs | 1 - .../Contents/GraphQL/GraphQLMutationTests.cs | 2 +- .../Contents/MongoDb/ContentsQueryFixture.cs | 1 - .../fields/types/assets-ui.component.html | 14 ++- .../client-connect-form.component.html | 96 ++++++++++++++----- .../contents/content-value.component.scss | 17 ++-- .../src/app/shared/services/schemas.types.ts | 11 ++- .../app/shared/state/contents.forms.spec.ts | 40 +++++++- .../state/contents.forms.visitors.spec.ts | 10 +- .../shared/state/contents.forms.visitors.ts | 47 +++++---- .../src/app/shared/state/schemas.forms.ts | 1 + .../TestSuite.ApiTests/AssetTests.cs | 4 +- .../TestSuite.Shared/ClientWrapper.cs | 2 +- 164 files changed, 843 insertions(+), 477 deletions(-) rename backend/src/Squidex.Domain.Apps.Entities/Assets/{AssetExtensions.cs => AssetHeaders.cs} (87%) rename backend/src/Squidex.Domain.Apps.Entities/Contents/{ContentExtensions.cs => ContentHeaders.cs} (61%) rename backend/src/Squidex.Domain.Apps.Entities/{ContextExtensions.cs => ContextHeaders.cs} (69%) create mode 100644 backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptHeaderAttribute.cs create mode 100644 backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs delete mode 100644 backend/src/Squidex/Areas/Api/Config/OpenApi/QueryParamsProcessor.cs rename backend/src/Squidex/Areas/IdentityServer/Config/{AlwaysAddTokenHandler.cs => AlwaysAddScopeHandler.cs} (100%) diff --git a/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverExceptionHandler.cs b/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverExceptionHandler.cs index ade8722969..5accd2b44b 100644 --- a/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverExceptionHandler.cs +++ b/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverExceptionHandler.cs @@ -50,7 +50,7 @@ public StackdriverExceptionHandler(IContextExceptionLogger logger, IHttpContextA httpContextWrapper = new HttpContextWrapper(httpContextAccessor); } - public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception exception) + public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception? exception) { try { diff --git a/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverSeverityLogAppender.cs b/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverSeverityLogAppender.cs index 059f5e4b14..71305e6484 100644 --- a/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverSeverityLogAppender.cs +++ b/backend/extensions/Squidex.Extensions/APM/Stackdriver/StackdriverSeverityLogAppender.cs @@ -11,7 +11,7 @@ namespace Squidex.Extensions.APM.Stackdriver; public sealed class StackdriverSeverityLogAppender : ILogAppender { - public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception exception) + public void Append(IObjectWriter writer, SemanticLogLevel logLevel, Exception? exception) { var severity = GetSeverity(logLevel); diff --git a/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs b/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs index eea5b7701f..4ee924315d 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaAction.cs @@ -42,9 +42,9 @@ public sealed record AlgoliaAction : RuleAction [Display(Name = "Document", Description = "The optional custom document.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Document { get; set; } + public string? Document { get; set; } [Display(Name = "Deletion", Description = "The condition when to delete the entry.")] [Editor(RuleFieldEditor.Text)] - public string Delete { get; set; } + public string? Delete { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs index 0693a74a18..bffac761ab 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs @@ -46,7 +46,7 @@ public AlgoliaActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEn var ruleDescription = string.Empty; var contentId = entityEvent.Id.ToString(); - var content = (AlgoliaContent)null; + var content = (AlgoliaContent?)null; if (delete) { @@ -58,7 +58,7 @@ public AlgoliaActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEn try { - string jsonString; + string? jsonString; if (!string.IsNullOrEmpty(action.Document)) { @@ -70,7 +70,7 @@ public AlgoliaActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEn jsonString = ToJson(@event); } - content = serializer.Deserialize(jsonString); + content = serializer.Deserialize(jsonString!); } catch (Exception ex) { @@ -92,7 +92,7 @@ public AlgoliaActionHandler(RuleEventFormatter formatter, IScriptEngine scriptEn ApiKey = action.ApiKey, Content = serializer.Serialize(content, true), ContentId = contentId, - IndexName = await FormatAsync(action.IndexName, @event) + IndexName = (await FormatAsync(action.IndexName, @event))! }; return (ruleDescription, ruleJob); diff --git a/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueAction.cs b/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueAction.cs index 1a4fe27d71..431de63ab2 100644 --- a/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueAction.cs @@ -37,7 +37,7 @@ public sealed record AzureQueueAction : RuleAction [Display(Name = "Payload (Optional)", Description = "Leave it empty to use the full event as body.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Payload { get; set; } + public string? Payload { get; set; } protected override IEnumerable CustomValidate() { diff --git a/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueActionHandler.cs index 6934d5015f..1db8b7f28b 100644 --- a/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/AzureQueue/AzureQueueActionHandler.cs @@ -36,7 +36,7 @@ public AzureQueueActionHandler(RuleEventFormatter formatter) { var queueName = await FormatAsync(action.Queue, @event); - string requestBody; + string? requestBody; if (!string.IsNullOrEmpty(action.Payload)) { @@ -51,7 +51,7 @@ public AzureQueueActionHandler(RuleEventFormatter formatter) var ruleJob = new AzureQueueJob { QueueConnectionString = action.ConnectionString, - QueueName = queueName, + QueueName = queueName!, MessageBodyV2 = requestBody }; @@ -75,5 +75,5 @@ public sealed class AzureQueueJob public string QueueName { get; set; } - public string MessageBodyV2 { get; set; } + public string? MessageBodyV2 { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/ClientPool.cs b/backend/extensions/Squidex.Extensions/Actions/ClientPool.cs index 7a052f4d84..6bbb193e70 100644 --- a/backend/extensions/Squidex.Extensions/Actions/ClientPool.cs +++ b/backend/extensions/Squidex.Extensions/Actions/ClientPool.cs @@ -12,7 +12,7 @@ namespace Squidex.Extensions.Actions; -internal sealed class ClientPool +internal sealed class ClientPool where TKey : notnull { private static readonly TimeSpan TimeToLive = TimeSpan.FromMinutes(30); private readonly MemoryCache memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions())); @@ -37,6 +37,6 @@ public async Task GetClientAsync(TKey key) memoryCache.Set(key, client, TimeToLive); } - return client; + return client!; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Comment/CommentAction.cs b/backend/extensions/Squidex.Extensions/Actions/Comment/CommentAction.cs index e52ede976a..4c41b54b61 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Comment/CommentAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Comment/CommentAction.cs @@ -28,5 +28,5 @@ public sealed record CommentAction : RuleAction [Display(Name = "Client", Description = "An optional client name.")] [Editor(RuleFieldEditor.Text)] - public string Client { get; set; } + public string? Client { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs index a53cb1f5e2..1865f7c381 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs @@ -33,7 +33,7 @@ public CommentActionHandler(RuleEventFormatter formatter, ICommandBus commandBus AppId = contentEvent.AppId }; - ruleJob.Text = await FormatAsync(action.Text, @event); + ruleJob.Text = (await FormatAsync(action.Text, @event))!; if (!string.IsNullOrEmpty(action.Client)) { diff --git a/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs index 2bc28199b2..b97e088572 100644 --- a/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs @@ -50,7 +50,7 @@ public CreateContentActionHandler(RuleEventFormatter formatter, IAppProvider app var json = await FormatAsync(action.Data, @event); - ruleJob.Data = jsonSerializer.Deserialize(json); + ruleJob.Data = jsonSerializer.Deserialize(json!); if (!string.IsNullOrEmpty(action.Client)) { diff --git a/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs b/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs index 22df74ced1..9234e708b7 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseAction.cs @@ -46,7 +46,7 @@ public sealed record DiscourseAction : RuleAction [Display(Name = "Title", Description = "The optional title when creating new topics.")] [Editor(RuleFieldEditor.Text)] [Formattable] - public string Title { get; set; } + public string? Title { get; set; } [Display(Name = "Topic", Description = "The optional topic id.")] [Editor(RuleFieldEditor.Text)] diff --git a/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs index 0d1bc38eeb..8e75a40b68 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Discourse/DiscourseActionHandler.cs @@ -30,9 +30,9 @@ public DiscourseActionHandler(RuleEventFormatter formatter, IHttpClientFactory h { var url = $"{action.Url.ToString().TrimEnd('/')}/posts.json?api_key={action.ApiKey}&api_username={action.ApiUsername}"; - var json = new Dictionary + var json = new Dictionary { - ["title"] = await FormatAsync(action.Title, @event) + ["title"] = await FormatAsync(action.Title!, @event) }; if (action.Topic != null) diff --git a/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs b/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs index 2afbf555e4..99355d2a79 100644 --- a/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchAction.cs @@ -35,18 +35,18 @@ public sealed record ElasticSearchAction : RuleAction [Display(Name = "Username", Description = "The optional username.")] [Editor(RuleFieldEditor.Text)] - public string Username { get; set; } + public string? Username { get; set; } [Display(Name = "Password", Description = "The optional password.")] [Editor(RuleFieldEditor.Text)] - public string Password { get; set; } + public string? Password { get; set; } [Display(Name = "Document", Description = "The optional custom document.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Document { get; set; } + public string? Document { get; set; } [Display(Name = "Deletion", Description = "The condition when to delete the document.")] [Editor(RuleFieldEditor.Text)] - public string Delete { get; set; } + public string? Delete { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchActionHandler.cs index a06719269d..a311160575 100644 --- a/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/ElasticSearch/ElasticSearchActionHandler.cs @@ -20,14 +20,14 @@ namespace Squidex.Extensions.Actions.ElasticSearch; public sealed class ElasticSearchActionHandler : RuleActionHandler { - private readonly ClientPool<(Uri Host, string Username, string Password), ElasticLowLevelClient> clients; + 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 => + clients = new ClientPool<(Uri Host, string? Username, string? Password), ElasticLowLevelClient>(key => { var config = new ConnectionConfiguration(key.Host); @@ -61,7 +61,7 @@ public ElasticSearchActionHandler(RuleEventFormatter formatter, IScriptEngine sc var ruleText = string.Empty; var ruleJob = new ElasticSearchJob { - IndexName = await FormatAsync(action.IndexName, @event), + IndexName = (await FormatAsync(action.IndexName, @event))!, ServerHost = action.Host.ToString(), ServerUser = action.Username, ServerPassword = action.Password, @@ -79,7 +79,7 @@ public ElasticSearchActionHandler(RuleEventFormatter formatter, IScriptEngine sc ElasticSearchContent content; try { - string jsonString; + string? jsonString; if (!string.IsNullOrEmpty(action.Document)) { @@ -91,7 +91,7 @@ public ElasticSearchActionHandler(RuleEventFormatter formatter, IScriptEngine sc jsonString = ToJson(@event); } - content = serializer.Deserialize(jsonString); + content = serializer.Deserialize(jsonString!); } catch (Exception ex) { @@ -156,9 +156,9 @@ public sealed class ElasticSearchJob { public string ServerHost { get; set; } - public string ServerUser { get; set; } + public string? ServerUser { get; set; } - public string ServerPassword { get; set; } + public string? ServerPassword { get; set; } public string ContentId { get; set; } diff --git a/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs index c394f48418..888fb19f77 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs @@ -29,11 +29,11 @@ public EmailActionHandler(RuleEventFormatter formatter) ServerHost = action.ServerHost, ServerPassword = action.ServerPassword, ServerPort = action.ServerPort, - ServerUsername = await FormatAsync(action.ServerUsername, @event), - MessageFrom = await FormatAsync(action.MessageFrom, @event), - MessageTo = await FormatAsync(action.MessageTo, @event), - MessageSubject = await FormatAsync(action.MessageSubject, @event), - MessageBody = await FormatAsync(action.MessageBody, @event) + ServerUsername = (await FormatAsync(action.ServerUsername, @event))!, + MessageFrom = (await FormatAsync(action.MessageFrom, @event))!, + MessageTo = (await FormatAsync(action.MessageTo, @event))!, + MessageSubject = (await FormatAsync(action.MessageSubject, @event))!, + MessageBody = (await FormatAsync(action.MessageBody, @event))! }; var description = $"Send an email to {action.MessageTo}"; diff --git a/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaAction.cs b/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaAction.cs index fc1ada0e51..658103f6bb 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaAction.cs @@ -30,17 +30,17 @@ public sealed record KafkaAction : RuleAction [Display(Name = "Payload (Optional)", Description = "Leave it empty to use the full event as body.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Payload { get; set; } + public string? Payload { get; set; } [Display(Name = "Key", Description = "The message key, commonly used for partitioning.")] [Editor(RuleFieldEditor.Text)] [Formattable] - public string Key { get; set; } + public string? Key { get; set; } [Display(Name = "Partition Key", Description = "The partition key, only used when we don't want to define partiontionig with key.")] [Editor(RuleFieldEditor.Text)] [Formattable] - public string PartitionKey { get; set; } + public string? PartitionKey { get; set; } [Display(Name = "Partition Count", Description = "Define the number of partitions for specific topic.")] [Editor(RuleFieldEditor.Text)] @@ -49,9 +49,9 @@ public sealed record KafkaAction : RuleAction [Display(Name = "Headers (Optional)", Description = "The message headers in the format '[Key]=[Value]', one entry per line.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Headers { get; set; } + public string? Headers { get; set; } [Display(Name = "Schema (Optional)", Description = "Define a specific AVRO schema in JSON format.")] [Editor(RuleFieldEditor.TextArea)] - public string Schema { get; set; } + public string? Schema { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaActionHandler.cs index 76d42ff1f6..f906b98473 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaActionHandler.cs @@ -25,7 +25,7 @@ public KafkaActionHandler(RuleEventFormatter formatter, KafkaProducer kafkaProdu protected override async Task<(string Description, KafkaJob Data)> CreateJobAsync(EnrichedEvent @event, KafkaAction action) { - string value, key; + string? value, key; if (!string.IsNullOrEmpty(action.Payload)) { @@ -59,7 +59,7 @@ public KafkaActionHandler(RuleEventFormatter formatter, KafkaProducer kafkaProdu return (Description, ruleJob); } - private async Task> ParseHeadersAsync(string headers, EnrichedEvent @event) + private async Task?> ParseHeadersAsync(string? headers, EnrichedEvent @event) { if (string.IsNullOrWhiteSpace(headers)) { @@ -76,12 +76,12 @@ private async Task> ParseHeadersAsync(string headers, if (indexEqual > 0 && indexEqual < line.Length - 1) { - var key = line[..indexEqual]; - var val = line[(indexEqual + 1)..]; + var headerKey = line[..indexEqual]; + var headerValue = line[(indexEqual + 1)..]; - val = await FormatAsync(val, @event); + headerValue = await FormatAsync(headerValue, @event); - headersDictionary[key] = val; + headersDictionary[headerKey] = headerValue!; } } @@ -108,15 +108,15 @@ public sealed class KafkaJob { public string TopicName { get; set; } - public string MessageKey { get; set; } + public string? MessageKey { get; set; } - public string MessageValue { get; set; } + public string? MessageValue { get; set; } - public string Schema { get; set; } + public string? Schema { get; set; } - public string PartitionKey { get; set; } + public string? PartitionKey { get; set; } - public Dictionary Headers { get; set; } + public Dictionary? Headers { get; set; } public int PartitionCount { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaProducer.cs b/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaProducer.cs index 1f8dc5467b..0f6da694af 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaProducer.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Kafka/KafkaProducer.cs @@ -108,7 +108,7 @@ public async Task SendAsync(KafkaJob job, { if (!string.IsNullOrWhiteSpace(job.Schema)) { - var value = CreateAvroRecord(job.MessageValue, job.Schema); + var value = CreateAvroRecord(job.MessageValue!, job.Schema); var message = new Message { Value = value }; @@ -116,7 +116,7 @@ public async Task SendAsync(KafkaJob job, } else { - var message = new Message { Value = job.MessageValue }; + var message = new Message { Value = job.MessageValue! }; await ProduceAsync(textProducer, message, job, ct); } @@ -125,7 +125,7 @@ public async Task SendAsync(KafkaJob job, private static async Task ProduceAsync(IProducer producer, Message message, KafkaJob job, CancellationToken ct) { - message.Key = job.MessageKey; + message.Key = job.MessageKey!; if (job.Headers?.Count > 0) { @@ -157,9 +157,7 @@ private GenericRecord CreateAvroRecord(string json, string avroSchema) var jsonObject = jsonSerializer.Deserialize(json); - var result = (GenericRecord)GetValue(jsonObject, schema); - - return result; + return (GenericRecord)GetValue(jsonObject, schema)!; } catch (JsonException ex) { @@ -173,7 +171,7 @@ public void Dispose() avroProducer?.Dispose(); } - private static object GetValue(JsonValue value, Schema schema) + private static object? GetValue(JsonValue value, Schema? schema) { switch (value.Value) { @@ -191,11 +189,11 @@ private static object GetValue(JsonValue value, Schema schema) return s; case JsonObject o when IsTypeOrUnionWith(schema, Schema.Type.Map): { - var mapResult = new Dictionary(); + var mapResult = new Dictionary(); if (schema is UnionSchema union) { - var map = (MapSchema)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Map); + var map = (MapSchema?)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Map); foreach (var (key, childValue) in o) { @@ -215,11 +213,11 @@ private static object GetValue(JsonValue value, Schema schema) case JsonObject o when IsTypeOrUnionWith(schema, Schema.Type.Record): { - GenericRecord result = null; + GenericRecord? result = null; if (schema is UnionSchema union) { - var record = (RecordSchema)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Record); + var record = (RecordSchema?)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Record); result = new GenericRecord(record); @@ -249,11 +247,11 @@ private static object GetValue(JsonValue value, Schema schema) case JsonArray a when IsTypeOrUnionWith(schema, Schema.Type.Array): { - var result = new List(); + var result = new List(); if (schema is UnionSchema union) { - var arraySchema = (ArraySchema)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Array); + var arraySchema = (ArraySchema?)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Array); foreach (var item in a) { @@ -275,8 +273,8 @@ private static object GetValue(JsonValue value, Schema schema) return null; } - private static bool IsTypeOrUnionWith(Schema schema, Schema.Type expected) + private static bool IsTypeOrUnionWith(Schema? schema, Schema.Type expected) { - return schema.Tag == expected || (schema is UnionSchema union && union.Schemas.Any(x => x.Tag == expected)); + return schema?.Tag == expected || (schema is UnionSchema union && union.Schemas.Any(x => x.Tag == expected)); } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Medium/MediumAction.cs b/backend/extensions/Squidex.Extensions/Actions/Medium/MediumAction.cs index 8308245407..8921958049 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Medium/MediumAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Medium/MediumAction.cs @@ -41,16 +41,16 @@ public sealed record MediumAction : RuleAction [Display(Name = "Canonical Url", Description = "The original home of this content, if it was originally published elsewhere.")] [Editor(RuleFieldEditor.Text)] [Formattable] - public string CanonicalUrl { get; set; } + public string? CanonicalUrl { get; set; } [Display(Name = "Tags", Description = "The optional comma separated list of tags.")] [Editor(RuleFieldEditor.Text)] [Formattable] - public string Tags { get; set; } + public string? Tags { get; set; } [Display(Name = "Publication Id", Description = "Optional publication id.")] [Editor(RuleFieldEditor.Text)] - public string PublicationId { get; set; } + public string? PublicationId { get; set; } [Display(Name = "Is Html", Description = "Indicates whether the content is markdown or html.")] [Editor(RuleFieldEditor.Text)] diff --git a/backend/extensions/Squidex.Extensions/Actions/Medium/MediumActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Medium/MediumActionHandler.cs index 7ad90bffc9..225939b9e4 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Medium/MediumActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Medium/MediumActionHandler.cs @@ -58,7 +58,7 @@ public MediumActionHandler(RuleEventFormatter formatter, IHttpClientFactory http return (Description, ruleJob); } - private async Task ParseTagsAsync(EnrichedEvent @event, MediumAction action) + private async Task ParseTagsAsync(EnrichedEvent @event, MediumAction action) { if (string.IsNullOrWhiteSpace(action.Tags)) { @@ -69,7 +69,7 @@ private async Task ParseTagsAsync(EnrichedEvent @event, MediumAction a { var jsonTags = await FormatAsync(action.Tags, @event); - return serializer.Deserialize(jsonTags); + return serializer.Deserialize(jsonTags!); } catch { @@ -90,7 +90,7 @@ protected override async Task ExecuteJobAsync(MediumJob job, } else { - HttpResponseMessage response = null; + HttpResponseMessage? response = null; var meRequest = BuildGetRequest(job, "/v1/me"); try @@ -141,7 +141,7 @@ public sealed class MediumJob { public string RequestBody { get; set; } - public string PublicationId { get; set; } + public string? PublicationId { get; set; } public string AccessToken { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationAction.cs b/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationAction.cs index c019ed3284..828f4554da 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationAction.cs @@ -34,9 +34,9 @@ public sealed record NotificationAction : RuleAction [Display(Name = "Url", Description = "The optional url to attach to the notification.")] [Editor(RuleFieldEditor.Text)] [Formattable] - public string Url { get; set; } + public string? Url { get; set; } [Display(Name = "Client", Description = "An optional client name.")] [Editor(RuleFieldEditor.Text)] - public string Client { get; set; } + public string? Client { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs index 7d933b418a..3f8c8c6c5e 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs @@ -53,7 +53,7 @@ public NotificationActionHandler(RuleEventFormatter formatter, ICommandBus comma CommentId = DomainId.NewGuid(), CommentsId = DomainId.Create(user.Id), FromRule = true, - Text = await FormatAsync(action.Text, @event) + Text = (await FormatAsync(action.Text, @event))! }; if (!string.IsNullOrWhiteSpace(action.Url)) diff --git a/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchAction.cs b/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchAction.cs index 2d8c18cfb8..094ae44a25 100644 --- a/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchAction.cs @@ -35,18 +35,18 @@ public sealed record OpenSearchAction : RuleAction [Display(Name = "Username", Description = "The optional username.")] [Editor(RuleFieldEditor.Text)] - public string Username { get; set; } + public string? Username { get; set; } [Display(Name = "Password", Description = "The optional password.")] [Editor(RuleFieldEditor.Text)] - public string Password { get; set; } + public string? Password { get; set; } [Display(Name = "Document", Description = "The optional custom document.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Document { get; set; } + public string? Document { get; set; } [Display(Name = "Deletion", Description = "The condition when to delete the document.")] [Editor(RuleFieldEditor.Text)] - public string Delete { get; set; } + public string? Delete { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchActionHandler.cs index c8829a1de5..776c8b8315 100644 --- a/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/OpenSearch/OpenSearchActionHandler.cs @@ -20,14 +20,14 @@ namespace Squidex.Extensions.Actions.OpenSearch; public sealed class OpenSearchActionHandler : RuleActionHandler { - private readonly ClientPool<(Uri Host, string Username, string Password), OpenSearchLowLevelClient> clients; + 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 => + clients = new ClientPool<(Uri Host, string? Username, string? Password), OpenSearchLowLevelClient>(key => { var config = new ConnectionConfiguration(key.Host); @@ -61,7 +61,7 @@ public OpenSearchActionHandler(RuleEventFormatter formatter, IScriptEngine scrip var ruleText = string.Empty; var ruleJob = new OpenSearchJob { - IndexName = await FormatAsync(action.IndexName, @event), + IndexName = (await FormatAsync(action.IndexName, @event))!, ServerHost = action.Host.ToString(), ServerUser = action.Username, ServerPassword = action.Password, @@ -79,7 +79,7 @@ public OpenSearchActionHandler(RuleEventFormatter formatter, IScriptEngine scrip OpenSearchContent content; try { - string jsonString; + string? jsonString; if (!string.IsNullOrEmpty(action.Document)) { @@ -91,7 +91,7 @@ public OpenSearchActionHandler(RuleEventFormatter formatter, IScriptEngine scrip jsonString = ToJson(@event); } - content = serializer.Deserialize(jsonString); + content = serializer.Deserialize(jsonString!); } catch (Exception ex) { @@ -156,9 +156,9 @@ public sealed class OpenSearchJob { public string ServerHost { get; set; } - public string ServerUser { get; set; } + public string? ServerUser { get; set; } - public string ServerPassword { get; set; } + public string? ServerPassword { get; set; } public string ContentId { get; set; } diff --git a/backend/extensions/Squidex.Extensions/Actions/RuleHelper.cs b/backend/extensions/Squidex.Extensions/Actions/RuleHelper.cs index d0cd7836ba..d665e72f53 100644 --- a/backend/extensions/Squidex.Extensions/Actions/RuleHelper.cs +++ b/backend/extensions/Squidex.Extensions/Actions/RuleHelper.cs @@ -14,7 +14,7 @@ namespace Squidex.Extensions.Actions; public static class RuleHelper { - public static bool ShouldDelete(this EnrichedEvent @event, IScriptEngine scriptEngine, string expression) + public static bool ShouldDelete(this EnrichedEvent @event, IScriptEngine scriptEngine, string? expression) { if (!string.IsNullOrWhiteSpace(expression)) { @@ -40,10 +40,10 @@ public static bool IsAssetDeletion(this EnrichedEvent @event) return @event is EnrichedAssetEvent { Type: EnrichedAssetEventType.Deleted }; } - public static async Task OneWayRequestAsync(this HttpClient client, HttpRequestMessage request, string requestBody = null, + public static async Task OneWayRequestAsync(this HttpClient client, HttpRequestMessage request, string? requestBody = null, CancellationToken ct = default) { - HttpResponseMessage response = null; + HttpResponseMessage? response = null; try { response = await client.SendAsync(request, ct); diff --git a/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRAction.cs b/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRAction.cs index 6fedfb2fb0..9ae964c604 100644 --- a/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRAction.cs @@ -42,17 +42,17 @@ public sealed record SignalRAction : RuleAction [Display(Name = "Methode Name", Description = "Set the Name of the hub method received by the customer.")] [Editor(RuleFieldEditor.Text)] - public string MethodName { get; set; } + public string? MethodName { get; set; } [Display(Name = "Target (Optional)", Description = "Define target users or groups by id or name. One item per line. Not needed for Broadcast action.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Target { get; set; } + public string? Target { get; set; } [Display(Name = "Payload (Optional)", Description = "Leave it empty to use the full event as body.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Payload { get; set; } + public string? Payload { get; set; } protected override IEnumerable CustomValidate() { diff --git a/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRActionHandler.cs index 3733aa6ec4..6c82f86f73 100644 --- a/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/SignalR/SignalRActionHandler.cs @@ -39,7 +39,7 @@ public SignalRActionHandler(RuleEventFormatter formatter) { var hubName = await FormatAsync(action.HubName, @event); - string requestBody; + string? requestBody; if (!string.IsNullOrWhiteSpace(action.Payload)) { @@ -53,14 +53,13 @@ public SignalRActionHandler(RuleEventFormatter formatter) var target = (await FormatAsync(action.Target, @event)) ?? string.Empty; var ruleText = $"Send SignalRJob to signalR hub '{hubName}'"; - var ruleJob = new SignalRJob { Action = action.Action, ConnectionString = action.ConnectionString, - HubName = hubName, + HubName = hubName!, MethodName = action.MethodName, - MethodPayload = requestBody, + MethodPayload = requestBody!, Targets = target.Split("\n") }; @@ -102,7 +101,7 @@ public sealed class SignalRJob public ActionTypeEnum Action { get; set; } - public string MethodName { get; set; } + public string? MethodName { get; set; } public string MethodPayload { get; set; } diff --git a/backend/extensions/Squidex.Extensions/Actions/Twitter/TweetActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Twitter/TweetActionHandler.cs index 834116f1d1..e5fdd1ec40 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Twitter/TweetActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Twitter/TweetActionHandler.cs @@ -30,7 +30,7 @@ public TweetActionHandler(RuleEventFormatter formatter, IOptions { var ruleJob = new TweetJob { - Text = await FormatAsync(action.Text, @event), + Text = (await FormatAsync(action.Text, @event))!, AccessToken = action.AccessToken, AccessSecret = action.AccessSecret }; diff --git a/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseAction.cs b/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseAction.cs index 4b43d1df2b..a062fc16b3 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseAction.cs @@ -41,9 +41,9 @@ public sealed record TypesenseAction : RuleAction [Display(Name = "Document", Description = "The optional custom document.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Document { get; set; } + public string? Document { get; set; } [Display(Name = "Deletion", Description = "The condition when to delete the document.")] [Editor(RuleFieldEditor.Text)] - public string Delete { get; set; } + public string? Delete { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseActionHandler.cs index 8c41ee5d23..0224a4ce2f 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Typesense/TypesenseActionHandler.cs @@ -68,7 +68,7 @@ public TypesenseActionHandler(RuleEventFormatter formatter, IHttpClientFactory h TypesenseContent content; try { - string jsonString; + string? jsonString; if (!string.IsNullOrEmpty(action.Document)) { @@ -80,7 +80,7 @@ public TypesenseActionHandler(RuleEventFormatter formatter, IHttpClientFactory h jsonString = ToJson(@event); } - content = serializer.Deserialize(jsonString); + content = serializer.Deserialize(jsonString!); } catch (Exception ex) { diff --git a/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookAction.cs b/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookAction.cs index 657eb316e0..166a595955 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookAction.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookAction.cs @@ -36,20 +36,20 @@ public sealed record WebhookAction : RuleAction [Display(Name = "Payload (Optional)", Description = "Leave it empty to use the full event as body.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Payload { get; set; } + public string? Payload { get; set; } [Display(Name = "Payload Type", Description = "The mime type of the payload.")] [Editor(RuleFieldEditor.Text)] - public string PayloadType { get; set; } + public string? PayloadType { get; set; } [Display(Name = "Headers (Optional)", Description = "The message headers in the format '[Key]=[Value]', one entry per line.")] [Editor(RuleFieldEditor.TextArea)] [Formattable] - public string Headers { get; set; } + public string? Headers { get; set; } [Display(Name = "Shared Secret", Description = "The shared secret that is used to calculate the payload signature.")] [Editor(RuleFieldEditor.Text)] - public string SharedSecret { get; set; } + public string? SharedSecret { get; set; } } public enum WebhookMethod diff --git a/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs index 4da3d39a80..32eacca292 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Webhook/WebhookActionHandler.cs @@ -48,9 +48,9 @@ public WebhookActionHandler(RuleEventFormatter formatter, IHttpClientFactory htt var ruleJob = new WebhookJob { Method = action.Method, - RequestUrl = await FormatAsync(action.Url.ToString(), @event), + RequestUrl = (await FormatAsync(action.Url.ToString(), @event))!, RequestSignature = requestSignature, - RequestBody = requestBody, + RequestBody = requestBody!, RequestBodyType = action.PayloadType, Headers = await ParseHeadersAsync(action.Headers, @event) }; @@ -58,7 +58,7 @@ public WebhookActionHandler(RuleEventFormatter formatter, IHttpClientFactory htt return (ruleText, ruleJob); } - private async Task> ParseHeadersAsync(string headers, EnrichedEvent @event) + private async Task?> ParseHeadersAsync(string? headers, EnrichedEvent @event) { if (string.IsNullOrWhiteSpace(headers)) { @@ -80,7 +80,7 @@ private async Task> ParseHeadersAsync(string headers, headerValue = await FormatAsync(headerValue, @event); - headersDictionary[headerKey] = headerValue; + headersDictionary[headerKey] = headerValue!; } } @@ -146,7 +146,7 @@ public sealed class WebhookJob public string RequestBody { get; set; } - public string RequestBodyType { get; set; } + public string? RequestBodyType { get; set; } - public Dictionary Headers { get; set; } + public Dictionary? Headers { get; set; } } diff --git a/backend/extensions/Squidex.Extensions/Samples/Middleware/DoubleLinkedContentMiddleware.cs b/backend/extensions/Squidex.Extensions/Samples/Middleware/DoubleLinkedContentMiddleware.cs index fbb69d7c9a..67c90c3722 100644 --- a/backend/extensions/Squidex.Extensions/Samples/Middleware/DoubleLinkedContentMiddleware.cs +++ b/backend/extensions/Squidex.Extensions/Samples/Middleware/DoubleLinkedContentMiddleware.cs @@ -101,11 +101,11 @@ await context.CommandBus.PublishAsync(new UpdateContent }, ct); } - private static string GetReference(ContentData data) + private static string? GetReference(ContentData? data) { - if (data != null && data.TryGetValue("reference", out ContentFieldData fieldData)) + if (data != null && data.TryGetValue("reference", out ContentFieldData? fieldData)) { - return fieldData.Values.OfType().SelectMany(x => x).SingleOrDefault().ToString(); + return fieldData?.Values.OfType().SelectMany(x => x).SingleOrDefault().ToString(); } return null; diff --git a/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj b/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj index 4d88871cf3..ee5279d211 100644 --- a/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj +++ b/backend/extensions/Squidex.Extensions/Squidex.Extensions.csproj @@ -3,6 +3,7 @@ net7.0 10.0 enable + enable diff --git a/backend/extensions/Squidex.Extensions/Text/Azure/AzureIndexDefinition.cs b/backend/extensions/Squidex.Extensions/Text/Azure/AzureIndexDefinition.cs index cbe4713ee6..436c5f3eaf 100644 --- a/backend/extensions/Squidex.Extensions/Text/Azure/AzureIndexDefinition.cs +++ b/backend/extensions/Squidex.Extensions/Text/Azure/AzureIndexDefinition.cs @@ -23,8 +23,8 @@ static AzureIndexDefinition() var analyzers = typeof(LexicalAnalyzerName) .GetProperties(BindingFlags.Public | BindingFlags.Static) - .Select(x => x.GetValue(null)) - .Select(x => x.ToString()) + .Select(x => x.GetValue(null)!) + .Select(x => x.ToString()!) .OrderBy(x => x) .ToList(); diff --git a/backend/extensions/Squidex.Extensions/Text/Azure/AzureTextIndex.cs b/backend/extensions/Squidex.Extensions/Text/Azure/AzureTextIndex.cs index 6d3629c752..ae281076ec 100644 --- a/backend/extensions/Squidex.Extensions/Text/Azure/AzureTextIndex.cs +++ b/backend/extensions/Squidex.Extensions/Text/Azure/AzureTextIndex.cs @@ -70,7 +70,7 @@ public async Task ExecuteAsync(IndexCommand[] commands, await searchClient.IndexDocumentsAsync(batch, cancellationToken: ct); } - public async Task> SearchAsync(IAppEntity app, GeoQuery query, SearchScope scope, + public async Task?> SearchAsync(IAppEntity app, GeoQuery query, SearchScope scope, CancellationToken ct = default) { Guard.NotNull(app); @@ -83,7 +83,7 @@ public async Task> SearchAsync(IAppEntity app, GeoQuery query, Se return result.OrderByDescending(x => x.Score).Select(x => x.Id).Distinct().ToList(); } - public async Task> SearchAsync(IAppEntity app, TextQuery query, SearchScope scope, + public async Task?> SearchAsync(IAppEntity app, TextQuery query, SearchScope scope, CancellationToken ct = default) { Guard.NotNull(app); @@ -157,7 +157,7 @@ private async Task SearchAsync(List<(DomainId, double)> result, string text, str { if (item != null) { - var id = DomainId.Create(item.Document["contentId"].ToString()); + var id = DomainId.Create(item.Document["contentId"].ToString()!); result.Add((id, factor * item.Score ?? 0)); } diff --git a/backend/extensions/Squidex.Extensions/Text/Azure/CommandFactory.cs b/backend/extensions/Squidex.Extensions/Text/Azure/CommandFactory.cs index aac1de14ea..a5c0a9fd98 100644 --- a/backend/extensions/Squidex.Extensions/Text/Azure/CommandFactory.cs +++ b/backend/extensions/Squidex.Extensions/Text/Azure/CommandFactory.cs @@ -33,7 +33,7 @@ public static void CreateCommands(IndexCommand command, IList> batch) { var geoField = string.Empty; - var geoObject = (object)null; + var geoObject = (object?)null; if (upsert.GeoObjects != null) { @@ -56,7 +56,7 @@ private static void UpsertTextEntry(UpsertIndexEntry upsert, IList args, strin private static void UpsertEntry(UpsertIndexEntry upsert, List args, string indexName) { var geoField = string.Empty; - var geoObject = (object)null; + var geoObject = (object?)null; if (upsert.GeoObjects != null) { @@ -63,18 +63,21 @@ private static void UpsertEntry(UpsertIndexEntry upsert, List args, stri var texts = new Dictionary(); - foreach (var (key, value) in upsert.Texts) + if (upsert.Texts != null) { - var text = value; + foreach (var (key, value) in upsert.Texts) + { + var text = value; - var languageCode = ElasticSearchIndexDefinition.GetFieldName(key); + var languageCode = ElasticSearchIndexDefinition.GetFieldName(key); - if (texts.TryGetValue(languageCode, out var existing)) - { - text = $"{existing} {value}"; - } + if (texts.TryGetValue(languageCode, out var existing)) + { + text = $"{existing} {value}"; + } - texts[languageCode] = text; + texts[languageCode] = text; + } } args.Add(new diff --git a/backend/extensions/Squidex.Extensions/Text/ElasticSearch/ElasticSearchTextIndex.cs b/backend/extensions/Squidex.Extensions/Text/ElasticSearch/ElasticSearchTextIndex.cs index 1d41d97cc9..e853d6e206 100644 --- a/backend/extensions/Squidex.Extensions/Text/ElasticSearch/ElasticSearchTextIndex.cs +++ b/backend/extensions/Squidex.Extensions/Text/ElasticSearch/ElasticSearchTextIndex.cs @@ -61,7 +61,7 @@ public Task ExecuteAsync(IndexCommand[] commands, return elasticClient.BulkAsync(args, ct); } - public async Task> SearchAsync(IAppEntity app, GeoQuery query, SearchScope scope, + public async Task?> SearchAsync(IAppEntity app, GeoQuery query, SearchScope scope, CancellationToken ct = default) { Guard.NotNull(app); @@ -123,7 +123,7 @@ public async Task> SearchAsync(IAppEntity app, GeoQuery query, Se return await SearchAsync(elasticQuery, ct); } - public async Task> SearchAsync(IAppEntity app, TextQuery query, SearchScope scope, + public async Task?> SearchAsync(IAppEntity app, TextQuery query, SearchScope scope, CancellationToken ct = default) { Guard.NotNull(app); @@ -194,7 +194,7 @@ public async Task> SearchAsync(IAppEntity app, TextQuery query, S { var bySchema = new { - terms = new Dictionary + terms = new Dictionary { ["schemaId.keyword"] = query.PreferredSchemaId.ToString() } diff --git a/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidator.cs b/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidator.cs index d2f1b2216a..2ff3abe8c3 100644 --- a/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidator.cs +++ b/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidator.cs @@ -27,7 +27,7 @@ public CompositeUniqueValidator(string contentTag, IContentRepository contentRep this.contentRepository = contentRepository; } - public void Validate(object value, ValidationContext context) + public void Validate(object? value, ValidationContext context) { if (value is ContentData data) { @@ -64,11 +64,11 @@ private async Task ValidateAsync(ContentData data, ValidationContext context) } } - private static ClrValue TryGetValue(IRootField field, ContentData data) + private static ClrValue? TryGetValue(IRootField field, ContentData data) { var value = JsonValue.Null; - if (data.TryGetValue(field.Name, out var fieldValue)) + if (data.TryGetValue(field.Name, out var fieldValue) && fieldValue != null) { if (fieldValue.TryGetValue(InvariantPartitioning.Key, out var temp) && temp != default) { diff --git a/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidatorFactory.cs b/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidatorFactory.cs index 16197370dc..f46b569ed7 100644 --- a/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidatorFactory.cs +++ b/backend/extensions/Squidex.Extensions/Validation/CompositeUniqueValidatorFactory.cs @@ -28,7 +28,7 @@ public IEnumerable CreateContentValidators(ValidationContext context } } - private static IEnumerable ValidatorTags(IEnumerable tags) + private static IEnumerable ValidatorTags(IEnumerable? tags) { if (tags == null) { diff --git a/backend/i18n/frontend_en.json b/backend/i18n/frontend_en.json index 87d927fbdd..0996599b13 100644 --- a/backend/i18n/frontend_en.json +++ b/backend/i18n/frontend_en.json @@ -183,6 +183,22 @@ "clients.connectWizard.cliStep3": "Add your app name the CLI config", "clients.connectWizard.cliStep3Hint": "You can manage configuration to multiple apps in the CLI and switch to an app.", "clients.connectWizard.cliStep4": "Switch to your app in the CLI", + "clients.connectWizard.dotnetSdk": "Use the .NET SDK", + "clients.connectWizard.dotnetSdkDocumentation": "Documentations for the .NET SDK is available: ", + "clients.connectWizard.dotnetSdkHint": "Install the .NET SDK and establish a connection to this app.", + "clients.connectWizard.dotnetSdkStep1": "Install the .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "The SDK is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Version 14 and before: Create a client manager", + "clients.connectWizard.dotnetSdkStep2_15": "Version 15 and later: Create a client", + "clients.connectWizard.dotnetSdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.dotnetSdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.dotnetSdkStep4": "Optionally: Register the client manager and all clients", + "clients.connectWizard.javascriptSdk": "Use the JavaScript SDK", + "clients.connectWizard.javascriptSdkDocumentation": "Documentations for the JavaScript SDK is available: ", + "clients.connectWizard.javascriptSdkHint": "Install the SDK and establish a connection to this app.", + "clients.connectWizard.javascriptSdkStep1": "Install the Javascript SDK", + "clients.connectWizard.javascriptSdkStep1Download": "The SDK is available on [npm](https://www.npmjs.com/package/@squidex/squidex", + "clients.connectWizard.javascriptSdkStep2": "Create a client", "clients.connectWizard.manually": "Connect manually", "clients.connectWizard.manuallyHint": "Get instructions how to establish a connection with Postman or curl.", "clients.connectWizard.manuallyStep1": "Get a token using curl", @@ -190,18 +206,8 @@ "clients.connectWizard.manuallyStep3": "Add the token as HTTP header to all requests", "clients.connectWizard.manuallyTokenHint": "Tokens usally expire after 30days, but you can request multiple tokens.", "clients.connectWizard.postManDocs": "Start with the Postman tutorial in the [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Connect to your App with SDK", - "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "You need another SDK?", "clients.connectWizard.sdkHelpLink": "Contact us in the Support Forum", - "clients.connectWizard.sdkHint": "Download an SDK and establish a connection to this app.", - "clients.connectWizard.sdkStep1": "Install the .NET SDK", - "clients.connectWizard.sdkStep1Download": "The SDK is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Version 14 and before: Create a client manager", - "clients.connectWizard.sdkStep2_15": "Version 15 and later: Create a client", - "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", - "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", - "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Setup client", "clients.connectWizard.step1Title": "Choose connection method", "clients.connectWizard.step2Title": "Connect", @@ -869,6 +875,8 @@ "schemas.fieldTypes.assets.folderId": "Folder", "schemas.fieldTypes.assets.folderIdHint": "The asset folder where the new assets will be uploaded to.", "schemas.fieldTypes.assets.previewFileName": "Only file name", + "schemas.fieldTypes.assets.previewFormat": "Preview Format", + "schemas.fieldTypes.assets.previewFormatHint": "Define custom formatting parameters for preview images. [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/assets-api#how-to-resize-images)", "schemas.fieldTypes.assets.previewImage": "Only thumbnail or file name if not an image", "schemas.fieldTypes.assets.previewImageAndFileName": "Thumbnail and file name", "schemas.fieldTypes.assets.previewMode": "PreviewMode", diff --git a/backend/i18n/frontend_it.json b/backend/i18n/frontend_it.json index 968da7f3f9..d65ddf8d32 100644 --- a/backend/i18n/frontend_it.json +++ b/backend/i18n/frontend_it.json @@ -183,6 +183,22 @@ "clients.connectWizard.cliStep3": "Inserisci il nome della tua app per la configurazione della CLI", "clients.connectWizard.cliStep3Hint": "È possibile gestire le configurazione per le diverse appi all'interno della CLI e passare ad un'app.", "clients.connectWizard.cliStep4": "Passa alla tua app usando CLI", + "clients.connectWizard.dotnetSdk": "Connetti la tua APP utilizzando SDK", + "clients.connectWizard.dotnetSdkDocumentation": "Documentations for the .NET SDK is available: ", + "clients.connectWizard.dotnetSdkHint": "Scarica l'SDK e connetti quest'app.", + "clients.connectWizard.dotnetSdkStep1": "Installa .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "L'SDK è disponibile su [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Crea un client manager", + "clients.connectWizard.dotnetSdkStep2_15": "Version 15 and later: Create a client", + "clients.connectWizard.dotnetSdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.dotnetSdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.dotnetSdkStep4": "Optionally: Register the client manager and all clients", + "clients.connectWizard.javascriptSdk": "Use the JavaScript SDK", + "clients.connectWizard.javascriptSdkDocumentation": "Documentations for the JavaScript SDK is available: ", + "clients.connectWizard.javascriptSdkHint": "Install the SDK and establish a connection to this app.", + "clients.connectWizard.javascriptSdkStep1": "Install the Javascript SDK", + "clients.connectWizard.javascriptSdkStep1Download": "The SDK is available on [npm](https://www.npmjs.com/package/@squidex/squidex", + "clients.connectWizard.javascriptSdkStep2": "Create a client", "clients.connectWizard.manually": "Connetti manualmente", "clients.connectWizard.manuallyHint": "Leggi le istruzioni su come stabilire una connessione utilizzando Postman o curl.", "clients.connectWizard.manuallyStep1": "Ottenere un token usando curl", @@ -190,18 +206,8 @@ "clients.connectWizard.manuallyStep3": "Aggiungi il token come header HTTP header a tutte le richieste", "clients.connectWizard.manuallyTokenHint": "Solitamente i Token scadono dopo 30 giorni, ma puoi richiedere token multipli.", "clients.connectWizard.postManDocs": "Per il tutorial Postman inizia da questo link [Documentazione](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Connetti la tua APP utilizzando SDK", - "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "Hai bisogno di un altro SDK?", "clients.connectWizard.sdkHelpLink": "Contattaci nel Forum di assistenza", - "clients.connectWizard.sdkHint": "Scarica l'SDK e connetti quest'app.", - "clients.connectWizard.sdkStep1": "Installa .NET SDK", - "clients.connectWizard.sdkStep1Download": "L'SDK è disponibile su [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Crea un client manager", - "clients.connectWizard.sdkStep2_15": "Version 15 and later: Create a client", - "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", - "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", - "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Setup client", "clients.connectWizard.step1Title": "Scegli la tipologia di connessione", "clients.connectWizard.step2Title": "Collega", @@ -869,6 +875,8 @@ "schemas.fieldTypes.assets.folderId": "Folder", "schemas.fieldTypes.assets.folderIdHint": "The asset folder where the new assets will be uploaded to.", "schemas.fieldTypes.assets.previewFileName": "Solamente il nome del file", + "schemas.fieldTypes.assets.previewFormat": "Preview Format", + "schemas.fieldTypes.assets.previewFormatHint": "Define custom formatting parameters for preview images. [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/assets-api#how-to-resize-images)", "schemas.fieldTypes.assets.previewImage": "Solamente l'anteprima o il nome del file se non è un immagine", "schemas.fieldTypes.assets.previewImageAndFileName": "L'anteprima e il nome del file", "schemas.fieldTypes.assets.previewMode": "Modalità anteprima", diff --git a/backend/i18n/frontend_nl.json b/backend/i18n/frontend_nl.json index f8e4cb765e..2ecf272b3e 100644 --- a/backend/i18n/frontend_nl.json +++ b/backend/i18n/frontend_nl.json @@ -183,6 +183,22 @@ "clients.connectWizard.cliStep3": "Voeg uw app-naam toe aan de CLI-configuratie", "clients.connectWizard.cliStep3Hint": "Je kunt de configuratie voor meerdere apps in de CLI beheren en overschakelen naar een app.", "clients.connectWizard.cliStep4": "Schakel over naar uw app in de CLI", + "clients.connectWizard.dotnetSdk": "Maak verbinding met uw app met SDK", + "clients.connectWizard.dotnetSdkDocumentation": "Documentations for the .NET SDK is available: ", + "clients.connectWizard.dotnetSdkHint": "Download een SDK en maak verbinding met deze app.", + "clients.connectWizard.dotnetSdkStep1": "Installeer de .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "De SDK is beschikbaar op [nuget] (https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Maak een klantenbeheerder", + "clients.connectWizard.dotnetSdkStep2_15": "Version 15 and later: Create a client", + "clients.connectWizard.dotnetSdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.dotnetSdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.dotnetSdkStep4": "Optionally: Register the client manager and all clients", + "clients.connectWizard.javascriptSdk": "Use the JavaScript SDK", + "clients.connectWizard.javascriptSdkDocumentation": "Documentations for the JavaScript SDK is available: ", + "clients.connectWizard.javascriptSdkHint": "Install the SDK and establish a connection to this app.", + "clients.connectWizard.javascriptSdkStep1": "Install the Javascript SDK", + "clients.connectWizard.javascriptSdkStep1Download": "The SDK is available on [npm](https://www.npmjs.com/package/@squidex/squidex", + "clients.connectWizard.javascriptSdkStep2": "Create a client", "clients.connectWizard.manually": "Handmatig verbinden", "clients.connectWizard.manuallyHint": "Krijg instructies om een ​​verbinding tot stand te brengen met Postman of curl.", "clients.connectWizard.manuallyStep1": "Verkrijg een token met curl", @@ -190,18 +206,8 @@ "clients.connectWizard.manuallyStep3": "Voeg het token toe als HTTP-header aan alle verzoeken", "clients.connectWizard.manuallyTokenHint": "Tokens vervallen gewoonlijk na 30 dagen, maar je kunt meerdere tokens aanvragen.", "clients.connectWizard.postManDocs": "Begin met de Postman-tutorial in de [Documentatie] (https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Maak verbinding met uw app met SDK", - "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "Heb je een andere SDK nodig?", "clients.connectWizard.sdkHelpLink": "Neem contact met ons op in het ondersteuningsforum", - "clients.connectWizard.sdkHint": "Download een SDK en maak verbinding met deze app.", - "clients.connectWizard.sdkStep1": "Installeer de .NET SDK", - "clients.connectWizard.sdkStep1Download": "De SDK is beschikbaar op [nuget] (https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Maak een klantenbeheerder", - "clients.connectWizard.sdkStep2_15": "Version 15 and later: Create a client", - "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", - "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", - "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Client instellen", "clients.connectWizard.step1Title": "Kies verbindingsmethode", "clients.connectWizard.step2Title": "Verbinden", @@ -869,6 +875,8 @@ "schemas.fieldTypes.assets.folderId": "Map", "schemas.fieldTypes.assets.folderIdHint": "De map waarnaar de nieuwe bestanden worden geüpload.", "schemas.fieldTypes.assets.previewFileName": "Alleen bestandsnaam", + "schemas.fieldTypes.assets.previewFormat": "Preview Format", + "schemas.fieldTypes.assets.previewFormatHint": "Define custom formatting parameters for preview images. [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/assets-api#how-to-resize-images)", "schemas.fieldTypes.assets.previewImage": "Alleen miniatuur- of bestandsnaam indien geen afbeelding", "schemas.fieldTypes.assets.previewImageAndFileName": "Miniatuur- en bestandsnaam", "schemas.fieldTypes.assets.previewMode": "PreviewMode", diff --git a/backend/i18n/frontend_pt.json b/backend/i18n/frontend_pt.json index 9b2874b878..532033b4a4 100644 --- a/backend/i18n/frontend_pt.json +++ b/backend/i18n/frontend_pt.json @@ -183,6 +183,22 @@ "clients.connectWizard.cliStep3": "Adicione o nome da sua aplicação ao CLI config", "clients.connectWizard.cliStep3Hint": "Pode gerir a configuração de várias aplicações no CLI e mudar para uma aplicação.", "clients.connectWizard.cliStep4": "Mude para a sua aplicação no CLI", + "clients.connectWizard.dotnetSdk": "Conecte-se à sua App com a SDK", + "clients.connectWizard.dotnetSdkDocumentation": "Documentations for the .NET SDK is available: ", + "clients.connectWizard.dotnetSdkHint": "Descarregue um SDK e estabeleça uma ligação a esta aplicação.", + "clients.connectWizard.dotnetSdkStep1": "Instale o .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "O SDK está disponível em [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Criar um gestor de clientes", + "clients.connectWizard.dotnetSdkStep2_15": "Version 15 and later: Create a client", + "clients.connectWizard.dotnetSdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.dotnetSdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.dotnetSdkStep4": "Optionally: Register the client manager and all clients", + "clients.connectWizard.javascriptSdk": "Use the JavaScript SDK", + "clients.connectWizard.javascriptSdkDocumentation": "Documentations for the JavaScript SDK is available: ", + "clients.connectWizard.javascriptSdkHint": "Install the SDK and establish a connection to this app.", + "clients.connectWizard.javascriptSdkStep1": "Install the Javascript SDK", + "clients.connectWizard.javascriptSdkStep1Download": "The SDK is available on [npm](https://www.npmjs.com/package/@squidex/squidex", + "clients.connectWizard.javascriptSdkStep2": "Create a client", "clients.connectWizard.manually": "Conecte-se manualmente", "clients.connectWizard.manuallyHint": "Obtenha instruções sobre como estabelecer uma ligação com o Carteiro ou o caracol.", "clients.connectWizard.manuallyStep1": "Obter um símbolo usando caracóis", @@ -190,18 +206,8 @@ "clients.connectWizard.manuallyStep3": "Adicione o token como cabeçalho HTTP a todos os pedidos", "clients.connectWizard.manuallyTokenHint": "Tokens normalmente expiram após 30 dias, mas você pode solicitar várias tokens.", "clients.connectWizard.postManDocs": "Comece com o tutorial do Carteiro na [Documentação](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Conecte-se à sua App com a SDK", - "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "Precisa de outro SDK?", "clients.connectWizard.sdkHelpLink": "Contacte-nos no Fórum de Apoio", - "clients.connectWizard.sdkHint": "Descarregue um SDK e estabeleça uma ligação a esta aplicação.", - "clients.connectWizard.sdkStep1": "Instale o .NET SDK", - "clients.connectWizard.sdkStep1Download": "O SDK está disponível em [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Criar um gestor de clientes", - "clients.connectWizard.sdkStep2_15": "Version 15 and later: Create a client", - "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", - "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", - "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Cliente de configuração", "clients.connectWizard.step1Title": "Escolha o método de ligação", "clients.connectWizard.step2Title": "Ligar", @@ -869,6 +875,8 @@ "schemas.fieldTypes.assets.folderId": "Pasta", "schemas.fieldTypes.assets.folderIdHint": "A pasta de ficheiros para onde os novos ficheiros serão carregados.", "schemas.fieldTypes.assets.previewFileName": "Apenas nome de ficheiro", + "schemas.fieldTypes.assets.previewFormat": "Preview Format", + "schemas.fieldTypes.assets.previewFormatHint": "Define custom formatting parameters for preview images. [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/assets-api#how-to-resize-images)", "schemas.fieldTypes.assets.previewImage": "Apenas miniatura ou nome de ficheiro se não uma imagem", "schemas.fieldTypes.assets.previewImageAndFileName": "Miniatura e nome do ficheiro", "schemas.fieldTypes.assets.previewMode": "Pré-visualizaçãoMode", diff --git a/backend/i18n/frontend_zh.json b/backend/i18n/frontend_zh.json index 9f29552f2a..ebeb592317 100644 --- a/backend/i18n/frontend_zh.json +++ b/backend/i18n/frontend_zh.json @@ -183,6 +183,22 @@ "clients.connectWizard.cliStep3": "在 CLI 配置中添加你的应用名称", "clients.connectWizard.cliStep3Hint": "您可以在 CLI 中管理多个应用程序的配置并切换到一个应用程序。", "clients.connectWizard.cliStep4": "在 CLI 中切换到您的应用程序", + "clients.connectWizard.dotnetSdk": "使用 SDK 连接到您的应用程序", + "clients.connectWizard.dotnetSdkDocumentation": "Documentations for the .NET SDK is available: ", + "clients.connectWizard.dotnetSdkHint": "下载 SDK 并建立与此应用程序的连接。", + "clients.connectWizard.dotnetSdkStep1": "安装.NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "SDK 可在 [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "创建客户端管理器", + "clients.connectWizard.dotnetSdkStep2_15": "Version 15 and later: Create a client", + "clients.connectWizard.dotnetSdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.dotnetSdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.dotnetSdkStep4": "Optionally: Register the client manager and all clients", + "clients.connectWizard.javascriptSdk": "Use the JavaScript SDK", + "clients.connectWizard.javascriptSdkDocumentation": "Documentations for the JavaScript SDK is available: ", + "clients.connectWizard.javascriptSdkHint": "Install the SDK and establish a connection to this app.", + "clients.connectWizard.javascriptSdkStep1": "Install the Javascript SDK", + "clients.connectWizard.javascriptSdkStep1Download": "The SDK is available on [npm](https://www.npmjs.com/package/@squidex/squidex", + "clients.connectWizard.javascriptSdkStep2": "Create a client", "clients.connectWizard.manually": "手动连接", "clients.connectWizard.manuallyHint": "获取如何与 Postman 或 curl 建立连接的说明。", "clients.connectWizard.manuallyStep1": "使用 curl 获取令牌", @@ -190,18 +206,8 @@ "clients.connectWizard.manuallyStep3": "将令牌作为 HTTP 标头添加到所有请求中", "clients.connectWizard.manuallyTokenHint": "令牌通常会在 30 天后过期,但您可以请求多个令牌。", "clients.connectWizard.postManDocs": "从 [文档](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman) 中的 Postman 教程开始。", - "clients.connectWizard.sdk": "使用 SDK 连接到您的应用程序", - "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "你需要另一个 SDK?", "clients.connectWizard.sdkHelpLink": "在支持论坛联系我们", - "clients.connectWizard.sdkHint": "下载 SDK 并建立与此应用程序的连接。", - "clients.connectWizard.sdkStep1": "安装.NET SDK", - "clients.connectWizard.sdkStep1Download": "SDK 可在 [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "创建客户端管理器", - "clients.connectWizard.sdkStep2_15": "Version 15 and later: Create a client", - "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", - "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", - "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "设置客户端", "clients.connectWizard.step1Title": "选择连接方式", "clients.connectWizard.step2Title": "连接", @@ -869,6 +875,8 @@ "schemas.fieldTypes.assets.folderId": "文件夹", "schemas.fieldTypes.assets.folderIdHint": "新资源将上传到的资源文件夹。", "schemas.fieldTypes.assets.previewFileName": "仅文件名", + "schemas.fieldTypes.assets.previewFormat": "Preview Format", + "schemas.fieldTypes.assets.previewFormatHint": "Define custom formatting parameters for preview images. [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/assets-api#how-to-resize-images)", "schemas.fieldTypes.assets.previewImage": "如果不是图像,则只有缩略图或文件名", "schemas.fieldTypes.assets.previewImageAndFileName": "缩略图和文件名", "schemas.fieldTypes.assets.previewMode": "PreviewMode", diff --git a/backend/i18n/source/frontend_en.json b/backend/i18n/source/frontend_en.json index 87d927fbdd..147d0e57c5 100644 --- a/backend/i18n/source/frontend_en.json +++ b/backend/i18n/source/frontend_en.json @@ -183,6 +183,22 @@ "clients.connectWizard.cliStep3": "Add your app name the CLI config", "clients.connectWizard.cliStep3Hint": "You can manage configuration to multiple apps in the CLI and switch to an app.", "clients.connectWizard.cliStep4": "Switch to your app in the CLI", + "clients.connectWizard.dotnetSdk": "Use the .NET SDK", + "clients.connectWizard.dotnetSdkDocumentation": "Documentations for the .NET SDK is available: ", + "clients.connectWizard.dotnetSdkHint": "Install the .NET SDK and establish a connection to this app.", + "clients.connectWizard.dotnetSdkStep1": "Install the .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "The SDK is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Version 14 and before: Create a client manager", + "clients.connectWizard.dotnetSdkStep2_15": "Version 15 and later: Create a client", + "clients.connectWizard.dotnetSdkStep3": "Optionally: Install the Service Extensions for the SDK", + "clients.connectWizard.dotnetSdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", + "clients.connectWizard.dotnetSdkStep4": "Optionally: Register the client manager and all clients", + "clients.connectWizard.javascriptSdk": "Use the JavaScript SDK", + "clients.connectWizard.javascriptSdkDocumentation": "Documentations for the JavaScript SDK is available: ", + "clients.connectWizard.javascriptSdkHint": "Install the SDK and establish a connection to this app.", + "clients.connectWizard.javascriptSdkStep1": "Install the Javascript SDK", + "clients.connectWizard.javascriptSdkStep1Download": "The SDK is available on [npm](https://www.npmjs.com/package/@squidex/squidex)", + "clients.connectWizard.javascriptSdkStep2": "Create a client", "clients.connectWizard.manually": "Connect manually", "clients.connectWizard.manuallyHint": "Get instructions how to establish a connection with Postman or curl.", "clients.connectWizard.manuallyStep1": "Get a token using curl", @@ -190,18 +206,8 @@ "clients.connectWizard.manuallyStep3": "Add the token as HTTP header to all requests", "clients.connectWizard.manuallyTokenHint": "Tokens usally expire after 30days, but you can request multiple tokens.", "clients.connectWizard.postManDocs": "Start with the Postman tutorial in the [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Connect to your App with SDK", - "clients.connectWizard.sdkDocumentation": "Documentations for the .NET SDK is available: ", "clients.connectWizard.sdkHelp": "You need another SDK?", "clients.connectWizard.sdkHelpLink": "Contact us in the Support Forum", - "clients.connectWizard.sdkHint": "Download an SDK and establish a connection to this app.", - "clients.connectWizard.sdkStep1": "Install the .NET SDK", - "clients.connectWizard.sdkStep1Download": "The SDK is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Version 14 and before: Create a client manager", - "clients.connectWizard.sdkStep2_15": "Version 15 and later: Create a client", - "clients.connectWizard.sdkStep3": "Optionally: Install the Service Extensions for the SDK", - "clients.connectWizard.sdkStep3Download": "The SDK Extension is available on [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary.ServiceExtensions/)", - "clients.connectWizard.sdkStep4": "Optionally: Register the client manager and all clients", "clients.connectWizard.step0Title": "Setup client", "clients.connectWizard.step1Title": "Choose connection method", "clients.connectWizard.step2Title": "Connect", @@ -869,6 +875,8 @@ "schemas.fieldTypes.assets.folderId": "Folder", "schemas.fieldTypes.assets.folderIdHint": "The asset folder where the new assets will be uploaded to.", "schemas.fieldTypes.assets.previewFileName": "Only file name", + "schemas.fieldTypes.assets.previewFormat": "Preview Format", + "schemas.fieldTypes.assets.previewFormatHint": "Define custom formatting parameters for preview images. [Documentation](https://docs.squidex.io/02-documentation/developer-guides/api-overview/assets-api#how-to-resize-images)", "schemas.fieldTypes.assets.previewImage": "Only thumbnail or file name if not an image", "schemas.fieldTypes.assets.previewImageAndFileName": "Thumbnail and file name", "schemas.fieldTypes.assets.previewMode": "PreviewMode", diff --git a/backend/i18n/source/frontend_it.json b/backend/i18n/source/frontend_it.json index dd30806ffc..db23907a4e 100644 --- a/backend/i18n/source/frontend_it.json +++ b/backend/i18n/source/frontend_it.json @@ -147,6 +147,11 @@ "clients.connectWizard.cliStep3": "Inserisci il nome della tua app per la configurazione della CLI", "clients.connectWizard.cliStep3Hint": "È possibile gestire le configurazione per le diverse appi all'interno della CLI e passare ad un'app.", "clients.connectWizard.cliStep4": "Passa alla tua app usando CLI", + "clients.connectWizard.dotnetSdk": "Connetti la tua APP utilizzando SDK", + "clients.connectWizard.dotnetSdkHint": "Scarica l'SDK e connetti quest'app.", + "clients.connectWizard.dotnetSdkStep1": "Installa .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "L'SDK è disponibile su [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Crea un client manager", "clients.connectWizard.manually": "Connetti manualmente", "clients.connectWizard.manuallyHint": "Leggi le istruzioni su come stabilire una connessione utilizzando Postman o curl.", "clients.connectWizard.manuallyStep1": "Ottenere un token usando curl", @@ -154,13 +159,8 @@ "clients.connectWizard.manuallyStep3": "Aggiungi il token come header HTTP header a tutte le richieste", "clients.connectWizard.manuallyTokenHint": "Solitamente i Token scadono dopo 30 giorni, ma puoi richiedere token multipli.", "clients.connectWizard.postManDocs": "Per il tutorial Postman inizia da questo link [Documentazione](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Connetti la tua APP utilizzando SDK", "clients.connectWizard.sdkHelp": "Hai bisogno di un altro SDK?", "clients.connectWizard.sdkHelpLink": "Contattaci nel Forum di assistenza", - "clients.connectWizard.sdkHint": "Scarica l'SDK e connetti quest'app.", - "clients.connectWizard.sdkStep1": "Installa .NET SDK", - "clients.connectWizard.sdkStep1Download": "L'SDK è disponibile su [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Crea un client manager", "clients.connectWizard.step0Title": "Setup client", "clients.connectWizard.step1Title": "Scegli la tipologia di connessione", "clients.connectWizard.step2Title": "Collega", diff --git a/backend/i18n/source/frontend_nl.json b/backend/i18n/source/frontend_nl.json index 634b61e40e..8ac3cb7d1a 100644 --- a/backend/i18n/source/frontend_nl.json +++ b/backend/i18n/source/frontend_nl.json @@ -169,6 +169,11 @@ "clients.connectWizard.cliStep3": "Voeg uw app-naam toe aan de CLI-configuratie", "clients.connectWizard.cliStep3Hint": "Je kunt de configuratie voor meerdere apps in de CLI beheren en overschakelen naar een app.", "clients.connectWizard.cliStep4": "Schakel over naar uw app in de CLI", + "clients.connectWizard.dotnetSdk": "Maak verbinding met uw app met SDK", + "clients.connectWizard.dotnetSdkHint": "Download een SDK en maak verbinding met deze app.", + "clients.connectWizard.dotnetSdkStep1": "Installeer de .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "De SDK is beschikbaar op [nuget] (https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Maak een klantenbeheerder", "clients.connectWizard.manually": "Handmatig verbinden", "clients.connectWizard.manuallyHint": "Krijg instructies om een ​​verbinding tot stand te brengen met Postman of curl.", "clients.connectWizard.manuallyStep1": "Verkrijg een token met curl", @@ -176,13 +181,8 @@ "clients.connectWizard.manuallyStep3": "Voeg het token toe als HTTP-header aan alle verzoeken", "clients.connectWizard.manuallyTokenHint": "Tokens vervallen gewoonlijk na 30 dagen, maar je kunt meerdere tokens aanvragen.", "clients.connectWizard.postManDocs": "Begin met de Postman-tutorial in de [Documentatie] (https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Maak verbinding met uw app met SDK", "clients.connectWizard.sdkHelp": "Heb je een andere SDK nodig?", "clients.connectWizard.sdkHelpLink": "Neem contact met ons op in het ondersteuningsforum", - "clients.connectWizard.sdkHint": "Download een SDK en maak verbinding met deze app.", - "clients.connectWizard.sdkStep1": "Installeer de .NET SDK", - "clients.connectWizard.sdkStep1Download": "De SDK is beschikbaar op [nuget] (https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Maak een klantenbeheerder", "clients.connectWizard.step0Title": "Client instellen", "clients.connectWizard.step1Title": "Kies verbindingsmethode", "clients.connectWizard.step2Title": "Verbinden", diff --git a/backend/i18n/source/frontend_pt.json b/backend/i18n/source/frontend_pt.json index 3af5086180..ca7e976b5e 100644 --- a/backend/i18n/source/frontend_pt.json +++ b/backend/i18n/source/frontend_pt.json @@ -180,6 +180,11 @@ "clients.connectWizard.cliStep3": "Adicione o nome da sua aplicação ao CLI config", "clients.connectWizard.cliStep3Hint": "Pode gerir a configuração de várias aplicações no CLI e mudar para uma aplicação.", "clients.connectWizard.cliStep4": "Mude para a sua aplicação no CLI", + "clients.connectWizard.dotnetSdk": "Conecte-se à sua App com a SDK", + "clients.connectWizard.dotnetSdkHint": "Descarregue um SDK e estabeleça uma ligação a esta aplicação.", + "clients.connectWizard.dotnetSdkStep1": "Instale o .NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "O SDK está disponível em [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "Criar um gestor de clientes", "clients.connectWizard.manually": "Conecte-se manualmente", "clients.connectWizard.manuallyHint": "Obtenha instruções sobre como estabelecer uma ligação com o Carteiro ou o caracol.", "clients.connectWizard.manuallyStep1": "Obter um símbolo usando caracóis", @@ -187,13 +192,8 @@ "clients.connectWizard.manuallyStep3": "Adicione o token como cabeçalho HTTP a todos os pedidos", "clients.connectWizard.manuallyTokenHint": "Tokens normalmente expiram após 30 dias, mas você pode solicitar várias tokens.", "clients.connectWizard.postManDocs": "Comece com o tutorial do Carteiro na [Documentação](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman).", - "clients.connectWizard.sdk": "Conecte-se à sua App com a SDK", "clients.connectWizard.sdkHelp": "Precisa de outro SDK?", "clients.connectWizard.sdkHelpLink": "Contacte-nos no Fórum de Apoio", - "clients.connectWizard.sdkHint": "Descarregue um SDK e estabeleça uma ligação a esta aplicação.", - "clients.connectWizard.sdkStep1": "Instale o .NET SDK", - "clients.connectWizard.sdkStep1Download": "O SDK está disponível em [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "Criar um gestor de clientes", "clients.connectWizard.step0Title": "Cliente de configuração", "clients.connectWizard.step1Title": "Escolha o método de ligação", "clients.connectWizard.step2Title": "Ligar", diff --git a/backend/i18n/source/frontend_zh.json b/backend/i18n/source/frontend_zh.json index ea3a1b62c5..64fac28ba3 100644 --- a/backend/i18n/source/frontend_zh.json +++ b/backend/i18n/source/frontend_zh.json @@ -157,6 +157,11 @@ "clients.connectWizard.cliStep3": "在 CLI 配置中添加你的应用名称", "clients.connectWizard.cliStep3Hint": "您可以在 CLI 中管理多个应用程序的配置并切换到一个应用程序。", "clients.connectWizard.cliStep4": "在 CLI 中切换到您的应用程序", + "clients.connectWizard.dotnetSdk": "使用 SDK 连接到您的应用程序", + "clients.connectWizard.dotnetSdkHint": "下载 SDK 并建立与此应用程序的连接。", + "clients.connectWizard.dotnetSdkStep1": "安装.NET SDK", + "clients.connectWizard.dotnetSdkStep1Download": "SDK 可在 [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", + "clients.connectWizard.dotnetSdkStep2": "创建客户端管理器", "clients.connectWizard.manually": "手动连接", "clients.connectWizard.manuallyHint": "获取如何与 Postman 或 curl 建立连接的说明。", "clients.connectWizard.manuallyStep1": "使用 curl 获取令牌", @@ -164,13 +169,8 @@ "clients.connectWizard.manuallyStep3": "将令牌作为 HTTP 标头添加到所有请求中", "clients.connectWizard.manuallyTokenHint": "令牌通常会在 30 天后过期,但您可以请求多个令牌。", "clients.connectWizard.postManDocs": "从 [文档](https://docs.squidex.io/02-documentation/developer-guides/api-overview/postman) 中的 Postman 教程开始。", - "clients.connectWizard.sdk": "使用 SDK 连接到您的应用程序", "clients.connectWizard.sdkHelp": "你需要另一个 SDK?", "clients.connectWizard.sdkHelpLink": "在支持论坛联系我们", - "clients.connectWizard.sdkHint": "下载 SDK 并建立与此应用程序的连接。", - "clients.connectWizard.sdkStep1": "安装.NET SDK", - "clients.connectWizard.sdkStep1Download": "SDK 可在 [nuget](https://www.nuget.org/packages/Squidex.ClientLibrary/)", - "clients.connectWizard.sdkStep2": "创建客户端管理器", "clients.connectWizard.step0Title": "设置客户端", "clients.connectWizard.step1Title": "选择连接方式", "clients.connectWizard.step2Title": "连接", diff --git a/backend/src/Migrations/OldEvents/SchemaCreated.cs b/backend/src/Migrations/OldEvents/SchemaCreated.cs index 5133029c0f..dc543d767f 100644 --- a/backend/src/Migrations/OldEvents/SchemaCreated.cs +++ b/backend/src/Migrations/OldEvents/SchemaCreated.cs @@ -32,7 +32,11 @@ public sealed class SchemaCreated : SchemaEvent, IMigrated public IEvent Migrate() { - var schema = new Schema(Name, Properties, Singleton ? SchemaType.Singleton : SchemaType.Default); + var type = Singleton ? + SchemaType.Singleton : + SchemaType.Default; + + var schema = new Schema(Name, Properties, type); if (Publish) { diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs index 1f3fbc9aff..dbf9856360 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs @@ -20,6 +20,8 @@ public sealed record AssetsFieldProperties : FieldProperties public string? FolderId { get; init; } + public string? PreviewFormat { get; set; } + public int? MinItems { get; init; } public int? MaxItems { get; init; } diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/IConverter.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/IConverter.cs index 4b66dca4c0..0827a1b41e 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/IConverter.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/IConverter.cs @@ -8,7 +8,6 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Json.Objects; -using static Google.Rpc.Context.AttributeContext.Types; #pragma warning disable MA0048 // File name must match type name diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs index 7e9fdc2362..895c2dbec7 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs @@ -46,7 +46,7 @@ protected virtual string ToEnvelopeJson(EnrichedEvent @event) return formatter.FormatAsync(uri.ToString(), @event); } - protected ValueTask FormatAsync(string text, EnrichedEvent @event) + protected ValueTask FormatAsync(string? text, EnrichedEvent @event) { return formatter.FormatAsync(text, @event); } diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs index 410b356e74..70587d8ad0 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs @@ -96,7 +96,7 @@ public virtual string ToEnvelope(string type, object payload, Instant timestamp) return serializer.Serialize(new { type, payload, timestamp }, true); } - public async ValueTask FormatAsync(string text, EnrichedEvent @event) + public async ValueTask FormatAsync(string? text, EnrichedEvent @event) { if (string.IsNullOrWhiteSpace(text)) { diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs index 39f2f1ecfa..4da26991a9 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Assets/Visitors/FindExtensions.cs @@ -47,10 +47,9 @@ public static (FilterDefinition, bool) BuildFilter(this ClrQue var isDefault = false; - if (!query.HasFilterField("IsDeleted")) + if (query.Filter?.HasField("IsDeleted") != true) { filters.Add(Filter.Ne(x => x.IsDeleted, true)); - isDefault = true; } diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs index a0ddc16e02..9d637ad2fb 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs @@ -11,6 +11,7 @@ using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.MongoDb; using Squidex.Infrastructure.MongoDb.Queries; using Squidex.Infrastructure.Queries; @@ -136,7 +137,7 @@ private static FilterDefinition BuildFilter(DomainId appId, Filter.Eq(x => x.IndexedSchemaId, schemaId) }; - if (filter?.HasField("dl") != true) + if (filter?.HasField(Field.Of(x => nameof(x.IsDeleted))) != true) { filters.Add(Filter.Ne(x => x.IsDeleted, true)); } @@ -162,31 +163,27 @@ private static (FilterDefinition, bool) CreateFilter(DomainI var isDefault = false; - if (query?.HasFilterField("dl") != true) + if (query?.Filter?.HasField(Field.Of(x => nameof(x.IsDeleted))) != true) { filters.Add(Filter.Ne(x => x.IsDeleted, true)); - isDefault = true; } if (query?.Filter != null) { filters.Add(query.Filter.BuildFilter()); - isDefault = false; } if (reference != default) { filters.Add(Filter.AnyEq(x => x.ReferencedIds, reference)); - isDefault = false; } if (createdBy != null) { filters.Add(Filter.Eq(x => x.CreatedBy, createdBy)); - isDefault = false; } diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryInDedicatedCollection.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryInDedicatedCollection.cs index 49cb125b21..df2c1cf3b8 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryInDedicatedCollection.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryInDedicatedCollection.cs @@ -151,7 +151,7 @@ private static FilterDefinition BuildFilter(FilterNode x.Id) }; - if (filter?.HasField("dl") != true) + if (filter?.HasField(Field.Of(x => nameof(x.IsDeleted))) != true) { filters.Add(Filter.Ne(x => x.IsDeleted, true)); } @@ -173,7 +173,7 @@ private static FilterDefinition CreateFilter(ClrQuery? query Filter.Gt(x => x.Id, default) }; - if (query?.HasFilterField("dl") != true) + if (query?.Filter?.HasField(Field.Of(x => nameof(x.IsDeleted))) != true) { filters.Add(Filter.Ne(x => x.IsDeleted, true)); } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetExtensions.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetHeaders.cs similarity index 87% rename from backend/src/Squidex.Domain.Apps.Entities/Assets/AssetExtensions.cs rename to backend/src/Squidex.Domain.Apps.Entities/Assets/AssetHeaders.cs index e7798fdd38..9e295ed373 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetHeaders.cs @@ -7,9 +7,9 @@ namespace Squidex.Domain.Apps.Entities.Assets; -public static class AssetExtensions +public static class AssetHeaders { - private const string HeaderNoEnrichment = "X-NoAssetEnrichment"; + public const string HeaderNoEnrichment = "X-NoAssetEnrichment"; public static bool ShouldSkipAssetEnrichment(this Context context) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreProcessor.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreProcessor.cs index 80b888bbfe..a63df4939d 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreProcessor.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/RestoreProcessor.cs @@ -139,6 +139,7 @@ private async Task ProcessAsync(Run run, await LogAsync(run, " * Restore events and attachments."); await LogAsync(run, " * Restore all objects like app, schemas and contents"); await LogAsync(run, " * Complete the restore operation for all objects"); + await LogFlushAsync(run); log.LogInformation("Backup with job id {backupId} with from URL '{url}' started.", run.Job.Id, run.Job.Url); @@ -430,7 +431,7 @@ private Task SetStatusAsync(Run run, JobStatus status, string message) run.Job.Log.Add($"{now}: {message}"); - return state.WriteAsync(ct: default); + return state.WriteAsync(default); } private Task LogAsync(Run run, string message, bool replace = false) @@ -448,4 +449,9 @@ private Task LogAsync(Run run, string message, bool replace = false) return state.WriteAsync(100, run.CancellationToken); } + + private Task LogFlushAsync(Run run) + { + return state.WriteAsync(run.CancellationToken); + } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentExtensions.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentHeaders.cs similarity index 61% rename from backend/src/Squidex.Domain.Apps.Entities/Contents/ContentExtensions.cs rename to backend/src/Squidex.Domain.Apps.Entities/Contents/ContentHeaders.cs index 6901765b90..e7ccca8a6c 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentHeaders.cs @@ -13,28 +13,29 @@ namespace Squidex.Domain.Apps.Entities.Contents; -public static class ContentExtensions +public static class ContentHeaders { - private const string HeaderFlatten = "X-Flatten"; - private const string HeaderLanguages = "X-Languages"; - private const string HeaderNoCleanup = "X-NoCleanup"; - private const string HeaderNoEnrichment = "X-NoEnrichment"; - private const string HeaderNoResolveLanguages = "X-NoResolveLanguages"; - private const string HeaderResolveFlow = "X-ResolveFlow"; - private const string HeaderResolveUrls = "X-Resolve-Urls"; - private const string HeaderUnpublished = "X-Unpublished"; private static readonly char[] Separators = { ',', ';' }; + public const string Flatten = "X-Flatten"; + public const string Languages = "X-Languages"; + public const string NoCleanup = "X-NoCleanup"; + public const string NoEnrichment = "X-NoEnrichment"; + public const string NoResolveLanguages = "X-NoResolveLanguages"; + public const string ResolveFlow = "X-ResolveFlow"; + public const string ResolveUrls = "X-Resolve-Urls"; + public const string Unpublished = "X-Unpublished"; + public static void AddCacheHeaders(this Context context, IRequestCache cache) { - cache.AddHeader(HeaderFlatten); - cache.AddHeader(HeaderLanguages); - cache.AddHeader(HeaderNoCleanup); - cache.AddHeader(HeaderNoEnrichment); - cache.AddHeader(HeaderNoResolveLanguages); - cache.AddHeader(HeaderResolveFlow); - cache.AddHeader(HeaderResolveUrls); - cache.AddHeader(HeaderUnpublished); + cache.AddHeader(Flatten); + cache.AddHeader(Languages); + cache.AddHeader(NoCleanup); + cache.AddHeader(NoEnrichment); + cache.AddHeader(NoResolveLanguages); + cache.AddHeader(ResolveFlow); + cache.AddHeader(ResolveUrls); + cache.AddHeader(Unpublished); } public static Status EditingStatus(this IContentEntity content) @@ -54,67 +55,67 @@ public static SearchScope Scope(this Context context) public static bool ShouldSkipCleanup(this Context context) { - return context.Headers.ContainsKey(HeaderNoCleanup); + return context.Headers.ContainsKey(NoCleanup); } public static ICloneBuilder WithoutCleanup(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderNoCleanup, value); + return builder.WithBoolean(NoCleanup, value); } public static bool ShouldSkipContentEnrichment(this Context context) { - return context.Headers.ContainsKey(HeaderNoEnrichment); + return context.Headers.ContainsKey(NoEnrichment); } public static ICloneBuilder WithoutContentEnrichment(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderNoEnrichment, value); + return builder.WithBoolean(NoEnrichment, value); } public static bool ShouldProvideUnpublished(this Context context) { - return context.Headers.ContainsKey(HeaderUnpublished); + return context.Headers.ContainsKey(Unpublished); } public static ICloneBuilder WithUnpublished(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderUnpublished, value); + return builder.WithBoolean(Unpublished, value); } public static bool ShouldFlatten(this Context context) { - return context.Headers.ContainsKey(HeaderFlatten); + return context.Headers.ContainsKey(Flatten); } public static ICloneBuilder WithFlatten(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderFlatten, value); + return builder.WithBoolean(Flatten, value); } public static bool ShouldResolveFlow(this Context context) { - return context.Headers.ContainsKey(HeaderResolveFlow); + return context.Headers.ContainsKey(ResolveFlow); } public static ICloneBuilder WithResolveFlow(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderResolveFlow, value); + return builder.WithBoolean(ResolveFlow, value); } public static bool ShouldResolveLanguages(this Context context) { - return !context.Headers.ContainsKey(HeaderNoResolveLanguages); + return !context.Headers.ContainsKey(NoResolveLanguages); } public static ICloneBuilder WithoutResolveLanguages(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderNoResolveLanguages, value); + return builder.WithBoolean(NoResolveLanguages, value); } public static IEnumerable AssetUrls(this Context context) { - if (context.Headers.TryGetValue(HeaderResolveUrls, out var value)) + if (context.Headers.TryGetValue(ResolveUrls, out var value)) { return value.Split(Separators, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToHashSet(); } @@ -124,12 +125,12 @@ public static IEnumerable AssetUrls(this Context context) public static ICloneBuilder WithAssetUrlsToResolve(this ICloneBuilder builder, IEnumerable? fieldNames) { - return builder.WithStrings(HeaderResolveUrls, fieldNames); + return builder.WithStrings(ResolveUrls, fieldNames); } - public static IEnumerable Languages(this Context context) + public static IEnumerable LanguageList(this Context context) { - if (context.Headers.TryGetValue(HeaderLanguages, out var value)) + if (context.Headers.TryGetValue(Languages, out var value)) { var languages = new HashSet(); @@ -146,6 +147,6 @@ public static IEnumerable Languages(this Context context) public static ICloneBuilder WithLanguages(this ICloneBuilder builder, IEnumerable fieldNames) { - return builder.WithStrings(HeaderLanguages, fieldNames); + return builder.WithStrings(Languages, fieldNames); } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs index d2df0ea64f..e01ba8f2f8 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs @@ -136,7 +136,7 @@ private ContentConverter GenerateConverter(Context context, ResolvedComponents c converter.Add( new ResolveLanguages( context.App.Languages, - context.Languages().ToArray()) + context.LanguageList().ToArray()) { ResolveFallback = !context.IsFrontendClient && context.ShouldResolveLanguages() }); diff --git a/backend/src/Squidex.Domain.Apps.Entities/ContextExtensions.cs b/backend/src/Squidex.Domain.Apps.Entities/ContextHeaders.cs similarity index 69% rename from backend/src/Squidex.Domain.Apps.Entities/ContextExtensions.cs rename to backend/src/Squidex.Domain.Apps.Entities/ContextHeaders.cs index a5e30e5aff..36e6fb9f50 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/ContextExtensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/ContextHeaders.cs @@ -7,51 +7,51 @@ namespace Squidex.Domain.Apps.Entities; -public static class ContextExtensions +public static class ContextHeaders { - private const string HeaderNoTotal = "X-NoTotal"; - private const string HeaderNoSlowTotal = "X-NoSlowTotal"; - private const string HeaderNoCacheKeys = "X-NoCacheKeys"; - private const string HeaderNoScripting = "X-NoScripting"; + public const string NoTotal = "X-NoTotal"; + public const string NoSlowTotal = "X-NoSlowTotal"; + public const string NoCacheKeys = "X-NoCacheKeys"; + public const string NoScripting = "X-NoScripting"; public static bool ShouldSkipCacheKeys(this Context context) { - return context.Headers.ContainsKey(HeaderNoCacheKeys); + return context.Headers.ContainsKey(NoCacheKeys); } public static ICloneBuilder WithoutCacheKeys(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderNoCacheKeys, value); + return builder.WithBoolean(NoCacheKeys, value); } public static bool ShouldSkipScripting(this Context context) { - return context.Headers.ContainsKey(HeaderNoScripting); + return context.Headers.ContainsKey(NoScripting); } public static ICloneBuilder WithoutScripting(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderNoScripting, value); + return builder.WithBoolean(NoScripting, value); } public static bool ShouldSkipTotal(this Context context) { - return context.Headers.ContainsKey(HeaderNoTotal); + return context.Headers.ContainsKey(NoTotal); } public static ICloneBuilder WithoutTotal(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderNoTotal, value); + return builder.WithBoolean(NoTotal, value); } public static bool ShouldSkipSlowTotal(this Context context) { - return context.Headers.ContainsKey(HeaderNoSlowTotal); + return context.Headers.ContainsKey(NoSlowTotal); } public static ICloneBuilder WithoutSlowTotal(this ICloneBuilder builder, bool value = true) { - return builder.WithBoolean(HeaderNoSlowTotal, value); + return builder.WithBoolean(NoSlowTotal, value); } public static ICloneBuilder WithBoolean(this ICloneBuilder builder, string key, bool value) diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterBuilder.cs b/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterBuilder.cs index e22b670faa..eae715222d 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterBuilder.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/Queries/FilterBuilder.cs @@ -7,28 +7,27 @@ using MongoDB.Driver; using Squidex.Infrastructure.Queries; -using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.Validation; namespace Squidex.Infrastructure.MongoDb.Queries; public static class FilterBuilder { - public static (FilterDefinition? Filter, bool Last) BuildFilter(this ClrQuery query, bool supportsSearch = true) + public static (FilterDefinition? Filter, bool Last) BuildFilter(this ClrQuery query, bool supportsSearch = true) { if (query.FullText != null) { if (!supportsSearch) { - throw new ValidationException(T.Get("common.fullTextNotSupported")); + throw new ValidationException(Translations.T.Get("common.fullTextNotSupported")); } - return (Builders.Filter.Text(query.FullText), false); + return (Builders.Filter.Text(query.FullText), false); } if (query.Filter != null) { - return (query.Filter.BuildFilter(), true); + return (query.Filter.BuildFilter(), true); } return (null, false); diff --git a/backend/src/Squidex.Infrastructure/Queries/QueryExtensions.cs b/backend/src/Squidex.Infrastructure/Queries/QueryExtensions.cs index 9e1388d912..fc75ea1b45 100644 --- a/backend/src/Squidex.Infrastructure/Queries/QueryExtensions.cs +++ b/backend/src/Squidex.Infrastructure/Queries/QueryExtensions.cs @@ -9,11 +9,6 @@ namespace Squidex.Infrastructure.Queries; public static class QueryExtensions { - public static bool HasFilterField(this Query? query, string field) - { - return HasField(query?.Filter, field); - } - public static bool HasField(this FilterNode? filter, string field) { if (filter == null) diff --git a/backend/src/Squidex.Infrastructure/Queries/SortNode.cs b/backend/src/Squidex.Infrastructure/Queries/SortNode.cs index dcc8e168e8..f131cd8f07 100644 --- a/backend/src/Squidex.Infrastructure/Queries/SortNode.cs +++ b/backend/src/Squidex.Infrastructure/Queries/SortNode.cs @@ -7,6 +7,8 @@ namespace Squidex.Infrastructure.Queries; +#pragma warning disable SA1313 // Parameter names should begin with lower-case letter + public sealed record SortNode(PropertyPath Path, SortOrder Order) { public override string ToString() diff --git a/backend/src/Squidex.Web/ApiExceptionConverter.cs b/backend/src/Squidex.Web/ApiExceptionConverter.cs index 372f0170e9..e02907c238 100644 --- a/backend/src/Squidex.Web/ApiExceptionConverter.cs +++ b/backend/src/Squidex.Web/ApiExceptionConverter.cs @@ -142,7 +142,7 @@ private static (ErrorDto Error, Exception? Unhandled) CreateError(Exception exce private static ErrorDto CreateError(int status, string? message = null, string? errorCode = null, IEnumerable? details = null) { - var error = new ErrorDto { StatusCode = status, Message = message }; + var error = new ErrorDto { StatusCode = status, Message = message ?? string.Empty }; if (!string.IsNullOrWhiteSpace(errorCode)) { diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptHeaderAttribute.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptHeaderAttribute.cs new file mode 100644 index 0000000000..3694b02570 --- /dev/null +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptHeaderAttribute.cs @@ -0,0 +1,96 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using NJsonSchema; +using NSwag; +using NSwag.Annotations; +using NSwag.Generation.Processors; +using NSwag.Generation.Processors.Contexts; +using Squidex.Domain.Apps.Entities; +using Squidex.Domain.Apps.Entities.Contents; + +#pragma warning disable MA0048 // File name must match type name + +namespace Squidex.Areas.Api.Config.OpenApi; + +public sealed class AcceptHeader_Unpublished : AcceptHeaderAttribute +{ + public AcceptHeader_Unpublished() + : base(ContentHeaders.Unpublished, "Return unpublished content items.", JsonObjectType.Boolean) + { + } +} + +public sealed class AcceptHeader_Flatten : AcceptHeaderAttribute +{ + public AcceptHeader_Flatten() + : base(ContentHeaders.Flatten, "Provide the data as flat object.", JsonObjectType.Boolean) + { + } +} + +public sealed class AcceptHeader_Languages : AcceptHeaderAttribute +{ + public AcceptHeader_Languages() + : base(ContentHeaders.Languages, "Only resolve these languages (comma-separated).") + { + } +} + +public sealed class AcceptHeader_NoTotal : AcceptHeaderAttribute +{ + public AcceptHeader_NoTotal() + : base(ContextHeaders.NoTotal, "Do not return the total amount.", JsonObjectType.Boolean) + { + } +} + +public sealed class AcceptHeader_NoSlowTotal : AcceptHeaderAttribute +{ + public AcceptHeader_NoSlowTotal() + : base(ContextHeaders.NoSlowTotal, "Do not return the total amount, if it would be slow.", JsonObjectType.Boolean) + { + } +} + +public class AcceptHeaderAttribute : OpenApiOperationProcessorAttribute +{ + public AcceptHeaderAttribute(string name, string description, JsonObjectType type = JsonObjectType.String) + : base(typeof(Processor), name, description, type) + { + } + + public sealed class Processor : IOperationProcessor + { + private readonly string name; + private readonly string description; + private readonly JsonObjectType type; + + public Processor(string name, string description, JsonObjectType type) + { + this.name = name; + this.description = description; + this.type = type; + } + + public bool Process(OperationProcessorContext context) + { + context.OperationDescription.Operation.Parameters.Add(new OpenApiParameter + { + Name = name, + Kind = OpenApiParameterKind.Header, + Schema = new JsonSchema + { + Type = type + }, + Description = description, + }); + + return true; + } + } +} diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs new file mode 100644 index 0000000000..8fc6300004 --- /dev/null +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs @@ -0,0 +1,36 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using NSwag.Annotations; +using NSwag.Generation.Processors; +using NSwag.Generation.Processors.Contexts; + +namespace Squidex.Areas.Api.Config.OpenApi; + +public sealed class AcceptQueryAttribute : OpenApiOperationProcessorAttribute +{ + public AcceptQueryAttribute(bool supportsSearch) + : base(typeof(Processor), supportsSearch) + { + } + + public sealed class Processor : IOperationProcessor + { + private readonly bool supportsSearch; + + public Processor(bool supportsSearch) + { + this.supportsSearch = supportsSearch; + } + + public bool Process(OperationProcessorContext context) + { + context.OperationDescription.Operation.AddQuery(supportsSearch); + return true; + } + } +} diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs index 936f3dfdf3..d4ff863670 100644 --- a/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/OpenApiServices.cs @@ -79,8 +79,6 @@ public static void AddSquidexOpenApiSettings(this IServiceCollection services) services.AddOpenApiDocument((settings, services) => { ConfigureSchemaSettings(settings, services.GetRequiredService(), false); - - settings.OperationProcessors.Add(new QueryParamsProcessor("/api/apps/{app}/assets")); }); } diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/QueryParamsProcessor.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/QueryParamsProcessor.cs deleted file mode 100644 index 050603ac48..0000000000 --- a/backend/src/Squidex/Areas/Api/Config/OpenApi/QueryParamsProcessor.cs +++ /dev/null @@ -1,34 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using NSwag; -using NSwag.Generation.Processors; -using NSwag.Generation.Processors.Contexts; - -namespace Squidex.Areas.Api.Config.OpenApi; - -public sealed class QueryParamsProcessor : IOperationProcessor -{ - private readonly string path; - - public QueryParamsProcessor(string path) - { - this.path = path; - } - - public bool Process(OperationProcessorContext context) - { - if (context.OperationDescription.Path == path && context.OperationDescription.Method == OpenApiOperationMethod.Get) - { - var operation = context.OperationDescription.Operation; - - operation.AddQuery(false); - } - - return true; - } -} diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/RequiredSchemaProcessor.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/RequiredSchemaProcessor.cs index 4961072699..2a20a8dfcf 100644 --- a/backend/src/Squidex/Areas/Api/Config/OpenApi/RequiredSchemaProcessor.cs +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/RequiredSchemaProcessor.cs @@ -17,9 +17,47 @@ public void Process(SchemaProcessorContext context) { if (context.ContextualType.GetAttribute() != null) { - return; + FixRequest(context); + } + else + { + FixResponse(context); + } + } + + private static void FixRequest(SchemaProcessorContext context) + { + FixRequired(context.Schema); + + foreach (var schema in context.Schema.AllOf) + { + FixRequired(schema); + } + + foreach (var schema in context.Schema.OneOf) + { + FixRequired(schema); } + static void FixRequired(JsonSchema schema) + { + foreach (var property in schema.Properties.Values) + { + if (IsValueType(property) || property.IsEnumeration) + { + property.IsRequired = false; + } + } + } + + static bool IsValueType(JsonSchemaProperty property) + { + return property.Type is JsonObjectType.Boolean or JsonObjectType.Integer or JsonObjectType.Number; + } + } + + private static void FixResponse(SchemaProcessorContext context) + { FixRequired(context.Schema); foreach (var schema in context.Schema.AllOf) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs index 99dffd7c3b..619f1a8dde 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppDto.cs @@ -21,7 +21,6 @@ using Squidex.Shared; using Squidex.Shared.Identity; using Squidex.Web; -using System.Text.Json; #pragma warning disable RECS0033 // Convert 'if' to '||' expression diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs index 1ccfa93e00..60c59a3d82 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguageDto.cs @@ -8,7 +8,6 @@ using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Entities.Apps; using Squidex.Infrastructure; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs index d80323b60f..07cace53b9 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppLanguagesDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Apps; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs index c67f7e0ef8..9a794d68bf 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/AppSettingsDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Apps; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs index 8e1b30c8e8..51b36451f7 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/ClientsDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Apps; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs index b5bc45b0ae..7c2a885ac7 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/EditorDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Core.Apps; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Apps.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs index e12d2d8027..f31aa6ab26 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/PatternDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Core.Apps; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Apps.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs index 28b6cc35b4..c520419ab4 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/UpdateAppSettingsDto.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.ComponentModel.DataAnnotations; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Entities.Apps.Commands; using Squidex.Infrastructure.Collections; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs index f53e5768fc..d06715d02d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowDto.cs @@ -9,12 +9,10 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Apps.Models; -[OpenApiRequest] public sealed class WorkflowDto : Resource { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs index 245d01c624..7dd02fa3a1 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/Models/WorkflowStepDto.cs @@ -8,7 +8,6 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; using NoUpdateType = Squidex.Domain.Apps.Core.Contents.NoUpdate; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs index 4b2efb836a..824c2d352f 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs @@ -8,6 +8,7 @@ using System.Globalization; using Microsoft.AspNetCore.Mvc; using Microsoft.Net.Http.Headers; +using Squidex.Areas.Api.Config.OpenApi; using Squidex.Areas.Api.Controllers.Assets.Models; using Squidex.Assets; using Squidex.Domain.Apps.Core.Scripting; @@ -113,6 +114,9 @@ public async Task PutTag(string app, string name, [FromBody] Rena [ProducesResponseType(typeof(AssetsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)] [ApiCosts(1)] + [AcceptQuery(false)] + [AcceptHeader_NoTotal] + [AcceptHeader_NoSlowTotal] public async Task GetAssets(string app, [FromQuery] DomainId? parentId, [FromQuery] string? ids = null, [FromQuery] string? q = null) { var assets = await assetQuery.QueryAsync(Context, parentId, CreateQuery(ids, q), HttpContext.RequestAborted); @@ -140,6 +144,8 @@ public async Task GetAssets(string app, [FromQuery] DomainId? par [ProducesResponseType(typeof(AssetsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppAssetsRead)] [ApiCosts(1)] + [AcceptHeader_NoTotal] + [AcceptHeader_NoSlowTotal] public async Task GetAssetsPost(string app, [FromBody] QueryDto query) { var assets = await assetQuery.QueryAsync(Context, query?.ParentId, query?.ToQuery() ?? Q.Empty, HttpContext.RequestAborted); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs index 7bf991eed5..ed738e4d9a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetDto.cs @@ -11,7 +11,6 @@ using Squidex.Domain.Apps.Entities.Assets; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs index 39ac4992ba..dc15e8dcb4 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFolderDto.cs @@ -8,7 +8,6 @@ using Squidex.Domain.Apps.Entities.Assets; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs index 8f7035bf28..e33da0e5ec 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetFoldersDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Assets; using Squidex.Infrastructure; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs index 86624077a0..f1686cfdd6 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Assets; using Squidex.Infrastructure; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs index e6bc4781e0..fb6d42758b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/BulkUpdateAssetsDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Assets.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs index e7a77391cf..a7900b59a3 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/CreateAssetDto.cs @@ -20,24 +20,25 @@ public sealed class CreateAssetDto /// /// The file to upload. /// + [FromForm(Name = "file")] public IFormFile File { get; set; } /// /// The optional parent folder id. /// - [FromQuery] + [FromQuery(Name = "parentId")] public DomainId ParentId { get; set; } /// /// The optional custom asset id. /// - [FromQuery] + [FromQuery(Name = "id")] public DomainId? Id { get; set; } /// /// True to duplicate the asset, event if the file has been uploaded. /// - [FromQuery] + [FromQuery(Name = "duplicate")] public bool Duplicate { get; set; } public CreateAsset ToCommand(AssetFile file) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs index 192de45c2a..5d7806650c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/DeleteAssetDto.cs @@ -19,13 +19,13 @@ public sealed class DeleteAssetDto /// /// True to check referrers of this asset. /// - [FromQuery] + [FromQuery(Name = "checkReferrers")] public bool CheckReferrers { get; set; } /// /// True to delete the asset permanently. /// - [FromQuery] + [FromQuery(Name = "permanent")] public bool Permanent { get; set; } public DeleteAsset ToCommand(DomainId id) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs index 92fe72427d..57957a982e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/Models/UpsertAssetDto.cs @@ -20,18 +20,19 @@ public sealed class UpsertAssetDto /// /// The file to upload. /// + [FromForm(Name = "file")] public IFormFile File { get; set; } /// /// The optional parent folder id. /// - [FromQuery] + [FromQuery(Name = "parentId")] public DomainId ParentId { get; set; } /// /// True to duplicate the asset, event if the file has been uploaded. /// - [FromQuery] + [FromQuery(Name = "duplicate")] public bool Duplicate { get; set; } public static UpsertAsset ToCommand(AssetTusFile file) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs index 563eccc906..429e39f8ab 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Backups/Models/RestoreJobDto.cs @@ -8,8 +8,6 @@ using NodaTime; using Squidex.Domain.Apps.Entities.Backup; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; -using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Backups.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs index 49d12768a4..961e987201 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Mvc; using NSwag.Annotations; +using Squidex.Areas.Api.Config.OpenApi; using Squidex.Areas.Api.Controllers.Contents.Models; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities; @@ -77,6 +78,12 @@ public IActionResult StreamContents(string app, string schema, [FromQuery] int s [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(1)] + [AcceptQuery(true)] + [AcceptHeader_Flatten] + [AcceptHeader_Languages] + [AcceptHeader_NoSlowTotal] + [AcceptHeader_NoTotal] + [AcceptHeader_Unpublished] public async Task GetContents(string app, string schema, [FromQuery] string? ids = null, [FromQuery] string? q = null) { var contents = await contentQuery.QueryAsync(Context, schema, CreateQuery(ids, q), HttpContext.RequestAborted); @@ -105,6 +112,11 @@ public async Task GetContents(string app, string schema, [FromQue [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(1)] + [AcceptHeader_Flatten] + [AcceptHeader_Languages] + [AcceptHeader_NoSlowTotal] + [AcceptHeader_NoTotal] + [AcceptHeader_Unpublished] public async Task GetContentsPost(string app, string schema, [FromBody] QueryDto query) { var contents = await contentQuery.QueryAsync(Context, schema, query?.ToQuery() ?? Q.Empty, HttpContext.RequestAborted); @@ -134,6 +146,9 @@ public async Task GetContentsPost(string app, string schema, [Fro [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(1)] + [AcceptHeader_Flatten] + [AcceptHeader_Languages] + [AcceptHeader_Unpublished] public async Task GetContent(string app, string schema, DomainId id, long version = EtagVersion.Any) { var content = await contentQuery.FindAsync(Context, schema, id, version, HttpContext.RequestAborted); @@ -194,6 +209,11 @@ public async Task GetContentValidity(string app, string schema, D [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(1)] + [AcceptHeader_Flatten] + [AcceptHeader_Languages] + [AcceptHeader_Unpublished] + [AcceptHeader_NoSlowTotal] + [AcceptHeader_NoTotal] public async Task GetReferences(string app, string schema, DomainId id, [FromQuery] string? q = null) { var contents = await contentQuery.QueryAsync(Context, CreateQuery(null, q).WithReferencing(id), HttpContext.RequestAborted); @@ -223,6 +243,11 @@ public async Task GetReferences(string app, string schema, Domain [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(1)] + [AcceptHeader_Flatten] + [AcceptHeader_Languages] + [AcceptHeader_Unpublished] + [AcceptHeader_NoSlowTotal] + [AcceptHeader_NoTotal] public async Task GetReferencing(string app, string schema, DomainId id, [FromQuery] string? q = null) { var contents = await contentQuery.QueryAsync(Context, CreateQuery(null, q).WithReference(id), HttpContext.RequestAborted); @@ -251,6 +276,8 @@ public async Task GetReferencing(string app, string schema, Domai [Route("content/{app}/{schema}/{id}/{version}/")] [ApiPermissionOrAnonymous(PermissionIds.AppContentsReadOwn)] [ApiCosts(1)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [Obsolete("Use ID endpoint with version query.")] public async Task GetContentVersion(string app, string schema, DomainId id, int version) { @@ -283,8 +310,10 @@ public async Task GetContentVersion(string app, string schema, Do /// [HttpPost] [Route("content/{app}/{schema}/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status201Created)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status201Created)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsCreate)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task PostContent(string app, string schema, CreateContentDto request) { @@ -369,8 +398,10 @@ public async Task BulkUpdateContents(string app, string schema, [ /// [HttpPost] [Route("content/{app}/{schema}/{id}/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsUpsert)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task PostUpsertContent(string app, string schema, DomainId id, UpsertContentDto request) { @@ -396,8 +427,10 @@ public async Task PostUpsertContent(string app, string schema, Do /// [HttpPut] [Route("content/{app}/{schema}/{id}/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsUpdateOwn)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task PutContent(string app, string schema, DomainId id, [FromBody] ContentData request) { @@ -423,8 +456,10 @@ public async Task PutContent(string app, string schema, DomainId /// [HttpPatch] [Route("content/{app}/{schema}/{id}/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsUpdateOwn)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task PatchContent(string app, string schema, DomainId id, [FromBody] ContentData request) { @@ -450,8 +485,10 @@ public async Task PatchContent(string app, string schema, DomainI /// [HttpPut] [Route("content/{app}/{schema}/{id}/status/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsChangeStatusOwn)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task PutContentStatus(string app, string schema, DomainId id, [FromBody] ChangeStatusDto request) { @@ -476,8 +513,10 @@ public async Task PutContentStatus(string app, string schema, Dom /// [HttpDelete] [Route("content/{app}/{schema}/{id}/status/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsChangeStatusOwn)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task DeleteContentStatus(string app, string schema, DomainId id) { @@ -501,8 +540,10 @@ public async Task DeleteContentStatus(string app, string schema, /// [HttpPost] [Route("content/{app}/{schema}/{id}/draft/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsVersionCreateOwn)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task CreateDraft(string app, string schema, DomainId id) { @@ -526,8 +567,10 @@ public async Task CreateDraft(string app, string schema, DomainId /// [HttpDelete] [Route("content/{app}/{schema}/{id}/draft/")] - [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ContentDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsVersionDeleteOwn)] + [AcceptHeader_Unpublished] + [AcceptHeader_Languages] [ApiCosts(1)] public async Task DeleteVersion(string app, string schema, DomainId id) { diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs index 194f4332b4..e2813b0d89 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs @@ -8,6 +8,7 @@ using GraphQL.Server.Transports.AspNetCore; using Microsoft.AspNetCore.Mvc; using Microsoft.Net.Http.Headers; +using Squidex.Areas.Api.Config.OpenApi; using Squidex.Areas.Api.Controllers.Contents.Models; using Squidex.Domain.Apps.Entities; using Squidex.Domain.Apps.Entities.Contents; @@ -47,6 +48,7 @@ public ContentsSharedController(ICommandBus commandBus, [Route("content/{app}/graphql/batch")] [ApiPermissionOrAnonymous] [ApiCosts(2)] + [AcceptHeader_Unpublished] [IgnoreCacheFilter] public IActionResult GetGraphQL(string app) { @@ -73,6 +75,11 @@ public IActionResult GetGraphQL(string app) [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(1)] + [AcceptHeader_Flatten] + [AcceptHeader_Languages] + [AcceptHeader_NoSlowTotal] + [AcceptHeader_NoTotal] + [AcceptHeader_Unpublished] public async Task GetAllContents(string app, AllContentsByGetDto query) { var contents = await contentQuery.QueryAsync(Context, (query ?? new AllContentsByGetDto()).ToQuery(Request), HttpContext.RequestAborted); @@ -100,6 +107,11 @@ public async Task GetAllContents(string app, AllContentsByGetDto [ProducesResponseType(typeof(ContentsDto), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(1)] + [AcceptHeader_Flatten] + [AcceptHeader_Languages] + [AcceptHeader_NoSlowTotal] + [AcceptHeader_NoTotal] + [AcceptHeader_Unpublished] public async Task GetAllContentsPost(string app, [FromBody] AllContentsByPostDto query) { var contents = await contentQuery.QueryAsync(Context, query?.ToQuery() ?? Q.Empty, HttpContext.RequestAborted); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs index b228e88109..ce955ad630 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/AllContentsByGetDto.cs @@ -27,25 +27,25 @@ public sealed class AllContentsByGetDto /// /// The start of the schedule. /// - [FromQuery] + [FromQuery(Name = "scheduleFrom")] public Instant? ScheduledFrom { get; set; } /// /// The end of the schedule. /// - [FromQuery] + [FromQuery(Name = "scheduleTo")] public Instant? ScheduledTo { get; set; } /// /// The ID of the referencing content item. /// - [FromQuery] + [FromQuery(Name = "referencing")] public DomainId? Referencing { get; set; } /// /// The ID of the reference content item. /// - [FromQuery] + [FromQuery(Name = "references")] public DomainId? References { get; set; } /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs index 5348770afb..a56a1ec48e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentDto.cs @@ -12,7 +12,6 @@ using Squidex.Domain.Apps.Entities.Contents; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs index 284572703c..3f6a6207d8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs @@ -8,7 +8,6 @@ using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Infrastructure; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Contents.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs index dbacabff1b..bcc6bcf347 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/CreateContentDto.cs @@ -24,19 +24,19 @@ public class CreateContentDto /// /// The initial status. /// - [FromQuery] + [FromQuery(Name = "status")] public StatusType? Status { get; set; } /// /// The optional custom content id. /// - [FromQuery] + [FromQuery(Name = "id")] public DomainId? Id { get; set; } /// /// True to automatically publish the content. /// - [FromQuery] + [FromQuery(Name = "publish")] [Obsolete("Use 'status' query string now.")] public bool Publish { get; set; } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/DeleteContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/DeleteContentDto.cs index 36d33f30b7..6b87f35b9c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/DeleteContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/DeleteContentDto.cs @@ -17,13 +17,13 @@ public sealed class DeleteContentDto /// /// True to check referrers of this content. /// - [FromQuery] + [FromQuery(Name = "checkReferrers")] public bool CheckReferrers { get; set; } /// /// True to delete the content permanently. /// - [FromQuery] + [FromQuery(Name = "permanent")] public bool Permanent { get; set; } public DeleteContent ToCommand(DomainId id) diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs index b1de3a7095..aa82cb465e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/ScheduleJobDto.cs @@ -8,7 +8,6 @@ using NodaTime; using Squidex.Domain.Apps.Core.Contents; using Squidex.Infrastructure; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Contents.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs index e0b48863d9..3820efaa00 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/StatusInfoDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Core.Contents; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Contents.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs index 08984499ea..73a2684109 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/UpsertContentDto.cs @@ -27,19 +27,19 @@ public class UpsertContentDto /// /// The initial status. /// - [FromQuery] + [FromQuery(Name = "status")] public StatusType? Status { get; set; } /// /// Makes the update as patch. /// - [FromQuery] + [FromQuery(Name = "patch")] public bool Patch { get; set; } /// /// True to automatically publish the content. /// - [FromQuery] + [FromQuery(Name = "publish")] [Obsolete("Use 'status' query string now.")] public bool Publish { get; set; } diff --git a/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs b/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs index e346bdf400..25a0f0f834 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/ContributorDto.cs @@ -8,7 +8,6 @@ using Squidex.Areas.Api.Controllers.Apps; using Squidex.Areas.Api.Controllers.Teams; using Squidex.Infrastructure.Translations; -using Squidex.Infrastructure.Validation; using Squidex.Shared.Identity; using Squidex.Shared.Users; using Squidex.Web; diff --git a/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs index 31868638f0..3efeaa698e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/ContributorsDto.cs @@ -11,7 +11,6 @@ using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Billing; using Squidex.Domain.Apps.Entities.Teams; -using Squidex.Infrastructure.Validation; using Squidex.Shared.Users; using Squidex.Web; diff --git a/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs b/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs index bf3f70ceb8..ffe6c906e2 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/History/Models/HistoryEventDto.cs @@ -9,7 +9,6 @@ using Squidex.Domain.Apps.Entities.History; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.History.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs b/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs index 2122952dd4..42dd913dd5 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/LanguageDto.cs @@ -7,7 +7,6 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers; diff --git a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs index 76107f871f..c35dd24102 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeatureDto.cs @@ -5,8 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure.Validation; - namespace Squidex.Areas.Api.Controllers.News.Models; public sealed class FeatureDto diff --git a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs index abedbd2e04..f207d6431e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/News/Models/FeaturesDto.cs @@ -5,8 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure.Validation; - namespace Squidex.Areas.Api.Controllers.News.Models; public class FeaturesDto diff --git a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs index 71a5c9cca1..6b2930865c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlanDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Billing; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Plans.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs index 617b790d81..78468a7a0d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Plans/Models/PlansDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Billing; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Plans.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs index 3cd1b4b45e..6df6c5c67b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs @@ -12,7 +12,6 @@ using Squidex.Domain.Apps.Entities.Rules.Runner; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Rules.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs index 2ecc1523aa..a017106e4c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Rules.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs index 0c143647c9..a34b09b1ca 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleElementPropertyDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Core.HandleRules; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Rules.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs index 143040e133..3e51f35180 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventDto.cs @@ -10,7 +10,6 @@ using Squidex.Domain.Apps.Entities.Rules; using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Rules.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs index b6738a2eff..e7c68d86a3 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleEventsDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Rules; using Squidex.Infrastructure; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Rules.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs index b2d0af4abe..658025d88c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RulesDto.cs @@ -8,7 +8,6 @@ using Squidex.Domain.Apps.Entities.Rules; using Squidex.Domain.Apps.Entities.Rules.Runner; using Squidex.Infrastructure; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Rules.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs index 291c8e33fa..dea34607b8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/Models/SimulatedRuleEventsDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Rules.Runner; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Rules.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ChangeCategoryDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ChangeCategoryDto.cs index e4a2eac1ae..18a5a7de6d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ChangeCategoryDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ChangeCategoryDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class ChangeCategoryDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureFieldRulesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureFieldRulesDto.cs index 7346bf531d..63a652c68d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureFieldRulesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureFieldRulesDto.cs @@ -6,9 +6,11 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class ConfigureFieldRulesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs index 398dde954d..8eea2125c4 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigurePreviewUrlsDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Collections; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class ConfigurePreviewUrlsDto : Dictionary { public ConfigurePreviewUrls ToCommand() diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs index dc6d4f56e9..9aece9763b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ConfigureUIFieldsDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class ConfigureUIFieldsDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs index 29726796c4..c0c9003bfa 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/CreateSchemaDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class CreateSchemaDto : UpsertSchemaDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldPropertiesDto.cs index 2fab0fe83c..45ced2ca50 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/FieldPropertiesDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public abstract class FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs index 62a8f8d3fb..933f4703d1 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class ArrayFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs index 2c46a4e644..f547c6c320 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/AssetsFieldPropertiesDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class AssetsFieldPropertiesDto : FieldPropertiesDto { /// @@ -34,6 +36,11 @@ public sealed class AssetsFieldPropertiesDto : FieldPropertiesDto /// public string? FolderId { get; set; } + /// + /// The preview format. + /// + public string? PreviewFormat { get; set; } + /// /// The minimum allowed items for the field value. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs index 6fe9830d38..70dc6472d8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/BooleanFieldPropertiesDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class BooleanFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentFieldPropertiesDto.cs index debcf34efc..18fb1f270d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentFieldPropertiesDto.cs @@ -9,9 +9,11 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class ComponentFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs index b6b4628364..f048b4f8a8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs @@ -9,9 +9,11 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class ComponentsFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs index e6b81c4853..0233ce2a73 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/DateTimeFieldPropertiesDto.cs @@ -8,9 +8,11 @@ using NodaTime; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class DateTimeFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/NumberFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/NumberFieldPropertiesDto.cs index 3431b46042..eaa28c3d68 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/NumberFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/NumberFieldPropertiesDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class NumberFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs index c0ca39339b..8e54fe8708 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs @@ -9,9 +9,11 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class ReferencesFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs index 4823537ea9..3da6a0f4f1 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs @@ -9,9 +9,11 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class StringFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/TagsFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/TagsFieldPropertiesDto.cs index a51ec27c62..dbf32ef245 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/TagsFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/TagsFieldPropertiesDto.cs @@ -8,9 +8,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class TagsFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/UIFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/UIFieldPropertiesDto.cs index a3c1f0e8a8..40ac046e78 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/UIFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/UIFieldPropertiesDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields; +[OpenApiRequest] public sealed class UIFieldPropertiesDto : FieldPropertiesDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ReorderFieldsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ReorderFieldsDto.cs index 5da1dbb566..613c8a7634 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ReorderFieldsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/ReorderFieldsDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class ReorderFieldsDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SynchronizeSchemaDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SynchronizeSchemaDto.cs index dccf64bf48..4cb7bd63d8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SynchronizeSchemaDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/SynchronizeSchemaDto.cs @@ -6,9 +6,11 @@ // ========================================================================== using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class SynchronizeSchemaDto : UpsertSchemaDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateFieldDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateFieldDto.cs index 5a4e8cb63d..4bd5f36fd2 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateFieldDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateFieldDto.cs @@ -7,9 +7,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class UpdateFieldDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateSchemaDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateSchemaDto.cs index 3eecd2bee0..e2005475f3 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateSchemaDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpdateSchemaDto.cs @@ -10,9 +10,11 @@ using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class UpdateSchemaDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs index ff8298ea28..7d494f89e4 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaDto.cs @@ -9,9 +9,11 @@ using Squidex.Domain.Apps.Entities.Schemas.Commands; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public abstract class UpsertSchemaDto { /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaFieldDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaFieldDto.cs index eaec3434bd..b28fb8c4dc 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaFieldDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaFieldDto.cs @@ -6,9 +6,11 @@ // ========================================================================== using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class UpsertSchemaFieldDto { /// @@ -48,4 +50,4 @@ public sealed class UpsertSchemaFieldDto /// The nested fields. /// public UpsertSchemaNestedFieldDto[]? Nested { get; set; } -} \ No newline at end of file +} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaNestedFieldDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaNestedFieldDto.cs index 7095de2c1b..b10620a855 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaNestedFieldDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/UpsertSchemaNestedFieldDto.cs @@ -6,9 +6,11 @@ // ========================================================================== using Squidex.Infrastructure.Validation; +using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Schemas.Models; +[OpenApiRequest] public sealed class UpsertSchemaNestedFieldDto { /// @@ -38,4 +40,4 @@ public sealed class UpsertSchemaNestedFieldDto /// [LocalizedRequired] public FieldPropertiesDto Properties { get; set; } -} \ No newline at end of file +} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs index 35a7fa3092..ec6a1f8e51 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Search/Models/SearchResultDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Search; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Search.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs index 989158b6ef..3e0bd0bfd3 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Statistics/Models/CallsUsageDtoDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Billing; using Squidex.Infrastructure.UsageTracking; -using Squidex.Infrastructure.Validation; namespace Squidex.Areas.Api.Controllers.Statistics.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs index f41490fd55..909909ce93 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Teams/Models/TeamDto.cs @@ -12,7 +12,6 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Security; -using Squidex.Infrastructure.Validation; using Squidex.Shared; using Squidex.Web; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs index 7c8bdbe391..0f17ad42c1 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDetailsDto.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Templates.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs index ccec699e40..6a53aa3a70 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Templates/Models/TemplateDto.cs @@ -7,7 +7,6 @@ using Squidex.Domain.Apps.Entities.Apps.Templates; using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Web; namespace Squidex.Areas.Api.Controllers.Templates.Models; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs index 5eadfefe9d..56b18c8237 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UserDto.cs @@ -6,7 +6,6 @@ // ========================================================================== using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; using Squidex.Shared.Identity; using Squidex.Shared.Users; using Squidex.Web; diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs index 15835ce811..2159d3c33f 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure.Validation; using Squidex.Shared.Users; using Squidex.Web; diff --git a/backend/src/Squidex/Areas/IdentityServer/Config/AlwaysAddTokenHandler.cs b/backend/src/Squidex/Areas/IdentityServer/Config/AlwaysAddScopeHandler.cs similarity index 100% rename from backend/src/Squidex/Areas/IdentityServer/Config/AlwaysAddTokenHandler.cs rename to backend/src/Squidex/Areas/IdentityServer/Config/AlwaysAddScopeHandler.cs diff --git a/backend/src/Squidex/Areas/IdentityServer/Controllers/Account/AccountController.cs b/backend/src/Squidex/Areas/IdentityServer/Controllers/Account/AccountController.cs index 64d87fec4d..8eab5d873b 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Controllers/Account/AccountController.cs +++ b/backend/src/Squidex/Areas/IdentityServer/Controllers/Account/AccountController.cs @@ -15,7 +15,6 @@ using Squidex.Infrastructure.Translations; using Squidex.Shared.Identity; using Squidex.Shared.Users; -using Squidex.Web; namespace Squidex.Areas.IdentityServer.Controllers.Account; diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryIntegrationTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryIntegrationTests.cs index 71ed4a4331..1b7235d168 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryIntegrationTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/MongoDb/AssetsQueryIntegrationTests.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Amazon.Runtime; using Squidex.Infrastructure; using Squidex.Infrastructure.MongoDb; using Squidex.Infrastructure.Queries; diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs index 1e63779411..829f0e2e31 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs @@ -27,7 +27,7 @@ public GraphQLMutationTests() { content = TestContent.Create(contentId, TestSchemas.Ref1.Id, TestSchemas.Ref2.Id, null); - A.CallTo(() => commandBus.PublishAsync(A.Ignored,A._)) + A.CallTo(() => commandBus.PublishAsync(A.Ignored, A._)) .Returns(commandContext); } diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs index afeac8a627..cbaed3237e 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs @@ -9,7 +9,6 @@ using LoremNET; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using MongoDB.Bson; using MongoDB.Driver; using NodaTime; using Squidex.Domain.Apps.Core; diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/assets-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/assets-ui.component.html index e6c5aaf7f8..36fb0801fd 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/assets-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/assets-ui.component.html @@ -16,6 +16,18 @@ +
+ + +
+ + + + + +
+
+
@@ -26,7 +38,7 @@
- {{ 'schemas.fieldTypes.assets.resolveHint' | sqxTranslate }} + {{ 'schemas.fieldTypes.assets.resolveHint' | sqxTranslate | sqxMarkdownInline }}
diff --git a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html index c702c5df55..7e30a5a6c1 100644 --- a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html +++ b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html @@ -54,10 +54,18 @@
{{ 'clients.connectWizard.cli' | sqxTranslate }}
-
-
{{ 'clients.connectWizard.sdk' | sqxTranslate }}
+
+
{{ 'clients.connectWizard.dotnetSdk' | sqxTranslate }}
- {{ 'clients.connectWizard.sdkHint' | sqxTranslate }} + {{ 'clients.connectWizard.dotnetSdkHint' | sqxTranslate }} + + +
+ +
+
{{ 'clients.connectWizard.javascriptSdk' | sqxTranslate }}
+ + {{ 'clients.connectWizard.javascriptSdkHint' | sqxTranslate }}
@@ -136,17 +144,17 @@
4 {{ 'clients.connectWizard.

- +
- {{ 'clients.connectWizard.sdkDocumentation' | sqxTranslate }} {{ 'common.documentation' | sqxTranslate }} + {{ 'clients.connectWizard.dotnetSdkDocumentation' | sqxTranslate }} {{ 'common.documentation' | sqxTranslate }}
-
1 {{ 'clients.connectWizard.sdkStep1' | sqxTranslate }}
+
1 {{ 'clients.connectWizard.dotnetSdkStep1' | sqxTranslate }}
-
+

dotnet add package Squidex.ClientLibrary @@ -154,41 +162,45 @@

1 {{ 'clients.connectWizard.
-
2 {{ 'clients.connectWizard.sdkStep2' | sqxTranslate }}
+
2 {{ 'clients.connectWizard.dotnetSdkStep2' | sqxTranslate }}

+

using Squidex.ClientLibrary;
+
 
var clientManager = new SquidexClientManager(new SquidexOptions
{{'{'}}
-
AppName = {{appName}},
-
ClientId = {{appName}}:{{client.id}},
-
ClientSecret = {{client.secret}},
-
Url = {{apiUrl.value}}
+
AppName = "{{appName}}",
+
ClientId = "{{appName}}:{{client.id}}",
+
ClientSecret = "{{client.secret}}",
+
Url = "{{apiUrl.value}}"
});

-
2 {{ 'clients.connectWizard.sdkStep2_15' | sqxTranslate }}
+
2 {{ 'clients.connectWizard.dotnetSdkStep2_15' | sqxTranslate }}

+

using Squidex.ClientLibrary;
+
 
var client = new SquidexClient(new SquidexOptions
{{'{'}}
-
AppName = {{appName}},
-
ClientId = {{appName}}:{{client.id}},
-
ClientSecret = {{client.secret}},
-
Url = {{apiUrl.value}}
+
AppName = "{{appName}}",
+
ClientId = "{{appName}}:{{client.id}},
+
ClientSecret = "{{client.secret}}",
+
Url = "{{apiUrl.value}}"
});

-
3 {{ 'clients.connectWizard.sdkStep3' | sqxTranslate }}
+
3 {{ 'clients.connectWizard.dotnetSdkStep3' | sqxTranslate }}
-
+

dotnet add package Squidex.ClientLibrary.ServiceExtensions @@ -196,16 +208,18 @@

3 {{ 'clients.connectWizard.
-
4 {{ 'clients.connectWizard.sdkStep4' | sqxTranslate }}
+
4 {{ 'clients.connectWizard.dotnetSdkStep4' | sqxTranslate }}

+

using Microsoft.Extensions.DependencyInjection;
+
 
services.AddSquidex(options =>
{{'{'}}
-
options.AppName = {{appName}};
-
options.ClientId = {{appName}}:{{client.id}};
-
options.ClientSecret = {{client.secret}};
-
options.Url = {{apiUrl.value}};
+
options.AppName = "{{appName}}";
+
options.ClientId = "{{appName}}:{{client.id}}";
+
options.ClientSecret = "{{client.secret}}";
+
options.Url = "{{apiUrl.value}}";
});

@@ -217,6 +231,40 @@
4 {{ 'clients.connectWizard.
+ +
+ + {{ 'clients.connectWizard.javascriptSdkDocumentation' | sqxTranslate }} {{ 'common.documentation' | sqxTranslate }} + +
+ +
+
1 {{ 'clients.connectWizard.javascriptSdkStep1' | sqxTranslate }}
+ +
+ +

+ npm i @squidex/squidex --save +

+
+ +
+
2 {{ 'clients.connectWizard.javascriptSdkStep2' | sqxTranslate }}
+ +

+ +

import {{'{'}} SquidexClient } from "@squidex/squidex";
+
 
+
const client = new SquidexClient({{'{'}}
+
appName: "{{appName}}",
+
clientId: "{{appName}}:{{client.id}}",
+
clientSecret: "{{client.secret}}",
+
environment: "{{apiUrl.value}}"
+
});
+ +

+
+
diff --git a/frontend/src/app/shared/components/contents/content-value.component.scss b/frontend/src/app/shared/components/contents/content-value.component.scss index 13e6def23a..142fdd4f13 100644 --- a/frontend/src/app/shared/components/contents/content-value.component.scss +++ b/frontend/src/app/shared/components/contents/content-value.component.scss @@ -26,18 +26,23 @@ } :host ::ng-deep { + .image { + @include truncate; + align-items: center; + display: flex; + flex-direction: row; + flex-wrap: nowrap; + margin-bottom: -8px; + margin-top: -8px; + } + img { background-image: $asset-background; background-size: 10px 10px; - margin-top: -25px; - max-height: 50px; - min-height: 50px; - position: absolute; - top: 50%; } img + span { - padding-left: 60px; + padding-left: 10px; } .html-value { diff --git a/frontend/src/app/shared/services/schemas.types.ts b/frontend/src/app/shared/services/schemas.types.ts index 1c64e8f75c..77cdd8a945 100644 --- a/frontend/src/app/shared/services/schemas.types.ts +++ b/frontend/src/app/shared/services/schemas.types.ts @@ -199,14 +199,13 @@ export const ASSET_PREVIEW_MODES: ReadonlyArray = [ export class AssetsFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'Assets'; - public readonly previewMode: AssetPreviewMode = 'FileName'; - public readonly defaultValue?: ReadonlyArray; - public readonly defaultValues?: DefaultValue>; public readonly allowDuplicates?: boolean; public readonly allowedExtensions?: ReadonlyArray; - public readonly resolveFirst = false; public readonly aspectHeight?: number; public readonly aspectWidth?: number; + public readonly defaultValue?: ReadonlyArray; + public readonly defaultValues?: DefaultValue>; + public readonly expectedType?: string; public readonly folderId?: string; public readonly maxHeight?: number; public readonly maxItems?: number; @@ -216,7 +215,9 @@ export class AssetsFieldPropertiesDto extends FieldPropertiesDto { public readonly minItems?: number; public readonly minSize?: number; public readonly minWidth?: number; - public readonly expectedType?: string; + public readonly previewFormat?: string; + public readonly previewMode: AssetPreviewMode = 'FileName'; + public readonly resolveFirst = false; public get isSortable() { return false; diff --git a/frontend/src/app/shared/state/contents.forms.spec.ts b/frontend/src/app/shared/state/contents.forms.spec.ts index 8dbaea5780..a77af866d6 100644 --- a/frontend/src/app/shared/state/contents.forms.spec.ts +++ b/frontend/src/app/shared/state/contents.forms.spec.ts @@ -193,7 +193,8 @@ describe('GetContentValue', () => { const result = getContentValue(content, language, assetWithImageAndFileName); - expect(result).toEqual({ value: ['url/to/13', 'file13'], formatted: new HtmlValue(' file13', 'url/to/13') }); + expect(result).toEqual({ value: ['url/to/13', 'file13'], + formatted: new HtmlValue('
file13
', 'url/to/13') }); }); it('should resolve image url only from referenced asset', () => { @@ -209,7 +210,42 @@ describe('GetContentValue', () => { const result = getContentValue(content, language, assetWithImage); - expect(result).toEqual({ value: ['url/to/13', 'file13'], formatted: new HtmlValue('', 'url/to/13') }); + expect(result).toEqual({ value: ['url/to/13', 'file13'], + formatted: new HtmlValue('
', 'url/to/13') }); + }); + + it('should resolve image url only from referenced asset with custom format', () => { + const content: any = { + referenceData: { + field1: { + en: ['url/to/13', 'file13'], + }, + }, + }; + + const assetWithImage = createField({ properties: createProperties('Assets', { previewMode: 'Image', previewFormat: 'width=100&height=100' }) }); + + const result = getContentValue(content, language, assetWithImage); + + expect(result).toEqual({ value: ['url/to/13', 'file13'], + formatted: new HtmlValue('
', 'url/to/13') }); + }); + + it('should resolve image url only from referenced asset with merged format', () => { + const content: any = { + referenceData: { + field1: { + en: ['url/to/13', 'file13'], + }, + }, + }; + + const assetWithImage = createField({ properties: createProperties('Assets', { previewMode: 'Image', previewFormat: 'bg=red' }) }); + + const result = getContentValue(content, language, assetWithImage); + + expect(result).toEqual({ value: ['url/to/13', 'file13'], + formatted: new HtmlValue('
', 'url/to/13') }); }); it('should resolve filename only from referenced asset', () => { diff --git a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts index c5f46514ec..e140448d95 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts @@ -394,22 +394,22 @@ describe('StringField', () => { expect(FieldFormatter.format(field, 'hello')).toBe('hello'); }); - it('should format to preview image', () => { + it('should not format to preview image if html not allowed', () => { const field2 = createField({ properties: createProperties('String', { editor: 'StockPhoto' }) }); - expect(FieldFormatter.format(field2, 'https://images.unsplash.com/123?x', true)).toEqual(new HtmlValue('', 'https://images.unsplash.com/123?x')); + expect(FieldFormatter.format(field2, 'https://images.unsplash.com/123?x', false)).toBe('https://images.unsplash.com/123?x'); }); - it('should not format to preview image if html not allowed', () => { + it('should format to preview image', () => { const field2 = createField({ properties: createProperties('String', { editor: 'StockPhoto' }) }); - expect(FieldFormatter.format(field2, 'https://images.unsplash.com/123?x', false)).toBe('https://images.unsplash.com/123?x'); + expect(FieldFormatter.format(field2, 'https://images.unsplash.com/123?x', true)).toEqual(new HtmlValue('
', 'https://images.unsplash.com/123?x')); }); it('should not format to preview image if not unsplash image', () => { const field2 = createField({ properties: createProperties('String', { editor: 'StockPhoto' }) }); - expect(FieldFormatter.format(field2, 'https://images.com/123?x', true)).toEqual(new HtmlValue('', 'https://images.com/123?x')); + expect(FieldFormatter.format(field2, 'https://images.com/123?x', true)).toEqual(new HtmlValue('
', 'https://images.com/123?x')); }); it('should return default value from properties', () => { diff --git a/frontend/src/app/shared/state/contents.forms.visitors.ts b/frontend/src/app/shared/state/contents.forms.visitors.ts index 9fbd022254..0ee9868470 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.ts @@ -10,7 +10,7 @@ import { DateTime, Types, ValidatorsEx } from '@app/framework'; import { ContentDto, ContentReferencesValue } from './../services/contents.service'; import { LanguageDto } from './../services/languages.service'; import { FieldDto, RootFieldDto } from './../services/schemas.service'; -import { ArrayFieldPropertiesDto, AssetsFieldPropertiesDto, BooleanFieldPropertiesDto, ComponentFieldPropertiesDto, ComponentsFieldPropertiesDto, DateTimeFieldPropertiesDto, fieldInvariant, FieldPropertiesVisitor, GeolocationFieldPropertiesDto, JsonFieldPropertiesDto, NumberFieldPropertiesDto, ReferencesFieldPropertiesDto, StringFieldPropertiesDto, TagsFieldPropertiesDto, UIFieldPropertiesDto } from './../services/schemas.types'; +import { ArrayFieldPropertiesDto, AssetPreviewMode, AssetsFieldPropertiesDto, BooleanFieldPropertiesDto, ComponentFieldPropertiesDto, ComponentsFieldPropertiesDto, DateTimeFieldPropertiesDto, fieldInvariant, FieldPropertiesVisitor, GeolocationFieldPropertiesDto, JsonFieldPropertiesDto, NumberFieldPropertiesDto, ReferencesFieldPropertiesDto, StringFieldPropertiesDto, TagsFieldPropertiesDto, UIFieldPropertiesDto } from './../services/schemas.types'; export class HtmlValue { constructor( @@ -45,30 +45,37 @@ export function getContentValue(content: ContentDto, language: LanguageDto, fiel value = fieldValue; } - let formatted: FieldValue = value!; + if (!value) { + return { value: '-', formatted: '-' }; + } - if (value) { - if (isAssets && Types.isArray(value)) { - if (value.length === 2) { - const previewMode = field.properties['previewMode']; + let formatted: FieldValue = value; - const buildImage = (src: string) => { - return ``; - }; + if (isAssets && Types.isArray(value)) { + if (value.length === 2) { + const buildImage = (src: string) => { + let format = field.properties['previewFormat'] || ''; - if (previewMode === 'ImageAndFileName') { - formatted = new HtmlValue(buildImage(value[0]) + ` ${value[1]}`, value[0]); - } else if (previewMode === 'Image') { - formatted = new HtmlValue(buildImage(value[0]), value[0]); - } else { - formatted = value[1]; + if (format.indexOf('width') < 0 || format.indexOf('height') < 0) { + format = `width=50&height=50&mode=Pad&${format}`; } - } else if (value.length === 1) { - formatted = value[0]; + + return ``; + }; + + switch (field.properties['previewMode'] as AssetPreviewMode) { + case 'ImageAndFileName': + formatted = new HtmlValue(`
${buildImage(value[0])} ${value[1]}
`, value[0]); + break; + case 'Image': + formatted = new HtmlValue(`
${buildImage(value[0])}
`, value[0]); + break; + default: + formatted = value[1]; } + } else if (value.length === 1) { + formatted = value[0]; } - } else { - value = formatted = '-'; } return { value, formatted }; @@ -211,7 +218,7 @@ export class FieldFormatter implements FieldPropertiesVisitor { } if (properties.editor === 'StockPhoto' && this.allowHtml && this.value) { - return new HtmlValue(``, this.value); + return new HtmlValue(`
`, this.value); } return this.value; diff --git a/frontend/src/app/shared/state/schemas.forms.ts b/frontend/src/app/shared/state/schemas.forms.ts index 56abb7f3c6..818ecc712b 100644 --- a/frontend/src/app/shared/state/schemas.forms.ts +++ b/frontend/src/app/shared/state/schemas.forms.ts @@ -272,6 +272,7 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor { this.config['minItems'] = new UntypedFormControl(undefined); this.config['minSize'] = new UntypedFormControl(undefined); this.config['minWidth'] = new UntypedFormControl(undefined); + this.config['previewFormat'] = new UntypedFormControl(undefined); this.config['previewMode'] = new UntypedFormControl(undefined); this.config['resolveFirst'] = new UntypedFormControl(undefined); } diff --git a/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs b/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs index d3353f20d6..f74ec4828b 100644 --- a/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs +++ b/tools/TestSuite/TestSuite.ApiTests/AssetTests.cs @@ -819,7 +819,9 @@ public override async ValueTask ReadAsync(Memory buffer, if (remaining < buffer.Length) { - buffer = buffer[..(int)remaining]; + var remainingBytes = (int)remaining; + + buffer = buffer[..remainingBytes]; } var bytesRead = await base.ReadAsync(buffer, cancellationToken); diff --git a/tools/TestSuite/TestSuite.Shared/ClientWrapper.cs b/tools/TestSuite/TestSuite.Shared/ClientWrapper.cs index 6fb6783642..064c86ed12 100644 --- a/tools/TestSuite/TestSuite.Shared/ClientWrapper.cs +++ b/tools/TestSuite/TestSuite.Shared/ClientWrapper.cs @@ -47,7 +47,7 @@ public async Task ConnectAsync() if (waitSeconds > 10) { - Console.WriteLine("Waiting {0} seconds to access server", waitSeconds); + Console.WriteLine("Waiting {0} seconds to access server.", waitSeconds); try {