Browse Source

feat: Add Webhooks Activities Module

pull/1568/head
colin 2 weeks ago
parent
commit
06adc1d0d1
  1. 3
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/LINGYUN.Abp.MicroService.WorkflowService.csproj
  2. 10
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.Configure.cs
  3. 7
      aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.cs
  4. 17
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/AbpElsaNextStudioWebhooksBlazorModule.cs
  5. 130
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Components/WebhookPicker.razor
  6. 156
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Components/WebhookSelectDialog.razor
  7. 13
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Extensions/ServiceCollectionExtensions.cs
  8. 3
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/FodyWeavers.xml
  9. 30
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/FodyWeavers.xsd
  10. 25
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Handlers/WebhookPickerHandler.cs
  11. 20
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.csproj
  12. 5
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/_Imports.razor
  13. 3
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/FodyWeavers.xml
  14. 30
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/FodyWeavers.xsd
  15. 26
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN.Abp.ElsaNext.Webhooks.csproj
  16. 38
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/AbpElsaNextWebhooksModule.cs
  17. 60
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Activities/PublishWebhook.cs
  18. 14
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Extensions/ModuleExtensions.cs
  19. 17
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Features/WebhooksFeature.cs
  20. 12
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Localization/Resources/en.json
  21. 12
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Localization/Resources/zh-Hans.json
  22. 6
      aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/UIHints/WebhooksUIHints.cs

3
aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/LINGYUN.Abp.MicroService.WorkflowService.csproj

@ -82,6 +82,7 @@
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.Quartz.PostgresSqlInstaller\LINGYUN.Abp.Quartz.PostgresSqlInstaller.csproj" />
<ProjectReference Include="..\..\modules\task-management\LINGYUN.Abp.TaskManagement.EntityFrameworkCore\LINGYUN.Abp.TaskManagement.EntityFrameworkCore.csproj" />-->
<ProjectReference Include="..\..\modules\text-templating\LINGYUN.Abp.TextTemplating.EntityFrameworkCore\LINGYUN.Abp.TextTemplating.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\webhooks\LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore\LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore.csproj" />
</ItemGroup>
<ItemGroup>
@ -98,6 +99,8 @@
<ProjectReference Include="..\..\modules\elsa\LINGYUN.Abp.ElsaNext.Studio.Identity.Blazor\LINGYUN.Abp.ElsaNext.Studio.Identity.Blazor.csproj" />
<ProjectReference Include="..\..\modules\elsa\LINGYUN.Abp.ElsaNext.Studio.Notifications.Blazor\LINGYUN.Abp.ElsaNext.Studio.Notifications.Blazor.csproj" />
<ProjectReference Include="..\..\modules\elsa\LINGYUN.Abp.ElsaNext.Studio.Saas.Blazor\LINGYUN.Abp.ElsaNext.Studio.Saas.Blazor.csproj" />
<ProjectReference Include="..\..\modules\elsa\LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor\LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.csproj" />
<ProjectReference Include="..\..\modules\elsa\LINGYUN.Abp.ElsaNext.Webhooks\LINGYUN.Abp.ElsaNext.Webhooks.csproj" />
</ItemGroup>
<ItemGroup>

10
aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.Configure.cs

