Skip to content

Commit

Permalink
feat(frontend): tasks view
Browse files Browse the repository at this point in the history
  • Loading branch information
Thundernerd committed Jan 2, 2024
1 parent 5b4839a commit 9f761bc
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/Mangarr.Frontend/Api/BackendApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public Task<Result<MangaRequestResponse>> RequestManga(
bool newChaptersOnly
) =>
_httpClient.Post<MangaRequestResponse>("manga/request",
new MangaRequestRequest()
new MangaRequestRequest
{
SearchId = searchId,
ProviderId = providerIdentifier,
Expand All @@ -55,7 +55,16 @@ bool newChaptersOnly

public Task<Result> DeleteManga(string id, bool deleteChaptersFromDisk) =>
_httpClient.Post($"manga/{id}/delete",
new MangaDeleteRequest() { Id = id, DeleteChaptersFromDisk = deleteChaptersFromDisk });
new MangaDeleteRequest { Id = id, DeleteChaptersFromDisk = deleteChaptersFromDisk });

public Task<Result<string>> RefreshManga(string id) => _httpClient.Get($"manga/{id}/refresh");

public Task<Result<JobsQueueResponse>> GetJobQueue() =>
_httpClient.Get<JobsQueueResponse>("jobs/queue");

public Task<Result<JobsScheduleResponse>> GetJobSchedule() =>
_httpClient.Get<JobsScheduleResponse>("jobs/schedule");

public Task<Result<string>> TriggerJob(string group, string name) =>
_httpClient.Get($"jobs/{group}/{name}/trigger");
}
1 change: 1 addition & 0 deletions src/Mangarr.Frontend/Mangarr.Frontend.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

<ItemGroup>
<PackageReference Include="FluentResults" Version="3.15.2"/>
<PackageReference Include="Humanizer.Core" Version="2.14.1"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
</ItemGroup>

Expand Down
33 changes: 33 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/Queue.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@using Mangarr.Shared.Models
<div class="p-4">
<p class="lead">Queue</p>

@if (_isRefreshing)
{
<Spinner/>
}
else if (_items.Count == 0)
{
<p class="lead">The queue is empty at the moment</p>
}
else
{
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Description</th>
<th>Last run</th>
<th>Next run</th>
</tr>
</thead>
<tbody>
@foreach (JobQueueItemModel item in _items)
{
<QueueItem Item="@item"/>
}
</tbody>
</table>
</div>
}
</div>
39 changes: 39 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/Queue.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using FluentResults;
using Mangarr.Frontend.Api;
using Mangarr.Shared.Models;
using Mangarr.Shared.Responses;
using Microsoft.AspNetCore.Components;

namespace Mangarr.Frontend.Pages.Settings.Tasks;

public partial class Queue
{
private readonly List<JobQueueItemModel> _items = new();

private bool _isRefreshing = false;

[Inject] public BackendApi BackendApi { get; set; }

protected override void OnInitialized() => RefreshAsync();

private async void RefreshAsync()
{
_isRefreshing = true;
await InvokeAsync(StateHasChanged);

Result<JobsQueueResponse> result = await BackendApi.GetJobQueue();

if (result.IsFailed)
{
// TODO: Log error
}
else
{
_items.Clear();
_items.AddRange(result.Value.Data);
}

_isRefreshing = false;
await InvokeAsync(StateHasChanged);
}
}
34 changes: 34 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/QueueItem.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@using Humanizer
@using Mangarr.Shared.Models

@code {
[Parameter] public JobQueueItemModel Item { get; set; }
}

<tr>
<td>
@Item.Description
</td>
<td>
@if (Item.PreviousFireTime.HasValue)
{
TimeSpan timeSinceLastRun = DateTimeOffset.UtcNow - Item.PreviousFireTime.Value;
<span>@timeSinceLastRun.Humanize() ago</span>
}
else
{
<span>-</span>
}
</td>
<td>
@if (Item.NextFireTime.HasValue)
{
TimeSpan timeUntilNextRun = Item.NextFireTime.Value - DateTimeOffset.UtcNow;
<span>in @timeUntilNextRun.Humanize()</span>
}
else
{
<span>-</span>
}
</td>
</tr>
34 changes: 34 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/Schedule.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@using Mangarr.Shared.Models
<div class="p-4">
<p class="lead">Schedule</p>

@if (_isRefreshing)
{
<Spinner/>
}
else if (_items.Count == 0)
{
<p class="lead">The queue is empty at the moment</p>
}
else
{
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Description</th>
<th>Last run</th>
<th>Next run</th>
<th>Request run</th>
</tr>
</thead>
<tbody>
@foreach (JobScheduleItemModel item in _items)
{
<ScheduleItem Item="@item"/>
}
</tbody>
</table>
</div>
}
</div>
37 changes: 37 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/Schedule.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using FluentResults;
using Mangarr.Frontend.Api;
using Mangarr.Shared.Models;
using Mangarr.Shared.Responses;
using Microsoft.AspNetCore.Components;

namespace Mangarr.Frontend.Pages.Settings.Tasks;

