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