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();
}
/// <summary>
/// Toast 组件实例
/// </summary>
protected Toast? Toast { get; set; }
/// <summary>
/// 显示提示信息
/// </summary>
/// <param name="title"></param>
/// <param name="text"></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>
/// 编辑按钮方法

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>
Success,
/// <summary>
/// 提示信息
/// </summary>
Information,
/// <summary>
/// 错误信息
/// </summary>

View File

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

View File

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

View File

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

View File

@ -228,5 +228,3 @@
</ModalFooter>
</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" />
</ItemTemplate>
</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" />
</ItemTemplate>
</AssignModal>
<Toast @ref="Toast" Id="menu_assign_toast"></Toast>

View File

@ -111,4 +111,3 @@
</div>
</div>
</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" />
</ItemTemplate>
</AssignModal>
<Toast @ref="Toast" Id="role_assign_toast"></Toast>

View File

@ -306,4 +306,3 @@
</Table>
</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" />
</ItemTemplate>
</AssignModal>
<Toast @ref="Toast" Id="user_assign_toast"></Toast>

View File

@ -1,6 +1,7 @@
using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
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;
/// <summary>
/// Toast 组件实例
/// IJSRuntime 接口实例
/// </summary>
protected Toast? Toast { get; set; }
[Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
/// 显示提示信息
@ -126,7 +128,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param>
/// <param name="text"></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>
/// 获得/设置 Modal 实例

View File

@ -1,9 +1,9 @@
using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess;
using Bootstrap.Security;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
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;
/// <summary>
/// Toast 组件实例
/// IJSRuntime 接口实例
/// </summary>
protected Toast? Toast { get; set; }
[Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
/// 显示提示信息
@ -238,6 +239,6 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param>
/// <param name="text"></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 Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
@ -49,9 +50,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
public string DisplayName { get; set; } = "";
/// <summary>
/// Toast 组件实例
/// IJSRuntime 接口实例
/// </summary>
protected Toast? Toast { get; set; }
[Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
/// 获得/设置 选中的样式项
@ -78,7 +80,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// </summary>
/// <param name="text"></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>
/// 组件初始化方法

View File

@ -1,6 +1,8 @@
using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
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;
/// <summary>
/// Toast 组件实例
/// IJSRuntime 接口实例
/// </summary>
protected Toast? Toast { get; set; }
[Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
/// 显示提示信息
@ -125,7 +128,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param>
/// <param name="text"></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>
/// 获得/设置 Modal 实例

View File

@ -37,9 +37,10 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
public DefaultLayout? RootLayout { get; protected set; }
/// <summary>
/// Toast 组件实例
/// IJSRuntime 接口实例
/// </summary>
protected Toast? Toast { get; set; }
[Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
/// NavigationManager 实例
@ -52,7 +53,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// </summary>
/// <param name="text"></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>
/// 设置参数方法

View File

@ -1,6 +1,7 @@
using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Shared;
using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
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;
/// <summary>
/// Toast 组件实例
/// IJSRuntime 接口实例
/// </summary>
protected Toast? Toast { get; set; }
[Inject]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
/// 显示提示信息
@ -129,7 +131,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
/// <param name="title"></param>
/// <param name="text"></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>
/// 获得/设置 Modal 实例

View File

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

View File

@ -111,8 +111,49 @@
toggleModal: function (modalId) {
$(modalId).modal('toggle');
},
showToast: function (id) {
$('#' + id).toast('show');
showToast: function (title, message, cate) {
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) {
var $ele = $(id);