コード例 #1
0
        private async Task ShowDialog()
        {
            var items = EditorItem <Foo> .GenerateEditorItems();

            var item = items.First(i => i.GetFieldName() == nameof(Foo.Hobby));

            item.Data = Foo.GenerateHobbys(Localizer);

            var option = new EditDialogOption <Foo>()
            {
                Title        = "编辑对话框",
                Model        = Model,
                Items        = items,
                OnCloseAsync = () =>
                {
                    Trace.Log("关闭按钮被点击");
                    return(Task.CompletedTask);
                },
                OnSaveAsync = context =>
                {
                    Trace.Log("保存按钮被点击");
                    return(Task.FromResult(true));
                }
            };

            await DialogService.ShowEditDialog(option);
        }
コード例 #2
0
    private async Task ShowAlignDialog()
    {
        var items = Utility.GenerateEditorItems <Foo>();
        var item  = items.First(i => i.GetFieldName() == nameof(Foo.Hobby));

        item.Items = Foo.GenerateHobbys(Localizer);

        var option = new EditDialogOption <Foo>()
        {
            Title        = "编辑对话框",
            Model        = Model,
            Items        = items,
            ItemsPerRow  = 2,
            RowType      = RowType.Inline,
            LabelAlign   = Alignment.Right,
            OnCloseAsync = () =>
            {
                Trace.Log("关闭按钮被点击");
                return(Task.CompletedTask);
            },
            OnEditAsync = context =>
            {
                Trace.Log("保存按钮被点击");
                return(Task.FromResult(true));
            }
        };

        await DialogService.ShowEditDialog(option);
    }
コード例 #3
0
 private async Task OnEditDialogClick()
 {
     var option = new EditDialogOption <Foo>()
     {
         Title           = "编辑弹窗",
         Model           = new Foo(),
         RowType         = RowType.Inline,
         ItemsPerRow     = 2,
         ItemChangedType = ItemChangedType.Update
     };
     await DialogService.ShowEditDialog(option);
 }
コード例 #4
0
        private async Task ShowDialog()
        {
            var option = new EditDialogOption <BindItem>()
            {
                Title        = "编辑对话框",
                Model        = Model,
                OnCloseAsync = () =>
                {
                    Trace.Log("关闭按钮被点击");
                    return(Task.CompletedTask);
                },
                OnSaveAsync = context =>
                {
                    Trace.Log("保存按钮被点击");
                    return(Task.FromResult(true));
                }
            };

            await DialogService.ShowEditDialog(option);
        }
コード例 #5
0
    /// <summary>
    /// 弹出编辑对话框
    /// </summary>
    /// <param name="service">DialogService 服务实例</param>
    /// <param name="option">EditDialogOption 配置类实例</param>
    /// <param name="dialog"></param>
    public static async Task ShowEditDialog <TModel>(this DialogService service, EditDialogOption <TModel> option, Dialog?dialog = null)
    {
        var parameters = new Dictionary <string, object?>
        {
            [nameof(EditDialog <TModel> .ShowUnsetGroupItemsOnTop)] = option.ShowUnsetGroupItemsOnTop,
            [nameof(EditDialog <TModel> .ShowLoading)]  = option.ShowLoading,
            [nameof(EditDialog <TModel> .ShowLabel)]    = option.ShowLabel,
            [nameof(EditDialog <TModel> .Items)]        = option.Items ?? Utility.GenerateColumns <TModel>(item => item.Editable),
            [nameof(EditDialog <TModel> .OnCloseAsync)] = new Func <Task>(async() =>
            {
                option.Dialog.RemoveDialog();
                await option.Dialog.CloseOrPopDialog();
            }),
            [nameof(EditDialog <TModel> .OnSaveAsync)] = new Func <EditContext, Task>(async context =>
            {
                if (option.OnEditAsync != null)
                {
                    var ret = await option.OnEditAsync(context);
                    if (ret)
                    {
                        option.Dialog.RemoveDialog();
                        await option.Dialog.CloseOrPopDialog();
                    }
                }
            }),
            [nameof(EditDialog <TModel> .RowType)]         = option.RowType,
            [nameof(EditDialog <TModel> .LabelAlign)]      = option.LabelAlign,
            [nameof(EditDialog <TModel> .ItemChangedType)] = option.ItemChangedType,
            [nameof(ItemsPerRow)] = option.ItemsPerRow,
            [nameof(EditDialog <TModel> .CloseButtonText)] = option.CloseButtonText,
            [nameof(EditDialog <TModel> .SaveButtonText)]  = option.SaveButtonText,
            [nameof(EditDialog <TModel> .Model)]           = option.Model,
            [nameof(EditDialog <TModel> .BodyTemplate)]    = option.DialogBodyTemplate
        };

        option.Component = BootstrapDynamicComponent.CreateComponent <EditDialog <TModel> >(parameters);
        await service.Show(option, dialog);
    }
