Browse Source

Notification action.

pull/464/head
Sebastian 7 years ago
parent
commit
f283a016e0
  1. 6
      backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs
  2. 43
      backend/extensions/Squidex.Extensions/Actions/Notification/NotificationAction.cs
  3. 102
      backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs
  4. 22
      backend/extensions/Squidex.Extensions/Actions/Notification/NotificationPlugin.cs
  5. 6
      frontend/app/features/settings/pages/more/more-page.component.html

6
backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs

@ -47,7 +47,7 @@ namespace Squidex.Extensions.Actions.Comment
{
AppId = contentEvent.AppId,
Actor = actor,
CommentsId = contentEvent.Id,
CommentsId = contentEvent.Id.ToString(),
Text = text
};
@ -59,7 +59,7 @@ namespace Squidex.Extensions.Actions.Comment
protected override async Task<Result> ExecuteJobAsync(CommentJob job, CancellationToken ct = default)
{
if (job.CommentsId == Guid.Empty)
if (string.IsNullOrWhiteSpace(job.CommentsId))
{
return Result.Ignored();
}
@ -78,7 +78,7 @@ namespace Squidex.Extensions.Actions.Comment
public RefToken Actor { get; set; }
public Guid CommentsId { get; set; }
public string CommentsId { get; set; }
public string Text { get; set; }
}

43
backend/extensions/Squidex.Extensions/Actions/Notification/NotificationAction.cs

@ -0,0 +1,43 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.ComponentModel.DataAnnotations;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules;
namespace Squidex.Extensions.Actions.Notification
{
[RuleAction(
Title = "Notification",
IconImage = "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'><path d='M20.016 15.984v-12h-16.031v14.016l2.016-2.016h14.016zM20.016 2.016c1.078 0 1.969 0.891 1.969 1.969v12c0 1.078-0.891 2.016-1.969 2.016h-14.016l-3.984 3.984v-18c0-1.078 0.891-1.969 1.969-1.969h16.031z'></path></svg>",
IconColor = "#3389ff",
Display = "Send a notification",
Description = "Send an integrated notification to a user.")]
public sealed class NotificationAction : RuleAction
{
[Required]
[Display(Name = "User", Description = "The user id or email.")]
[DataType(DataType.Text)]
public string User { get; set; }
[Required]
[Display(Name = "Title", Description = "The text to send.")]
[DataType(DataType.MultilineText)]
[Formattable]
public string Text { get; set; }
[Display(Name = "Url", Description = "The optional url to attach to the notification.")]
[DataType(DataType.Text)]
[Formattable]
public string Url { get; set; }
[Display(Name = "Client", Description = "An optional client name.")]
[DataType(DataType.Text)]
public string Client { get; set; }
}
}

102
backend/extensions/Squidex.Extensions/Actions/Notification/NotificationActionHandler.cs

@ -0,0 +1,102 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
using Squidex.Domain.Apps.Entities.Comments.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Reflection;
using Squidex.Shared.Users;
namespace Squidex.Extensions.Actions.Notification
{
public sealed class NotificationActionHandler : RuleActionHandler<NotificationAction, NotificationJob>
{
private const string Description = "Send a Notification";
private static readonly NamedId<Guid> NoApp = NamedId.Of(Guid.Empty, "none");
private readonly ICommandBus commandBus;
private readonly IUserResolver userResolver;
public NotificationActionHandler(RuleEventFormatter formatter, ICommandBus commandBus, IUserResolver userResolver)
: base(formatter)
{
Guard.NotNull(commandBus);
Guard.NotNull(userResolver);
this.commandBus = commandBus;
this.userResolver = userResolver;
}
protected override async Task<(string Description, NotificationJob Data)> CreateJobAsync(EnrichedEvent @event, NotificationAction action)
{
if (@event is EnrichedUserEventBase userEvent)
{
var text = Format(action.Text, @event);
var actor = userEvent.Actor;
if (!string.IsNullOrEmpty(action.Client))
{
actor = new RefToken(RefTokenType.Client, action.Client);
}
var user = await userResolver.FindByIdOrEmailAsync(action.User);
if (user == null)
{
throw new InvalidOperationException($"Cannot find user by '{action.User}'");
}
var ruleJob = new NotificationJob { Actor = actor, CommentsId = user.Id, Text = text };
if (!string.IsNullOrWhiteSpace(action.Url))
{
var url = Format(action.Url, @event);
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
{
ruleJob.Url = uri;
}
}
return (Description, ruleJob);
}
return ("Ignore", new NotificationJob());
}
protected override async Task<Result> ExecuteJobAsync(NotificationJob job, CancellationToken ct = default)
{
if (string.IsNullOrWhiteSpace(job.CommentsId))
{
return Result.Ignored();
}
var command = SimpleMapper.Map(job, new CreateComment { AppId = NoApp });
await commandBus.PublishAsync(command);
return Result.Success($"Notified: {job.Text}");
}
}
public sealed class NotificationJob
{
public RefToken Actor { get; set; }
public string CommentsId { get; set; }
public string Text { get; set; }
public Uri Url { get; set; }
}
}

22
backend/extensions/Squidex.Extensions/Actions/Notification/NotificationPlugin.cs

@ -0,0 +1,22 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Infrastructure.Plugins;
namespace Squidex.Extensions.Actions.Notification
{
public sealed class NotificationPlugin : IPlugin
{
public void ConfigureServices(IServiceCollection services, IConfiguration config)
{
services.AddRuleAction<NotificationAction, NotificationActionHandler>();
}
}
}

6
frontend/app/features/settings/pages/more/more-page.component.html

@ -14,7 +14,7 @@
<div class="form-group">
<label for="email">Name</label>
<input type="text" class="form-control" readonly [value]="app.name" />
<input type="text" class="form-control" readonly [value]="app?.name" />
</div>
<div class="form-group">
@ -55,9 +55,9 @@
<ng-template #notUploading>
<div>
<sqx-avatar [image]="app.image" [identifier]="app.name" [size]="150"></sqx-avatar>
<sqx-avatar [image]="app?.image" [identifier]="app?.name" [size]="150"></sqx-avatar>
<ng-container *ngIf="isImageEditable && app.image">
<ng-container *ngIf="isImageEditable && app?.image">
<button class="btn btn-danger btn-sm app-image-remove" title="Remove image" (click)="removeImage()">
<i class="icon-bin2"></i>
</button>

Loading…
Cancel
Save