Skip to content
This repository has been archived by the owner on Apr 8, 2023. It is now read-only.

Add confirmation dialog for important things #118

Merged
merged 2 commits into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion src/Client/Features/Admin/StartSeason.razor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DynamoLeagueBlazor.Shared.Features.Admin;
using DynamoLeagueBlazor.Client.Shared.Components;
using DynamoLeagueBlazor.Shared.Features.Admin;
using DynamoLeagueBlazor.Shared.Infastructure.Identity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
Expand All @@ -12,6 +13,8 @@ public sealed partial class StartSeason : IDisposable
{
[Inject] private HttpClient HttpClient { get; set; } = null!;
[Inject] private ISnackbar SnackBar { get; set; } = null!;
[Inject] private IConfirmDialogService ConfirmDialogService { get; set; } = null!;


private bool _isDisabled = true;
private const string _title = "Start Season";
Expand All @@ -24,6 +27,8 @@ protected override async Task OnInitializedAsync()

private async Task StartSeasonAsync()
{
if (await ConfirmDialogService.IsCancelledAsync()) return;

await HttpClient.PostAsync(StartSeasonRouteFactory.Uri, null);

SnackBar.Add("A new season has begun!", Severity.Success);
Expand Down
2 changes: 1 addition & 1 deletion src/Client/Features/OfferMatching/List.razor
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Actions">
<MudIconButton Icon="@Icons.Filled.Handshake" Color="Color.Primary" Variant="Variant.Outlined" Size="Size.Small" Class="ma-2" OnClick="(e) => MatchPlayerAsync(context.Id,context.Offer)"/>
<MudIconButton Icon="@Icons.Filled.Handshake" Color="Color.Primary" Variant="Variant.Outlined" Size="Size.Small" Class="ma-2" OnClick="(e) => MatchPlayerAsync(context.Id)"/>
</MudTd>
<MudTd DataLabel="Player Name">
<NameWithImage Name="@context.Name" ImageUrl="@context.HeadShotUrl" />
Expand Down
9 changes: 7 additions & 2 deletions src/Client/Features/OfferMatching/List.razor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DynamoLeagueBlazor.Shared.Features.OfferMatching;
using DynamoLeagueBlazor.Client.Shared.Components;
using DynamoLeagueBlazor.Shared.Features.OfferMatching;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using MudBlazor;
Expand All @@ -10,6 +11,8 @@ public sealed partial class List : IDisposable
{
[Inject] private HttpClient HttpClient { get; set; } = null!;
[Inject] private ISnackbar SnackBar { get; set; } = null!;
[Inject] private IConfirmDialogService ConfirmDialogService { get; set; } = null!;

private const string _title = "Offer Matching";
private bool _loading;
private readonly CancellationTokenSource _cts = new();
Expand All @@ -36,8 +39,10 @@ private async Task LoadDataAsync()
_result = await HttpClient.GetFromJsonAsync<OfferMatchingListResult>(OfferMatchingListRouteFactory.Uri, _cts.Token) ?? new();
}

private async Task MatchPlayerAsync(int playerId, int amount)
private async Task MatchPlayerAsync(int playerId)
{
if (await ConfirmDialogService.IsCancelledAsync()) return;

var response = await HttpClient.PostAsJsonAsync(OfferMatchingListRouteFactory.Uri, new MatchPlayerRequest() { PlayerId = playerId });

if (response.IsSuccessStatusCode)
Expand Down
16 changes: 8 additions & 8 deletions src/Client/Features/Players/AddFine.razor
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
@if(_fineDetail is null)
{
<MudDialog>
<DialogContent>
<MudSkeleton SkeletonType=SkeletonType.Text Width=300px Height=60px/>
<MudSkeleton SkeletonType=SkeletonType.Rectangle Width=100% Height=100px />
</DialogContent>
<DialogActions>
<MudSkeleton SkeletonType=SkeletonType.Text Width=100% Height=80px/>
</DialogActions>
</MudDialog>
<DialogContent>
<MudSkeleton SkeletonType=SkeletonType.Text Width=300px Height=60px/>
<MudSkeleton SkeletonType=SkeletonType.Rectangle Width=100% Height=100px />
</DialogContent>
<DialogActions>
<MudSkeleton SkeletonType=SkeletonType.Text Width=100% Height=80px/>
</DialogActions>
</MudDialog>
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/Client/Features/Players/AddFine.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ private async Task GetPlayerFineDetailsAsync()
{
try
{
_fineDetail = await HttpClient.GetFromJsonAsync<FineDetailResult>(FineDetailRouteFactory.Create(PlayerId), _cts.Token) ?? new();
_fineDetail = await HttpClient.GetFromJsonAsync<FineDetailResult>(FineDetailRouteFactory.Create(PlayerId), _cts.Token);
}
catch (AccessTokenNotAvailableException exception)
{
Expand Down
16 changes: 10 additions & 6 deletions src/Client/Features/Teams/Detail.razor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using DynamoLeagueBlazor.Shared.Features.Teams;
using DynamoLeagueBlazor.Client.Shared.Components;
using DynamoLeagueBlazor.Shared.Features.Teams;
using DynamoLeagueBlazor.Shared.Infastructure.Identity;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
Expand All @@ -13,6 +14,7 @@ public sealed partial class Detail : IDisposable
{
[Inject] private HttpClient HttpClient { get; set; } = null!;
[Inject] private IDialogService DialogService { get; set; } = null!;
[Inject] private IConfirmDialogService ConfirmDialogService { get; set; } = null!;
[Inject] private ISnackbar Snackbar { get; set; } = null!;
[CascadingParameter] public Task<AuthenticationState> AuthenticationStateTask { get; set; } = null!;
[Parameter, EditorRequired] public int TeamId { get; set; }
Expand Down Expand Up @@ -55,7 +57,7 @@ private void ShowRosteredPlayers()
{
_playersToDisplay = _result!.RosteredPlayers;
_playerTableHeader = "Rostered Players";
_onPlayerTableActionClick = DropPlayerAsync;
_onPlayerTableActionClick = UnrosterPlayerAsync;
_tableActionIcon = Icons.Outlined.PersonRemove;
}

Expand All @@ -74,15 +76,17 @@ private void ShowUnsignedPlayers()
_tableActionIcon = Icons.Filled.AssignmentLate;
}

private async Task DropPlayerAsync(int playerId)
private async Task UnrosterPlayerAsync(int playerId)
{
if (await ConfirmDialogService.IsCancelledAsync()) return;

try
{
var response = await HttpClient.PostAsJsonAsync(DropPlayerRouteFactory.Uri, new DropPlayerRequest { PlayerId = playerId }, _cts.Token);

if (response.IsSuccessStatusCode)
{
Snackbar.Add("Successfully dropped player.", Severity.Success);
Snackbar.Add("Successfully unrostered player.", Severity.Success);

await LoadDataAsync();
ShowRosteredPlayers();
Expand All @@ -100,13 +104,13 @@ private async Task DropPlayerAsync(int playerId)

private async Task OpenSignPlayerDialogAsync(int playerId)
{
var maxWidth = new DialogOptions() { MaxWidth = MaxWidth.Small, FullWidth = true };
var dialogOptions = new DialogOptions() { MaxWidth = MaxWidth.Small, FullWidth = true };
var parameters = new DialogParameters
{
{ nameof(SignPlayer.PlayerId), playerId }
};

var dialog = DialogService.Show<SignPlayer>("Sign Player", parameters, maxWidth);
var dialog = DialogService.Show<SignPlayer>("Sign Player", parameters, dialogOptions);
var result = await dialog.Result;

if (!result.Cancelled)
Expand Down
3 changes: 3 additions & 0 deletions src/Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using DynamoLeagueBlazor.Client.Areas.Identity;
using DynamoLeagueBlazor.Client.Features.Admin;
using DynamoLeagueBlazor.Client.Features.FreeAgents;
using DynamoLeagueBlazor.Client.Shared.Components;
using DynamoLeagueBlazor.Shared.Features.Admin.Shared;
using DynamoLeagueBlazor.Shared.Features.FreeAgents;
using DynamoLeagueBlazor.Shared.Infastructure.Identity;
Expand Down Expand Up @@ -37,10 +38,12 @@
builder.Services.AddMudServices(config =>
{
config.SnackbarConfiguration.PositionClass = Defaults.Classes.Position.BottomCenter;
config.SnackbarConfiguration.PreventDuplicates = false;
});

builder.Services.AddTransient<IBidValidator, BidValidator>();
builder.Services.AddTransient<IPlayerHeadshotService, PlayerHeadshotService>();
builder.Services.AddScoped<IConfirmDialogService, ConfirmDialogService>();

var host = builder.Build();

Expand Down
15 changes: 15 additions & 0 deletions src/Client/Shared/Components/ConfirmDialog.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<MudDialog>
<TitleContent>
<MudText Color=Color.Warning Typo=Typo.h6>
Confirm Your Action
</MudText>
</TitleContent>
<DialogContent>
Are you sure you want to perform this action? It is irreversable!
</DialogContent>
<DialogActions>
<MudButton Color=Color.Warning [email protected] OnClick=Confirm FullWidth=true>
Confirm
</MudButton>
</DialogActions>
</MudDialog>
34 changes: 34 additions & 0 deletions src/Client/Shared/Components/ConfirmDialog.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Components;
using MudBlazor;

namespace DynamoLeagueBlazor.Client.Shared.Components;

public partial class ConfirmDialog
{
[CascadingParameter] MudDialogInstance MudDialog { get; set; } = null!;

private void Confirm() => MudDialog.Close(DialogResult.Ok(true));
}

public interface IConfirmDialogService
{
Task<bool> IsCancelledAsync();
}

public class ConfirmDialogService : IConfirmDialogService
{
private readonly IDialogService _dialogService;

public ConfirmDialogService(IDialogService dialogService)
{
_dialogService = dialogService;
}

public async Task<bool> IsCancelledAsync()
{
var dialog = _dialogService.Show<ConfirmDialog>();
var result = await dialog.Result;

return result.Cancelled;
}
}
6 changes: 3 additions & 3 deletions src/Server/Models/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public Player()

_machine.Configure(PlayerState.Rostered)
.OnEntryFrom(_rosteredTrigger, (yearContractExpires, contractValue) => SetToRostered(yearContractExpires, contractValue))
.Permit(PlayerStateTrigger.DroppedByTeam, PlayerState.Unrostered)
.Permit(PlayerStateTrigger.UnrosteredByTeam, PlayerState.Unrostered)
.Permit(PlayerStateTrigger.NewSeasonStarted, PlayerState.FreeAgent);

_machine.Configure(PlayerState.FreeAgent)
Expand Down Expand Up @@ -53,7 +53,7 @@ public Player(string name, string position, string headShotUrl) : this()
public ICollection<Bid> Bids { get; private set; } = new HashSet<Bid>();
public ICollection<Fine> Fines { get; private set; } = new HashSet<Fine>();

private enum PlayerStateTrigger { NewSeasonStarted, BiddingEnded, OfferMatchedByTeam, MatchExpired, SignedByTeam, DroppedByTeam }
private enum PlayerStateTrigger { NewSeasonStarted, BiddingEnded, OfferMatchedByTeam, MatchExpired, SignedByTeam, UnrosteredByTeam }
public enum PlayerState { FreeAgent, OfferMatching, Unsigned, Rostered, Unrostered }

public Player SetToUnrostered()
Expand Down Expand Up @@ -104,7 +104,7 @@ public Bid AddBid(int amount, int teamIdOfBidder)
return bid;
}

public void DropFromCurrentTeam() => _machine.Fire(PlayerStateTrigger.DroppedByTeam);
public void DropFromCurrentTeam() => _machine.Fire(PlayerStateTrigger.UnrosteredByTeam);

private void GrantExtensionToFreeAgency()
{
Expand Down
2 changes: 2 additions & 0 deletions src/Tests/UITestBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Bunit.TestDoubles;
using DynamoLeagueBlazor.Client.Shared.Components;
using DynamoLeagueBlazor.Shared.Infastructure.Identity;
using Microsoft.Extensions.DependencyInjection;
using MockHttp.Json;
Expand All @@ -25,6 +26,7 @@ public UITestBase()

testContext.Services.AddMudServices();
testContext.Services.AddSingleton(mockSnackBar.Object);
testContext.Services.AddSingleton(Mock.Of<IConfirmDialogService>());
testContext.JSInterop.SetupVoid();

var mockHttpHandler = new MockHttpHandler();
Expand Down