コード例 #6
0
    public void Show_Ok()
    {
        #region Show
        var cut = Context.RenderComponent <BootstrapBlazorRoot>(pb =>
        {
            pb.AddChildContent <MockDialogTest>();
        });
        var dialog = cut.FindComponent <MockDialogTest>().Instance.DialogService;

        var closed = false;
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            BodyTemplate       = builder => builder.AddContent(0, "Test-BodyTemplate"),
            HeaderTemplate     = builder => builder.AddContent(0, "Test-HeaderTemplate"),
            FooterTemplate     = builder => builder.AddContent(0, "Test-FooterTemplate"),
            Class              = "test-class",
            ShowMaximizeButton = true,
            OnCloseAsync       = () =>
            {
                closed = true;
                return(Task.CompletedTask);
            }
        }));

        // 全屏按钮
        Assert.Contains("btn-maximize", cut.Markup);

        // 代码覆盖模板单元测试
        Assert.Contains("Test-BodyTemplate", cut.Markup);
        Assert.Contains("Test-HeaderTemplate", cut.Markup);
        Assert.Contains("Test-FooterTemplate", cut.Markup);
        Assert.Contains("test-class", cut.Markup);

        // 测试关闭逻辑
        var modal = cut.FindComponent <Modal>();
        cut.InvokeAsync(() => modal.Instance.Close());
        Assert.True(closed);

        // 测试 Component 赋值逻辑
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            Component    = BootstrapDynamicComponent.CreateComponent <Button>(),
            BodyTemplate = null
        }));
        Assert.Contains("class=\"btn btn-primary\"", cut.Markup);
        modal = cut.FindComponent <Modal>();
        cut.InvokeAsync(() => modal.Instance.Close());

        // 测试 Component 与 BodyTemplate 均为 null 逻辑
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            Component    = null,
            BodyTemplate = null
        }));
        cut.InvokeAsync(() => modal.Instance.Close());
        #endregion

        #region ShowSearchDialog
        // 无按钮回调赋值
        var option = new SearchDialogOption <Foo>()
        {
            Title           = "Test-SearchDialogTitle",
            Model           = new Foo(),
            ItemsPerRow     = 2,
            RowType         = RowType.Inline,
            LabelAlign      = Alignment.Left,
            ResetButtonText = null,
            QueryButtonText = null,
            Items           = null
        };
        cut.InvokeAsync(() => dialog.ShowSearchDialog(option));

        // 重置按钮委托为空 null
        var button = cut.FindComponents <Button>().First(b => b.Instance.Text == "重置");
        cut.InvokeAsync(() => button.Instance.OnClickWithoutRender !.Invoke());

        // 搜索按钮委托为空
        cut.InvokeAsync(() => dialog.ShowSearchDialog(option));
        button = cut.FindComponents <Button>().First(b => b.Instance.Text == "查询");
        cut.InvokeAsync(() => button.Instance.OnClickWithoutRender !.Invoke());

        // 重置按钮
        var reset = false;
        option.OnResetSearchClick = () =>
        {
            reset = true;
            return(Task.CompletedTask);
        };
        cut.InvokeAsync(() => dialog.ShowSearchDialog(option));
        button = cut.FindComponents <Button>().First(b => b.Instance.Text == "重置");
        cut.InvokeAsync(() => button.Instance.OnClickWithoutRender !.Invoke());
        Assert.True(reset);

        // 搜索按钮
        var search = false;
        option.DialogBodyTemplate = foo => builder => builder.AddContent(0, foo.Name);
        option.OnSearchClick      = () =>
        {
            search = true;
            return(Task.CompletedTask);
        };
        cut.InvokeAsync(() => dialog.ShowSearchDialog(option));
        button = cut.FindComponents <Button>().First(b => b.Instance.Text == "查询");
        cut.InvokeAsync(() => button.Instance.OnClickWithoutRender !.Invoke());
        Assert.True(search);
        #endregion

        #region ShowEditDialog
        // 无按钮回调赋值
        var editOption = new EditDialogOption <Foo>()
        {
            Model           = new Foo(),
            ItemsPerRow     = 2,
            RowType         = RowType.Inline,
            ItemChangedType = ItemChangedType.Add,
            LabelAlign      = Alignment.Left,
            ShowLabel       = true
        };
        cut.InvokeAsync(() => dialog.ShowEditDialog(editOption));
        cut.InvokeAsync(() => modal.Instance.Close());

        // 设置关闭回调
        closed = false;
        editOption.OnCloseAsync = () =>
        {
            closed = true;
            return(Task.CompletedTask);
        };
        cut.InvokeAsync(() => dialog.ShowEditDialog(editOption));
        button = cut.FindComponents <Button>().First(b => b.Instance.Text == "关闭");
        cut.InvokeAsync(() => button.Instance.OnClickWithoutRender !.Invoke());
        Assert.True(closed);

        // 设置保存回调
        var saved = false;
        editOption.ShowLoading = true;
        editOption.OnEditAsync = context =>
        {
            saved = true;
            return(Task.FromResult(true));
        };

        var model = new Foo()
        {
            Name = "Test"
        };
        var parameters = new Dictionary <string, object?>()
        {
            ["Field"]           = "Name",
            ["FieldExpression"] = model.GenerateValueExpression()
        };
        var item = new EditorItem <Foo, string>();
        cut.InvokeAsync(() => item.SetParametersAsync(ParameterView.FromDictionary(parameters)));
        editOption.Items = new IEditorItem[]
        {
            item
        };
        editOption.Model = model;
        cut.InvokeAsync(() => dialog.ShowEditDialog(editOption));
        var form = cut.Find("form");
        form.Submit();
        Assert.True(saved);

        // 测试 DialogBodyTemplate
        editOption.DialogBodyTemplate = foo => builder => builder.AddContent(0, "test");
        cut.InvokeAsync(() => dialog.ShowEditDialog(editOption));
        form.Submit();

        // Modal is Null
        editOption.Model = null;
        Assert.ThrowsAsync <InvalidOperationException>(() => cut.InvokeAsync(() => dialog.ShowEditDialog(editOption)));
        cut.InvokeAsync(() => cut.Find(".btn-close").Click());
        #endregion

        #region ShowModal
        var result       = false;
        var resultOption = new ResultDialogOption()
        {
            ComponentParamters = new Dictionary <string, object>()
            {
                [nameof(MockModalDialog.Value)]        = result,
                [nameof(MockModalDialog.ValueChanged)] = EventCallback.Factory.Create <bool>(this, b => result = b)
            }
        };

        // 点击的是 Yes 按钮
        cut.InvokeAsync(() => dialog.ShowModal <MockModalDialog>(resultOption));
        button = cut.FindComponents <Button>().First(b => b.Instance.Text == "确认");
        cut.InvokeAsync(() => button.Instance.OnClick.InvokeAsync());
        Assert.True(result);

        // 点击的是 No 按钮
        result       = true;
        resultOption = new ResultDialogOption()
        {
            ComponentParamters = new Dictionary <string, object>()
            {
                [nameof(MockModalDialog.Value)]        = result,
                [nameof(MockModalDialog.ValueChanged)] = EventCallback.Factory.Create <bool>(this, b => result = b)
            }
        };
        cut.InvokeAsync(() => dialog.ShowModal <MockModalDialog>(resultOption));
        button = cut.FindComponents <Button>().First(b => b.Instance.Text == "取消");
        cut.InvokeAsync(() => button.Instance.OnClick.InvokeAsync());
        Assert.False(result);

        // 点击关闭按钮
        resultOption = new ResultDialogOption()
        {
            ShowCloseButton    = true,
            ComponentParamters = new Dictionary <string, object>()
            {
                [nameof(MockModalDialog.Value)]        = result,
                [nameof(MockModalDialog.ValueChanged)] = EventCallback.Factory.Create <bool>(this, b => result = b)
            },
            OnCloseAsync = () => Task.CompletedTask
        };
        cut.InvokeAsync(() => dialog.ShowModal <MockModalDialog>(resultOption));
        button = cut.FindComponents <Button>().First(b => b.Instance.Text == "关闭");
        cut.InvokeAsync(() => button.Instance.OnClick.InvokeAsync());
        #endregion

        #region 弹窗中的弹窗测试
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            // 弹窗中按钮
            BodyTemplate = BootstrapDynamicComponent.CreateComponent <Button>(new Dictionary <string, object?>()
            {
                [nameof(Button.OnClickWithoutRender)] = () =>
                {
                    // 继续弹窗
                    dialog.Show(new DialogOption()
                    {
                        BodyTemplate = builder =>
                        {
                            builder.AddContent(0, "Test");
                        }
                    });
                    return(Task.CompletedTask);
                }
            }).Render()
        }));

        // 弹出第二个弹窗
        var buttonInDialog = cut.Find(".btn-primary");
        buttonInDialog.Click();
        Assert.Equal(2, cut.FindComponents <ModalDialog>().Count);

        // 关闭第二个弹窗
        var btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();
        Assert.Equal(1, cut.FindComponents <ModalDialog>().Count);

        // 关闭第一个弹窗
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();
        Assert.Equal(0, cut.FindComponents <ModalDialog>().Count);
        #endregion

        #region 全屏弹窗
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            FullScreenSize = FullScreenSize.Large
        }));
        Assert.Contains("modal-fullscreen-lg-down", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();
        #endregion

        #region IsCenter
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            IsCentered = true
        }));
        Assert.Contains("modal-dialog-centered", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();

        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            IsCentered = false
        }));
        Assert.DoesNotContain("modal-dialog-centered", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();
        #endregion

        #region IsKeyboard
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            IsKeyboard = true
        }));
        Assert.Contains("data-bs-keyboard=\"true\"", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();

        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            IsKeyboard = false
        }));
        Assert.DoesNotContain("data-bs-keyboard\"false\"", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();
        #endregion

        #region ShowHeaderCloseButton
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            ShowHeaderCloseButton = true
        }));
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();

        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            ShowHeaderCloseButton = false
        }));
        Assert.DoesNotContain("btn-close", cut.Markup);
        btnClose = cut.FindAll(".btn-secondary")[cut.FindAll(".btn-secondary").Count - 1];
        btnClose.Click();
        #endregion

        #region ShowPrintButton
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            ShowPrintButton = true
        }));
        Assert.Contains("btn-print", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();

        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            ShowPrintButton = false
        }));
        Assert.DoesNotContain("btn-print", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();

        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            ShowPrintButton         = true,
            ShowPrintButtonInHeader = true,
            PrintButtonText         = "Print-Test"
        }));
        Assert.Contains("btn-print", cut.Markup);
        Assert.Contains("Print-Test", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();
        #endregion

        #region ShowSaveButton
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            ShowSaveButton  = true,
            SaveButtonText  = "Save-Test",
            CloseButtonText = "Close-Test",
            BodyContext     = "Test"
        }));
        Assert.Contains("Save-Test", cut.Markup);
        Assert.Contains("Close-Test", cut.Markup);
        btnClose = cut.FindAll(".btn-close")[cut.FindAll(".btn-close").Count - 1];
        btnClose.Click();
        #endregion

        #region OnSaveAsync
        var save = false;
        cut.InvokeAsync(() => dialog.Show(new DialogOption()
        {
            ShowSaveButton       = true,
            IsAutoCloseAfterSave = true,
            IsDraggable          = false,
            OnSaveAsync          = () =>
            {
                save = true;
                return(Task.FromResult(save));
            }
        }));
        btnClose = cut.FindAll(".btn-primary")[cut.FindAll(".btn-primary").Count - 1];
        btnClose.Click();
        Assert.True(save);
        #endregion

        #region ShowSaveDialog
        cut.InvokeAsync(() => dialog.ShowSaveDialog <MockDialogTest>("Title", () => Task.FromResult(true), p => { }, op => op.Class = "test"));
        modal.FindAll("button")[modal.FindAll("button").Count - 1].Click();
        cut.InvokeAsync(() => dialog.ShowSaveDialog <MockDialogTest>("Title"));
        modal.FindAll("button")[modal.FindAll("button").Count - 1].Click();
        #endregion

        #region ShowValidateFormDialog
        cut.InvokeAsync(() => dialog.ShowValidateFormDialog <MockValidateFormDialog>("ValidateFormDialog"));
        var btn = cut.Find(".btn-close");
        cut.InvokeAsync(() => btn.Click());

        Func <DialogOption, Dictionary <string, object?> > parameterFactory = op => new Dictionary <string, object?>();
        Action <DialogOption> configureOption = op => op.Class = "ValidateFormDialog-Class";
        cut.InvokeAsync(() => dialog.ShowValidateFormDialog <MockValidateFormDialog>("ValidateFormDialog", parameterFactory, configureOption));
        btn = cut.Find(".btn-close");
        cut.InvokeAsync(() => btn.Click());
        #endregion

        #region ShowCloseDialog
        Action <Dictionary <string, object?> > closeDialogParameterFactory = op => new Dictionary <string, object?>();
        cut.InvokeAsync(() => dialog.ShowCloseDialog <MockValidateFormDialog>("CloseDialog", closeDialogParameterFactory, configureOption));
        btn = cut.Find(".btn-close");
        cut.InvokeAsync(() => btn.Click());
        cut.InvokeAsync(() => dialog.ShowCloseDialog <MockValidateFormDialog>("CloseDialog"));
        btn = cut.Find(".btn-close");
        cut.InvokeAsync(() => btn.Click());
        #endregion
    }