21-12-2022
This commit is contained in:
parent
6bca1f53f4
commit
e3f271ac33
@ -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()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using DigitalData.Modules.Logging;
|
||||
using ECM.JobRunner.Common.JobRunnerReference;
|
||||
using System;
|
||||
|
||||
namespace ECM.JobRunner.Web.Data
|
||||
{
|
||||
@ -8,13 +9,59 @@ 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)
|
||||
{
|
||||
logger = Logging.LogConfig.GetLogger();
|
||||
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)
|
||||
{
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
@ -19,7 +19,7 @@
|
||||
</svg> Last 5 Minutes
|
||||
</h5>
|
||||
<h6 class="card-subtitle mb-2">
|
||||
<span>@last5MinutesItems.total jobs executed</span>,
|
||||
<span>@last5MinutesItems.total jobs executed</span>,
|
||||
<span class="text-success">@last5MinutesItems.success Successful</span>,
|
||||
<span class="text-danger">@last5MinutesItems.failed Failed</span>,
|
||||
<span class="text-muted">@last5MinutesItems.waiting Waiting</span>
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user