mirror of https://github.com/Squidex/squidex.git
33 changed files with 431 additions and 53 deletions
@ -0,0 +1,28 @@ |
|||||
|
// ==========================================================================
|
||||
|
// 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.Triggers |
||||
|
{ |
||||
|
[TypeName(nameof(AssetChangedTrigger))] |
||||
|
public sealed class AssetChangedTrigger : RuleTrigger |
||||
|
{ |
||||
|
public bool SendCreate { get; set; } |
||||
|
|
||||
|
public bool SendUpdate { get; set; } |
||||
|
|
||||
|
public bool SendRename { get; set; } |
||||
|
|
||||
|
public bool SendDelete { get; set; } |
||||
|
|
||||
|
public override T Accept<T>(IRuleTriggerVisitor<T> visitor) |
||||
|
{ |
||||
|
return visitor.Visit(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
|
||||
|
#pragma warning disable RECS0108 // Warns about static fields in generic types
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.HandleRules |
||||
|
{ |
||||
|
internal sealed class ClientPool<TKey, TClient> |
||||
|
{ |
||||
|
private static readonly TimeSpan TTL = TimeSpan.FromMinutes(30); |
||||
|
private readonly MemoryCache memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions())); |
||||
|
private readonly Func<TKey, TClient> factory; |
||||
|
|
||||
|
public ClientPool(Func<TKey, TClient> factory) |
||||
|
{ |
||||
|
this.factory = factory; |
||||
|
} |
||||
|
|
||||
|
public TClient GetClient(TKey key) |
||||
|
{ |
||||
|
if (!memoryCache.TryGetValue<TClient>(key, out var client)) |
||||
|
{ |
||||
|
client = factory(key); |
||||
|
|
||||
|
memoryCache.Set(key, client, TTL); |
||||
|
} |
||||
|
|
||||
|
return client; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Net.Http; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.HandleRules |
||||
|
{ |
||||
|
public static class HttpClientPool |
||||
|
{ |
||||
|
private static readonly ClientPool<string, HttpClient> Pool = new ClientPool<string, HttpClient>(key => |
||||
|
{ |
||||
|
return new HttpClient { Timeout = TimeSpan.FromSeconds(2) }; |
||||
|
}); |
||||
|
|
||||
|
public static HttpClient GetHttpClient() |
||||
|
{ |
||||
|
return Pool.GetClient(string.Empty); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Rules.Triggers; |
||||
|
using Squidex.Domain.Apps.Events; |
||||
|
using Squidex.Domain.Apps.Events.Assets; |
||||
|
using Squidex.Infrastructure.EventSourcing; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.HandleRules.Triggers |
||||
|
{ |
||||
|
public sealed class AssetChangedTriggerHandler : RuleTriggerHandler<AssetChangedTrigger> |
||||
|
{ |
||||
|
protected override bool Triggers(Envelope<AppEvent> @event, AssetChangedTrigger trigger) |
||||
|
{ |
||||
|
return @event.Payload is AssetEvent assetEvent && MatchsType(trigger, assetEvent); |
||||
|
} |
||||
|
|
||||
|
private static bool MatchsType(AssetChangedTrigger trigger, AssetEvent @event) |
||||
|
{ |
||||
|
return |
||||
|
(trigger.SendCreate && @event is AssetCreated) || |
||||
|
(trigger.SendUpdate && @event is AssetUpdated) || |
||||
|
(trigger.SendDelete && @event is AssetDeleted) || |
||||
|
(trigger.SendRename && @event is AssetRenamed); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using NJsonSchema.Annotations; |
||||
|
using Squidex.Domain.Apps.Core.Rules; |
||||
|
using Squidex.Domain.Apps.Core.Rules.Triggers; |
||||
|
using Squidex.Infrastructure.Reflection; |
||||
|
|
||||
|
namespace Squidex.Areas.Api.Controllers.Rules.Models.Triggers |
||||
|
{ |
||||
|
[JsonSchema("AssetChanged")] |
||||
|
public sealed class AssetChangedTriggerDto : RuleTriggerDto |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Determines whether to handle the event when an asset is created.
|
||||
|
/// </summary>
|
||||
|
public bool SendCreate { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines whether to handle the event when an asset is updated.
|
||||
|
/// </summary>
|
||||
|
public bool SendUpdate { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines whether to handle the event when an asset is renamed.
|
||||
|
/// </summary>
|
||||
|
public bool SendRename { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines whether to handle the event when an asset is deleted.
|
||||
|
/// </summary>
|
||||
|
public bool SendDelete { get; set; } |
||||
|
|
||||
|
public override RuleTrigger ToTrigger() |
||||
|
{ |
||||
|
return SimpleMapper.Map(this, new AssetChangedTrigger()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
<h3>Trigger rule when asset has been...</h3> |
||||
|
|
||||
|
|
||||
|
<form [formGroup]="triggerForm" class="form-horizontal" (ngSubmit)="save()"> |
||||
|
<div class="form-group"> |
||||
|
<div class="form-check"> |
||||
|
<input class="form-check-input" type="checkbox" id="sendCreate" formControlName="sendCreate"> |
||||
|
<label class="form-check-label" for="sendCreate"> |
||||
|
created |
||||
|
</label> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<div class="form-check"> |
||||
|
<input class="form-check-input" type="checkbox" id="sendUpdate" formControlName="sendUpdate"> |
||||
|
<label class="form-check-label" for="sendUpdate"> |
||||
|
updated |
||||
|
</label> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<div class="form-check"> |
||||
|
<input class="form-check-input" type="checkbox" id="sendRename" formControlName="sendRename"> |
||||
|
<label class="form-check-label" for="sendRename"> |
||||
|
renamed |
||||
|
</label> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<div class="form-check"> |
||||
|
<input class="form-check-input" type="checkbox" id="sendDelete" formControlName="sendDelete"> |
||||
|
<label class="form-check-label" for="sendDelete"> |
||||
|
deleted |
||||
|
</label> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
@ -0,0 +1,2 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
@ -0,0 +1,59 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; |
||||
|
import { FormBuilder } from '@angular/forms'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'sqx-asset-changed-trigger', |
||||
|
styleUrls: ['./asset-changed-trigger.component.scss'], |
||||
|
templateUrl: './asset-changed-trigger.component.html' |
||||
|
}) |
||||
|
export class AssetChangedTriggerComponent implements OnInit { |
||||
|
@Input() |
||||
|
public trigger: any; |
||||
|
|
||||
|
@Output() |
||||
|
public triggerChanged = new EventEmitter<object>(); |
||||
|
|
||||
|
public triggerFormSubmitted = false; |
||||
|
public triggerForm = |
||||
|
this.formBuilder.group({ |
||||
|
sendCreate: false, |
||||
|
sendUpdate: false, |
||||
|
sendRename: false, |
||||
|
sendDelete: false |
||||
|
}); |
||||
|
|
||||
|
constructor( |
||||
|
private readonly formBuilder: FormBuilder |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.trigger = Object.assign({}, { |
||||
|
sendCreate: false, |
||||
|
sendUpdate: false, |
||||
|
sendRename: false, |
||||
|
sendDelete: false |
||||
|
}, this.trigger || {}); |
||||
|
|
||||
|
this.triggerFormSubmitted = false; |
||||
|
this.triggerForm.reset(); |
||||
|
this.triggerForm.setValue(this.trigger); |
||||
|
} |
||||
|
|
||||
|
public save() { |
||||
|
this.triggerFormSubmitted = true; |
||||
|
|
||||
|
if (this.triggerForm.valid) { |
||||
|
const trigger = this.triggerForm.value; |
||||
|
|
||||
|
this.triggerChanged.emit(trigger); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Binary file not shown.
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,60 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using Squidex.Domain.Apps.Core.HandleRules; |
||||
|
using Squidex.Domain.Apps.Core.HandleRules.Triggers; |
||||
|
using Squidex.Domain.Apps.Core.Rules.Triggers; |
||||
|
using Squidex.Domain.Apps.Events; |
||||
|
using Squidex.Domain.Apps.Events.Assets; |
||||
|
using Squidex.Domain.Apps.Events.Rules; |
||||
|
using Squidex.Infrastructure.EventSourcing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Operations.HandleRules.Triggers |
||||
|
{ |
||||
|
public sealed class AssetChangedTriggerTests |
||||
|
{ |
||||
|
private readonly IRuleTriggerHandler sut = new AssetChangedTriggerHandler(); |
||||
|
|
||||
|
public static IEnumerable<object[]> TestData |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return new[] |
||||
|
{ |
||||
|
new object[] { 0, 1, 1, 1, 1, new RuleCreated() }, |
||||
|
new object[] { 1, 1, 0, 0, 0, new AssetCreated() }, |
||||
|
new object[] { 0, 0, 0, 0, 0, new AssetCreated() }, |
||||
|
new object[] { 1, 0, 1, 0, 0, new AssetUpdated() }, |
||||
|
new object[] { 0, 0, 0, 0, 0, new AssetUpdated() }, |
||||
|
new object[] { 1, 0, 0, 1, 0, new AssetRenamed() }, |
||||
|
new object[] { 0, 0, 0, 0, 0, new AssetRenamed() }, |
||||
|
new object[] { 1, 0, 0, 0, 1, new AssetDeleted() }, |
||||
|
new object[] { 0, 0, 0, 0, 0, new AssetDeleted() } |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Theory] |
||||
|
[MemberData(nameof(TestData))] |
||||
|
public void Should_return_result_depending_on_event(int expected, int sendCreate, int sendUpdate, int sendRename, int sendDelete, AppEvent @event) |
||||
|
{ |
||||
|
var trigger = new AssetChangedTrigger |
||||
|
{ |
||||
|
SendCreate = sendCreate == 1, |
||||
|
SendUpdate = sendUpdate == 1, |
||||
|
SendRename = sendRename == 1, |
||||
|
SendDelete = sendDelete == 1 |
||||
|
}; |
||||
|
|
||||
|
var result = sut.Triggers(new Envelope<AppEvent>(@event), trigger); |
||||
|
|
||||
|
Assert.Equal(expected == 1, result); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue