From 88a61bd99e3c5debda14bac1ddb3a341b3bb1645 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Mon, 1 Apr 2024 12:19:28 -0700 Subject: [PATCH] Add HTML support to notification summary (#15607) --- src/OrchardCore.Cms.Web/appsettings.json | 4 + .../UpdateContentTask.Fields.Design.cshtml | 2 +- .../Activities/NotifyUserTaskActivity.cs | 9 ++- .../Assets/js/notification-manager.js | 80 ++++++++++--------- .../Controllers/AdminController.cs | 20 ++--- .../NotificationNavbarDisplayDriver.cs | 12 +-- .../NotifyContentOwnerTaskDisplayDriver.cs | 14 +++- .../NotifyUserTaskActivityDisplayDriver.cs | 71 ++++++++++++++-- .../Drivers/NotifyUserTaskDisplayDriver.cs | 13 +++ .../Handlers/CoreNotificationEventsHandler.cs | 1 - .../OrchardCore.Notifications/Manifest.cs | 6 +- .../OrchardCore.Notifications/Startup.cs | 10 +++ .../NotifyUserTaskActivityViewModel.cs | 2 + .../NotifyContentOwnerTask.Fields.Edit.cshtml | 39 ++++++++- .../NotifyUserTaskActivity.Fields.Edit.cshtml | 39 ++++++++- .../Views/Notification.Header.cshtml | 6 +- .../Views/Notification.SummaryAdmin.cshtml | 14 ++-- ...cationsAdminList.Fields.BulkActions.cshtml | 7 +- .../Views/UserNotificationNavbar.cshtml | 5 +- .../wwwroot/Scripts/notification-manager.js | 77 +++++++++--------- .../Scripts/notification-manager.min.js | 2 +- .../Views/UserNotificationNavbar.cshtml | 4 +- .../INotificationMessage.cs | 11 ++- .../Notification.cs | 5 ++ .../Models/NotificationBodyInfo.cs | 7 +- .../Models/NotificationMessage.cs | 2 + .../Models/NotificationOptions.cs | 14 ++++ .../Services/EmailNotificationProvider.cs | 4 +- .../Services/NotificationService.cs | 1 + .../Services/SmsNotificationProvider.cs | 2 +- .../reference/modules/Notifications/README.md | 20 +++-- src/docs/releases/1.9.0.md | 10 +++ 32 files changed, 372 insertions(+), 141 deletions(-) create mode 100644 src/OrchardCore/OrchardCore.Notifications.Core/Models/NotificationOptions.cs diff --git a/src/OrchardCore.Cms.Web/appsettings.json b/src/OrchardCore.Cms.Web/appsettings.json index d8e6f6e8ac8..aa1cc7bea36 100644 --- a/src/OrchardCore.Cms.Web/appsettings.json +++ b/src/OrchardCore.Cms.Web/appsettings.json @@ -198,6 +198,10 @@ // } // ] //}, + //"OrchardCore_Notifications": { + // "TotalUnreadNotifications": 10, + // "DisableNotificationHtmlBodySanitizer": false + //}, //"OrchardCore_HealthChecks": { // "Url": "/health/live" //}, diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/UpdateContentTask.Fields.Design.cshtml b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/UpdateContentTask.Fields.Design.cshtml index 7647969ca50..f5ca078f340 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/UpdateContentTask.Fields.Design.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Views/Items/UpdateContentTask.Fields.Design.cshtml @@ -1,7 +1,7 @@ @model ContentTaskViewModel
-

@Model.Activity.GetTitleOrDefault(() => T["Update Content"])

+

@Model.Activity.GetTitleOrDefault(() => T["Update Content"])

@if (string.IsNullOrWhiteSpace(Model.Activity.Content?.Expression)) diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Activities/NotifyUserTaskActivity.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Activities/NotifyUserTaskActivity.cs index 3cdc7730e94..34815c350ab 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Activities/NotifyUserTaskActivity.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Activities/NotifyUserTaskActivity.cs @@ -44,6 +44,12 @@ public WorkflowExpression Subject set => SetProperty(value); } + public WorkflowExpression Summary + { + get => GetProperty(() => new WorkflowExpression()); + set => SetProperty(value); + } + public WorkflowExpression TextBody { get => GetProperty(() => new WorkflowExpression()); @@ -97,7 +103,8 @@ protected virtual async Task GetMessageAsync(WorkflowExecu { return new NotificationMessage() { - Summary = await _expressionEvaluator.EvaluateAsync(Subject, workflowContext, null), + Subject = await _expressionEvaluator.EvaluateAsync(Subject, workflowContext, null), + Summary = await _expressionEvaluator.EvaluateAsync(Summary, workflowContext, _htmlEncoder), TextBody = await _expressionEvaluator.EvaluateAsync(TextBody, workflowContext, null), HtmlBody = await _expressionEvaluator.EvaluateAsync(HtmlBody, workflowContext, _htmlEncoder), IsHtmlPreferred = IsHtmlPreferred, diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Assets/js/notification-manager.js b/src/OrchardCore.Modules/OrchardCore.Notifications/Assets/js/notification-manager.js index 6ad0824c9b5..8dc734e8b40 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Assets/js/notification-manager.js +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Assets/js/notification-manager.js @@ -11,49 +11,51 @@ notificationManager = function () { var elements = document.getElementsByClassName('mark-notification-as-read'); for (let i = 0; i < elements.length; i++) { - let element = elements[i]; - element.addEventListener('click', () => { - - if (element.getAttribute('data-is-read') != "false") { - return; - } - - var messageId = element.getAttribute('data-message-id'); - - if (!messageId) { - return; - } - - fetch(readUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ messageId: messageId }) - }).then(response => response.json()) - .then(result => { - if (result.updated) { - if (wrapperSelector) { - var wrapper = element.closest(wrapperSelector); - if (wrapper) { - wrapper.classList.remove('notification-is-unread'); - wrapper.classList.add('notification-is-read'); - wrapper.setAttribute('data-is-read', true); + + ['click', 'mouseover'].forEach((evt) => { + elements[i].addEventListener(evt, (e) => { + + if (e.target.getAttribute('data-is-read') != "false") { + return; + } + + var messageId = e.target.getAttribute('data-message-id'); + + if (!messageId) { + return; + } + + fetch(readUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ messageId: messageId }) + }).then(response => response.json()) + .then(result => { + if (result.updated) { + if (wrapperSelector) { + var wrapper = e.target.closest(wrapperSelector); + if (wrapper) { + wrapper.classList.remove('notification-is-unread'); + wrapper.classList.add('notification-is-read'); + wrapper.setAttribute('data-is-read', true); + } + } else { + e.target.classList.remove('notification-is-unread'); + e.target.classList.add('notification-is-read'); + e.target.setAttribute('data-is-read', true); } - } else { - element.classList.remove('notification-is-unread'); - element.classList.add('notification-is-read'); - element.setAttribute('data-is-read', true); } - } - var targetUrl = element.getAttribute('data-target-url'); + var targetUrl = e.target.getAttribute('data-target-url'); - if (targetUrl) { - window.location.href = targetUrl; - } - }); - }); + if (targetUrl) { + window.location.href = targetUrl; + } + }); + }); + }) } } diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Controllers/AdminController.cs index 4f3e00846a2..8bcb805bd34 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Controllers/AdminController.cs @@ -112,23 +112,23 @@ public async Task List( var queryResult = await _notificationsAdminListQueryService.QueryAsync(pager.Page, pager.PageSize, options, this); - dynamic pagerShape = await _shapeFactory.PagerAsync(pager, queryResult.TotalCount, options.RouteValues); + var pagerShape = await _shapeFactory.PagerAsync(pager, queryResult.TotalCount, options.RouteValues); - var notificationSummaries = new List(); + var notificationShapes = new List(); foreach (var notification in queryResult.Notifications) { - dynamic shape = await _notificationDisplayManager.BuildDisplayAsync(notification, this, "SummaryAdmin"); - shape.Notification = notification; + var shape = await _notificationDisplayManager.BuildDisplayAsync(notification, this, "SummaryAdmin"); + shape.Properties[nameof(Notification)] = notification; - notificationSummaries.Add(shape); + notificationShapes.Add(shape); } - var startIndex = (pagerShape.Page - 1) * pagerShape.PageSize + 1; + var startIndex = (pager.Page - 1) * pager.PageSize + 1; options.StartIndex = startIndex; - options.EndIndex = startIndex + notificationSummaries.Count - 1; - options.NotificationsCount = notificationSummaries.Count; - options.TotalItemCount = pagerShape.TotalItemCount; + options.EndIndex = startIndex + notificationShapes.Count - 1; + options.NotificationsCount = notificationShapes.Count; + options.TotalItemCount = queryResult.TotalCount; var header = await _notificationOptionsDisplayManager.BuildEditorAsync(options, this, false, string.Empty, string.Empty); @@ -136,7 +136,7 @@ public async Task List( { viewModel.Options = options; viewModel.Header = header; - viewModel.Notifications = notificationSummaries; + viewModel.Notifications = notificationShapes; viewModel.Pager = pagerShape; }); diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotificationNavbarDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotificationNavbarDisplayDriver.cs index ef1b8fd1b85..7a9f94e1b8c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotificationNavbarDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotificationNavbarDisplayDriver.cs @@ -2,10 +2,12 @@ using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using OrchardCore.Admin.Models; using OrchardCore.DisplayManagement.Handlers; using OrchardCore.DisplayManagement.Views; using OrchardCore.Notifications.Indexes; +using OrchardCore.Notifications.Models; using OrchardCore.Notifications.ViewModels; using YesSql; @@ -13,20 +15,20 @@ namespace OrchardCore.Notifications.Drivers; public class NotificationNavbarDisplayDriver : DisplayDriver { - // TODO, make this part of a configurable of NotificationOptions - private const int MaxVisibleNotifications = 10; - private readonly IAuthorizationService _authorizationService; private readonly IHttpContextAccessor _httpContextAccessor; + private readonly NotificationOptions _notificationOptions; private readonly YesSql.ISession _session; public NotificationNavbarDisplayDriver( IAuthorizationService authorizationService, IHttpContextAccessor httpContextAccessor, + IOptions notificationOptions, YesSql.ISession session) { _authorizationService = authorizationService; _httpContextAccessor = httpContextAccessor; + _notificationOptions = notificationOptions.Value; _session = session; } @@ -37,11 +39,11 @@ public override IDisplayResult Display(Navbar model) var userId = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier); var notifications = (await _session.Query(x => x.UserId == userId && !x.IsRead, collection: NotificationConstants.NotificationCollection) .OrderByDescending(x => x.CreatedAtUtc) - .Take(MaxVisibleNotifications + 1) + .Take(_notificationOptions.TotalUnreadNotifications + 1) .ListAsync()).ToList(); model.Notifications = notifications; - model.MaxVisibleNotifications = MaxVisibleNotifications; + model.MaxVisibleNotifications = _notificationOptions.TotalUnreadNotifications; model.TotalUnread = notifications.Count; }).Location("Detail", "Content:9") diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyContentOwnerTaskDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyContentOwnerTaskDisplayDriver.cs index e0803912ae4..f3952df7aea 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyContentOwnerTaskDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyContentOwnerTaskDisplayDriver.cs @@ -1,8 +1,20 @@ +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; +using OrchardCore.Infrastructure.Html; +using OrchardCore.Liquid; using OrchardCore.Notifications.Activities; +using OrchardCore.Notifications.Models; namespace OrchardCore.Notifications.Drivers; public class NotifyContentOwnerTaskDisplayDriver : NotifyUserTaskActivityDisplayDriver { - + public NotifyContentOwnerTaskDisplayDriver( + IHtmlSanitizerService htmlSanitizerService, + ILiquidTemplateManager liquidTemplateManager, + IOptions notificationOptions, + IStringLocalizer stringLocalizer) + : base(htmlSanitizerService, liquidTemplateManager, notificationOptions, stringLocalizer) + { + } } diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskActivityDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskActivityDisplayDriver.cs index 9dcd4a24af4..c44d2f08195 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskActivityDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskActivityDisplayDriver.cs @@ -1,8 +1,14 @@ using System; using System.Threading.Tasks; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; using OrchardCore.DisplayManagement.ModelBinding; using OrchardCore.DisplayManagement.Views; +using OrchardCore.Infrastructure.Html; +using OrchardCore.Liquid; +using OrchardCore.Mvc.ModelBinding; using OrchardCore.Notifications.Activities; +using OrchardCore.Notifications.Models; using OrchardCore.Notifications.ViewModels; using OrchardCore.Workflows.Display; using OrchardCore.Workflows.Models; @@ -10,18 +16,36 @@ namespace OrchardCore.Notifications.Drivers; -public class NotifyUserTaskActivityDisplayDriver : ActivityDisplayDriver +public abstract class NotifyUserTaskActivityDisplayDriver : ActivityDisplayDriver where TActivity : NotifyUserTaskActivity where TEditViewModel : NotifyUserTaskActivityViewModel, new() { + private readonly IHtmlSanitizerService _htmlSanitizerService; + private readonly ILiquidTemplateManager _liquidTemplateManager; + private readonly NotificationOptions _notificationOptions; + + protected readonly IStringLocalizer S; + protected virtual string EditShapeType => $"{nameof(NotifyUserTaskActivity)}_Fields_Edit"; + public NotifyUserTaskActivityDisplayDriver( + IHtmlSanitizerService htmlSanitizerService, + ILiquidTemplateManager liquidTemplateManager, + IOptions notificationOptions, + IStringLocalizer stringLocalizer) + { + _htmlSanitizerService = htmlSanitizerService; + _liquidTemplateManager = liquidTemplateManager; + _notificationOptions = notificationOptions.Value; + S = stringLocalizer; + } + public override IDisplayResult Edit(TActivity model) { - return Initialize(EditShapeType, (Func)(viewModel => + return Initialize(EditShapeType, viewModel => { return EditActivityAsync(model, viewModel); - })).Location("Content"); + }).Location("Content"); } public async override Task UpdateAsync(TActivity model, IUpdateModel updater) @@ -29,7 +53,30 @@ public async override Task UpdateAsync(TActivity model, IUpdateM var viewModel = new TEditViewModel(); if (await updater.TryUpdateModelAsync(viewModel, Prefix)) { - await UpdateActivityAsync(viewModel, model); + if (!_liquidTemplateManager.Validate(viewModel.Subject, out var subjectErrors)) + { + updater.ModelState.AddModelError(Prefix, nameof(viewModel.Subject), S["Subject field does not contain a valid Liquid expression. Details: {0}", string.Join(' ', subjectErrors)]); + } + + if (!_liquidTemplateManager.Validate(viewModel.Summary, out var summaryErrors)) + { + updater.ModelState.AddModelError(Prefix, nameof(viewModel.Summary), S["Summary field does not contain a valid Liquid expression. Details: {0}", string.Join(' ', summaryErrors)]); + } + + if (!_liquidTemplateManager.Validate(viewModel.TextBody, out var textBodyErrors)) + { + updater.ModelState.AddModelError(Prefix, nameof(viewModel.TextBody), S["Text Body field does not contain a valid Liquid expression. Details: {0}", string.Join(' ', textBodyErrors)]); + } + + if (!_liquidTemplateManager.Validate(viewModel.HtmlBody, out var htmlBodyErrors)) + { + updater.ModelState.AddModelError(Prefix, nameof(viewModel.HtmlBody), S["HTML Body field does not contain a valid Liquid expression. Details: {0}", string.Join(' ', htmlBodyErrors)]); + } + + if (updater.ModelState.IsValid) + { + await UpdateActivityAsync(viewModel, model); + } } return Edit(model); @@ -51,6 +98,7 @@ protected override ValueTask EditActivityAsync(TActivity activity, TEditViewMode protected override void EditActivity(TActivity activity, TEditViewModel model) { model.Subject = activity.Subject.Expression; + model.Summary = activity.Summary.Expression; model.TextBody = activity.TextBody.Expression; model.HtmlBody = activity.HtmlBody.Expression; model.IsHtmlPreferred = activity.IsHtmlPreferred; @@ -72,8 +120,9 @@ protected override Task UpdateActivityAsync(TEditViewModel model, TActivity acti protected override void UpdateActivity(TEditViewModel model, TActivity activity) { activity.Subject = new WorkflowExpression(model.Subject); + activity.Summary = new WorkflowExpression(_htmlSanitizerService.Sanitize(model.Summary)); activity.TextBody = new WorkflowExpression(model.TextBody); - activity.HtmlBody = new WorkflowExpression(model.HtmlBody); + activity.HtmlBody = new WorkflowExpression(_notificationOptions.DisableNotificationHtmlBodySanitizer ? model.HtmlBody : _htmlSanitizerService.Sanitize(model.HtmlBody)); activity.IsHtmlPreferred = model.IsHtmlPreferred; } @@ -88,7 +137,15 @@ public override IDisplayResult Display(TActivity activity) } } -public class NotifyUserTaskActivityDisplayDriver : NotifyUserTaskActivityDisplayDriver - where TActivity : NotifyUserTaskActivity +public abstract class NotifyUserTaskActivityDisplayDriver : NotifyUserTaskActivityDisplayDriver + where TActivity : NotifyUserTaskActivity { + public NotifyUserTaskActivityDisplayDriver( + IHtmlSanitizerService htmlSanitizerService, + ILiquidTemplateManager liquidTemplateManager, + IOptions notificationOptions, + IStringLocalizer stringLocalizer) + : base(htmlSanitizerService, liquidTemplateManager, notificationOptions, stringLocalizer) + { + } } diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskDisplayDriver.cs index 0a48ac77866..680ec405072 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Drivers/NotifyUserTaskDisplayDriver.cs @@ -1,7 +1,20 @@ +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; +using OrchardCore.Infrastructure.Html; +using OrchardCore.Liquid; using OrchardCore.Notifications.Activities; +using OrchardCore.Notifications.Models; namespace OrchardCore.Notifications.Drivers; public class NotifyUserTaskDisplayDriver : NotifyUserTaskActivityDisplayDriver { + public NotifyUserTaskDisplayDriver( + IHtmlSanitizerService htmlSanitizerService, + ILiquidTemplateManager liquidTemplateManager, + IOptions notificationOptions, + IStringLocalizer stringLocalizer) + : base(htmlSanitizerService, liquidTemplateManager, notificationOptions, stringLocalizer) + { + } } diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Handlers/CoreNotificationEventsHandler.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Handlers/CoreNotificationEventsHandler.cs index 0968b4973fa..a007bd4c8b9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Handlers/CoreNotificationEventsHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Handlers/CoreNotificationEventsHandler.cs @@ -17,7 +17,6 @@ public override Task CreatingAsync(NotificationContext context) var bodyPart = context.Notification.As(); - bodyPart.Summary = context.NotificationMessage.Summary; bodyPart.TextBody = context.NotificationMessage.TextBody; bodyPart.HtmlBody = context.NotificationMessage.HtmlBody; diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Manifest.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Manifest.cs index b1f8cc1d53d..b2dd718323e 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Manifest.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Manifest.cs @@ -10,7 +10,11 @@ Id = "OrchardCore.Notifications", Name = "Notifications", Description = "Provides a way to notify users.", - Category = "Notifications" + Category = "Notifications", + Dependencies = + [ + "OrchardCore.Liquid" + ] )] [assembly: Feature( diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Startup.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/Startup.cs index 56f33fb571d..c53d0cf8b37 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Startup.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Startup.cs @@ -4,6 +4,7 @@ using OrchardCore.Data; using OrchardCore.Data.Migration; using OrchardCore.DisplayManagement.Handlers; +using OrchardCore.Environment.Shell.Configuration; using OrchardCore.Modules; using OrchardCore.Navigation.Core; using OrchardCore.Notifications.Activities; @@ -23,6 +24,13 @@ namespace OrchardCore.Notifications; public class Startup : StartupBase { + private readonly IShellConfiguration _shellConfiguration; + + public Startup(IShellConfiguration shellConfiguration) + { + _shellConfiguration = shellConfiguration; + } + public override void ConfigureServices(IServiceCollection services) { services.AddScoped(); @@ -52,6 +60,8 @@ public override void ConfigureServices(IServiceCollection services) return new DefaultNotificationAdminListFilterParser(parser); }); + services.Configure(_shellConfiguration.GetSection("OrchardCore_Notifications")); + services.AddTransient, NotificationOptionsConfiguration>(); services.AddScoped, UserNotificationPreferencesPartDisplayDriver>(); services.AddScoped, NotificationNavbarDisplayDriver>(); diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/ViewModels/NotifyUserTaskActivityViewModel.cs b/src/OrchardCore.Modules/OrchardCore.Notifications/ViewModels/NotifyUserTaskActivityViewModel.cs index 2b00bf5e3ad..68807877ff9 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/ViewModels/NotifyUserTaskActivityViewModel.cs +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/ViewModels/NotifyUserTaskActivityViewModel.cs @@ -7,6 +7,8 @@ public class NotifyUserTaskActivityViewModel [Required] public string Subject { get; set; } + public string Summary { get; set; } + public string TextBody { get; set; } public string HtmlBody { get; set; } diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyContentOwnerTask.Fields.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyContentOwnerTask.Fields.Edit.cshtml index 36826021dc6..a867065f300 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyContentOwnerTask.Fields.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyContentOwnerTask.Fields.Edit.cshtml @@ -7,9 +7,16 @@ @T["You may use Liquid syntax."] +
+ + + + @T["HTML summary for the notification. You may use Liquid syntax."] +
+
- + @T["This optional text body does not support HTML. You may use Liquid syntax."]
@@ -26,3 +33,33 @@ @T["When checked, the notification provider will use the HTML body if it supports HTML."] + + + + + + + + + + + diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyUserTaskActivity.Fields.Edit.cshtml b/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyUserTaskActivity.Fields.Edit.cshtml index 36826021dc6..c88bd61e20f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyUserTaskActivity.Fields.Edit.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Items/NotifyUserTaskActivity.Fields.Edit.cshtml @@ -7,9 +7,16 @@ @T["You may use Liquid syntax."] +
+ + + + @T["You may use Liquid syntax. Html is supported."] +
+
- + @T["This optional text body does not support HTML. You may use Liquid syntax."]
@@ -26,3 +33,33 @@ @T["When checked, the notification provider will use the HTML body if it supports HTML."] + + + + + + + + + + + diff --git a/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Notification.Header.cshtml b/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Notification.Header.cshtml index 28fe7a3bbfd..20532267866 100644 --- a/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Notification.Header.cshtml +++ b/src/OrchardCore.Modules/OrchardCore.Notifications/Views/Notification.Header.cshtml @@ -18,6 +18,8 @@ var readInfo = notification.As(); } -