public partial class Schedule
{
private readonly List<JobScheduleItemModel> _items = new();
private bool _isRefreshing;
[Inject] public BackendApi BackendApi { get; set; }

protected override void OnInitialized() => RefreshAsync();

private async void RefreshAsync()
{
_isRefreshing = true;
await InvokeAsync(StateHasChanged);

Result<JobsScheduleResponse> result = await BackendApi.GetJobSchedule();

if (result.IsFailed)
{
// TODO: Log error
}
else
{
_items.Clear();
_items.AddRange(result.Value.Data);
}

_isRefreshing = false;
await InvokeAsync(StateHasChanged);
}
}
39 changes: 39 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/ScheduleItem.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@using Humanizer
<tr>
<td>
@Item.Description
</td>
<td>
@if (Item.PreviousFireTime.HasValue)
{
TimeSpan timeSinceLastRun = DateTimeOffset.UtcNow - Item.PreviousFireTime.Value;
<span>@timeSinceLastRun.Humanize() ago</span>
}
else
{
<span>-</span>
}
</td>
<td>
@if (Item.NextFireTime.HasValue)
{
TimeSpan timeUntilNextRun = Item.NextFireTime.Value - DateTimeOffset.UtcNow;
<span>in @timeUntilNextRun.Humanize()</span>
}
else
{
<span>-</span>
}
</td>
<td>
@if (_isRequesting)
{
<input type="button" class="btn btn-primary disabled" value="Request" @onclick="RequestClicked"/>
}
else
{
<input type="button" class="btn btn-primary" value="Request" @onclick="RequestClicked"/>
}

</td>
</tr>
24 changes: 24 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/ScheduleItem.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Mangarr.Frontend.Api;
using Mangarr.Shared.Models;
using Microsoft.AspNetCore.Components;

namespace Mangarr.Frontend.Pages.Settings.Tasks;

public partial class ScheduleItem
{
private bool _isRequesting;
[Parameter] public JobScheduleItemModel Item { get; set; }

[Inject] public BackendApi BackendApi { get; set; }

private async void RequestClicked()
{
_isRequesting = true;
await InvokeAsync(StateHasChanged);

await BackendApi.TriggerJob(Item.Group, Item.Name);

_isRequesting = true;
await InvokeAsync(StateHasChanged);
}
}
6 changes: 6 additions & 0 deletions src/Mangarr.Frontend/Pages/Settings/Tasks/Tasks.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@page "/settings/tasks"

<div id="wrapper" class="overflow-auto d-flex flex-column">
<Schedule/>
<Queue/>
</div>
7 changes: 7 additions & 0 deletions src/Mangarr.Frontend/Shared/NavigationLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
<path d="M16 3a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"></path>
</svg>General
</a>
<a class="nav-link" href="/settings/tasks">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-list-task me-2">
<path fill-rule="evenodd" d="M2 2.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5V3a.5.5 0 0 0-.5-.5zM3 3H2v1h1z"/>
<path d="M5 3.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5M5.5 7a.5.5 0 0 0 0 1h9a.5.5 0 0 0 0-1zm0 4a.5.5 0 0 0 0 1h9a.5.5 0 0 0 0-1z"/>
<path fill-rule="evenodd" d="M1.5 7a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H2a.5.5 0 0 1-.5-.5zM2 7h1v1H2zm0 3.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm1 .5H2v1h1z"/>
</svg>Tasks
</a>
<a class="nav-link" href="/settings/sources">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-database me-2">
<path d="M4.318 2.687C5.234 2.271 6.536 2 8 2s2.766.27 3.682.687C12.644 3.125 13 3.627 13 4c0 .374-.356.875-1.318 1.313C10.766 5.729 9.464 6 8 6s-2.766-.27-3.682-.687C3.356 4.875 3 4.373 3 4c0-.374.356-.875 1.318-1.313ZM13 5.698V7c0 .374-.356.875-1.318 1.313C10.766 8.729 9.464 9 8 9s-2.766-.27-3.682-.687C3.356 7.875 3 7.373 3 7V5.698c.271.202.58.378.904.525C4.978 6.711 6.427 7 8 7s3.022-.289 4.096-.777A4.92 4.92 0 0 0 13 5.698ZM14 4c0-1.007-.875-1.755-1.904-2.223C11.022 1.289 9.573 1 8 1s-3.022.289-4.096.777C2.875 2.245 2 2.993 2 4v9c0 1.007.875 1.755 1.904 2.223C4.978 15.71 6.427 16 8 16s3.022-.289 4.096-.777C13.125 14.755 14 14.007 14 13V4Zm-1 4.698V10c0 .374-.356.875-1.318 1.313C10.766 11.729 9.464 12 8 12s-2.766-.27-3.682-.687C3.356 10.875 3 10.373 3 10V8.698c.271.202.58.378.904.525C4.978 9.71 6.427 10 8 10s3.022-.289 4.096-.777A4.92 4.92 0 0 0 13 8.698Zm0 3V13c0 .374-.356.875-1.318 1.313C10.766 14.729 9.464 15 8 15s-2.766-.27-3.682-.687C3.356 13.875 3 13.373 3 13v-1.302c.271.202.58.378.904.525C4.978 12.71 6.427 13 8 13s3.022-.289 4.096-.777c.324-.147.633-.323.904-.525Z"></path>
Expand Down

0 comments on commit 9f761bc

Please sign in to comment.