@ -17,6 +17,7 @@ using LINGYUN.Abp.MicroService.WorkflowService.Extensions;
using LINGYUN.Abp.MicroService.WorkflowService.Navigation;
using LINGYUN.Abp.Notifications;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.WebhooksManagement;
using Localization.Resources.AbpUi;
using Medallion.Threading;
using Medallion.Threading.Redis;
@ -352,6 +353,15 @@ public partial class WorkflowServiceModule
});
}
private void ConfigureWebhooksManagement()
{
Configure<WebhooksManagementOptions>(options =>
{
options.IsDynamicWebhookStoreEnabled = true;
options.SaveStaticWebhooksToDatabase = false;
});
}
private void ConfigureMultiTenancy(IConfiguration configuration)
{
// 多租户

7
aspnet-core/aspire/LINGYUN.Abp.MicroService.WorkflowService/WorkflowServiceModule.cs

@ -19,6 +19,8 @@ using LINGYUN.Abp.ElsaNext.Studio.Diagnostics.StructuredLogs.Blazor;
using LINGYUN.Abp.ElsaNext.Studio.Identity.Blazor;
using LINGYUN.Abp.ElsaNext.Studio.Notifications.Blazor;
using LINGYUN.Abp.ElsaNext.Studio.Saas.Blazor;
using LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor;
using LINGYUN.Abp.ElsaNext.Webhooks;
using LINGYUN.Abp.Emailing.Platform;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling.Emailing;
@ -31,6 +33,7 @@ using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
using LINGYUN.Abp.Sms.Platform;
using LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
@ -63,6 +66,7 @@ namespace LINGYUN.Abp.MicroService.WorkflowService;
typeof(AbpElsaNextBlobStoringModule),
typeof(AbpElsaNextEmailModule),
typeof(AbpElsaNextNotificationsModule),
typeof(AbpElsaNextWebhooksModule),
typeof(AbpElsaNextServerModule),
typeof(AbpElsaNextStudioBlazorModule),
typeof(AbpElsaNextAgentsBlazorModule),
@ -73,6 +77,7 @@ namespace LINGYUN.Abp.MicroService.WorkflowService;
typeof(AbpElsaNextStudioIdentityBlazorModule),
typeof(AbpElsaNextStudioNotificationsBlazorModule),
typeof(AbpElsaNextStudioSaasBlazorModule),
typeof(AbpElsaNextStudioWebhooksBlazorModule),
typeof(AbpEmailingExceptionHandlingModule),
typeof(AbpHttpClientIdentityModelWebModule),
typeof(AbpAspNetCoreMultiTenancyModule),
@ -87,6 +92,7 @@ namespace LINGYUN.Abp.MicroService.WorkflowService;
typeof(AbpIdentityEntityFrameworkCoreModule),
typeof(AbpLocalizationManagementEntityFrameworkCoreModule),
typeof(AbpNotificationsEntityFrameworkCoreModule),
typeof(WebhooksManagementEntityFrameworkCoreModule),
typeof(AbpAuthorizationOrganizationUnitsModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpAspNetCoreAuthenticationOpenIdConnectModule),
@ -135,6 +141,7 @@ public partial class WorkflowServiceModule : AbpModule
ConfigureVirtualFileSystem();
ConfigureNotificationsManagement();
ConfigurePermissionManagement();
ConfigureWebhooksManagement();
ConfigureTiming(configuration);
ConfigureCaching(configuration);
ConfigureAuditing(configuration);

17
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/AbpElsaNextStudioWebhooksBlazorModule.cs

@ -0,0 +1,17 @@
using LINGYUN.Abp.ElsaNext.Studio.Blazor;
using LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.Extensions;
using LINGYUN.Abp.ElsaNext.Webhooks;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor;
[DependsOn(
typeof(AbpElsaNextWebhooksModule),
typeof(AbpElsaNextStudioBlazorModule))]
public class AbpElsaNextStudioWebhooksBlazorModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddWebhooksUIHintHandlers();
}
}

130
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Components/WebhookPicker.razor

