Skip to content

Commit

Permalink
Merge pull request #28 from SSchulze1989/develop
Browse files Browse the repository at this point in the history
v0.4.1
  • Loading branch information
SSchulze1989 authored Jan 6, 2023
2 parents d55c911 + 3c571bd commit 7be98b4
Show file tree
Hide file tree
Showing 106 changed files with 4,026 additions and 2,419 deletions.
31 changes: 30 additions & 1 deletion src/iRLeagueManager.Web/App.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
@using iRLeagueManager.Web.ViewModels
@inject EventListViewModel EventList
@inject LeagueApiService ApiService

@inject SharedStateService SharedState
@inject IJSRuntime JsRuntime

<CascadingValue Value="EventList">
<CascadingValue Value="SharedState">
<CascadingBlazoredModal>
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(App).Assembly">
Expand All @@ -28,3 +30,30 @@
</CascadingAuthenticationState>
</CascadingBlazoredModal>
</CascadingValue>
</CascadingValue>

@code {
public DateTimeOffset LocalTimeOffset { get; set; }

private TimeSpan? userTime { get; set; }

protected override async Task OnInitializedAsync()
{
if (userTime == null)
{
try
{
int timeDiffer = await JsRuntime.InvokeAsync<int>("GetTimezoneValue");
userTime = TimeSpan.FromMinutes(-timeDiffer);
}
catch (InvalidOperationException)
{
// this throws when jsinterop is not yet available
}
}

// Converting to local time using UTC and local time minute difference.
LocalTimeOffset = DateTimeOffset.UtcNow.ToOffset(userTime ?? TimeSpan.Zero);
SharedState.LocalTimeOffset = LocalTimeOffset.Offset;
}
}
13 changes: 6 additions & 7 deletions src/iRLeagueManager.Web/Components/ButtonTypes.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace iRLeagueManager.Web.Components
namespace iRLeagueManager.Web.Components;

public enum ButtonTypes
{
public enum ButtonTypes
{
Ok,
OkCancel,
YesNo,
}
Ok,
OkCancel,
YesNo,
}
2 changes: 1 addition & 1 deletion src/iRLeagueManager.Web/Components/ConfirmModal.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="container justify-content-center">
<div class="container justify-content-center preserve-format">
@Text
</div>
<div class="pt-2 pb-2">
Expand Down
15 changes: 7 additions & 8 deletions src/iRLeagueManager.Web/Components/ConfirmResult.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
namespace iRLeagueManager.Web.Components
namespace iRLeagueManager.Web.Components;

public enum ConfirmResult
{
public enum ConfirmResult
{
Ok,
Yes,
No,
Cancel
}
Ok,
Yes,
No,
Cancel
}
47 changes: 39 additions & 8 deletions src/iRLeagueManager.Web/Components/DisplaySchedule.razor
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<div>@Bind(Schedule, x => x.Name)</div>
}
</LoadingHeader>
<div class="card-body overflow-scroll">
<div class="card-body overflow-auto">
<table class="table table-striped table-hover">
<thead>
<tr>
Expand Down Expand Up @@ -78,17 +78,23 @@
}
}
<td>
<button class="btn btn-outline-danger btn-sm" @onclick=@(() => RemoveEventClick(@event)) @onclick:stopPropagation @onclick:preventDefault>
<span class="oi oi-trash"/>
</button>
@if (ReadOnly == false)
{
<button class="btn btn-outline-danger btn-sm" @onclick=@(() => RemoveEventClick(@event)) @onclick:stopPropagation @onclick:preventDefault>
<span class="oi oi-trash"/>
</button>
}
</td>
</tr>
}
</tbody>
</table>
<div class="mb-1">
<button class="btn btn-outline-secondary" @onclick=AddEventClick>Add Event</button>
</div>
@if (ReadOnly == false)
{
<div class="mb-1">
<button class="btn btn-outline-secondary" @onclick=AddEventClick>Add Event</button>
</div>
}
</div>
</div>
</div>
Expand Down Expand Up @@ -203,7 +209,7 @@
return;
}
var parameters = new ModalParameters()
.Add(nameof(EditEventModal.EventModel), new EventModel() { Date = DateTime.Now.Date })
.Add(nameof(EditEventModal.EventModel), GetNewEvent())
.Add(nameof(EditEventModal.OnSubmit),
new Func<EventViewModel, CancellationToken,
Task<StatusResult>>(async (@event, cancellationToken) => await Schedule.AddEvent(@event)));
Expand All @@ -214,6 +220,31 @@
var result = await ModalService.Show<EditEventModal>("Add Event", parameters, options).Result;
}

