diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/Default.cshtml b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/Default.cshtml new file mode 100644 index 0000000..b188d1e --- /dev/null +++ b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/Default.cshtml @@ -0,0 +1,52 @@ +@using EasyAbp.ProcessManagement.Localization +@using Microsoft.AspNetCore.Mvc.Localization +@inject IHtmlLocalizer L +@model EasyAbp.ProcessManagement.Web.Components.NotificationsOffcanvasWidget.NotificationsOffcanvasWidgetViewModel + + + + + +
+
+
@L["Notifications"]
+ +
+
+
+
+
\ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/Default.js b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/Default.js new file mode 100644 index 0000000..4441fe5 --- /dev/null +++ b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/Default.js @@ -0,0 +1,95 @@ +(function ($) { + + abp.widgets.NotificationsOffcanvasWidget = function ($widget) { + + function fetchAndShowAlerts() { + easyAbp.processManagement.notifications.notification.getList({ + fromCreationTime: new Date(abp.clock.now() - notificationLifetimeMilliseconds), + userId: abp.currentUser.id, + dismissed: false, + maxResultCount: 10 + }).then(function (res) { + var alertPlaceholder = $('#alert-placeholder'); + var existingAlerts = alertPlaceholder.find('.alert'); + + var existingAlertIds = new Map(); + existingAlerts.each(function () { + var id = $(this).data('id'); + existingAlertIds.set(id, $(this)); + }); + + res.items.forEach(function (item) { + if (!existingAlertIds.has(item.id)) { + var newAlert = createAlert(item); + alertPlaceholder.append(newAlert); + } + }); + + existingAlertIds.forEach(function (alert, id) { + if (!res.items.some(item => item.id === id)) { + alert.addClass('fade-out').one('animationend', function () { + $(this).remove(); + }); + } + }); + }); + } + + function getAlertColorClassName(stateFlag) { + switch (stateFlag) { + case 1: + return "alert-dark"; + case 2: + return "alert-success"; + case 3: + return "alert-danger"; + case 4: + return "alert-primary"; + case 5: + return "alert-purple"; + case 6: + return "alert-warning"; + default: + break; + } + } + + function createAlert(item) { + return $(` + + `).data('id', item.id); + } + + function init() { + var offcanvasElement = document.getElementById('notificationsOffcanvas'); + var intervalId; + + offcanvasElement.addEventListener('show.bs.offcanvas', function () { + fetchAndShowAlerts(); + intervalId = setInterval(fetchAndShowAlerts, 5000); + }); + + offcanvasElement.addEventListener('hide.bs.offcanvas', function () { + if (intervalId) clearInterval(intervalId); + }); + } + + return { + init: init + }; + }; +})(jQuery); \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/NotificationsOffcanvasWidgetViewComponent.cs b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/NotificationsOffcanvasWidgetViewComponent.cs new file mode 100644 index 0000000..62c3d3e --- /dev/null +++ b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/NotificationsOffcanvasWidgetViewComponent.cs @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using EasyAbp.ProcessManagement.Web.Options; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace EasyAbp.ProcessManagement.Web.Components.NotificationsOffcanvasWidget; + +[Widget( + AutoInitialize = true, + RefreshUrl = "/Widgets/ProcessManagement/NotificationsOffcanvas", + ScriptFiles = ["/Components/NotificationsOffcanvasWidget/Default.js"] +)] +public class NotificationsOffcanvasWidgetViewComponent : AbpViewComponent +{ + protected ProcessManagementWebOptions Options => + LazyServiceProvider.LazyGetRequiredService>().Value; + + public NotificationsOffcanvasWidgetViewComponent() + { + } + + public virtual async Task InvokeAsync() + { + return View("~/Components/NotificationsOffcanvasWidget/Default.cshtml", + new NotificationsOffcanvasWidgetViewModel(Options)); + } +} \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/NotificationsOffcanvasWidgetViewModel.cs b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/NotificationsOffcanvasWidgetViewModel.cs new file mode 100644 index 0000000..463cda9 --- /dev/null +++ b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsOffcanvasWidget/NotificationsOffcanvasWidgetViewModel.cs @@ -0,0 +1,13 @@ +using EasyAbp.ProcessManagement.Web.Options; + +namespace EasyAbp.ProcessManagement.Web.Components.NotificationsOffcanvasWidget; + +public class NotificationsOffcanvasWidgetViewModel +{ + public ProcessManagementWebOptions Options { get; } + + public NotificationsOffcanvasWidgetViewModel(ProcessManagementWebOptions options) + { + Options = options; + } +} \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/Default.cshtml b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/Default.cshtml new file mode 100644 index 0000000..714f524 --- /dev/null +++ b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/Default.cshtml @@ -0,0 +1,10 @@ +@using EasyAbp.ProcessManagement.Localization +@using Microsoft.AspNetCore.Mvc.Localization +@inject IHtmlLocalizer L +@model EasyAbp.ProcessManagement.Web.Components.NotificationsToolbarItemWidget.NotificationsToolbarItemWidgetViewModel + + \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/NotificationsWidgetViewComponent.cs b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/NotificationsToolbarItemWidgetViewComponent.cs similarity index 57% rename from src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/NotificationsWidgetViewComponent.cs rename to src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/NotificationsToolbarItemWidgetViewComponent.cs index bff5886..445eef5 100644 --- a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/NotificationsWidgetViewComponent.cs +++ b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/NotificationsToolbarItemWidgetViewComponent.cs @@ -4,18 +4,17 @@ using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc.UI.Widgets; -namespace EasyAbp.ProcessManagement.Web.Components.NotificationsWidget; +namespace EasyAbp.ProcessManagement.Web.Components.NotificationsToolbarItemWidget; [Widget( AutoInitialize = true, - RefreshUrl = "/Widgets/ProcessManagement/Notifications", - ScriptFiles = ["/Components/NotificationsWidget/Default.js"] + RefreshUrl = "/Widgets/ProcessManagement/NotificationsToolbarItem" )] -public class NotificationsWidgetViewComponent : AbpViewComponent +public class NotificationsToolbarItemWidgetViewComponent : AbpViewComponent { private readonly NotificationCountCache _notificationCountCache; - public NotificationsWidgetViewComponent(NotificationCountCache notificationCountCache) + public NotificationsToolbarItemWidgetViewComponent(NotificationCountCache notificationCountCache) { _notificationCountCache = notificationCountCache; } @@ -24,7 +23,7 @@ public virtual async Task InvokeAsync() { var notificationCount = await _notificationCountCache.GetOrAddAsync(); - return View("~/Components/NotificationsWidget/Default.cshtml", - new NotificationsWidgetViewModel(notificationCount)); + return View("~/Components/NotificationsToolbarItemWidget/Default.cshtml", + new NotificationsToolbarItemWidgetViewModel(notificationCount)); } } \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/NotificationsWidgetViewModel.cs b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/NotificationsToolbarItemWidgetViewModel.cs similarity index 55% rename from src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/NotificationsWidgetViewModel.cs rename to src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/NotificationsToolbarItemWidgetViewModel.cs index a42de34..5141716 100644 --- a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/NotificationsWidgetViewModel.cs +++ b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsToolbarItemWidget/NotificationsToolbarItemWidgetViewModel.cs @@ -1,17 +1,17 @@ -namespace EasyAbp.ProcessManagement.Web.Components.NotificationsWidget; +namespace EasyAbp.ProcessManagement.Web.Components.NotificationsToolbarItemWidget; -public class NotificationsWidgetViewModel +public class NotificationsToolbarItemWidgetViewModel { /// /// 0~99 unread notifications. /// public int UnreadCount { get; set; } - public NotificationsWidgetViewModel() + public NotificationsToolbarItemWidgetViewModel() { } - public NotificationsWidgetViewModel(int unreadCount) + public NotificationsToolbarItemWidgetViewModel(int unreadCount) { UnreadCount = unreadCount; } diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/Default.cshtml b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/Default.cshtml deleted file mode 100644 index b62234e..0000000 --- a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/Default.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@using EasyAbp.ProcessManagement.Localization -@using Microsoft.AspNetCore.Mvc.Localization -@inject IHtmlLocalizer L -@model EasyAbp.ProcessManagement.Web.Components.NotificationsWidget.NotificationsWidgetViewModel - - \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/Default.js b/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/Default.js deleted file mode 100644 index 2c3bde6..0000000 --- a/src/EasyAbp.ProcessManagement.Web/Components/NotificationsWidget/Default.js +++ /dev/null @@ -1,19 +0,0 @@ -(function ($) { - - let modal = new abp.ModalManager(abp.appPath + 'ProcessManagement/Notifications/Notification/NotificationsModal'); - - abp.widgets.NotificationsWidget = function ($widget) { - - let widgetManager = $widget.data('abp-widget-manager'); - - function init() { - $('.notifications-toolbar-item').click(function () { - modal.open(); - }) - } - - return { - init: init - }; - }; -})(jQuery); \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Components/Toolbar/Notifications/Default.cshtml b/src/EasyAbp.ProcessManagement.Web/Components/Toolbar/Notifications/Default.cshtml index 550da59..feb69fa 100644 --- a/src/EasyAbp.ProcessManagement.Web/Components/Toolbar/Notifications/Default.cshtml +++ b/src/EasyAbp.ProcessManagement.Web/Components/Toolbar/Notifications/Default.cshtml @@ -1,3 +1,12 @@ 
- @await Component.InvokeAsync("NotificationsWidget") -
\ No newline at end of file + @await Component.InvokeAsync("NotificationsToolbarItemWidget") + + + \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Controllers/ProcessManagementWidgetsController.cs b/src/EasyAbp.ProcessManagement.Web/Controllers/ProcessManagementWidgetsController.cs index 8c341b6..50e1ea8 100644 --- a/src/EasyAbp.ProcessManagement.Web/Controllers/ProcessManagementWidgetsController.cs +++ b/src/EasyAbp.ProcessManagement.Web/Controllers/ProcessManagementWidgetsController.cs @@ -7,9 +7,9 @@ namespace EasyAbp.ProcessManagement.Web.Controllers; public class ProcessManagementWidgetsController : AbpController { [HttpGet] - [Route("Notifications")] - public IActionResult Notifications() + [Route("NotificationsToolbarItem")] + public IActionResult NotificationsToolbarItem() { - return ViewComponent("NotificationsWidget"); + return ViewComponent("NotificationsToolbarItemWidget"); } } \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/NotificationsModal.cshtml b/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/NotificationsModal.cshtml deleted file mode 100644 index 6cbb51e..0000000 --- a/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/NotificationsModal.cshtml +++ /dev/null @@ -1,32 +0,0 @@ -@page -@using EasyAbp.ProcessManagement.Localization -@using EasyAbp.ProcessManagement.Web.Options -@using Microsoft.AspNetCore.Mvc.Localization -@using Microsoft.Extensions.Options -@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal; -@inject IHtmlLocalizer L -@inject IOptions Options - -@{ - Layout = null; -} - - - -
- - - - - - - @L["More"] - @L["Close"] - - -
- - - \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/notificationsModal.css b/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/notificationsModal.css deleted file mode 100644 index e8637eb..0000000 --- a/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/notificationsModal.css +++ /dev/null @@ -1,19 +0,0 @@ -.row-text-bold { - font-weight: bold; -} - -tr:hover { - cursor: pointer; -} - -.svg-icon { - vertical-align: middle; - width: 20px; - height: 20px; - margin-right: 10px; -} - -.stage-flag-name-container { - display: flex; - align-items: center; -} \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/notificationsModal.js b/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/notificationsModal.js deleted file mode 100644 index dc98a6d..0000000 --- a/src/EasyAbp.ProcessManagement.Web/Pages/ProcessManagement/Notifications/Notification/notificationsModal.js +++ /dev/null @@ -1,113 +0,0 @@ -$(function () { - - $('#go-to-management-page').click(function () { - document.location = abp.appPath + 'ProcessManagement/Processes/Process'; - }); - - var l = abp.localization.getResource('EasyAbpProcessManagement'); - - var notificationService = easyAbp.processManagement.notifications.notification; - var processService = easyAbp.processManagement.processes.process; - var widgetManager = new abp.WidgetManager({wrapper: '#ToolbarNotificationsWidgetArea'}); - - var dataTable = $('#NotificationsTable').DataTable(abp.libs.datatables.normalizeConfiguration({ - processing: true, - serverSide: true, - paging: false, - lengthChange: false, - pageLength: 10, - searching: false, // disable default searchbox - autoWidth: false, - scrollCollapse: true, - ordering: false, - ajax: abp.libs.datatables.createAjax(notificationService.getList, { - fromCreationTime: new Date(abp.clock.now() - notificationLifetime), - userId: abp.currentUser.id, - dismissed: false - }), - columnDefs: [ - { - data: "stateName", - render: function (data, type, row, meta) { - return `
` + getStateFlagIcon(row) + ' ' + renderRow(row, row.actionName ? row.actionName : data) + `
`; - } - }, - { - data: "creationTime", - render: function (data, type, row, meta) { - return renderRow(row, toTimeAgo(data)) - } - } - ] - })); - - function renderRow(row, data) { - return row.readTime == null ? '' + data + '' : data; - } - - function toTimeAgo(time) { - var timeTag = ``; - return `` - + timeTag - + `` - } - - function formatChildRow(data) { - return data; - } - - function getStateFlagIcon(row) { - // https://commons.wikimedia.org/wiki/File:Emojione_BW_23F8.svg - if (row.stateFlag === 0) { - return ``; - } - if (row.stateFlag === 1) { - return ``; - } - if (row.stateFlag === 2) { - return ``; - } - if (row.stateFlag === 3) { - return ``; - } - if (row.stateFlag === 4) { - return ``; - } - if (row.stateFlag === 5) { - return ``; - } - return '' - } - - // Add event listener for opening and closing details - $('#NotificationsTable tbody').on('click', 'td', function () { - var tr = $(this).closest('tr'); - var row = dataTable.row(tr); - - if (row.child.isShown()) { - // This row is already open - close it - row.child.hide(); - tr.removeClass('shown'); - } else { - var rowData = row.data(); - if (!rowData) return; - // Hide other rows' child - dataTable.rows().every(function () { - var otherRow = this; - if (otherRow.child.isShown()) { - otherRow.child.hide(); - } - }); - tr.removeClass('shown'); - // Open this row - row.child(formatChildRow(rowData.stateSummaryText)).show(); - tr.addClass('shown'); - if (!rowData.readTime) { - notificationService.read(rowData.id).then(function () { - widgetManager.refresh(); - tr.find('span.row-text-bold').removeClass('row-text-bold'); - }); - } - } - }); -}); \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/ProcessManagementWebModule.cs b/src/EasyAbp.ProcessManagement.Web/ProcessManagementWebModule.cs index 3fe1ccd..954eb3d 100644 --- a/src/EasyAbp.ProcessManagement.Web/ProcessManagementWebModule.cs +++ b/src/EasyAbp.ProcessManagement.Web/ProcessManagementWebModule.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; using EasyAbp.ProcessManagement.Localization; +using EasyAbp.ProcessManagement.Web.Components.NotificationsOffcanvasWidget; using EasyAbp.ProcessManagement.Web.Menus; using EasyAbp.ProcessManagement.Web.Toolbars; using Volo.Abp.AspNetCore.Mvc.Localization; @@ -8,6 +9,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; +using Volo.Abp.Ui.LayoutHooks; using Volo.Abp.UI.Navigation; using Volo.Abp.VirtualFileSystem; @@ -56,5 +58,10 @@ public override void ConfigureServices(ServiceConfigurationContext context) Configure( options => { options.Contributors.Add(new ProcessManagementToolbarContributor()); }); + + Configure(options => + { + options.Add(LayoutHooks.Body.First, typeof(NotificationsOffcanvasWidgetViewComponent)); + }); } } \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/0.svg b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/0.svg deleted file mode 100644 index c6f66b4..0000000 --- a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/0.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/1.svg b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/1.svg index d80a524..c6f66b4 100644 --- a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/1.svg +++ b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/1.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/2.svg b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/2.svg index ae7e564..d80a524 100644 --- a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/2.svg +++ b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/2.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/3.svg b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/3.svg index 97c3e93..ae7e564 100644 --- a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/3.svg +++ b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/3.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/4.svg b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/4.svg index 2313337..97c3e93 100644 --- a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/4.svg +++ b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/4.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/5.svg b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/5.svg index 5299332..f908d28 100644 --- a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/5.svg +++ b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/5.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/6.svg b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/6.svg new file mode 100644 index 0000000..5299332 --- /dev/null +++ b/src/EasyAbp.ProcessManagement.Web/wwwroot/images/process-management/icons/6.svg @@ -0,0 +1 @@ + \ No newline at end of file