@ -0,0 +1,130 @@
@using Elsa.Api.Client.Shared.UIHints.DropDown
@using Elsa.Studio.Models
@using LINGYUN.Abp.ElsaNext.Studio.Blazor.Components
@using LINGYUN.Abp.Webhooks
@using Microsoft.Extensions.Localization
@inject ILocalizer Localizer
@inherits StudioComponentBase
@{
var inputDescriptor = EditorContext.InputDescriptor;
var displayName = inputDescriptor.DisplayName;
var description = inputDescriptor.Description;
}
<ExpressionInput EditorContext="@EditorContext">
<ChildContent>
<MudTextFieldEx Value="@(_selectedItem?.Text ?? string.Empty)"
Label="@Localizer[displayName]"
HelperText="@Localizer[description]"
Variant="Variant.Outlined"
Margin="Margin.Dense"
ReadOnly="true"
Disabled="EditorContext.IsReadOnly"
OnFieldClick="@(_ => OpenSelectDialogAsync())"
AdornmentIcons="GetAdornmentIcons()" />
</ChildContent>
</ExpressionInput>
@code {
private SelectListItem? _selectedItem;
[Parameter] public DisplayInputEditorContext EditorContext { get; set; } = null!;
[Inject] protected IDialogService DialogService { get; set; } = null!;
[Inject] private IStringLocalizerFactory StringLocalizerFactory { get; set; } = null!;
[Inject] private IWebhookDefinitionManager WebhookDefinitionManager { get; set; } = null!;
protected async override Task OnInitializedAsync()
{
var selectedItem = await ResolveSelectedItemAsync();
if (selectedItem != null)
{
await InvokeAsync(() => _selectedItem = selectedItem);
}
}
private async Task<SelectListItem?> ResolveSelectedItemAsync()
{
var value = EditorContext.GetLiteralValueOrDefault();
if (string.IsNullOrWhiteSpace(value))
{
return null;
}
var webhookDefine = await WebhookDefinitionManager.GetOrNullAsync(value);
if (webhookDefine != null)
{
return new SelectListItem(
webhookDefine.DisplayName != null
? webhookDefine.DisplayName.Localize(StringLocalizerFactory)
: webhookDefine.Name,
webhookDefine.Name);
}
return new SelectListItem(value, value);
}
private async Task OpenSelectDialogAsync()
{
if (EditorContext.IsReadOnly)
{
return;
}
var inputDescriptor = EditorContext.InputDescriptor;
var parameters = new DialogParameters<WebhookSelectDialog>
{
{ x => x.Title, Localizer[inputDescriptor.DisplayName ?? inputDescriptor.Name] },
{ x => x.SelectedValue, _selectedItem?.Value }
};
var options = new DialogOptions
{
CloseOnEscapeKey = true,
FullWidth = true,
MaxWidth = MaxWidth.Medium
};
var dialog = await DialogService.ShowAsync<WebhookSelectDialog>(string.Empty, parameters, options);
var result = await dialog.Result;
if (result is { Canceled: false, Data: SelectListItem item })
{
await InvokeAsync(async () =>
{
_selectedItem = item;
await EditorContext.UpdateValueOrLiteralExpressionAsync(item.Value);
});
}
}
private MudTextFieldExIcon[] GetAdornmentIcons() =>
[
new()
{
Icon = Icons.Material.Filled.Search,
Tooltip = Localizer["Search"],
Disabled = EditorContext.IsReadOnly,
OnClick = OpenSelectDialogAsync
},
new()
{
Icon = Icons.Material.Filled.Clear,
Tooltip = Localizer["Clear"],
Visible = _selectedItem != null,
Disabled = EditorContext.IsReadOnly,
OnClick = ClearAsync
}
];
private async Task ClearAsync()
{
await InvokeAsync(async () =>
{
_selectedItem = null;
await EditorContext.UpdateValueOrLiteralExpressionAsync(string.Empty);
});
}
}

156
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Components/WebhookSelectDialog.razor

