Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dev-v5] [Dialog Service] Add the FluentDialog and services #3112

Merged
merged 58 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
f35282a
Add FluentDialogBody
dvoituron Dec 14, 2024
0a052be
Add JS Sample method
dvoituron Dec 14, 2024
e184f98
Update styles
dvoituron Dec 14, 2024
4e16f19
Update Styles
dvoituron Dec 16, 2024
28172a1
Remove unused sub Id
dvoituron Dec 16, 2024
5449f5e
Add draft of Dialog classes
dvoituron Dec 16, 2024
94eb0dd
Add samples and update Provider
dvoituron Dec 16, 2024
1130a11
Fix missing properties
dvoituron Dec 16, 2024
97cab25
Add Id
dvoituron Dec 16, 2024
b3a9aea
Add show and hide methods
dvoituron Dec 17, 2024
a8f156b
Add Dialog events
dvoituron Dec 17, 2024
7740683
Refactoring
dvoituron Dec 17, 2024
32ee054
Fix event
dvoituron Dec 17, 2024
c69b904
Refactoring
dvoituron Dec 17, 2024
1c68deb
Refactoring
dvoituron Dec 17, 2024
350e29f
refactoring
dvoituron Dec 17, 2024
c0bde70
Refacroring
dvoituron Dec 17, 2024
113d21d
Refactoring
dvoituron Dec 17, 2024
9ff60e3
Add DialogAlignment
dvoituron Dec 19, 2024
e88e730
Add fluent-drawer
dvoituron Dec 19, 2024
261e102
Refactoring
dvoituron Dec 20, 2024
38f5fd9
Refactoring
dvoituron Dec 20, 2024
fa30ec7
Add documentation
dvoituron Dec 20, 2024
429d74c
Remove the Drawer
dvoituron Dec 20, 2024
ce28c27
Add Height and Width
dvoituron Dec 20, 2024
69d27af
Refactoring
dvoituron Dec 20, 2024
025d1e3
Update the event orders
dvoituron Dec 20, 2024
9911d44
Updating examples
dvoituron Dec 20, 2024
b8ab0aa
Update the doc
dvoituron Dec 20, 2024
dd596bc
Add Header and Footer
dvoituron Dec 23, 2024
66dffb1
Add FluentDialogInstance
dvoituron Dec 23, 2024
1e88522
Fix default values
dvoituron Dec 23, 2024
be779e7
Add documentation
dvoituron Dec 23, 2024
847d27e
Fix doc
dvoituron Dec 23, 2024
e9ff699
Fix Samples
dvoituron Dec 23, 2024
5b79df7
Add MessageBox
dvoituron Dec 24, 2024
c68f1c4
Refactoring
dvoituron Dec 24, 2024
2f9cfb3
aDD lOCALIZATION
dvoituron Dec 24, 2024
fbf5116
Update ShowDialogAsync to return DialogResult
dvoituron Dec 24, 2024
5c77cb4
Add Shortcuts
dvoituron Dec 24, 2024
b4931ce
Add first Unit Tests
dvoituron Dec 27, 2024
6e49173
Add ShortCut tests
dvoituron Dec 27, 2024
3b170b0
Add a ClassData attribute
dvoituron Dec 28, 2024
dbf123f
Update Shortcut Unit Tests
dvoituron Dec 28, 2024
a061ffb
Add Unit Tests
dvoituron Dec 28, 2024
4af756e
Add Unit Tests
dvoituron Dec 28, 2024
51b86f0
Add Unit Tests
dvoituron Dec 28, 2024
8b3f881
Add Unit Tests
dvoituron Dec 28, 2024
ed44f38
Update Localized items
dvoituron Dec 29, 2024
24b3915
Add Unit Tests
dvoituron Dec 29, 2024
bae3ce4
Add Unit Tests
dvoituron Dec 29, 2024
5ed5130
Add Unit Tests
dvoituron Dec 29, 2024
075e98f
Add Unit Tests
dvoituron Dec 29, 2024
5e9ef3a
Order the dialog in the Provider
dvoituron Dec 30, 2024
7060cb8
Merge branch 'dev-v5' into users/dvoituron/dialog
dvoituron Dec 30, 2024
5e76fbb
Inverse Primary and Secondary buttons
dvoituron Dec 31, 2024
440e7a9
Also copy *.cs files to sources
vnbaaij Jan 7, 2025
d531102
Update PR comments
dvoituron Jan 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@ dotnet_diagnostic.IDE2005.severity = warning
# MA0001: StringComparison is missing
dotnet_diagnostic.MA0001.severity = warning

