From 2589cbef807696a7b70330f2e894785c10b38ca3 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 1 Feb 2018 15:45:25 +0100 Subject: [PATCH] Azure queue action. --- .../Rules/Actions/AzureQueueAction.cs | 51 +++++++++++++ .../Rules/IRuleActionVisitor.cs | 2 + .../Actions/AzureQueueActionHandler.cs | 72 ++++++++++++++++++ .../HandleRules/Actions/SlackActionHandler.cs | 13 ++-- .../Actions/WebhookActionHandler.cs | 22 ++---- .../HandleRules/RuleEventFormatter.cs | 8 ++ ...Squidex.Domain.Apps.Core.Operations.csproj | 1 + .../Rules/Guards/RuleActionValidator.cs | 22 ++++++ .../Models/Actions/AzureQueueActionDto.cs | 36 +++++++++ .../Models/Converters/RuleActionDtoFactory.cs | 5 ++ .../Controllers/Rules/Models/RuleActionDto.cs | 1 + src/Squidex/Config/Domain/ReadServices.cs | 3 + .../app/features/rules/declarations.ts | 1 + src/Squidex/app/features/rules/module.ts | 2 + .../actions/algolia-action.component.html | 12 +-- .../actions/azure-queue-action.component.html | 29 +++++++ .../actions/azure-queue-action.component.scss | 2 + .../actions/azure-queue-action.component.ts | 61 +++++++++++++++ .../rules/actions/slack-action.component.html | 8 +- .../actions/webhook-action.component.html | 8 +- .../pages/rules/rule-wizard.component.html | 6 ++ .../app/shared/services/rules.service.ts | 1 + src/Squidex/app/theme/_rules.scss | 5 ++ src/Squidex/app/theme/icomoon/demo.html | 16 ++++ .../app/theme/icomoon/fonts/icomoon.eot | Bin 22428 -> 22428 bytes .../app/theme/icomoon/fonts/icomoon.svg | 2 +- .../app/theme/icomoon/fonts/icomoon.ttf | Bin 22264 -> 22264 bytes .../app/theme/icomoon/fonts/icomoon.woff | Bin 22340 -> 22340 bytes src/Squidex/app/theme/icomoon/selection.json | 2 +- src/Squidex/app/theme/icomoon/style.css | 13 ++-- 30 files changed, 361 insertions(+), 43 deletions(-) create mode 100644 src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AzureQueueAction.cs create mode 100644 src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AzureQueueActionHandler.cs create mode 100644 src/Squidex/Areas/Api/Controllers/Rules/Models/Actions/AzureQueueActionDto.cs create mode 100644 src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html create mode 100644 src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.scss create mode 100644 src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.ts diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AzureQueueAction.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AzureQueueAction.cs new file mode 100644 index 000000000..7a55f99c8 --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AzureQueueAction.cs @@ -0,0 +1,51 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.Infrastructure; + +namespace Squidex.Domain.Apps.Core.Rules.Actions +{ + [TypeName(nameof(AzureQueueAction))] + public sealed class AzureQueueAction : RuleAction + { + private string connectionString; + private string queue; + + public string ConnectionString + { + get + { + return connectionString; + } + set + { + ThrowIfFrozen(); + + connectionString = value; + } + } + + public string Queue + { + get + { + return queue; + } + set + { + ThrowIfFrozen(); + + queue = value; + } + } + + public override T Accept(IRuleActionVisitor visitor) + { + return visitor.Visit(this); + } + } +} diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs index ae9543b0a..b90f8b872 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs @@ -13,6 +13,8 @@ namespace Squidex.Domain.Apps.Core.Rules { T Visit(AlgoliaAction action); + T Visit(AzureQueueAction action); + T Visit(SlackAction action); T Visit(WebhookAction action); diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AzureQueueActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AzureQueueActionHandler.cs new file mode 100644 index 000000000..92e28ba1b --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AzureQueueActionHandler.cs @@ -0,0 +1,72 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; +using Microsoft.WindowsAzure.Storage; +using Microsoft.WindowsAzure.Storage.Queue; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Squidex.Domain.Apps.Core.Rules; +using Squidex.Domain.Apps.Core.Rules.Actions; +using Squidex.Domain.Apps.Events; +using Squidex.Infrastructure; +using Squidex.Infrastructure.EventSourcing; + +namespace Squidex.Domain.Apps.Core.HandleRules.Actions +{ + public sealed class AzureQueueActionHandler : RuleActionHandler + { + private readonly ConcurrentDictionary<(string ConnectionString, string QueueName), CloudQueue> queues = new ConcurrentDictionary<(string ConnectionString, string QueueName), CloudQueue>(); + private readonly RuleEventFormatter formatter; + + public AzureQueueActionHandler(RuleEventFormatter formatter) + { + Guard.NotNull(formatter, nameof(formatter)); + + this.formatter = formatter; + } + + protected override (string Description, RuleJobData Data) CreateJob(Envelope @event, string eventName, AzureQueueAction action) + { + var body = formatter.ToRouteData(@event, eventName); + + var ruleDescription = $"Send event to azure queue '{action.Queue}'"; + var ruleData = new RuleJobData + { + ["QueueConnectionString"] = action.ConnectionString, + ["QueueName"] = action.Queue, + ["MessageBody"] = body + }; + + return (ruleDescription, ruleData); + } + + public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job) + { + var queueConnectionString = job["QueueConnectionString"].Value(); + var queueName = job["QueueName"].Value(); + + var queue = queues.GetOrAdd((queueConnectionString, queueName), s => + { + var storageAccount = CloudStorageAccount.Parse(queueConnectionString); + + var queueClient = storageAccount.CreateCloudQueueClient(); + var queueRef = queueClient.GetQueueReference(queueName); + + return queueRef; + }); + + var messageBody = job["MessageBody"].ToString(Formatting.Indented); + + await queue.AddMessageAsync(new CloudQueueMessage(messageBody)); + + return ("Completed", null); + } + } +} diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs index 9899c5a2e..dc10c3afd 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs @@ -49,31 +49,30 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions private JObject CreatePayload(Envelope @event, string text) { - return new JObject( - new JProperty("text", formatter.FormatString(text, @event))); + return new JObject(new JProperty("text", formatter.FormatString(text, @event))); } public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job) { var requestBody = job["RequestBody"].ToString(Formatting.Indented); - var request = BuildRequest(job, requestBody); + var requestMsg = BuildRequest(job, requestBody); HttpResponseMessage response = null; try { - response = await Client.SendAsync(request); + response = await Client.SendAsync(requestMsg); var responseString = await response.Content.ReadAsStringAsync(); - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, responseString, TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, responseString, TimeSpan.Zero, false); return (requestDump, null); } catch (Exception ex) { - if (request != null) + if (requestMsg != null) { - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, ex.ToString(), TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, ex.ToString(), TimeSpan.Zero, false); return (requestDump, ex); } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs index 88baca09f..bb0d00cbd 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs @@ -35,11 +35,11 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions protected override (string Description, RuleJobData Data) CreateJob(Envelope @event, string eventName, WebhookAction action) { - var body = CreatePayload(@event, eventName); + var body = formatter.ToRouteData(@event, eventName); var signature = $"{body.ToString(Formatting.Indented)}{action.SharedSecret}".Sha256Base64(); - var ruleDescription = $"Send event to webhook {action.Url}"; + var ruleDescription = $"Send event to webhook '{action.Url}'"; var ruleData = new RuleJobData { ["RequestUrl"] = action.Url, @@ -50,18 +50,10 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions return (ruleDescription, ruleData); } - private JObject CreatePayload(Envelope @event, string eventName) - { - return new JObject( - new JProperty("type", eventName), - new JProperty("payload", formatter.ToRouteData(@event.Payload)), - new JProperty("timestamp", @event.Headers.Timestamp().ToString())); - } - public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job) { var requestBody = job["RequestBody"].ToString(Formatting.Indented); - var request = BuildRequest(job, requestBody); + var requestMsg = BuildRequest(job, requestBody); HttpResponseMessage response = null; @@ -69,19 +61,19 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions { using (var client = new HttpClient { Timeout = Timeout }) { - response = await client.SendAsync(request); + response = await client.SendAsync(requestMsg); var responseString = await response.Content.ReadAsStringAsync(); - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, responseString, TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, responseString, TimeSpan.Zero, false); return (requestDump, null); } } catch (Exception ex) { - if (request != null) + if (requestMsg != null) { - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, ex.ToString(), TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, ex.ToString(), TimeSpan.Zero, false); return (requestDump, ex); } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs index 9b0d70043..0e64960f9 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs @@ -43,6 +43,14 @@ namespace Squidex.Domain.Apps.Core.HandleRules return JToken.FromObject(value, serializer); } + public virtual JToken ToRouteData(Envelope @event, string eventName) + { + return new JObject( + new JProperty("type", eventName), + new JProperty("payload", JToken.FromObject(@event.Payload, serializer)), + new JProperty("timestamp", @event.Headers.Timestamp().ToString())); + } + public virtual string FormatString(string text, Envelope @event) { var sb = new StringBuilder(text); diff --git a/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj b/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj index 631f0b094..8a5057653 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj +++ b/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj @@ -23,6 +23,7 @@ + ..\..\Squidex.ruleset diff --git a/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs b/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs index b2801f751..7cb300d54 100644 --- a/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs +++ b/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs @@ -6,6 +6,7 @@ // ========================================================================== using System.Collections.Generic; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules.Actions; @@ -46,6 +47,27 @@ namespace Squidex.Domain.Apps.Entities.Rules.Guards return Task.FromResult>(errors); } + public Task> Visit(AzureQueueAction action) + { + var errors = new List(); + + if (string.IsNullOrWhiteSpace(action.ConnectionString)) + { + errors.Add(new ValidationError("Connection string must be defined.", nameof(action.ConnectionString))); + } + + if (string.IsNullOrWhiteSpace(action.Queue)) + { + errors.Add(new ValidationError("Queue must be defined.", nameof(action.Queue))); + } + else if (!Regex.IsMatch(action.Queue, "^[a-z][a-z0-9]{2,}(\\-[a-z0-9]+)*$")) + { + errors.Add(new ValidationError("Queue must be valid azure queue name.", nameof(action.Queue))); + } + + return Task.FromResult>(errors); + } + public Task> Visit(SlackAction action) { var errors = new List(); diff --git a/src/Squidex/Areas/Api/Controllers/Rules/Models/Actions/AzureQueueActionDto.cs b/src/Squidex/Areas/Api/Controllers/Rules/Models/Actions/AzureQueueActionDto.cs new file mode 100644 index 000000000..bfcafb1ac --- /dev/null +++ b/src/Squidex/Areas/Api/Controllers/Rules/Models/Actions/AzureQueueActionDto.cs @@ -0,0 +1,36 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.ComponentModel.DataAnnotations; +using NJsonSchema.Annotations; +using Squidex.Domain.Apps.Core.Rules; +using Squidex.Domain.Apps.Core.Rules.Actions; +using Squidex.Infrastructure.Reflection; + +namespace Squidex.Areas.Api.Controllers.Rules.Models.Actions +{ + [JsonSchema("AzureQueue")] + public class AzureQueueActionDto : RuleActionDto + { + /// + /// The connection string to the storage account. + /// + [Required] + public string ConnectionString { get; set; } + + /// + /// The queue name. + /// + [Required] + public string Queue { get; set; } + + public override RuleAction ToAction() + { + return SimpleMapper.Map(this, new AzureQueueAction()); + } + } +} diff --git a/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs b/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs index 1d3ab43b2..6fee353e9 100644 --- a/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs +++ b/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs @@ -30,6 +30,11 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models.Converters return SimpleMapper.Map(action, new AlgoliaActionDto()); } + public RuleActionDto Visit(AzureQueueAction action) + { + return SimpleMapper.Map(action, new AzureQueueActionDto()); + } + public RuleActionDto Visit(SlackAction action) { return SimpleMapper.Map(action, new SlackActionDto()); diff --git a/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs b/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs index 21b9cc39b..7a6643d18 100644 --- a/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs @@ -14,6 +14,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models { [JsonConverter(typeof(JsonInheritanceConverter), "actionType")] [KnownType(typeof(AlgoliaActionDto))] + [KnownType(typeof(AzureQueueActionDto))] [KnownType(typeof(SlackActionDto))] [KnownType(typeof(WebhookActionDto))] public abstract class RuleActionDto diff --git a/src/Squidex/Config/Domain/ReadServices.cs b/src/Squidex/Config/Domain/ReadServices.cs index 1a24fedd5..d6e8e4979 100644 --- a/src/Squidex/Config/Domain/ReadServices.cs +++ b/src/Squidex/Config/Domain/ReadServices.cs @@ -98,6 +98,9 @@ namespace Squidex.Config.Domain services.AddSingletonAs() .As(); + services.AddSingletonAs() + .As(); + services.AddSingletonAs() .As(); diff --git a/src/Squidex/app/features/rules/declarations.ts b/src/Squidex/app/features/rules/declarations.ts index 815788500..e4ead5d30 100644 --- a/src/Squidex/app/features/rules/declarations.ts +++ b/src/Squidex/app/features/rules/declarations.ts @@ -6,6 +6,7 @@ */ export * from './pages/rules/actions/algolia-action.component'; +export * from './pages/rules/actions/azure-queue-action.component'; export * from './pages/rules/actions/slack-action.component'; export * from './pages/rules/actions/webhook-action.component'; export * from './pages/rules/triggers/content-changed-trigger.component'; diff --git a/src/Squidex/app/features/rules/module.ts b/src/Squidex/app/features/rules/module.ts index d9630a213..6a95936fb 100644 --- a/src/Squidex/app/features/rules/module.ts +++ b/src/Squidex/app/features/rules/module.ts @@ -16,6 +16,7 @@ import { import { AlgoliaActionComponent, + AzureQueueActionComponent, ContentChangedTriggerComponent, RuleEventsPageComponent, RulesPageComponent, @@ -52,6 +53,7 @@ const routes: Routes = [ ], declarations: [ AlgoliaActionComponent, + AzureQueueActionComponent, ContentChangedTriggerComponent, RuleEventsPageComponent, RulesPageComponent, diff --git a/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html index f7e39f603..8e9594229 100644 --- a/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html +++ b/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html @@ -1,8 +1,8 @@
- + -
+
@@ -14,9 +14,9 @@
- + -
+
@@ -28,9 +28,9 @@
- + -
+
diff --git a/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html new file mode 100644 index 000000000..0a5a6831d --- /dev/null +++ b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html @@ -0,0 +1,29 @@ + +
+ + +
+ + + + + + The connection string to the storage account. + +
+
+ +
+ + +
+ + + + + + The name of the queue. + +
+
+ \ No newline at end of file diff --git a/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.scss b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.scss new file mode 100644 index 000000000..fbb752506 --- /dev/null +++ b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.scss @@ -0,0 +1,2 @@ +@import '_vars'; +@import '_mixins'; \ No newline at end of file diff --git a/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.ts b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.ts new file mode 100644 index 000000000..0556f59a1 --- /dev/null +++ b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.ts @@ -0,0 +1,61 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, Validators } from '@angular/forms'; + +import { ValidatorsEx } from 'shared'; + +@Component({ + selector: 'sqx-azure-queue-action', + styleUrls: ['./azure-queue-action.component.scss'], + templateUrl: './azure-queue-action.component.html' +}) +export class AzureQueueActionComponent implements OnInit { + @Input() + public action: any; + + @Output() + public actionChanged = new EventEmitter(); + + public actionFormSubmitted = false; + public actionForm = + this.formBuilder.group({ + connectionString: ['', + [ + Validators.required + ]], + queue: ['squidex', + [ + Validators.required, + ValidatorsEx.pattern('[a-z][a-z0-9]{2,}(\-[a-z0-9]+)*', 'Name must be a valid azure queue name.') + ]] + }); + + constructor( + private readonly formBuilder: FormBuilder + ) { + } + + public ngOnInit() { + this.action = Object.assign({}, { connectionString: '', queue: 'squidex' }, this.action || {}); + + this.actionFormSubmitted = false; + this.actionForm.reset(); + this.actionForm.setValue(this.action); + } + + public save() { + this.actionFormSubmitted = true; + + if (this.actionForm.valid) { + const action = this.actionForm.value; + + this.actionChanged.emit(action); + } + } +} \ No newline at end of file diff --git a/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html index 4a278f6aa..37c237b09 100644 --- a/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html +++ b/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html @@ -1,8 +1,8 @@
- + -
+
@@ -14,9 +14,9 @@
- + -
+
diff --git a/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html index b643d8cef..f85e3b298 100644 --- a/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html +++ b/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html @@ -1,8 +1,8 @@
- + -
+
@@ -14,9 +14,9 @@
- + -
+
diff --git a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html index cb1d67acf..77cad1927 100644 --- a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html +++ b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html @@ -68,6 +68,12 @@ (actionChanged)="selectAction($event)">
+
+ + +
+
+
+ + + + icon-action-AzureQueue +
+
+ + +
+
+ liga: + +
+
diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.eot b/src/Squidex/app/theme/icomoon/fonts/icomoon.eot index 1430ee4632c2d05d5de487434cdde3a839702500..af30e1e7940e740a3ae10653030ffaaa0b635b13 100644 GIT binary patch delta 55 zcmbQUo^j54#tAme-4!P%+HYg-UwVDxkIo?JlNH_Z{5D@1xLFuL;M$B0t6}uwIl(Ld Di?kLA delta 55 zcmbQUo^j54#tAme+*)@g+HYfS^A+FtqcceQjuv-3zs*+$ZWaa*xHg5w8%8gl6U+ht D7Bmr3 diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.svg b/src/Squidex/app/theme/icomoon/fonts/icomoon.svg index 068a00b7a..b87ca2593 100644 --- a/src/Squidex/app/theme/icomoon/fonts/icomoon.svg +++ b/src/Squidex/app/theme/icomoon/fonts/icomoon.svg @@ -71,7 +71,7 @@ - + diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.ttf b/src/Squidex/app/theme/icomoon/fonts/icomoon.ttf index e279c01a10cc62ec930217d685ce091910347fc9..7bcee5687c8b6c5394a8493125e98671d2222f74 100644 GIT binary patch delta 48 wcmeydmhs10#tDJU{Y$TJ4CxG#K3UNn&u{aUft!T^1g_24uo^}${t?6i0P&dA3-btor@1R diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.woff b/src/Squidex/app/theme/icomoon/fonts/icomoon.woff index d2f1d093690d8440e2442402cd9dd7c9a31c12b1..0eb4b51999378b90175b5b74349257fb6bcf2e96 100644 GIT binary patch delta 48 wcmX@Ij`7Gk#tFU5{Y$TJoG>#;`ea3SJipCX25uGx5V$sD!)h44*d>?+0PyA#qW}N^ delta 48 vcmX@Ij`7Gk#tFU5ZNB0gC(I0zzN5t*&u{aUft!T^1g=eC@rKchU4mHvoY)Sh diff --git a/src/Squidex/app/theme/icomoon/selection.json b/src/Squidex/app/theme/icomoon/selection.json index 4392c15c9..af9b52817 100644 --- a/src/Squidex/app/theme/icomoon/selection.json +++ b/src/Squidex/app/theme/icomoon/selection.json @@ -2121,7 +2121,7 @@ "id": 1, "prevSize": 32, "code": 59712, - "name": "microsoft" + "name": "microsoft, action-AzureQueue" }, "setIdx": 2, "setId": 1, diff --git a/src/Squidex/app/theme/icomoon/style.css b/src/Squidex/app/theme/icomoon/style.css index 5a9cd9d98..435cb8160 100644 --- a/src/Squidex/app/theme/icomoon/style.css +++ b/src/Squidex/app/theme/icomoon/style.css @@ -1,10 +1,10 @@ @font-face { font-family: 'icomoon'; - src: url('fonts/icomoon.eot?fb43dg'); - src: url('fonts/icomoon.eot?fb43dg#iefix') format('embedded-opentype'), - url('fonts/icomoon.ttf?fb43dg') format('truetype'), - url('fonts/icomoon.woff?fb43dg') format('woff'), - url('fonts/icomoon.svg?fb43dg#icomoon') format('svg'); + src: url('fonts/icomoon.eot?knmn0p'); + src: url('fonts/icomoon.eot?knmn0p#iefix') format('embedded-opentype'), + url('fonts/icomoon.ttf?knmn0p') format('truetype'), + url('fonts/icomoon.woff?knmn0p') format('woff'), + url('fonts/icomoon.svg?knmn0p#icomoon') format('svg'); font-weight: normal; font-style: normal; } @@ -265,6 +265,9 @@ .icon-microsoft:before { content: "\e940"; } +.icon-action-AzureQueue:before { + content: "\e940"; +} .icon-pause:before { content: "\e92f"; }