@ -0,0 +1,156 @@
@using System.Threading
@using Elsa.Api.Client.Shared.UIHints.DropDown
@using LINGYUN.Abp.Webhooks
@using Microsoft.Extensions.Localization
@inject ILocalizer Localizer
@implements IDisposable
<MudDialog>
<TitleContent>
<MudText Typo="Typo.h6">@Title</MudText>
</TitleContent>
<DialogContent>
<MudStack Spacing="3">
<MudTextField T="string"
Value="_searchText"
ValueChanged="OnSearchTextChangedAsync"
Immediate="true"
Placeholder="@Localizer["Search"]"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search"
Variant="Variant.Outlined"
Margin="Margin.Dense" />
<MudTable T="SelectListItem"
@ref="_table"
ServerData="LoadTenantsAsync"
Dense="true"
Hover="true"
Breakpoint="Breakpoint.None"
OnRowClick="OnRowClickAsync">
<HeaderContent>
<MudTh>@Localizer["Name"]</MudTh>
<MudTh Style="text-align:right" />
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="@Localizer["Name"]">@context.Text</MudTd>
<MudTd DataLabel="" Style="text-align:right">
@if (context.Value == SelectedValue)
{
<MudIcon Icon="@Icons.Material.Filled.Check" Color="Color.Success" Size="Size.Small" />
}
else
{
<MudButton Size="Size.Small" Variant="Variant.Text" Color="Color.Primary" OnClick="@(() => SelectAsync(context))">
@Localizer["Select"]
</MudButton>
}
</MudTd>
</RowTemplate>
<PagerContent>
<MudTablePager PageSizeOptions="new int[] { 10, 25, 50, 100 }" />
</PagerContent>
<NoRecordsContent>
<MudText Typo="Typo.body2">@Localizer["No results found"]</MudText>
</NoRecordsContent>
</MudTable>
</MudStack>
</DialogContent>
<DialogActions>
<MudButton Variant="Variant.Text" OnClick="CancelAsync">@Localizer["Cancel"]</MudButton>
</DialogActions>
</MudDialog>
@code {
private const int DebounceIntervalMilliseconds = 350;
private MudTable<SelectListItem>? _table;
private string? _searchText;
private CancellationTokenSource? _debounceCancellationTokenSource;
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
[Parameter] public string Title { get; set; } = string.Empty;
[Parameter] public string? SelectedValue { get; set; }
[Inject] private IStringLocalizerFactory StringLocalizerFactory { get; set; } = null!;
[Inject] private IWebhookDefinitionManager WebhookDefinitionManager { get; set; } = null!;
public void Dispose()
{
_debounceCancellationTokenSource?.Cancel();
_debounceCancellationTokenSource?.Dispose();
}
private async Task OnSearchTextChangedAsync(string? searchValue)
{
_searchText = searchValue;
_debounceCancellationTokenSource?.Cancel();
_debounceCancellationTokenSource?.Dispose();
_debounceCancellationTokenSource = new CancellationTokenSource();
try
{
await Task.Delay(DebounceIntervalMilliseconds, _debounceCancellationTokenSource.Token);
var table = _table;
if (table != null)
{
await InvokeAsync(() => table.ReloadServerData());
}
}
catch (OperationCanceledException)
{
}
}
private async Task<TableData<SelectListItem>> LoadTenantsAsync(TableState state, CancellationToken cancellationToken)
{
var filter = string.IsNullOrWhiteSpace(_searchText) ? null : _searchText.Trim();
var webhooks = await WebhookDefinitionManager.GetWebhooksAsync();
var items = webhooks
.Select(webhook => new SelectListItem(
webhook.DisplayName != null
? webhook.DisplayName.Localize(StringLocalizerFactory)
: webhook.Name,
webhook.Name))
.WhereIf(!string.IsNullOrWhiteSpace(filter), x => x.Text.Contains(filter!) || x.Value.Contains(filter!))
.OrderBy(x => x.Text)
.Skip(state.Page * state.PageSize)
.Take(state.PageSize)
.ToList();
return new TableData<SelectListItem>
{
Items = items,
TotalItems = webhooks.Count,
};
}
private async Task OnRowClickAsync(TableRowClickEventArgs<SelectListItem> args)
{
await SelectAsync(args.Item);
}
private Task SelectAsync(SelectListItem? item)
{
if (item == null)
{
return Task.CompletedTask;
}
MudDialog.Close(DialogResult.Ok(item));
return Task.CompletedTask;
}
private void CancelAsync()
{
MudDialog.Cancel();
}
}

13
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Extensions/ServiceCollectionExtensions.cs

