Skip to content

Commit 184cd1f

Browse files
Added StatusList, improved DeleteDialog, added better styled MudDialogEx
1 parent 9c7ce2c commit 184cd1f

File tree

13 files changed

+419
-46
lines changed

13 files changed

+419
-46
lines changed
Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
1-
<MudDialog OnKeyUp="OnKeyUp">
1+
<MudDialogEx OnKeyUp="OnKeyUp">
22
<TitleContent>
33
<MudText Typo="Typo.h6">
4-
<MudIcon Icon="@Icons.Material.Filled.DeleteForever" Class="mr-3 mb-n1" />
4+
<MudIcon Icon="@Icons.Material.Filled.DeleteForever" Color="Color.Error" Class="mr-3 mb-n1" />
55
@DialogInstance.Title
66
</MudText>
77
</TitleContent>
88
<DialogContent>
9-
<MudTextField Value="@ItemValue" Label="@ItemLabel" ReadOnly="true" />
9+
<MudText>Delete the @ItemLabel <strong>@ItemValue</strong>?</MudText>
10+
@if (NeedToConfirmValue)
11+
{
12+
<div class="mt-4">
13+
<MudText Typo="Typo.caption">Enter <strong>@ItemValue</strong> to confirm</MudText>
14+
<MudTextField @bind-Value="confirmedItemValue" Required="true" FullWidth="true" Error="hasError" ErrorText="Value does not match" />
15+
</div>
16+
}
1017
</DialogContent>
1118
<DialogActions>
12-
<MudButton OnClick="OnCancel">Cancel</MudButton>
13-
<MudButton Color="Color.Error" OnClick="OnConfirm">Delete</MudButton>
19+
<MudButton OnClick="OnCancel" Variant="Variant.Outlined" Class="mr-4">Cancel</MudButton>
20+
<MudButton Color="Color.Error" OnClick="OnConfirm" Variant="Variant.Filled">Delete</MudButton>
1421
</DialogActions>
15-
</MudDialog>
22+
</MudDialogEx>
1623