private EventModel GetNewEvent()
{
var newEvent = new EventModel() { Date = DateTime.Now.Date };
var lastEvent = Schedule.Events.LastOrDefault()?.CopyModel();
if (lastEvent == null)
{
return newEvent;
}

newEvent.Date = lastEvent.Date;
newEvent.Duration = lastEvent.Duration;
newEvent.EventType = lastEvent.EventType;
newEvent.ResultConfigs = lastEvent.ResultConfigs;
newEvent.Sessions = lastEvent.Sessions.Select(x => new SessionModel()
{
Duration = x.Duration,
Laps = x.Laps,
Name = x.Name,
SessionNr = x.SessionNr,
SessionType = x.SessionType,
}).ToList();

return newEvent;
}

private async Task RemoveEventClick(EventViewModel @event)
{
var parameters = new ModalParameters()
Expand Down
2 changes: 1 addition & 1 deletion src/iRLeagueManager.Web/Components/EditEventModal.razor
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<InputText class="form-control" placeholder="Event Name" aria-label="EventName" id="name" @bind-Value="Event.Name"/>
</InputGroup>
<InputGroup Label="Date">
<InputDate class="form-control" aria-label="Date" id="date" @bind-Value="Event.Date" />
<InputDate class="form-control" aria-label="Date" id="date" @bind-Value="Event.Date"/>
</InputGroup>
<InputGroup Label="Start-Time">
<input class="form-control" type="time" arial-label="StartTime" @bind="Event.StartTime"/>
Expand Down
86 changes: 86 additions & 0 deletions src/iRLeagueManager.Web/Components/EditModalBase.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Blazored.Modal;
using Blazored.Modal.Services;
using iRLeagueManager.Web.Data;
using iRLeagueManager.Web.Exceptions;
using iRLeagueManager.Web.Shared;
using iRLeagueManager.Web.ViewModels;
using Microsoft.AspNetCore.Components;
using MvvmBlazor.Components;

namespace iRLeagueManager.Web.Components;

public class EditModalBase<TViewModel, TModel> : MvvmComponentBase where TViewModel : LeagueViewModelBase<TViewModel, TModel>
{
[Inject]
protected TViewModel Vm { get; set; } = default!;

[CascadingParameter]
public BlazoredModalInstance ModalInstance { get; set; } = default!;
[CascadingParameter]
public IModalService ModalService { get; set; } = default!;

private TModel model = default!;
[Parameter, EditorRequired]
public TModel Model
{
get => model;
set
{
if (EqualityComparer<TModel>.Default.Equals(model, value) == false)
{
model = value;
Vm.SetModel(model);
}
}
}

[Parameter]
public Func<TViewModel, CancellationToken, Task<StatusResult>>? OnSubmit { get; set; }
[Parameter]
public Func<TViewModel, CancellationToken, Task>? OnCancel { get; set; }

private CancellationTokenSource cts = new();
protected StatusResultValidator? ResultValidator { get; set; }

protected override void OnParametersSet()
{
_ = ModalInstance ?? throw BlazorParameterNullException.New(this, ModalInstance);
_ = ModalService ?? throw BlazorParameterNullException.New(this, ModalService);
_ = Model ?? throw BlazorParameterNullException.New(this, Model);
}

protected virtual async Task Submit()
{
var success = true;
if (OnSubmit is not null)
{
var status = await OnSubmit(Vm, cts.Token);
success &= status.IsSuccess;
ResultValidator?.ValidateResult(status);
}
if (success)
{
var result = ModalResult.Ok(Vm.GetModel());
await ModalInstance.CloseAsync(result);
}
}

protected virtual async Task Cancel()
{
if (OnCancel is not null)
{
await OnCancel(Vm, cts.Token);
}
await ModalInstance.CancelAsync();
}

protected override void Dispose(bool disposing)
{
if (disposing == false)
{
cts.Cancel();
cts.Dispose();
}
base.Dispose(disposing);
}
}
12 changes: 5 additions & 7 deletions src/iRLeagueManager.Web/Components/EditSession.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

@if (Session != null)
{
<div class="input-group">
<span class="input-group-text w-25">Duration</span>
<InputGroup Label="Duration">
<input class="form-control" type="time" arial-label="StartTime" @bind="Session!.Duration"/>
</div>
<div class="input-group">
<span class="input-group-text w-25">Laps</span>
<input class="form-control" type="number" placholder="10" aria-label="TrackId" @bind="Session!.LapsString"/>
</div>
</InputGroup>
<InputGroup Label="Laps">
<InputNumber class="form-control" placholder="10" aria-label="TrackId" @bind-Value=Session!.Laps/>
</InputGroup>
}

@code {
Expand Down
2 changes: 1 addition & 1 deletion src/iRLeagueManager.Web/Components/InputMemberSelect.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@using System.Collections.Specialized
@using System.Diagnostics.CodeAnalysis
@using iRLeagueApiCore.Common.Models.Members
@using iRLeagueApiCore.Common.Models
@*@inherits InputBase<IEnumerable<MemberInfoModel>>*@

<select @attributes=AdditionalAttributes value=SelectedMemberIds @onchange=OnSelectionChange multiple>
Expand Down
41 changes: 41 additions & 0 deletions src/iRLeagueManager.Web/Components/InputTimeSpan.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Rendering;
using System.Diagnostics.CodeAnalysis;

namespace iRLeagueManager.Web.Components;

public class InputTimeSpan : InputBase<TimeSpan>
{
/// <summary>
/// Gets or sets the associated <see cref="ElementReference"/>.
/// <para>
/// May be <see langword="null"/> if accessed before the component is rendered.
/// </para>
/// </summary>
[DisallowNull] public ElementReference? Element { get; protected set; }

protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TimeSpan result, [NotNullWhen(false)] out string? validationErrorMessage)
{
if (TimeSpan.TryParse(value, out result) == false)
{
validationErrorMessage = "Input is not a valid time span format";
result = TimeSpan.Zero;
return false;
}
validationErrorMessage = null;
return true;
}

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "input");
builder.AddMultipleAttributes(1, AdditionalAttributes);
builder.AddAttribute(2, "type", "time");
builder.AddAttribute(3, "class", CssClass);
builder.AddAttribute(4, "value", BindConverter.FormatValue(CurrentValueAsString));
builder.AddAttribute(5, "onchange", EventCallback.Factory.CreateBinder<string?>(this, __value => CurrentValueAsString = __value, CurrentValueAsString));
builder.AddElementReferenceCapture(6, __inputReference => Element = __inputReference);
builder.CloseElement();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
var displayStartPos = resultRows.Any(x => x.StartPosition != 0);
var displayQualyLap = resultRows.Any(x => x.QualifyingTime > TimeSpan.FromSeconds(1));
}
<div class="card-body overflow-scroll p-1">
<div class="card-body overflow-auto p-1">
<table class="table table-sm table-striped table-hover" style="font-size: 0.9rem; line-height: 1rem">
<thead>
<tr>
Expand Down Expand Up @@ -68,7 +68,7 @@
{
<td class="@(IsFastestLap(resultRows, row, x => x.QualifyingTime) ? "fw-bold" : "")">@row.QualifyingTime.LapTimeString()</td>
}
<td class="@(IsFastestLap(resultRows, row, x => x.FastestLapTime) ? "fw-bold" : "")">@row.FastestLapTime.LapTimeString() (@row.FastLapNr)</td>
<td class="@(IsFastestLap(resultRows, row, x => x.FastestLapTime) ? "fw-bold" : "")">@row.FastestLapTime.LapTimeString() @(row.FastLapNr != 0 ? $"({row.FastLapNr})" : "")</td>
<td class="@(IsFastestLap(resultRows, row, x => x.AvgLapTime) ? "fw-bold" : "")">@row.AvgLapTime.LapTimeString()</td>
@if (isTeamResult == false)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@using iRLeagueApiCore.Common.Enums
@using iRLeagueApiCore.Common.Models.Members
@using iRLeagueApiCore.Common.Models
@using iRLeagueApiCore.Common.Models.Reviews
@using iRLeagueManager.Web.ViewModels
@inherits MvvmComponentBase
Expand Down Expand Up @@ -62,7 +62,7 @@
public ReviewCommentModel Model { get; set; } = default!;

