feat: 移除 Toast 服务器端组件

#Comment
使用 JavaScript 实现
This commit is contained in:
Argo Zhang 2020-03-09 16:53:11 +08:00
parent 04c769c84b
commit 41d967c910
No known key found for this signature in database
GPG Key ID: 152E398953DDF19F
22 changed files with 112 additions and 220 deletions

View File

@ -358,18 +358,13 @@ namespace Bootstrap.Admin.Pages.Components
EditModal?.Toggle(); EditModal?.Toggle();
} }
/// <summary>
/// Toast 组件实例
/// </summary>
protected Toast? Toast { get; set; }
/// <summary> /// <summary>
/// 显示提示信息 /// 显示提示信息
/// </summary> /// </summary>
/// <param name="title"></param> /// <param name="title"></param>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="cate"></param> /// <param name="cate"></param>
protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => Toast?.ShowMessage(title, text, cate); protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => JSRuntime?.ShowToast(title, text, cate);
/// <summary> /// <summary>
/// 编辑按钮方法 /// 编辑按钮方法

View File

@ -1,133 +0,0 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
namespace Bootstrap.Admin.Pages.Components
{
/// <summary>
/// Toast 组件基类
/// </summary>
public class ToastBase : ComponentBase
{
/// <summary>
/// IJSRuntime 实例
/// </summary>
[Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
/// 是否自动隐藏 默认为 true
/// </summary>
[Parameter]
public bool AutoHide { get; set; } = true;
/// <summary>
/// 自动隐藏延时 默认为 1500 毫秒
/// </summary>
[Parameter]
public int Interval { get; set; } = 2000;
/// <summary>
/// 组件显示位置
/// </summary>
[Parameter]
public Placement Placement { get; set; }
/// <summary>
/// Toast 类型
/// </summary>
[Parameter]
public ToastCategory Category { get; set; }
/// <summary>
/// 组件标题文本
/// </summary>
[Parameter]
public string Title { get; set; } = "BootstrapAdmin Blazor";
/// <summary>
/// 消息正文
/// </summary>
[Parameter]
public string Text { get; set; } = "Toast 消息正文内容-未设置";
/// <summary>
/// 获得/设置 组件 ID
/// </summary>
[Parameter]
public string Id { get; set; } = "";
/// <summary>
/// 控件呈现后回调方法
/// </summary>
/// <param name="firstRender"></param>
protected override void OnAfterRender(bool firstRender)
{
if (_show)
{
_show = false;
Show();
}
}
/// <summary>
/// OnParametersSet 方法
/// </summary>
protected override void OnParametersSet()
{
if (string.IsNullOrEmpty(Id)) throw new InvalidOperationException("Toast component must have Id property");
}
/// <summary>
/// 显示 Toast 提示框方法
/// </summary>
protected void Show()
{
JSRuntime.ShowToast(Id);
}
private bool _show;
/// <summary>
/// 显示 Toast 提示框方法
/// </summary>
public void ShowMessage(string title, string text, ToastCategory category = ToastCategory.Success)
{
Title = title;
Text = text;
Category = category;
_show = true;
StateHasChanged();
}
/// <summary>
/// 呈现不同类别方法
/// </summary>
/// <returns></returns>
protected string RenderCategory()
{
var ret = "";
switch (Category)
{
case ToastCategory.Error:
ret = "fa fa-times-circle text-danger";
break;
case ToastCategory.Information:
ret = "fa fa-exclamation-triangle text-info";
break;
case ToastCategory.Success:
ret = "fa fa-check-circle text-success";
break;
}
return ret;
}
/// <summary>
/// 呈现动画方法
/// </summary>
/// <returns></returns>
protected string RenderAnimation()
{
return AutoHide ? $"transition: width {(Interval * 1.0 - 200) / 1000}s linear;" : "";
}
}
}

View File

@ -9,10 +9,12 @@
/// 成功 /// 成功
/// </summary> /// </summary>
Success, Success,
/// <summary> /// <summary>
/// 提示信息 /// 提示信息
/// </summary> /// </summary>
Information, Information,
/// <summary> /// <summary>
/// 错误信息 /// 错误信息
/// </summary> /// </summary>

View File

@ -2,11 +2,10 @@
using Bootstrap.Security; using Bootstrap.Security;
using Longbow.Cache; using Longbow.Cache;
using Longbow.Web; using Longbow.Web;
using Microsoft.Extensions.DependencyInjection;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.Extensions.DependencyInjection
{ {
/// <summary> /// <summary>
/// 显示名称扩展方法类 /// 显示名称扩展方法类

View File

@ -1,5 +1,5 @@
using Bootstrap.Admin.Pages.Components; using Bootstrap.Admin.Pages.Components;
using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection;
using System.ComponentModel; using System.ComponentModel;
namespace Microsoft.AspNetCore.Components.Forms namespace Microsoft.AspNetCore.Components.Forms

View File

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Bootstrap.Admin.Pages.Components;
namespace Microsoft.JSInterop namespace Microsoft.JSInterop
{ {
@ -57,8 +58,10 @@ namespace Microsoft.JSInterop
/// 弹出 Toast 组件 /// 弹出 Toast 组件
/// </summary> /// </summary>
/// <param name="jSRuntime"></param> /// <param name="jSRuntime"></param>
/// <param name="id"></param> /// <param name="title"></param>
public static void ShowToast(this IJSRuntime? jSRuntime, string id) => jSRuntime.InvokeVoidAsync("$.showToast", id); /// <param name="message"></param>
/// <param name="cate"></param>
public static void ShowToast(this IJSRuntime? jSRuntime, string title, string message, ToastCategory cate) => jSRuntime.InvokeVoidAsync("$.showToast", title, message, cate.ToString());
/// <summary> /// <summary>
/// 弹出 Tooltip 组件 /// 弹出 Tooltip 组件

View File

@ -228,5 +228,3 @@
</ModalFooter> </ModalFooter>
</Modal> </Modal>
} }
<Toast @ref="Toast" Id="@($"{Id}_toast")"></Toast>

View File

@ -1,19 +0,0 @@
@inherits ToastBase
<div class="toast fade @Placement.ToCss("toast")" id="@Id" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="@(AutoHide ? "true":"false")" data-delay="@Interval">
<div class="toast-header">
<div class="toast-bar"><i class="@RenderCategory()"></i></div>
<strong class="mr-auto">@Title</strong>
<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="toast-body">
@Text
</div>
<div class="toast-progress" style="@RenderAnimation()"></div>
</div>
@code {
}

View File

@ -48,5 +48,3 @@
<Checkbox TItem="Bootstrap.DataAccess.Role" Item="@context" Text="@context.RoleName" SetCheckCallback="SetCheck" OnClick="OnClick" /> <Checkbox TItem="Bootstrap.DataAccess.Role" Item="@context" Text="@context.RoleName" SetCheckCallback="SetCheck" OnClick="OnClick" />
</ItemTemplate> </ItemTemplate>
</AssignModal> </AssignModal>
<Toast @ref="Toast" Id="group_assign_toast"></Toast>

View File

@ -60,5 +60,3 @@
<Checkbox TItem="Bootstrap.DataAccess.Role" Item="@context" Text="@context.RoleName" SetCheckCallback="SetCheck" OnClick="OnClick" /> <Checkbox TItem="Bootstrap.DataAccess.Role" Item="@context" Text="@context.RoleName" SetCheckCallback="SetCheck" OnClick="OnClick" />
</ItemTemplate> </ItemTemplate>
</AssignModal> </AssignModal>
<Toast @ref="Toast" Id="menu_assign_toast"></Toast>

View File

@ -111,4 +111,3 @@
</div> </div>
</div> </div>
</ConditionComponent> </ConditionComponent>
<Toast @ref="Toast" Id="toast_profile"></Toast>

View File

@ -55,5 +55,3 @@
<Checkbox TItem="Bootstrap.DataAccess.App" Item="@context" Text="@context.AppName" SetCheckCallback="SetAppCheck" OnClick="OnAppClick" /> <Checkbox TItem="Bootstrap.DataAccess.App" Item="@context" Text="@context.AppName" SetCheckCallback="SetAppCheck" OnClick="OnAppClick" />
</ItemTemplate> </ItemTemplate>
</AssignModal> </AssignModal>
<Toast @ref="Toast" Id="role_assign_toast"></Toast>

View File

@ -306,4 +306,3 @@
</Table> </Table>
</div> </div>
</div> </div>
<Toast @ref="Toast" Id="toast_settings"></Toast>

View File

@ -59,5 +59,3 @@
<Checkbox TItem="Bootstrap.DataAccess.Role" Item="@context" Text="@context.RoleName" SetCheckCallback="SetCheck" OnClick="OnClick" /> <Checkbox TItem="Bootstrap.DataAccess.Role" Item="@context" Text="@context.RoleName" SetCheckCallback="SetCheck" OnClick="OnClick" />
</ItemTemplate> </ItemTemplate>
</AssignModal> </AssignModal>
<Toast @ref="Toast" Id="user_assign_toast"></Toast>

View File

@ -1,6 +1,7 @@
using Bootstrap.Admin.Pages.Components; using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -116,9 +117,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
protected CheckBoxState SetUserCheck(User item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked; protected CheckBoxState SetUserCheck(User item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked;
/// <summary> /// <summary>
/// Toast 组件实例 /// IJSRuntime 接口实例
/// </summary> /// </summary>
protected Toast? Toast { get; set; } [Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary> /// <summary>
/// 显示提示信息 /// 显示提示信息
@ -126,7 +128,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param> /// <param name="title"></param>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="cate"></param> /// <param name="cate"></param>
protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => Toast?.ShowMessage(title, text, cate); protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => JSRuntime?.ShowToast(title, text, cate);
/// <summary> /// <summary>
/// 获得/设置 Modal 实例 /// 获得/设置 Modal 实例

View File

@ -1,9 +1,9 @@
using Bootstrap.Admin.Pages.Components; using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Bootstrap.Security; using Bootstrap.Security;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.JSInterop;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -228,9 +228,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
protected CheckBoxState SetCheck(Role item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked; protected CheckBoxState SetCheck(Role item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked;
/// <summary> /// <summary>
/// Toast 组件实例 /// IJSRuntime 接口实例
/// </summary> /// </summary>
protected Toast? Toast { get; set; } [Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary> /// <summary>
/// 显示提示信息 /// 显示提示信息
@ -238,6 +239,6 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param> /// <param name="title"></param>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="cate"></param> /// <param name="cate"></param>
protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => Toast?.ShowMessage(title, text, cate); protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => JSRuntime?.ShowToast(title, text, cate);
} }
} }

View File

@ -5,6 +5,7 @@ using Bootstrap.DataAccess;
using Bootstrap.Security; using Bootstrap.Security;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -49,9 +50,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
public string DisplayName { get; set; } = ""; public string DisplayName { get; set; } = "";
/// <summary> /// <summary>
/// Toast 组件实例 /// IJSRuntime 接口实例
/// </summary> /// </summary>
protected Toast? Toast { get; set; } [Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary> /// <summary>
/// 获得/设置 选中的样式项 /// 获得/设置 选中的样式项
@ -78,7 +80,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// </summary> /// </summary>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="ret"></param> /// <param name="ret"></param>
protected void ShowMessage(string text, bool ret = true) => Toast?.ShowMessage("个人中心", text, ret ? ToastCategory.Success : ToastCategory.Error); protected void ShowMessage(string text, bool ret = true) => JSRuntime?.ShowToast("个人中心", text, ret ? ToastCategory.Success : ToastCategory.Error);
/// <summary> /// <summary>
/// 组件初始化方法 /// 组件初始化方法

View File

@ -1,6 +1,8 @@
using Bootstrap.Admin.Pages.Components; using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared; using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -115,9 +117,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
protected CheckBoxState SetUserCheck(User item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked; protected CheckBoxState SetUserCheck(User item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked;
/// <summary> /// <summary>
/// Toast 组件实例 /// IJSRuntime 接口实例
/// </summary> /// </summary>
protected Toast? Toast { get; set; } [Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary> /// <summary>
/// 显示提示信息 /// 显示提示信息
@ -125,7 +128,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param> /// <param name="title"></param>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="cate"></param> /// <param name="cate"></param>
protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => Toast?.ShowMessage(title, text, cate); protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => JSRuntime?.ShowToast(title, text, cate);
/// <summary> /// <summary>
/// 获得/设置 Modal 实例 /// 获得/设置 Modal 实例

View File

@ -37,9 +37,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
public DefaultLayout? RootLayout { get; protected set; } public DefaultLayout? RootLayout { get; protected set; }
/// <summary> /// <summary>
/// Toast 组件实例 /// IJSRuntime 接口实例
/// </summary> /// </summary>
protected Toast? Toast { get; set; } [Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary> /// <summary>
/// NavigationManager 实例 /// NavigationManager 实例
@ -52,7 +53,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// </summary> /// </summary>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="ret"></param> /// <param name="ret"></param>
protected void ShowMessage(string text, bool ret = true) => Toast?.ShowMessage("网站设置", ret ? $"{text}成功" : $"{text}失败", ret ? ToastCategory.Success : ToastCategory.Error); protected void ShowMessage(string text, bool ret = true) => JSRuntime?.ShowToast("网站设置", ret ? $"{text}成功" : $"{text}失败", ret ? ToastCategory.Success : ToastCategory.Error);
/// <summary> /// <summary>
/// 设置参数方法 /// 设置参数方法

View File

@ -1,6 +1,7 @@
using Bootstrap.Admin.Pages.Components; using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess; using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -119,9 +120,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
protected CheckBoxState SetGroupCheck(Group item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked; protected CheckBoxState SetGroupCheck(Group item) => item.Checked == "checked" ? CheckBoxState.Checked : CheckBoxState.UnChecked;
/// <summary> /// <summary>
/// Toast 组件实例 /// IJSRuntime 接口实例
/// </summary> /// </summary>
protected Toast? Toast { get; set; } [Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary> /// <summary>
/// 显示提示信息 /// 显示提示信息
@ -129,7 +131,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param> /// <param name="title"></param>
/// <param name="text"></param> /// <param name="text"></param>
/// <param name="cate"></param> /// <param name="cate"></param>
protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => Toast?.ShowMessage(title, text, cate); protected void ShowMessage(string title, string text, ToastCategory cate = ToastCategory.Success) => JSRuntime?.ShowToast(title, text, cate);
/// <summary> /// <summary>
/// 获得/设置 Modal 实例 /// 获得/设置 Modal 实例

View File

@ -131,9 +131,9 @@ nav .dropdown .nav-link-close.dropdown-toggle:after {
clear: both; clear: both;
} }
.bootstrap-table .fixed-table-toolbar .columns-right { .bootstrap-table .fixed-table-toolbar .columns-right {
margin-left: 5px; margin-left: 5px;
} }
.bootstrap-table .table-fixed { .bootstrap-table .table-fixed {
height: 388px; height: 388px;
@ -160,27 +160,27 @@ nav .dropdown .nav-link-close.dropdown-toggle:after {
border-bottom: 1px solid #dee2e6; border-bottom: 1px solid #dee2e6;
} }
.bootstrap-table .datetime { .bootstrap-table .datetime {
min-width: 170px; min-width: 170px;
}
.bootstrap-table .sortable {
padding-right: 30px;
cursor: pointer;
}
.bootstrap-table .sortable span {
display: inline-block;
width: 100%;
} }
.bootstrap-table .sortable i { .bootstrap-table .sortable {
margin-left: 8px; padding-right: 30px;
cursor: pointer;
} }
.bootstrap-table .sortable .fa-sort { .bootstrap-table .sortable span {
color: #dee2e6; display: inline-block;
} width: 100%;
}
.bootstrap-table .sortable i {
margin-left: 8px;
}
.bootstrap-table .sortable .fa-sort {
color: #dee2e6;
}
.table-wrapper { .table-wrapper {
border-radius: 4px; border-radius: 4px;
@ -234,7 +234,11 @@ nav .dropdown .nav-link-close.dropdown-toggle:after {
} }
.toast.show { .toast.show {
z-index: 1080; z-index: 1030;
}
.toast:not(:last-child) {
margin-bottom: 0;
} }
.toast-top { .toast-top {
@ -303,6 +307,7 @@ nav .dropdown .nav-link-close.dropdown-toggle:after {
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
filter: alpha(opacity=40); filter: alpha(opacity=40);
width: 0; width: 0;
transition: all 4s linear;
} }
.showing .toast-progress, .show .toast-progress { .showing .toast-progress, .show .toast-progress {

View File

@ -111,8 +111,49 @@
toggleModal: function (modalId) { toggleModal: function (modalId) {
$(modalId).modal('toggle'); $(modalId).modal('toggle');
}, },
showToast: function (id) { showToast: function (title, message, cate) {
$('#' + id).toast('show'); var cateToCss = function (c) {
var ret = "";
switch (c) {
case "Success":
ret = "fa fa-check-circle text-success";
break;
case "Information":
ret = "fa fa-exclamation-triangle text-info";
break;
case "Error":
default:
ret = "fa fa-times-circle text-danger";
break;
}
return ret;
}
var toastTemplate = '<div class="toast fade toast-bottom-right" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="true" data-delay="4200">';
toastTemplate += '<div class="toast-header">';
toastTemplate += '<div class="toast-bar"><i class="' + cateToCss(cate) + '"></i></div>';
toastTemplate += '<strong class="mr-auto">' + title + '</strong>';
toastTemplate += '<button type="button" class="ml-2 mb-1 close" data-dismiss="toast" aria-label="Close">';
toastTemplate += '<span aria-hidden="true">&times;</span>';
toastTemplate += '</button>';
toastTemplate += '</div><div class="toast-body">';
toastTemplate += message;
toastTemplate += '</div>';
toastTemplate += '<div class="toast-progress"></div>';
toastTemplate += '</div>';
// 利用 js 生成一个临时 toast 弹窗后自我销毁
var $toast = $(toastTemplate).appendTo('body');
var handler = window.setTimeout(function () {
window.clearTimeout(handler);
$toast.toast('show');
}, 200);
var handlerDismiss = window.setTimeout(function () {
window.clearTimeout(handlerDismiss);
//$toast.remove();
// 回调重新排列方法
}, 4400);
}, },
tooltip: function (id, method) { tooltip: function (id, method) {
var $ele = $(id); var $ele = $(id);