feat(app): wire main window, DI services, and demo dataset
This commit is contained in:
1 parent
c3fc019994
commit
90d047c29a
4 files changed
+156
No files matched your search
@@ -0,0 +1,38 @@
|
||||
using Vantage.Core.Alerts;
|
||||
using Vantage.Core.Logs;
|
||||
using Vantage.Core.Models;
|
||||
|
||||
namespace Vantage.App;
|
||||
|
||||
public static class DemoData
|
||||
{
|
||||
public static VantageConfig Build() => new()
|
||||
{
|
||||
RefreshIntervalSeconds = 3,
|
||||
HistoryLength = 120,
|
||||
AlertRules =
|
||||
{
|
||||
new AlertRule { Name = "CPU saturated", Metric = "cpu", Comparison = AlertComparison.GreaterOrEqual, Threshold = 80, For = TimeSpan.FromSeconds(30), Severity = AlertSeverity.Warning },
|
||||
new AlertRule { Name = "Memory pressure", Metric = "memory", Comparison = AlertComparison.GreaterOrEqual, Threshold = 90, For = TimeSpan.FromMinutes(2), Severity = AlertSeverity.Critical },
|
||||
new AlertRule { Name = "Disk almost full", Metric = "disk", Comparison = AlertComparison.GreaterOrEqual, Threshold = 90, For = TimeSpan.Zero, Severity = AlertSeverity.Critical }
|
||||
},
|
||||
LogSources =
|
||||
{
|
||||
LogSource.Journal("docker", "Docker"),
|
||||
LogSource.Journal("ssh", "SSH"),
|
||||
LogSource.File("/var/log/syslog", "syslog")
|
||||
},
|
||||
Hosts =
|
||||
{
|
||||
new HostConfig { Name = "edge-01", Address = "10.10.0.11", Username = "root", AuthMethod = SshAuthMethod.PrivateKey, PrivateKeyPath = "~/.ssh/id_ed25519" },
|
||||
new HostConfig { Name = "storage-01", Address = "10.10.0.21", Username = "ops", AuthMethod = SshAuthMethod.PrivateKey, PrivateKeyPath = "~/.ssh/id_ed25519" },
|
||||
new HostConfig { Name = "vps-main", Address = "vps.example.net", Username = "deploy", AuthMethod = SshAuthMethod.PrivateKey, PrivateKeyPath = "~/.ssh/id_ed25519" }
|
||||
},
|
||||
HealthChecks =
|
||||
{
|
||||
new HealthCheckConfig { Name = "Gateway HTTP", Kind = HealthKind.Http, Target = "https://example.com" },
|
||||
new HealthCheckConfig { Name = "Local SSH", Kind = HealthKind.Tcp, Target = "127.0.0.1:22" },
|
||||
new HealthCheckConfig { Name = "DNS TCP", Kind = HealthKind.Tcp, Target = "1.1.1.1:53" }
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Vantage.App.ViewModels;
|
||||
using Vantage.Core;
|
||||
|
||||
namespace Vantage.App;
|
||||
|
||||
public static class VantageAppServices
|
||||
{
|
||||
public static IServiceCollection AddVantageApp(this IServiceCollection services, bool useMockProviders) =>
|
||||
services.AddVantageApp(useMockProviders ? VantageProviderMode.Mock : VantageProviderMode.Ssh);
|
||||
|
||||
public static IServiceCollection AddVantageApp(this IServiceCollection services, VantageProviderMode mode)
|
||||
{
|
||||
services.AddVantageCore(mode);
|
||||
services.AddTransient<MainWindowViewModel>();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static bool ResolveMockMode() => ResolveProviderMode() == VantageProviderMode.Mock;
|
||||
|
||||
public static VantageProviderMode ResolveProviderMode()
|
||||
{
|
||||
var mode = Environment.GetEnvironmentVariable("VANTAGE_PROVIDERS");
|
||||
return mode?.ToLowerInvariant() switch
|
||||
{
|
||||
"ssh" => VantageProviderMode.Ssh,
|
||||
"prometheus" => VantageProviderMode.Prometheus,
|
||||
_ => VantageProviderMode.Mock
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:Vantage.App.ViewModels"
|
||||
xmlns:views="clr-namespace:Vantage.App.Views"
|
||||
xmlns:conv="clr-namespace:Vantage.App.Converters"
|
||||
mc:Ignorable="d"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Class="Vantage.App.Views.MainWindow"
|
||||
x:DataType="vm:MainWindowViewModel"
|
||||
x:CompileBindings="True"
|
||||
Width="1080" Height="720"
|
||||
MinWidth="820" MinHeight="560"
|
||||
Background="#12151B"
|
||||
Title="Vantage - homelab dashboard">
|
||||
|
||||
<Grid ColumnDefinitions="260,*" RowDefinitions="*,Auto">
|
||||
|
||||
<Border Grid.Row="0" Grid.Column="0" Background="#161A22" BorderBrush="#2C323D" BorderThickness="0,0,1,0">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<StackPanel Grid.Row="0" Margin="16,16,16,8" Spacing="2">
|
||||
<TextBlock Text="VANTAGE" FontSize="18" FontWeight="Bold" Foreground="{DynamicResource AccentBrush}" />
|
||||
<TextBlock Text="Hosts" Foreground="#8891A0" FontSize="12" />
|
||||
</StackPanel>
|
||||
|
||||
<ListBox Grid.Row="1" ItemsSource="{Binding Hosts}" SelectedItem="{Binding SelectedHost}"
|
||||
Background="Transparent" Margin="8,0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate x:DataType="vm:HostViewModel">
|
||||
<Grid ColumnDefinitions="Auto,*" Margin="4,6">
|
||||
<Ellipse Grid.Column="0" Width="10" Height="10" VerticalAlignment="Center" Margin="0,0,10,0"
|
||||
Fill="{Binding IsOnline, Converter={x:Static conv:StateBrushConverters.RunningBrush}}" />
|
||||
<StackPanel Grid.Column="1">
|
||||
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" />
|
||||
<TextBlock Text="{Binding Endpoint}" Foreground="#8891A0" FontSize="11" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<Grid Grid.Row="0" Grid.Column="1" RowDefinitions="Auto,*" Margin="16">
|
||||
<DockPanel Grid.Row="0" Margin="0,0,0,12">
|
||||
<Button DockPanel.Dock="Right" Content="Refresh now" Command="{Binding RefreshSelectedHostCommand}" />
|
||||
<StackPanel Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
|
||||
<TextBlock Text="Monitoring" Foreground="#8891A0" VerticalAlignment="Center" />
|
||||
<Ellipse Width="9" Height="9" VerticalAlignment="Center"
|
||||
Fill="{Binding IsMonitoring, Converter={x:Static conv:StateBrushConverters.RunningBrush}}" />
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
|
||||
<TabControl Grid.Row="1">
|
||||
<TabItem Header="Fleet">
|
||||
<views:FleetView DataContext="{Binding}" />
|
||||
</TabItem>
|
||||
<TabItem Header="Host">
|
||||
<views:HostMetricsView DataContext="{Binding SelectedHost}" />
|
||||
</TabItem>
|
||||
<TabItem Header="Alerts">
|
||||
<views:AlertsView DataContext="{Binding}" />
|
||||
</TabItem>
|
||||
<TabItem Header="Docker">
|
||||
<views:DockerView DataContext="{Binding Docker}" />
|
||||
</TabItem>
|
||||
<TabItem Header="Health">
|
||||
<views:HealthView DataContext="{Binding}" />
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Background="#161A22" BorderBrush="#2C323D" BorderThickness="0,1,0,0" Padding="16,6">
|
||||
<TextBlock Text="{Binding StatusLine}" Foreground="#8891A0" FontSize="12" />
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,9 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Vantage.App.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow() => AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
Reference in new issue
Block a user