@ -0,0 +1,13 @@
using Elsa.Studio.Extensions;
using LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.Handlers;
using Microsoft.Extensions.DependencyInjection;
namespace LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.Extensions;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddWebhooksUIHintHandlers(this IServiceCollection services)
{
return services.AddUIHintHandler<WebhookPickerHandler>();
}
}

3
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

25
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/Handlers/WebhookPickerHandler.cs

@ -0,0 +1,25 @@
using Elsa.Studio;
using Elsa.Studio.Contracts;
using Elsa.Studio.Models;
using LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.Components;
using LINGYUN.Abp.ElsaNext.Webhooks.UIHints;
using Microsoft.AspNetCore.Components;
namespace LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.Handlers;
public class WebhookPickerHandler : IUIHintHandler
{
public bool GetSupportsUIHint(string uiHint) => uiHint is WebhooksUIHints.WebhookPicker;
public string UISyntax => WellKnownSyntaxNames.Object;
public RenderFragment DisplayInputEditor(DisplayInputEditorContext context)
{
return builder =>
{
builder.OpenComponent(0, typeof(WebhookPicker));
builder.AddAttribute(1, nameof(WebhookPicker.EditorContext), context);
builder.CloseComponent();
};
}
}

20
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor</AssemblyName>
<PackageId>LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext.Webhooks\LINGYUN.Abp.ElsaNext.Webhooks.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext.Studio.Blazor\LINGYUN.Abp.ElsaNext.Studio.Blazor.csproj" />
</ItemGroup>
</Project>

5
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Studio.Webhooks.Blazor/_Imports.razor

@ -0,0 +1,5 @@
@using Microsoft.AspNetCore.Components.Web
@using Elsa.Studio.Components
@using Elsa.Studio.Localization
@using MudBlazor
@using MudExtensions

3
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

26
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN.Abp.ElsaNext.Webhooks.csproj

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.ElsaNext.Webhooks</AssemblyName>
<PackageId>LINGYUN.Abp.ElsaNext.Webhooks</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<Content Remove="LINGYUN\Abp\ElsaNext\Webhooks\Localization\**\*.json" />
<EmbeddedResource Include="LINGYUN\Abp\ElsaNext\Webhooks\Localization\**\*.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\webhooks\LINGYUN.Abp.Webhooks\LINGYUN.Abp.Webhooks.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext\LINGYUN.Abp.ElsaNext.csproj" />
</ItemGroup>
</Project>

38
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/AbpElsaNextWebhooksModule.cs

@ -0,0 +1,38 @@
using Elsa.Features.Services;
using LINGYUN.Abp.ElsaNext.Localization;
using LINGYUN.Abp.ElsaNext.Webhooks.Extensions;
using LINGYUN.Abp.Webhooks;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.ElsaNext.Webhooks;
[DependsOn(
typeof(AbpWebhooksModule),
typeof(AbpElsaNextModule))]
public class AbpElsaNextWebhooksModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IModule>(elsa =>
{
elsa.UseAbpWebhooks();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpElsaNextWebhooksModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<ElsaNextResource>()
.AddVirtualJson("/LINGYUN/Abp/ElsaNext/Webhooks/Localization/Resources");
});
}
}

60
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Activities/PublishWebhook.cs

