21-12-2022

This commit is contained in:
Jonathan Jenne 2022-12-21 16:09:49 +01:00
parent 6bca1f53f4
commit e3f271ac33
13 changed files with 139 additions and 80 deletions

View File

@ -6,31 +6,5 @@ namespace ECM.JobRunner.Web.Data
{
public DateTime heartbeat = DateTime.MinValue;
public List<StatusItem> jobStatus = new();
public class JobHistory
{
public List<StatusItem> items;
public int total;
public int success;
public int failed;
public int waiting;
}
public JobHistory GetHistoryForLastMinutes(int pMinutes)
{
var items = jobStatus.
Where(s => (DateTime.Now - s.CompleteTime) < new TimeSpan(0, pMinutes, 0)).
Where(s => s.Executing == false).
ToList();
return new JobHistory()
{
items = items,
total = items.Count,
success = items.Where(i => i.Successful && i.Waiting == false).Count(),
failed = items.Where(i => i.Successful == false).Count(),
waiting = items.Where(i => i.Successful && i.Waiting == true).Count()
};
}
}
}

View File

@ -1,5 +1,6 @@
using DigitalData.Modules.Logging;
using ECM.JobRunner.Common.JobRunnerReference;
using System;
namespace ECM.JobRunner.Web.Data
{
@ -8,7 +9,7 @@ namespace ECM.JobRunner.Web.Data
private readonly Logger logger;
private readonly IEDMIServiceChannel channel;
public string Title = "No Title";
public event EventHandler<string>? PageTitleChanged;
public HelperService(LoggingService Logging, WcfService Wcf)
{
@ -16,6 +17,52 @@ namespace ECM.JobRunner.Web.Data
channel = Wcf.Channel;
}
public void SetPageTitle(string title)
{
PageTitleChanged?.Invoke(this, title);
}
public List<StatusItem> GetItemsForTimespan(List<StatusItem> items, TimeSpan timespan)
{
return items.
Where(s => (DateTime.Now - s.CompleteTime) < timespan).
ToList();
}
public List<StatusItem> GetItemsForLastMinutes(List<StatusItem> items, int minutes) =>
GetItemsForTimespan(items, new TimeSpan(0, minutes, 0));
public List<StatusItem> GetItemsForLastHours(List<StatusItem> items, int hours) =>
GetItemsForTimespan(items, new TimeSpan(hours, 0, 0));
public List<StatusItem> GetItemsForLastSeconds(List<StatusItem> items, int seconds) =>
GetItemsForTimespan(items, new TimeSpan(0, 0, seconds));
public class JobHistory
{
public List<StatusItem> items;
public int total;
public int success;
public int failed;
public int waiting;
}
public JobHistory GetJobHistory(List<StatusItem> items, int sinceMinutes)
{
var filteredItems = GetItemsForLastMinutes(items, sinceMinutes);
var executingItems = filteredItems.Where(s => s.Executing == false);
return new JobHistory()
{
items = executingItems.ToList(),
total = executingItems.Count(),
success = executingItems.Where(i => i.Successful && i.Waiting == false).Count(),
failed = executingItems.Where(i => i.Successful == false).Count(),
waiting = executingItems.Where(i => i.Successful && i.Waiting == true).Count()
};
}
public DateTime GetNextExecutionTime(string pCronExpression)
{
Quartz.CronExpression expression = new(pCronExpression);

View File

@ -5,8 +5,6 @@
<PageTitle>History</PageTitle>
<h3>Job History</h3>
<div class="container-fluid">
<div class="row">
<div class="col-2">
@ -15,6 +13,17 @@
<form>
<legend>Filter</legend>
<select class="form-select" aria-label="Default select example" value="@dateFilter" @oninput="DateFilterChanged">
<option selected>Please select a value..</option>
<option value="1">1 hour</option>
<option value="3">3 hours</option>
<option value="6">6 hours</option>
<option value="12">12 hours</option>
<option value="24">24 hours</option>
<option value="72">3 days</option>
<option value="168">1 week</option>
</select>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="showWaiting" checked="@showWaiting" @oninput="CheckboxChanged">
<label class="form-check-label" for="exampleCheck1">Waiting</label>
@ -37,7 +46,7 @@
else if (filteredEntries.Count == 0)
{
<ul class="list-group">
<li class="list-group-item">No Job History yet.</li>
<li class="list-group-item">No Job History.</li>
</ul>
}
else
@ -116,12 +125,16 @@
private List<StatusItem>? statusEntries;
private List<StatusItem>? filteredEntries;
private int dateFilter = 1;
private bool showWaiting = true;
// TODO: implement more filters
private bool showSuccessful = true;
private bool showFailed = true;
private bool showWaiting = true;
protected async override void OnInitialized()
{
Helper.SetPageTitle("History");
DashboardResponse data = await Api.GetData();
UpdateData(data);
@ -137,6 +150,14 @@
InvokeAsync(StateHasChanged);
}
private void DateFilterChanged(ChangeEventArgs e)
{
var dateFilterString = e.Value.ToString();
dateFilter = int.Parse(dateFilterString);
UpdateEntries(statusEntries);
InvokeAsync(StateHasChanged);
}
protected void Api_DataUpdated(object? sender, DashboardResponse e)
{
UpdateData(e);
@ -146,26 +167,29 @@
{
today = response.heartbeat;
statusEntries = response.jobStatus;
UpdateEntries(response.jobStatus);
filteredEntries = UpdateEntries(response.jobStatus);
InvokeAsync(StateHasChanged);
}
protected void UpdateEntries(List<StatusItem>? entries)
protected List<StatusItem>? UpdateEntries(List<StatusItem>? entries)
{
if (entries == null)
{
return;
return null;
}
var filtered = entries.
Where(s => s.Executing == false);
Where(s => s.Executing == false).
ToList();
if (!showWaiting)
{
filtered = filtered.
Where(e => e.Waiting == false);
Where(e => e.Waiting == false).ToList();
}
filteredEntries = filtered.ToList();
filtered = Helper.GetItemsForLastHours(filtered, dateFilter);
return filtered;
}
}

View File

@ -7,8 +7,6 @@
<PageTitle>Job bearbeiten</PageTitle>
<h3>Job bearbeiten</h3>
<ProfileForm ProfileId="ProfileId" OnValidSubmit="OnFormSubmit" />
@code {
@ -21,6 +19,7 @@
private async void OnFormSubmit(EditContext ctx)
{
ImportProfile profile = (ImportProfile)ctx.Model;
Helper.SetPageTitle(profile.Job.Name);
bool result = await Profile.UpdateProfile(profile);
if (result == true)

View File

@ -6,8 +6,6 @@
<PageTitle>Import Profiles</PageTitle>
<h3>Import Profiles</h3>
@if (filteredProfiles == null)
{
<ul class="list-group">
@ -95,6 +93,7 @@ else
protected async override void OnInitialized()
{
Helper.SetPageTitle("Import Profiles");
profiles = await Import.GetProfiles();
filteredProfiles = profiles;

View File

@ -19,25 +19,18 @@
}
else
{
<h3>
@if (profile.Active)
{
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-play-circle text-success me-1" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M6.271 5.055a.5.5 0 0 1 .52.038l3.5 2.5a.5.5 0 0 1 0 .814l-3.5 2.5A.5.5 0 0 1 6 10.5v-5a.5.5 0 0 1 .271-.445z" />
</svg>
}
else
{
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="bi bi-stop-circle text-danger me-1" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M5 6.5A1.5 1.5 0 0 1 6.5 5h3A1.5 1.5 0 0 1 11 6.5v3A1.5 1.5 0 0 1 9.5 11h-3A1.5 1.5 0 0 1 5 9.5v-3z" />
</svg>
}
@profile.Job.Name
</h3>
<ul class="list-group mb-3">
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="me-auto">
<div class="fw-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z" />
</svg> Aktiv
</div>
@profile.Active
</div>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<div class="me-auto">
<div class="fw-bold">
@ -111,6 +104,7 @@ else
if (profile != null)
{
Helper.SetPageTitle(profile.Job.Name);
nextExecution = Helper.GetNextExecutionTime(profile.Job.CronSchedule);
StateHasChanged();
}

View File

@ -149,7 +149,7 @@ else
protected string GetBackUrl()
{
return $"/profiles/import/{ProfileId}/steps/{StepId}";
return StepId < 0 ? $"/profiles/import/{ProfileId}/steps" : $"/profiles/import/{ProfileId}/steps/{StepId}";
}
protected override async Task OnInitializedAsync()

View File

@ -1,5 +1,4 @@
@using ECM.JobRunner.Web.Data;
@inject HelperService Helper;
@page "/"
<PageTitle>Index</PageTitle>
@ -9,6 +8,6 @@
@code {
protected override void OnInitialized()
{
Helper.Title = "Start";
Helper.SetPageTitle("Index");
}
}

View File

@ -2,8 +2,6 @@
<PageTitle>Profile</PageTitle>
<h3>Profile</h3>
<div class="list-group">
<a href="profiles/import" class="list-group-item list-group-item-action d-flex justify-content-between align-items-start">
<div class="me-auto">
@ -26,3 +24,11 @@
</div>
</a>
</div>
@code {
protected override void OnInitialized()
{
base.OnInitialized();
Helper.SetPageTitle("Profile");
}
}

View File

@ -112,12 +112,13 @@
private List<StatusItem>? executingEntries;
private List<StatusItem>? completedEntries;
private DashboardResponse.JobHistory? last5MinutesItems;
private DashboardResponse.JobHistory? lastHourItems;
private DashboardResponse.JobHistory? last12HoursItems;
private HelperService.JobHistory last5MinutesItems;
private HelperService.JobHistory lastHourItems;
private HelperService.JobHistory last12HoursItems;
protected async override void OnInitialized()
{
Helper.SetPageTitle("Status");
DashboardResponse data = await Dashboard.GetData();
UpdateData(data);
@ -143,12 +144,14 @@
Where(s => s.StartTime.AddMinutes(10) > DateTime.Now).
ToList();
last5MinutesItems = response.GetHistoryForLastMinutes(5);
lastHourItems = response.GetHistoryForLastMinutes(60);
last12HoursItems = response.GetHistoryForLastMinutes(60 * 12);
last5MinutesItems = Helper.GetJobHistory(response.jobStatus, 5);
lastHourItems = Helper.GetJobHistory(response.jobStatus, 60);
last12HoursItems = Helper.GetJobHistory(response.jobStatus, 60 * 12);
InvokeAsync(StateHasChanged);
}
}

View File

@ -10,9 +10,11 @@ builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddTransient<LoggingService>();
builder.Services.AddTransient<DatabaseService>();
builder.Services.AddSingleton<WcfService>();
builder.Services.AddSingleton<HelperService>();
builder.Services.AddTransient<DashboardService>();
builder.Services.AddTransient<HelperService>();
builder.Services.AddTransient<ImportProfileService>();
var app = builder.Build();

View File

@ -5,15 +5,16 @@
<PageTitle>ECM.JobRunner.Web</PageTitle>
<div class=@(connected ? "page connected" : "page disconnected")>
<div class=@(Connected ? "page connected" : "page disconnected")>
<div class="sidebar">
<NavMenu connected="connected" />
<NavMenu connected="Connected" />
</div>
<main>
<div class="top-row px-4 d-flex align-content-between justify-content-between">
<strong>@Helper.Title</strong>
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
<div class="top-row navbar navbar-light">
<div class="container-fluid ps-0">
<span class="navbar-brand">@Title</span>
</div>
</div>
<article class="content px-4">
@ -23,17 +24,25 @@
</div>
@code {
private bool connected = true;
private bool Connected = true;
private string Title = "";
protected override Task OnInitializedAsync()
{
Helper.PageTitleChanged += Helper_PageTitleChanged;
Wcf.ConnectedChanged += Wcf_ConnectedChanged;
return Task.FromResult(true);
}
public void Helper_PageTitleChanged(object? sender, string title)
{
Title = title;
InvokeAsync(StateHasChanged);
}
public void Wcf_ConnectedChanged(object? sender, bool status)
{
connected = status;
Connected = status;
InvokeAsync(StateHasChanged);
}
}

View File

@ -7,4 +7,7 @@
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using ECM.JobRunner.Web
@using ECM.JobRunner.Web.Data
@using ECM.JobRunner.Web.Shared
@inject HelperService Helper