# MA0004: Use ConfigureAwait when awaiting a task
dotnet_diagnostic.MA0004.severity = none

# MA0015: Do not call overridable members in constructor
dotnet_diagnostic.MA0056.severity = none

Expand Down
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<PackageVersion Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19" />
<PackageVersion Include="Microsoft.VisualStudioEng.MicroBuild.Core" Version="1.0.0" />
<PackageVersion Include="Microsoft.TypeScript.MSBuild" Version="5.6.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.ResxSourceGenerator" Version="3.11.0-beta1.24508.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.ResxSourceGenerator" Version="3.11.0-beta1.24527.2" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="$(RuntimeVersion9)" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<FluentDialogBody>

<TitleTemplate>
@Dialog.Options.Header.Title
</TitleTemplate>

<ChildContent>
<FluentTextInput Label="Name:" @bind-Value="@Name" Disabled="true" />
<FluentTextInput Label="Age:" @bind-Value="@Person.Age" />
<FluentLabel>Description</FluentLabel>
@Person.VeryLongDescription
</ChildContent>

<ActionTemplate>
<FluentButton OnClick="btnCancel_Click">Cancel</FluentButton>
<FluentButton OnClick="btnOK_Click" Appearance="ButtonAppearance.Primary">OK</FluentButton>
</ActionTemplate>

</FluentDialogBody>