1724
@code
1825
{
@@ -25,19 +32,45 @@
2532
[Parameter, EditorRequired]
2633
public string ItemLabel { get; set; } = default!;
2734

35+
[Parameter]
36+
public bool NeedToConfirmValue { get; set; }
37+
38+
private bool hasError;
39+
private string? confirmedItemValue;
40+
2841
private void OnKeyUp(KeyboardEventArgs args)
2942
{
30-
if (args.Key == "Enter")
31-
OnConfirm();
43+
if (args.Key != "Enter")
44+
return;
45+
46+
if (!Validate())
47+
return;
48+
49+
OnConfirm();
3250
}
3351

3452
private void OnConfirm()
3553
{
54+
if (!Validate())
55+
return;
56+
3657
DialogInstance.Close(DialogResult.Ok(true));
3758
}
3859

3960
private void OnCancel()
4061
{
4162
DialogInstance.Cancel();
4263
}
64+
65+
private bool Validate()
66+
{
67+
if (NeedToConfirmValue && confirmedItemValue != ItemValue)
68+
{
69+
hasError = true;
70+
return false;
71+
}
72+
73+
hasError = false;
74+
return true;
75+
}
4376
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
@using System.Linq.Expressions
2+
@using DotNetElements.AppFramework.MudBlazorExtensions.Util
3+
4+
@* todo check if we want to move this to css file *@
5+
<style>
6+
.mud-input-inline-edit {
7+
display: flex;
8+
flex-direction: row;
9+
align-items: stretch;
10+
}
11+
12+
.mud-input-inline-edit .mud-input-outlined-border {
13+
border-top-right-radius: 0 !important;
14+
border-bottom-right-radius: 0 !important;
15+
}
16+
</style>
17+
18+
<div class="mud-input-inline-edit">
19+
<MudTextField Value="@Value" ValueChanged="@ValueChanged" ReadOnly="@(!isEditMode)" Label="@Label" For="@For" Required="@Required" />
20+
@if (isEditMode)
21+
{
22+
<MudIconButton Icon="@Icons.Material.Outlined.Save"
23+
Variant="Variant.Outlined"
24+
Color="Color.Primary"
25+
OnClick="OnSaveAsync"
26+
Class="mt-2 mb-1"
27+
Style="border-radius: 0; border: 1px solid var(--mud-palette-lines-inputs); border-left-width: 0;" />
28+
<MudIconButton Icon="@Icons.Material.Outlined.Cancel"
29+
Variant="Variant.Outlined"
30+
Color="Color.Default"
31+
OnClick="OnCancelAsync"
32+
Class="mt-2 mb-1"
33+
Style="border-bottom-left-radius: 0; border-top-left-radius: 0; border: 1px solid var(--mud-palette-lines-inputs); border-left-width: 0;" />
34+
}
35+
else
36+
{
37+
<MudIconButton Icon="@Icons.Material.Outlined.Edit"
38+
Variant="Variant.Outlined"
39+
Color="Color.Warning"
40+
OnClick="OnEnterEditMode"
41+
Class="mt-2 mb-1"
42+
Style="border-bottom-left-radius: 0; border-top-left-radius: 0; border: 1px solid var(--mud-palette-lines-inputs); border-left-width: 0;" />
43+
}
44+
</div>
45+
46+
@code
47+
{
48+
[Parameter, EditorRequired]
49+
public string? Value { get; set; }
50+
51+
[Parameter, EditorRequired]
52+
public EventCallback<string?> ValueChanged { get; set; }
53+
54+
[Parameter]
55+
public Expression<Func<string?>>? For { get; set; }
56+
57+
[Parameter]
58+
public string? Label { get; set; }
59+
60+
[Parameter]
61+
public bool Required { get; set; }
62+
63+
[Parameter]
64+
public EventCallback<CallbackResultArgs> OnSave { get; set; }
65+
66+
[Parameter]
67+
public EventCallback OnCancel { get; set; }
68+
69+
private bool isEditMode;
70+
private string? initialValue;
71+
72+
private void OnEnterEditMode()
73+
{
74+
initialValue = Value;
75+
isEditMode = true;
76+
}
77+
78+
private async Task OnSaveAsync()
79+
{
80+
if (!OnSave.HasDelegate)
81+
{
82+
isEditMode = false;
83+
}
84+
85+
CallbackResultArgs resultArgs = new();
86+
87+
await OnSave.InvokeAsync(resultArgs);
88+
89+
if (resultArgs.Cancelled)
90+
return;
91+
92+
initialValue = Value;
93+
isEditMode = false;
94+
}
95+
96+
private async Task OnCancelAsync()
97+
{
98+
isEditMode = false;
99+
Value = initialValue;
100+
101+
if (!OnCancel.HasDelegate)
102+
return;
103+
104+
await OnCancel.InvokeAsync();
105+
}
106+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace DotNetElements.AppFramework.MudBlazorExtensions.Components;
2+
3+
public sealed class MudDialogEx : MudDialog
4+
{
5+
protected const string DefaultTitleClass = "pa-4";
6+
protected const string DefaultContentClass = "pa-4 ma-0";
7+
protected const string DefaultContentStyle = "border-top: 1px solid var(--mud-palette-lines-default); border-top-left-radius: 0; border-top-right-radius: 0;";
8+
protected const string DefaultActionsClass = "px-4 pb-4";
9+
10+
public MudDialogEx()
11+
{
12+
Gutters = false;
13+
TitleClass = DefaultTitleClass;
14+
ContentClass = DefaultContentClass;
15+
ContentStyle = DefaultContentStyle;
16+
ActionsClass = DefaultActionsClass;
17+
}
18+
}

src/DotNetElements.AppFramework.MudBlazorExtensions/Components/MudEditFormDialog.razor

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
@typeparam TValue
44
@typeparam TReturnValue
55

6-
<MudDialog>
6+
<MudDialogEx>
77
<DialogContent>
88
@if (Value is not null && editContext is not null)
99
{
@@ -22,13 +22,13 @@
2222
}
2323
</DialogContent>
2424
<DialogActions>
25-
<MudButton OnClick="OnCancelAsync_Internal">@CancelButtonText</MudButton>
25+
<MudButton OnClick="OnCancelAsync_Internal" Variant="Variant.Outlined">@CancelButtonText</MudButton>
2626
@if (Value is not null && editContext is not null && SubmitButtonShown)
2727
{
28-
<MudButton Color="Color.Primary" OnClick="OnSubmitAsync_Internal">@SubmitButtonText</MudButton>
28+
<MudButton Color="Color.Primary" OnClick="OnSubmitAsync_Internal" Variant="Variant.Filled" Class="ml-4">@SubmitButtonText</MudButton>
2929
}
3030
</DialogActions>
31-
</MudDialog>
31+
</MudDialogEx>
3232

3333
@code
3434
{
@@ -42,7 +42,10 @@
4242
public RenderFragment<TValue> FormContent { get; set; } = default!;
4343

4444
[Parameter]
45-
public EventCallback<EditFormDialogArgs<TValue, TReturnValue>> OnSubmit { get; set; }
45+
public EventCallback<EditFormLoadArgs> OnLoad { get; set; }
46+
47+
[Parameter]
48+
public EventCallback<EditFormSubmitArgs<TValue, TReturnValue>> OnSubmit { get; set; }
4649

4750
[Parameter]
4851
public EventCallback OnCancel { get; set; }
@@ -61,23 +64,26 @@
6164
private bool hasError;
6265
private string? errorMessage;
6366

64-
public void ShowError(string message)
67+
public bool Validate()
6568
{
66-
hasError = true;
67-
errorMessage = message;
68-
}
69+
ArgumentNullException.ThrowIfNull(editContext);
6970

70-
public void ClearError()
71-
{
72-
hasError = false;
73-
errorMessage = null;
71+
return editContext.Validate();
7472
}
7573

76-
public bool Validate()
74+
protected override async Task OnInitializedAsync()
7775
{
78-
ArgumentNullException.ThrowIfNull(editContext);
76+
if (!OnLoad.HasDelegate)
77+
return;
7978

80-
return editContext.Validate();
79+
EditFormLoadArgs args = new();
80+
await OnLoad.InvokeAsync(args);
81+
82+
if (!args.HasError)
83+
return;
84+
85+
hasError = true;
86+
errorMessage = args.ErrorMessage;
8187
}
8288

8389
// todo check how this behaves when a parameter is updated!!!
@@ -94,7 +100,7 @@
94100
ArgumentNullException.ThrowIfNull(Value);
95101
ArgumentNullException.ThrowIfNull(editContext);
96102

97-
EditFormDialogArgs<TValue, TReturnValue> args = new(Value, editContext);
103+
EditFormSubmitArgs<TValue, TReturnValue> args = new(Value, editContext);
98104

99105
if (OnSubmit.HasDelegate)
100106
await OnSubmit.InvokeAsync(args);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
@using DotNetElements.AppFramework.MudBlazorExtensions.Util
2+
3+
<MudTreeView T="StatusListItem" ReadOnly="true">
4+
@foreach (StatusListItem item in Items)
5+
{
6+
<StatusListItemPresenter Item="item" />
7+
}
8+
</MudTreeView>
9+
10+
@code
11+
{
12+
public List<StatusListItem> Items { get; set; } =
13+
[
14+
new StatusListItem("Item 1", StatusListStatus.Pending),
15+
new StatusListItem("Item 2", StatusListStatus.Success),
16+
new StatusListItem("Item 3", StatusListStatus.Warning, externalLink: "/staticForms/formDetails?formDraftId=92b6e86e-1920-48fd-4b04-08ddabf9e157"),
17+
new StatusListItem("Item 4",
18+
StatusListStatus.Error,
19+
"One of the items is invalid",
20+
externalLink: "/staticForms/formDetails?formDraftId=92b6e86e-1920-48fd-4b04-08ddabf9e157",
21+
children:
22+
[
23+
new StatusListItem("Child Item 1", StatusListStatus.Success),
24+
new StatusListItem("Child Item 2", StatusListStatus.Success),
25+
new StatusListItem("Child Item 3", StatusListStatus.Error, "Items is invalid")
26+
])
27+
];
28+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
@using DotNetElements.AppFramework.MudBlazorExtensions.Util
2+
3+
@if (Item.Children is not null or [])
4+
{
5+
<MudTreeViewItem T="StatusListItem" Icon="@Item.GetIcon()" IconColor="@Item.GetColor()" Class="@(Indent ? "ml-4" : "")">
6+
<BodyContent Context="childContext">
7+
<MudStack Row="true" AlignItems="AlignItems.Center">
8+
<MudStack Spacing="0" Class="ml-1">
9+
<MudText>@Item.Label</MudText>
10+
@if (Item.Message is not null)
11+
{
12+
<MudText Typo="Typo.caption" Color="@Item.GetColor()">@Item.Message</MudText>
13+
}
14+
</MudStack>
15+
<MudSpacer />
16+
@if (Item.ShouldShowExternalLink())
17+
{
18+
<MudIconButton Icon="@Icons.Material.Outlined.OpenInNew" Color="Color.Info" Size="Size.Small" Href="@Item.ExternalLink" Target="_blank" />
19+
}
20+
</MudStack>
21+
</BodyContent>
22+
<ChildContent>
23+
@foreach (StatusListItem item in Item.Children ?? [])
24+
{
25+
<StatusListItemPresenter Item="item" Indent="true" />
26+
}
27+
</ChildContent>
28+
</MudTreeViewItem>
29+
}
30+
else
31+
{
32+
<MudTreeViewItem T="StatusListItem" Icon="@Item.GetIcon()" IconColor="@Item.GetColor()" Class="@(Indent ? "ml-4" : "")">
33+
<BodyContent Context="childContext">
34+
<MudStack Row="true" AlignItems="AlignItems.Center">
35+
<MudStack Spacing="0" Class="ml-1">
36+
<MudText>@Item.Label</MudText>
37+
@if (Item.Message is not null)
38+
{
39+
<MudText Typo="Typo.caption" Color="@Item.GetColor()">@Item.Message</MudText>
40+
}
41+
</MudStack>
42+
<MudSpacer />
43+
@if (Item.ShouldShowExternalLink())
44+
{
45+
<MudIconButton Icon="@Icons.Material.Outlined.OpenInNew" Color="Color.Info" Size="Size.Small" Href="@Item.ExternalLink" Target="_blank" />
46+
}
47+
</MudStack>
48+
</BodyContent>
49+
</MudTreeViewItem>
50+
}
51+
52+
@code
53+
{
54+
[Parameter, EditorRequired]
55+
public StatusListItem Item { get; set; } = default!;
56+
57+
[Parameter]
58+
public bool Indent { get; set; }
59+
}

0 commit comments

Comments
 (0)