@ -0,0 +1,60 @@
using Elsa.Extensions;
using Elsa.Workflows;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Models;
using Elsa.Workflows.UIHints;
using LINGYUN.Abp.ElsaNext.Webhooks.UIHints;
using LINGYUN.Abp.Webhooks;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LINGYUN.Abp.ElsaNext.Webhooks.Activities;
[Activity("Elsa", "Webhooks", "Send webhooks to subscriptions.", Kind = ActivityKind.Task)]
public class PublishWebhook : CodeActivity
{
[Input(
Description = "Unique name of the webhook.",
UIHint = WebhooksUIHints.WebhookPicker)]
public Input<string> WebhookName { get; set; } = default!;
[Input(Description = "Data to send.")]
public Input<object> WebhookData { get; set; } = default!;
[Input(Description = "If true, It sends the exact same data as the parameter to clients.")]
public Input<bool?> SendExactSameData { get; set; } = default!;
[Input(Description = "If true, webhook will only contain given headers. If false given headers will be added to predefined headers in subscription.")]
public Input<bool?> UseOnlyGivenHeaders { get; set; } = default!;
[Input(
Description = "That headers will be sent with the webhook.",
UIHint = InputUIHints.Dictionary)]
public Input<Dictionary<string, string>> Headers { get; set; } = default!;
protected async override ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var webhookPublisher = context.GetRequiredService<IWebhookPublisher>();
var webhookName = WebhookName.Get(context);
var webhookData = WebhookData.Get(context);
var sendExactSameData = SendExactSameData.GetOrDefault(context) ?? true;
WebhookHeader? webhookHeader = null;
var headers = Headers.GetOrDefault(context);
if (headers != null)
{
var useOnlyGivenHeaders = UseOnlyGivenHeaders.GetOrDefault(context) ?? false;
webhookHeader = new WebhookHeader
{
UseOnlyGivenHeaders = useOnlyGivenHeaders,
Headers = headers,
};
}
await webhookPublisher.PublishAsync(
webhookName,
webhookData,
sendExactSameData,
webhookHeader);
}
}

14
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Extensions/ModuleExtensions.cs

@ -0,0 +1,14 @@
using Elsa.Features.Services;
using LINGYUN.Abp.ElsaNext.Webhooks.Features;
using System;
namespace LINGYUN.Abp.ElsaNext.Webhooks.Extensions;
public static class ModuleExtensions
{
public static IModule UseAbpWebhooks(this IModule configuration, Action<WebhooksFeature>? configure = null)
{
configuration.Configure(configure);
return configuration;
}
}

17
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Features/WebhooksFeature.cs

@ -0,0 +1,17 @@
using Elsa.Extensions;
using Elsa.Features.Abstractions;
using Elsa.Features.Services;
namespace LINGYUN.Abp.ElsaNext.Webhooks.Features;
public class WebhooksFeature : FeatureBase
{
public WebhooksFeature(IModule module) : base(module)
{
}
public override void Configure()
{
Module.AddActivitiesFrom<WebhooksFeature>();
}
}

12
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Localization/Resources/en.json

@ -0,0 +1,12 @@
{
"culture": "en",
"texts": {
"Webhooks": "Webhooks",
"Publish Webhook": "Publish Webhook",
"Send webhooks to subscriptions.": "Send webhooks to subscriptions.",
"Data to send.": "Data to send.",
"If true, It sends the exact same data as the parameter to clients.": "If true, It sends the exact same data as the parameter to clients.",
"If true, webhook will only contain given headers. If false given headers will be added to predefined headers in subscription.": "If true, webhook will only contain given headers. If false given headers will be added to predefined headers in subscription.",
"That headers will be sent with the webhook.": "That headers will be sent with the webhook."
}
}

12
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/Localization/Resources/zh-Hans.json

@ -0,0 +1,12 @@
{
"culture": "zh-Hans",
"texts": {
"Webhooks": "Webhooks",
"Publish Webhook": "发布Webhook",
"Send webhooks to subscriptions.": "向订阅方发布Webhook。",
"Data to send.": "要发送的数据。",
"If true, It sends the exact same data as the parameter to clients.": "如果为True,它会向客户端发送与参数完全相同的数据。",
"If true, webhook will only contain given headers. If false given headers will be added to predefined headers in subscription.": "如果为True,webhook 将仅包含指定的标头。如果为False,则在订阅中预定义的标头将添加给定的标头。",
"That headers will be sent with the webhook.": "将随 webhook 一起发送的请求头。"
}
}

6
aspnet-core/modules/elsa/LINGYUN.Abp.ElsaNext.Webhooks/LINGYUN/Abp/ElsaNext/Webhooks/UIHints/WebhooksUIHints.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Abp.ElsaNext.Webhooks.UIHints;
public static class WebhooksUIHints
{
public const string WebhookPicker = "webhook-picker";
}
Loading…
Cancel
Save