Compare commits
2 Commits
261d2db417
...
7b1216eec1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b1216eec1 | ||
|
|
9787422f65 |
@ -71,6 +71,7 @@ public class EventManager
|
|||||||
DateTime? to = null,
|
DateTime? to = null,
|
||||||
int? limit = null,
|
int? limit = null,
|
||||||
int? offset = null,
|
int? offset = null,
|
||||||
|
Event.ValenceType? valenceType = null,
|
||||||
Dictionary<string, object>? filters = null)
|
Dictionary<string, object>? filters = null)
|
||||||
{
|
{
|
||||||
if(History is null)
|
if(History is null)
|
||||||
@ -92,6 +93,9 @@ public class EventManager
|
|||||||
if (to is not null)
|
if (to is not null)
|
||||||
ret = ret.Where(x => x.When <= to);
|
ret = ret.Where(x => x.When <= to);
|
||||||
|
|
||||||
|
if (valenceType is not null)
|
||||||
|
ret = ret.Where(x => x.Valence == valenceType);
|
||||||
|
|
||||||
if (offset is not null)
|
if (offset is not null)
|
||||||
ret = ret.Skip(offset.Value);
|
ret = ret.Skip(offset.Value);
|
||||||
|
|
||||||
@ -101,12 +105,14 @@ public class EventManager
|
|||||||
foreach (var i in ret)
|
foreach (var i in ret)
|
||||||
yield return i;
|
yield return i;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: Implement filters
|
//TODO: Implement filters
|
||||||
|
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await foreach (var i in History.GetEvents(subject, from, to, limit, offset, filters))
|
await foreach (var i in History.GetEvents(subject, from, to, limit, offset, valenceType, filters))
|
||||||
yield return i;
|
yield return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +31,14 @@ public abstract class Persistence
|
|||||||
|
|
||||||
public abstract Task RegisterEvent(Event e);
|
public abstract Task RegisterEvent(Event e);
|
||||||
public abstract Task<Event?> GetEvent(string id);
|
public abstract Task<Event?> GetEvent(string id);
|
||||||
public abstract IAsyncEnumerable<Event> GetEvents(string? subject = null, DateTime? from = null, DateTime? to = null, int? limit = null, int? offset = null, Dictionary<string, object>? filters = null);
|
public abstract IAsyncEnumerable<Event> GetEvents(
|
||||||
|
string? subject = null,
|
||||||
|
DateTime? from = null,
|
||||||
|
DateTime? to = null,
|
||||||
|
int? limit = null,
|
||||||
|
int? offset = null,
|
||||||
|
Event.ValenceType? valenceType = null,
|
||||||
|
Dictionary<string, object>? filters = null);
|
||||||
|
|
||||||
protected virtual void ExceptionCatched(Exception e)
|
protected virtual void ExceptionCatched(Exception e)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,12 +2,22 @@
|
|||||||
|
|
||||||
public class Event
|
public class Event
|
||||||
{
|
{
|
||||||
|
public enum ValenceType
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
Error,
|
||||||
|
Emergency
|
||||||
|
}
|
||||||
|
|
||||||
public const string TYPE_STATE_CHANGED = "state_changed";
|
public const string TYPE_STATE_CHANGED = "state_changed";
|
||||||
|
public const string TYPE_LOG = "log";
|
||||||
|
|
||||||
public string UniqueId { get; set; }
|
public string UniqueId { get; set; }
|
||||||
public string ThrowerId { get; set; }
|
public string ThrowerId { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public DateTime When { get; set; } = DateTime.Now;
|
public DateTime When { get; set; } = DateTime.Now;
|
||||||
|
public string Description { get; set; } = "";
|
||||||
|
public ValenceType Valence { get; set; } = default;
|
||||||
|
|
||||||
public Dictionary<string, object> Properties { get; protected set; } = new Dictionary<string, object>();
|
public Dictionary<string, object> Properties { get; protected set; } = new Dictionary<string, object>();
|
||||||
public object? this[string key]
|
public object? this[string key]
|
||||||
@ -32,11 +42,12 @@ public class Event
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Event(string uniqueId, string throwerId, string type, DateTime? when = null)
|
public Event(string uniqueId, string throwerId, string type, string description = "", DateTime? when = null)
|
||||||
{
|
{
|
||||||
UniqueId = uniqueId;
|
UniqueId = uniqueId;
|
||||||
ThrowerId = throwerId;
|
ThrowerId = throwerId;
|
||||||
Type = type;
|
Type = type;
|
||||||
|
Description = description;
|
||||||
if(when != null)
|
if(when != null)
|
||||||
When = when.Value;
|
When = when.Value;
|
||||||
}
|
}
|
||||||
@ -44,8 +55,28 @@ public class Event
|
|||||||
public static Event FromStateChange(string key, object? value, DateTime when)
|
public static Event FromStateChange(string key, object? value, DateTime when)
|
||||||
{
|
{
|
||||||
string id = Guid.NewGuid().ToString();
|
string id = Guid.NewGuid().ToString();
|
||||||
var ret = new Event(id, key, TYPE_STATE_CHANGED, when);
|
var ret = new Event(id, key, TYPE_STATE_CHANGED, when:when);
|
||||||
ret[nameof(Triplet.value)] = value;
|
ret[nameof(Triplet.value)] = value;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Event FromLog(
|
||||||
|
string thrower,
|
||||||
|
string content,
|
||||||
|
DateTime? when = null,
|
||||||
|
int severity = 6,
|
||||||
|
Exception? exception = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (when == null)
|
||||||
|
when = DateTime.Now;
|
||||||
|
|
||||||
|
string id = Guid.NewGuid().ToString();
|
||||||
|
var ret = new Event(id, thrower, TYPE_LOG, description: content, when: when);
|
||||||
|
ret["severity"] = severity;
|
||||||
|
if (exception is not null && exception.StackTrace is not null)
|
||||||
|
ret["trace"] = exception.StackTrace;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,12 @@ public class Instance
|
|||||||
State.Push(t.key, t.predicate, t.value, t.LastFlush);
|
State.Push(t.key, t.predicate, t.value, t.LastFlush);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Add(IEnumerable<Event> events)
|
||||||
|
{
|
||||||
|
foreach (var i in events)
|
||||||
|
Event.Push(i);
|
||||||
|
}
|
||||||
|
|
||||||
public T? RetrieveElement<T>(string id) where T : Element
|
public T? RetrieveElement<T>(string id) where T : Element
|
||||||
{
|
{
|
||||||
var triplets = State.Get(id).ToList();
|
var triplets = State.Get(id).ToList();
|
||||||
|
|||||||
12
Salmon.Core/Salmon - Backup.Core.csproj
Normal file
12
Salmon.Core/Salmon - Backup.Core.csproj
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<Title>Salmon.Core</Title>
|
||||||
|
<Description>Common parts of Salmon</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@ -4,6 +4,11 @@
|
|||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<Title>Salmon.Core</Title>
|
||||||
|
<PackageId>Salmon</PackageId>
|
||||||
|
<Version>0.1.0</Version>
|
||||||
|
<Description>Common parts of Salmon</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Salmon.Core;
|
namespace Salmon.Core;
|
||||||
|
|
||||||
@ -17,17 +14,18 @@ public class Transmitter
|
|||||||
foreach (Element element in elements)
|
foreach (Element element in elements)
|
||||||
triplets.AddRange(Translator.Encode(element));
|
triplets.AddRange(Translator.Encode(element));
|
||||||
|
|
||||||
Console.WriteLine(JsonSerializer.Serialize(triplets));
|
|
||||||
var result = await Client.PostAsJsonAsync(uri, triplets, cancellationToken: tk);
|
var result = await Client.PostAsJsonAsync(uri, triplets, cancellationToken: tk);
|
||||||
|
|
||||||
if (!result.IsSuccessStatusCode)
|
if (!result.IsSuccessStatusCode)
|
||||||
throw new Exception($"SendAsync call return code {result.StatusCode} when call {uri}.");
|
throw new Exception($"SendAsync(elements) call return code {result.StatusCode} when call {uri}.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendAsync(Uri uri, IEnumerable<Event> events, CancellationToken tk = default)
|
public async Task SendAsync(Uri uri, IEnumerable<Event> events, CancellationToken tk = default)
|
||||||
{
|
{
|
||||||
await Client.PostAsJsonAsync(uri, events, cancellationToken: tk);
|
var result = await Client.PostAsJsonAsync(uri, events, cancellationToken: tk);
|
||||||
|
|
||||||
|
if (!result.IsSuccessStatusCode)
|
||||||
|
throw new Exception($"SendAsync(events) call return code {result.StatusCode} when call {uri}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendAsync(IEnumerable<Element> elements, CancellationToken tk = default)
|
public async Task SendAsync(IEnumerable<Element> elements, CancellationToken tk = default)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"Url":"http://127.0.0.1:5009/api/",
|
"Url":"http://salmon.voie93quarts.fr/api/",
|
||||||
"Period":15000,
|
"Period":15000,
|
||||||
"Watch":[
|
"Watch":[
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.6.33723.286
|
VisualStudioVersion = 17.6.33723.286
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Model", "Salmon.Model\Salmon.Model.csproj", "{DD4EDB99-A7A9-413F-967B-FE4D0ADD8D0A}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Core", "Salmon.Core\Salmon.Core.csproj", "{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Core", "Salmon.Core\Salmon.Core.csproj", "{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Test", "Salmon.Test\Salmon.Test.csproj", "{CA8F6995-ED22-43BC-BE20-EB9D8477225A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Test", "Salmon.Test\Salmon.Test.csproj", "{CA8F6995-ED22-43BC-BE20-EB9D8477225A}"
|
||||||
@ -13,16 +11,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Web", "Salmon.Web\Sa
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Service", "Salmon.Service\Salmon.Service.csproj", "{357108AA-4D7C-479D-93AA-9D7FC9455A48}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Service", "Salmon.Service\Salmon.Service.csproj", "{357108AA-4D7C-479D-93AA-9D7FC9455A48}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Salmon.Model", "Salmon.Model\Salmon.Model.csproj", "{5F083251-3DD9-4124-B467-B82665C32792}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{DD4EDB99-A7A9-413F-967B-FE4D0ADD8D0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{DD4EDB99-A7A9-413F-967B-FE4D0ADD8D0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{DD4EDB99-A7A9-413F-967B-FE4D0ADD8D0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{DD4EDB99-A7A9-413F-967B-FE4D0ADD8D0A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{97733A9E-5BBB-484F-B8C7-AF4A6EC41731}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -39,6 +35,10 @@ Global
|
|||||||
{357108AA-4D7C-479D-93AA-9D7FC9455A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{357108AA-4D7C-479D-93AA-9D7FC9455A48}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{357108AA-4D7C-479D-93AA-9D7FC9455A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{357108AA-4D7C-479D-93AA-9D7FC9455A48}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{357108AA-4D7C-479D-93AA-9D7FC9455A48}.Release|Any CPU.Build.0 = Release|Any CPU
|
{357108AA-4D7C-479D-93AA-9D7FC9455A48}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5F083251-3DD9-4124-B467-B82665C32792}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{5F083251-3DD9-4124-B467-B82665C32792}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5F083251-3DD9-4124-B467-B82665C32792}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5F083251-3DD9-4124-B467-B82665C32792}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
29
Salmon.Web/Components/CopyButton.razor
Normal file
29
Salmon.Web/Components/CopyButton.razor
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
||||||
|
<button type="button" class="btn" @onclick="CopyTextToClipboard">
|
||||||
|
@if(Clicked)
|
||||||
|
{
|
||||||
|
<i class="bi bi-clipboard-check"></i>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<i class="bi bi-clipboard"></i>
|
||||||
|
}
|
||||||
|
|
||||||
|
</button>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string Value { get; set; }
|
||||||
|
|
||||||
|
bool Clicked { get; set; } = false;
|
||||||
|
|
||||||
|
private async Task CopyTextToClipboard()
|
||||||
|
{
|
||||||
|
if (Value is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await JSRuntime.InvokeVoidAsync("clipboardCopy.copyText", Value.ToString());
|
||||||
|
Clicked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Salmon.Web/Components/ElementCard.razor
Normal file
40
Salmon.Web/Components/ElementCard.razor
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
@inject Salmon.Core.Instance Salmon;
|
||||||
|
|
||||||
|
@if(Target is not null)
|
||||||
|
{
|
||||||
|
<Card Class="col-6" Style="width:18rem;margin:10px;">
|
||||||
|
<CardHeader>
|
||||||
|
<NavLink href=@($"Element/{System.Web.HttpUtility.UrlEncode(Target.UniqueId)}")>
|
||||||
|
<span class="oi oi-zoom-in" aria-hidden="true"></span>
|
||||||
|
</NavLink>
|
||||||
|
@Target.LastType
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<CardTitle>@Target.ShortName</CardTitle>
|
||||||
|
@if (!String.IsNullOrEmpty(Target.LongName))
|
||||||
|
{
|
||||||
|
<CardSubTitle>
|
||||||
|
@Target.LongName
|
||||||
|
</CardSubTitle>
|
||||||
|
}
|
||||||
|
<CardText>@Target.Description</CardText>
|
||||||
|
</CardBody>
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
@foreach (var kv in Target.ImportantProperties())
|
||||||
|
{
|
||||||
|
<li class="list-group-item">@kv.Key: @kv.Value</li>
|
||||||
|
}
|
||||||
|
<li class="list-group-item"><small>id: @Target.UniqueId</small></li>
|
||||||
|
</ul>
|
||||||
|
@if (Salmon.GetLastElementUpdate(Target.UniqueId) is not null)
|
||||||
|
{
|
||||||
|
<CardFooter>
|
||||||
|
<small class="text-muted">Last updated <i>@TimespanHelper.GetReadableTimespan(DateTime.Now - Salmon.GetLastElementUpdate(Target.UniqueId).Value)</i></small>
|
||||||
|
</CardFooter>
|
||||||
|
}
|
||||||
|
</Card>
|
||||||
|
}
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public Element? Target { get; set; }
|
||||||
|
}
|
||||||
39
Salmon.Web/Components/ElementDeck.razor
Normal file
39
Salmon.Web/Components/ElementDeck.razor
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
@inject Salmon.Core.Instance Salmon;
|
||||||
|
|
||||||
|
<div Style="display:flex;flex-wrap:wrap; height:100%;">
|
||||||
|
@foreach (var e in Elements)
|
||||||
|
{
|
||||||
|
<ElementCard Target=e />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public string? FilterByParent { get; set; } = null;
|
||||||
|
|
||||||
|
List<Element> Elements { get; set; } = new();
|
||||||
|
private static System.Timers.Timer Time = new System.Timers.Timer(5000);
|
||||||
|
|
||||||
|
protected async override Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
await base.OnInitializedAsync();
|
||||||
|
|
||||||
|
Time.Elapsed += async (Object? source, System.Timers.ElapsedEventArgs e) =>
|
||||||
|
{
|
||||||
|
await InvokeAsync(() => Refresh());
|
||||||
|
};
|
||||||
|
Time.AutoReset = true;
|
||||||
|
Time.Enabled = true;
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
Elements = Salmon.GetAllElements().ToList();
|
||||||
|
if (FilterByParent is not null)
|
||||||
|
Elements = Elements.Where(x => x.ParentId == FilterByParent).ToList();
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Salmon.Web/Components/EventTable.razor
Normal file
26
Salmon.Web/Components/EventTable.razor
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
@if (Events is not null)
|
||||||
|
{
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Type</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@if (Events is not null)
|
||||||
|
@foreach (var e in Events)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>@e.When</td>
|
||||||
|
<td>@e.Type</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public List<Event>? Events { get; set; } = null;
|
||||||
|
}
|
||||||
34
Salmon.Web/Components/PrettyValueDisplay.razor
Normal file
34
Salmon.Web/Components/PrettyValueDisplay.razor
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
@using Salmon.Core.Cliff
|
||||||
|
|
||||||
|
|
||||||
|
@if(Value is null)
|
||||||
|
{
|
||||||
|
<span>(null)</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Predicate is not null && Predicate == "parent")
|
||||||
|
{
|
||||||
|
<a href=@($"Element/{System.Web.HttpUtility.UrlEncode(Value.ToString())}")>@Value.ToString()</a>
|
||||||
|
}
|
||||||
|
else if (Predicate is not null && Predicate == "Uri")
|
||||||
|
{
|
||||||
|
<a href=@Value.ToString()>@Value.ToString()</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span>@Value.ToString()</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
<CopyButton Value=@Value.ToString() />
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public object? Value { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Predicate { get; set; }
|
||||||
|
}
|
||||||
34
Salmon.Web/Components/TripletTable.razor
Normal file
34
Salmon.Web/Components/TripletTable.razor
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
@if(Triplets is not null)
|
||||||
|
{
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Dernier changement</th>
|
||||||
|
<th>Nom</th>
|
||||||
|
<th>Valeur</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@if (Triplets is not null)
|
||||||
|
@foreach (var t in Triplets)
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>@t.LastFlush</td>
|
||||||
|
<td>@t.predicate</td>
|
||||||
|
<td>
|
||||||
|
<PrettyValueDisplay Predicate=@t.predicate Value=@t.value />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public List<Triplet>? Triplets { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -38,5 +38,11 @@ namespace Salmon.Web.Controllers
|
|||||||
{
|
{
|
||||||
Instance.Set(triplets);
|
Instance.Set(triplets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("Push/Events")]
|
||||||
|
public void Post([FromBody] IEnumerable<Event> events)
|
||||||
|
{
|
||||||
|
Instance.Add(events);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -218,6 +218,8 @@ public class MongoDbInterface
|
|||||||
new KeyValuePair<string, object>("_id", e.UniqueId),
|
new KeyValuePair<string, object>("_id", e.UniqueId),
|
||||||
new KeyValuePair<string, object>("Thrower", e.ThrowerId),
|
new KeyValuePair<string, object>("Thrower", e.ThrowerId),
|
||||||
new KeyValuePair<string, object>("Type", e.Type),
|
new KeyValuePair<string, object>("Type", e.Type),
|
||||||
|
new KeyValuePair<string, object>("Description", e.Description),
|
||||||
|
new KeyValuePair<string, object>("Valence", (int)e.Valence),
|
||||||
new KeyValuePair<string, object>("When", e.When),
|
new KeyValuePair<string, object>("When", e.When),
|
||||||
new KeyValuePair<string, object>("Properties", properties),
|
new KeyValuePair<string, object>("Properties", properties),
|
||||||
});
|
});
|
||||||
@ -232,7 +234,19 @@ public class MongoDbInterface
|
|||||||
|
|
||||||
private Event EventFromBson(BsonDocument bson)
|
private Event EventFromBson(BsonDocument bson)
|
||||||
{
|
{
|
||||||
Event ret = new(bson["_id"].AsString, bson["Thrower"].AsString, bson["Type"].AsString, bson["When"].ToUniversalTime());
|
Event ret = new(
|
||||||
|
bson["_id"].AsString,
|
||||||
|
bson["Thrower"].AsString,
|
||||||
|
bson["Type"].AsString,
|
||||||
|
"",
|
||||||
|
bson["When"].ToUniversalTime());
|
||||||
|
|
||||||
|
if (bson.Contains("Description"))
|
||||||
|
ret.Description = bson["Description"].ToString() ?? "";
|
||||||
|
|
||||||
|
if (bson.Contains("Valence"))
|
||||||
|
ret.Valence = (Event.ValenceType)bson["Valence"].ToInt32();
|
||||||
|
|
||||||
foreach (var kv in bson["Properties"].AsBsonDocument)
|
foreach (var kv in bson["Properties"].AsBsonDocument)
|
||||||
ret.Properties.Add(kv.Name, kv.Value);
|
ret.Properties.Add(kv.Name, kv.Value);
|
||||||
|
|
||||||
@ -247,14 +261,25 @@ public class MongoDbInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async IAsyncEnumerable<Event> GetEvents(string? subject = null, DateTime? from = null, DateTime? to = null, int? limit = null, int? offset = null, Dictionary<string, object>? filters = null)
|
public override async IAsyncEnumerable<Event> GetEvents(
|
||||||
|
string? subject = null,
|
||||||
|
DateTime? from = null,
|
||||||
|
DateTime? to = null,
|
||||||
|
int? limit = null,
|
||||||
|
int? offset = null,
|
||||||
|
Event.ValenceType? valenceType = null,
|
||||||
|
Dictionary<string, object>? filters = null
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var conditions = new List<FilterDefinition<BsonDocument>>();
|
var conditions = new List<FilterDefinition<BsonDocument>>();
|
||||||
|
|
||||||
if (subject is not null)
|
if (subject is not null)
|
||||||
conditions.Add(Builders<BsonDocument>.Filter.Eq("Thrower", subject));
|
conditions.Add(Builders<BsonDocument>.Filter.Eq("Thrower", subject));
|
||||||
|
|
||||||
if(filters is not null)
|
if (valenceType is not null)
|
||||||
|
conditions.Add(Builders<BsonDocument>.Filter.Eq("Valence", (int)valenceType.Value));
|
||||||
|
|
||||||
|
if (filters is not null)
|
||||||
{
|
{
|
||||||
Func<Constraint, string, object, FilterDefinition<BsonDocument>> createFilter = (Constraint c, string property, object value) =>
|
Func<Constraint, string, object, FilterDefinition<BsonDocument>> createFilter = (Constraint c, string property, object value) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,71 +1,3 @@
|
|||||||
@page "/ElementList"
|
@page "/ElementList"
|
||||||
|
|
||||||
@inject Salmon.Core.Instance Salmon;
|
<ElementDeck />
|
||||||
|
|
||||||
<h3>Éléments</h3>
|
|
||||||
|
|
||||||
<div Style="display:flex;flex-wrap:wrap; height:100%;">
|
|
||||||
@foreach(var e in Elements)
|
|
||||||
{
|
|
||||||
<Card Class="col-6" Style="width:18rem;margin:10px;">
|
|
||||||
<CardHeader>
|
|
||||||
<NavLink href=@($"Element/{System.Web.HttpUtility.UrlEncode(e.UniqueId)}")>
|
|
||||||
<span class="oi oi-zoom-in" aria-hidden="true"></span>
|
|
||||||
</NavLink>
|
|
||||||
@e.LastType
|
|
||||||
</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<CardTitle>@e.ShortName</CardTitle>
|
|
||||||
@if(!String.IsNullOrEmpty(e.LongName))
|
|
||||||
{
|
|
||||||
<CardSubTitle>
|
|
||||||
@e.LongName
|
|
||||||
</CardSubTitle>
|
|
||||||
}
|
|
||||||
<CardText>@e.Description</CardText>
|
|
||||||
</CardBody>
|
|
||||||
<ul class="list-group list-group-flush">
|
|
||||||
@foreach(var kv in e.ImportantProperties())
|
|
||||||
{
|
|
||||||
<li class="list-group-item">@kv.Key: @kv.Value</li>
|
|
||||||
}
|
|
||||||
<li class="list-group-item"><small>id: @e.UniqueId</small></li>
|
|
||||||
</ul>
|
|
||||||
@if(Salmon.GetLastElementUpdate(e.UniqueId) is not null)
|
|
||||||
{
|
|
||||||
<CardFooter>
|
|
||||||
<small class="text-muted">Last updated <i>@TimespanHelper.GetReadableTimespan(DateTime.Now - Salmon.GetLastElementUpdate(e.UniqueId).Value)</i></small>
|
|
||||||
</CardFooter>
|
|
||||||
}
|
|
||||||
</Card>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
List<Element> Elements = new();
|
|
||||||
private static System.Timers.Timer Time = new System.Timers.Timer(5000);
|
|
||||||
|
|
||||||
|
|
||||||
protected async override Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
await base.OnInitializedAsync();
|
|
||||||
|
|
||||||
Time.Elapsed += async (Object? source, System.Timers.ElapsedEventArgs e) =>
|
|
||||||
{
|
|
||||||
await InvokeAsync(() => Refresh());
|
|
||||||
};
|
|
||||||
Time.AutoReset = true;
|
|
||||||
Time.Enabled = true;
|
|
||||||
|
|
||||||
Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void Refresh()
|
|
||||||
{
|
|
||||||
Elements = Salmon.GetAllElements().ToList();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -22,46 +22,13 @@ else
|
|||||||
<h3>@ThisElement.LongName</h3>
|
<h3>@ThisElement.LongName</h3>
|
||||||
|
|
||||||
<h4>Propriétés</h4>
|
<h4>Propriétés</h4>
|
||||||
<table class="table">
|
<TripletTable Triplets=@Triplets />
|
||||||
<thead>
|
|
||||||
<tr>
|
<h4>Enfants</h4>
|
||||||
<th>Dernier changement</th>
|
<ElementDeck FilterByParent=@Id />
|
||||||
<th>Nom</th>
|
|
||||||
<th>Valeur</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@if (Triplets is not null)
|
|
||||||
@foreach (var t in Triplets)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@t.LastFlush</td>
|
|
||||||
<td>@t.predicate</td>
|
|
||||||
<td>@t.value</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h4>Évènements</h4>
|
<h4>Évènements</h4>
|
||||||
<table class="table">
|
<EventTable Events=@Events />
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Date</th>
|
|
||||||
<th>Type</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@if(Events is not null)
|
|
||||||
@foreach (var e in Events)
|
|
||||||
{
|
|
||||||
<tr>
|
|
||||||
<td>@e.When</td>
|
|
||||||
<td>@e.Type</td>
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
@ -70,8 +37,8 @@ else
|
|||||||
string? Error = $"Chargement...";
|
string? Error = $"Chargement...";
|
||||||
|
|
||||||
Salmon.Core.Element? ThisElement = null;
|
Salmon.Core.Element? ThisElement = null;
|
||||||
List<Triplet>? Triplets = null;
|
List<Triplet>? Triplets { get; set; } = null;
|
||||||
List<Event>? Events = null;
|
List<Event>? Events { get; set; } = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -107,6 +74,8 @@ else
|
|||||||
events.Add(e);
|
events.Add(e);
|
||||||
|
|
||||||
Events = events;
|
Events = events;
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -15,9 +15,6 @@
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet" />
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet" />
|
||||||
<link href="_content/Blazor.Bootstrap/blazor.bootstrap.css" rel="stylesheet" />
|
<link href="_content/Blazor.Bootstrap/blazor.bootstrap.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
||||||
<link href="css/site.css" rel="stylesheet" />
|
<link href="css/site.css" rel="stylesheet" />
|
||||||
<link href="Salmon.Web.styles.css" rel="stylesheet" />
|
<link href="Salmon.Web.styles.css" rel="stylesheet" />
|
||||||
@ -47,6 +44,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.clipboardCopy = {
|
||||||
|
copyText: function (text) {
|
||||||
|
navigator.clipboard.writeText(text).then(function () {
|
||||||
|
//alert("Copied to clipboard!");
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
alert(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -6,6 +6,8 @@ using System.Text.Json.Serialization;
|
|||||||
|
|
||||||
Salmon.Core.Instance CoreInstance;
|
Salmon.Core.Instance CoreInstance;
|
||||||
|
|
||||||
|
Salmon.Model.Monitor.Drive _;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
builder.Services
|
builder.Services
|
||||||
.AddControllers()
|
.AddControllers()
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Blazor.Bootstrap" Version="2.1.0" />
|
<PackageReference Include="Blazor.Bootstrap" Version="2.1.0" />
|
||||||
|
<PackageReference Include="FontAwesome" Version="4.7.0" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
|
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
|
||||||
<PackageReference Include="MongoDB.Driver" Version="2.25.0" />
|
<PackageReference Include="MongoDB.Driver" Version="2.25.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<div class="top-row ps-3 navbar navbar-dark">
|
<div class="top-row ps-3 navbar navbar-dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
<img src="favicon.png" style="width:32px; height:32px;" />
|
||||||
<a class="navbar-brand" href="">Salmon.Web</a>
|
<a class="navbar-brand" href="">Salmon.Web</a>
|
||||||
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
@ -24,16 +25,6 @@
|
|||||||
<span class="oi oi-home" aria-hidden="true"></span> Event List
|
<span class="oi oi-home" aria-hidden="true"></span> Event List
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="counter">
|
|
||||||
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
<div class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="fetchdata">
|
|
||||||
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
@using Microsoft.JSInterop
|
@using Microsoft.JSInterop
|
||||||
@using Salmon.Web
|
@using Salmon.Web
|
||||||
@using Salmon.Web.Shared
|
@using Salmon.Web.Shared
|
||||||
|
@using Salmon.Web.Components
|
||||||
|
|
||||||
@using Salmon.Core;
|
@using Salmon.Core;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 804 KiB |
Loading…
Reference in New Issue
Block a user