@code {
// If you want to use this razor component in standalone mode,
// you can use a nullable IDialogInstance property.
// If the value is not null, the component is running using the DialogService.
// `public IDialogInstance? FluentDialog { get; set; }`
[CascadingParameter]
public required IDialogInstance Dialog { get; set; }

[Inject]
public required IDialogService DialogService { get; set; }

// A simple type is not updatable
[Parameter]
public string? Name { get; set; }

// A class is updatable
[Parameter]
public PersonDetails Person { get; set; } = new();

// A nullable type is optional
[Parameter]
public int? NotAssignedParam { get; set; }

private async Task btnOK_Click()
{
int.TryParse(Person.Age, out var age);
if (age <= 0)
{
await DialogService.ShowErrorAsync("Age must be a positive number.");
}
else
{
await Dialog.CloseAsync(DialogResult.Ok("Yes"));
}
}

private async Task btnCancel_Click()
{
await Dialog.CloseAsync(DialogResult.Cancel("No"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// ------------------------------------------------------------------------
// MIT License - Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------------------

using Microsoft.AspNetCore.Components;

namespace FluentUI.Demo.Client.Documentation.Components.Dialog.Examples.Dialog;

public class PersonDetails
{
private static readonly string _longDescription = string.Join("", SampleData.Text.LoremIpsum.Select(i => $"<p>{i}</p>"));

public string Age { get; set; } = "";

public MarkupString VeryLongDescription => (MarkupString)_longDescription;

public override string ToString() => $"Age: {Age}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@inherits FluentDialogInstance

<FluentDialogBody>
<FluentTextInput Label="Name:" @bind-Value="@Name" Disabled="true" />
<FluentTextInput Label="Age:" @bind-Value="@Person.Age" />
</FluentDialogBody>

@code {
// A simple type is not updatable
[Parameter]
public string? Name { get; set; }

// A class is updatable
[Parameter]
public PersonDetails Person { get; set; } = new();

// Initialize the dialog
protected override void OnInitializeDialog(DialogOptionsHeader header, DialogOptionsFooter footer)
{
header.Title = $"Dialog Title - {Name}";
footer.SecondaryAction.Visible = true;
}

// Handle the action click
protected override async Task OnActionClickedAsync(bool primary)
{
if (primary)
{
await DialogInstance.CloseAsync("Yes");
}
else
{
await DialogInstance.CancelAsync();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<FluentDialogBody>

<TitleTemplate>
My title
</TitleTemplate>

<ChildContent>
@SampleData.Text.GenerateLoremIpsum(paragraphCount: 1)
</ChildContent>

<ActionTemplate>
<FluentButton Disabled="true" Appearance="ButtonAppearance.Primary">One</FluentButton>
<FluentButton Disabled="true">Two</FluentButton>
</ActionTemplate>

</FluentDialogBody>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@inject IDialogService DialogService

<FluentButton OnClick="@ShowSuccessAsync" Appearance="ButtonAppearance.Primary">Success</FluentButton>
<FluentButton OnClick="@ShowWarningAsync" Appearance="ButtonAppearance.Primary">Warning</FluentButton>
<FluentButton OnClick="@ShowErrorAsync" Appearance="ButtonAppearance.Primary">Error</FluentButton>
<FluentButton OnClick="@ShowInformationAsync" Appearance="ButtonAppearance.Primary">Information</FluentButton>
<FluentButton OnClick="@ShowConfirmationAsync" Appearance="ButtonAppearance.Primary">Confirmation</FluentButton>
<FluentButton OnClick="@ShowMessageBoxLongAsync" Appearance="ButtonAppearance.Primary">Long message</FluentButton>
<FluentButton OnClick="@ShowMessageBoxAsync" Appearance="ButtonAppearance.Primary">Custom message</FluentButton>

<p>
Last result: @GetResult()
</p>

@code
{
private bool? Canceled;

private async Task ShowSuccessAsync()
{
var result = await DialogService.ShowSuccessAsync("The action was a success");
Canceled = result.Cancelled;
}

private async Task ShowWarningAsync()
{
var result = await DialogService.ShowWarningAsync("This is your final warning");
Canceled = result.Cancelled;
}

private async Task ShowErrorAsync()
{
var result = await DialogService.ShowErrorAsync("This is an error");
Canceled = result.Cancelled;
}

private async Task ShowInformationAsync()
{
var result = await DialogService.ShowInfoAsync("This is a message");
Canceled = result.Cancelled;
}

private async Task ShowConfirmationAsync()
{
var result = await DialogService.ShowConfirmationAsync("Are you <strong>sure</strong> you want to delete this item? <br />This will also remove any linked items");
Canceled = result.Cancelled;
}

private async Task ShowMessageBoxLongAsync()
{
var result = await DialogService.ShowInfoAsync(SampleData.Text.GenerateLoremIpsum(1));
Canceled = result.Cancelled;
}

private async Task ShowMessageBoxAsync()
{
var result = await DialogService.ShowMessageBoxAsync(new MessageBoxOptions()
{
Title = "My title",
Message = "My <strong>customized</strong> message",
Icon = new Icons.Regular.Size24.Games(),
IconColor = Color.Success,
PrimaryButton = "Plus",
SecondaryButton = "Minus",
});

Canceled = result.Cancelled;
}

private string GetResult()
{
return Canceled switch
{
true => "❌ Canceled",
false => "✅ OK",
_ => ""
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
@inject IDialogService DialogService

<FluentButton OnClick="@(e => OpenDialogAsync(DialogAlignment.Default))" Appearance="ButtonAppearance.Primary">Open Dialog</FluentButton>

<hr />
<div>
John: @John
</div>

@code
{
private Dialog.PersonDetails John = new() { Age = "20" };

private async Task OpenDialogAsync(DialogAlignment alignment)
{
var result = await DialogService.ShowDialogAsync<Dialog.CustomizedDialog>(options =>
{
options.Header.Title = "Dialog Title";
options.Alignment = alignment;
options.Style = alignment == DialogAlignment.Default ? "max-height: 400px;" : null;

options.Parameters.Add(nameof(Dialog.CustomizedDialog.Name), "John"); // Simple type
options.Parameters.Add(nameof(Dialog.CustomizedDialog.Person), John); // Updatable object

options.OnStateChange = (e) =>
{
Console.WriteLine($"State changed: {e.State}");
};
});

if (result.Cancelled)
{
Console.WriteLine($"Dialog Canceled: {result.Value}");
}
else
{
Console.WriteLine($"Dialog Saved: {result.Value}");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
@inject IDialogService DialogService

<FluentButton OnClick="@(e => OpenDialogAsync())" Appearance="ButtonAppearance.Primary">Open Dialog</FluentButton>

<hr />
<div>
John: @John
</div>

@code
{
private Dialog.PersonDetails John = new() { Age = "20" };

private async Task OpenDialogAsync()
{
var result = await DialogService.ShowDialogAsync<Dialog.SimpleDialog>(options =>
{
options.Parameters.Add(nameof(Dialog.SimpleDialog.Name), "John"); // Simple type
options.Parameters.Add(nameof(Dialog.SimpleDialog.Person), John); // Updatable object
options.OnStateChange = (e) =>
{
Console.WriteLine($"State changed: {e.State}");
};
});

if (result.Cancelled)
{
Console.WriteLine($"Dialog Canceled: {result.Value}");
}
else
{
Console.WriteLine($"Dialog Saved: {result.Value}");
}
}
}
Loading
Loading