[Parameter]
public Func<ReviewCommentViewModel, CancellationToken, Task<bool>>? OnSubmit { get; set; }
public Func<ReviewCommentViewModel, CancellationToken, Task<StatusResult>>? OnSubmit { get; set; }

private long? NewValue
{
Expand Down Expand Up @@ -137,7 +137,7 @@
bool success = true;
if (OnSubmit != null)
{
success |= await OnSubmit.Invoke(Comment, cts.Token);
success &= (await OnSubmit.Invoke(Comment, cts.Token)).IsSuccess;
}
if (success && ModalInstance != null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@using Blazored.Typeahead
@using iRLeagueApiCore.Common.Enums
@using iRLeagueApiCore.Common.Models.Members
@using iRLeagueApiCore.Common.Models
@using iRLeagueApiCore.Common.Models.Reviews
@using iRLeagueManager.Web.ViewModels
@inherits MvvmComponentBase
Expand Down Expand Up @@ -33,6 +33,9 @@
<InputGroup Label="Incident">
<InputText class="form-control" placeholder="Incident Kind" aria-label="Incident Kind" id="incident_kind" @bind-Value="Review.IncidentKind" />
</InputGroup>
<InputGroup Label="Description">
<InputTextArea class="form-control" placeholder="Description" aria-label="Description" id="description" @bind-Value="Review.FullDescription" style="height: 140px;"/>
</InputGroup>
</div>
<FormValidationMessage For=@(() => Review.IncidentKind) />
<div class="p-1">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@using iRLeagueApiCore.Common.Enums
@using iRLeagueApiCore.Common.Models.Members
@using iRLeagueApiCore.Common.Models
@using iRLeagueApiCore.Common.Models.Reviews
@using iRLeagueManager.Web.ViewModels
@inherits MvvmComponentBase
Expand Down
Loading

0 comments on commit 7be98b4

Please sign in to comment.