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 b555f569d..5c64af3bb 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs @@ -12,6 +12,7 @@ using System.Linq; using System.Reflection; using System.Text; using System.Text.RegularExpressions; +using System.Threading.Tasks; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; using Squidex.Domain.Apps.Core.Scripting; @@ -86,7 +87,8 @@ namespace Squidex.Domain.Apps.Core.HandleRules var trimmed = text.Trim(); - if (trimmed.StartsWith(ScriptPrefix, StringComparison.OrdinalIgnoreCase) && trimmed.EndsWith(ScriptSuffix, StringComparison.OrdinalIgnoreCase)) + if (trimmed.StartsWith(ScriptPrefix, StringComparison.OrdinalIgnoreCase) && + trimmed.EndsWith(ScriptSuffix, StringComparison.OrdinalIgnoreCase)) { var script = trimmed.Substring(ScriptPrefix.Length, trimmed.Length - ScriptPrefix.Length - ScriptSuffix.Length); @@ -98,33 +100,48 @@ namespace Squidex.Domain.Apps.Core.HandleRules return scriptEngine.Interpolate(context, script); } - var current = text.AsSpan(); + var span = text.AsSpan(); - var sb = new StringBuilder(); + var currentOffset = 0; + + var parts = new List<(int Offset, int Length, ValueTask Task)>(); - for (var i = 0; i < current.Length; i++) + for (var i = 0; i < text.Length; i++) { - var c = current[i]; + var c = text[i]; if (c == '$') { - sb.Append(current.Slice(0, i).ToString()); - - current = current.Slice(i); + parts.Add((currentOffset, i - currentOffset, default)); - var (replacement, length) = GetReplacement(current.Slice(1), @event); + var (replacement, length) = GetReplacement(span.Slice(i + 1), @event); if (length > 0) { - sb.Append(replacement); + parts.Add((0, 0, new ValueTask(replacement))); - current = current.Slice(length + 1); - i = 0; + i += length + 1; } + + currentOffset = i; } } - sb.Append(current.ToString()); + parts.Add((currentOffset, text.Length - currentOffset, default)); + + var sb = new StringBuilder(); + + foreach (var (offset, length, task) in parts) + { + if (task.Result != null) + { + sb.Append(task.Result); + } + else + { + sb.Append(span.Slice(offset, length)); + } + } return sb.ToString(); } @@ -234,7 +251,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules { if (@event is EnrichedUserEventBase userEvent) { - return userEvent.User?.DisplayName() ?? Fallback; + return userEvent.User?.DisplayName(); } return null; @@ -244,50 +261,50 @@ namespace Squidex.Domain.Apps.Core.HandleRules { if (@event is EnrichedUserEventBase userEvent) { - return userEvent.User?.Id ?? Fallback; + return userEvent.User?.Id; } return null; } - private static string UserEmail(EnrichedEvent @event) + private static string? UserEmail(EnrichedEvent @event) { if (@event is EnrichedUserEventBase userEvent) { - return userEvent.User?.Email ?? Fallback; + return userEvent.User?.Email; } - return Fallback; + return null; } - private static string MentionedName(EnrichedEvent @event) + private static string? MentionedName(EnrichedEvent @event) { if (@event is EnrichedCommentEvent commentEvent) { - return commentEvent.MentionedUser.DisplayName() ?? Fallback; + return commentEvent.MentionedUser.DisplayName(); } - return Fallback; + return null; } - private static string MentionedId(EnrichedEvent @event) + private static string? MentionedId(EnrichedEvent @event) { if (@event is EnrichedCommentEvent commentEvent) { - return commentEvent.MentionedUser.Id ?? Fallback; + return commentEvent.MentionedUser.Id; } - return Fallback; + return null; } - private static string MentionedEmail(EnrichedEvent @event) + private static string? MentionedEmail(EnrichedEvent @event) { if (@event is EnrichedCommentEvent commentEvent) { - return commentEvent.MentionedUser.Email ?? Fallback; + return commentEvent.MentionedUser.Email; } - return Fallback; + return null; } private static string? CalculateData(object @event, string[] path) diff --git a/frontend/app/framework/angular/forms/editors/dropdown.component.ts b/frontend/app/framework/angular/forms/editors/dropdown.component.ts index 4d09c6c04..585935b56 100644 --- a/frontend/app/framework/angular/forms/editors/dropdown.component.ts +++ b/frontend/app/framework/angular/forms/editors/dropdown.component.ts @@ -127,7 +127,7 @@ export class DropdownComponent extends StatefulControlComponent= items.length) { + if (selectedIndex >= items.length && fromUserAction) { selectedIndex = items.length - 1; } const value = items[selectedIndex]; if (value !== this.snapshot.selectedItem) { - if (emitEvents) { + if (fromUserAction) { this.callChange(value); this.callTouched(); }