Files
OTSSignsOrchestrator/OTSSignsOrchestrator.Desktop/Views/InstancesView.axaml

169 lines
10 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:OTSSignsOrchestrator.Desktop.ViewModels"
xmlns:dto="using:OTSSignsOrchestrator.Core.Models.DTOs"
xmlns:svc="using:OTSSignsOrchestrator.Core.Services"
x:Class="OTSSignsOrchestrator.Desktop.Views.InstancesView"
x:DataType="vm:InstancesViewModel">
<DockPanel>
<!-- Page header -->
<StackPanel DockPanel.Dock="Top" Margin="0,0,0,4">
<TextBlock Text="Instances" Classes="pageTitle" />
<TextBlock Text="View and manage deployed CMS stacks" Classes="pageSubtitle" />
</StackPanel>
<!-- Toolbar -->
<Border DockPanel.Dock="Top" Classes="toolbar" Margin="0,0,0,16">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Orientation="Horizontal" Spacing="8">
<Button Content="Refresh" Command="{Binding LoadInstancesCommand}" />
<Button Content="Details" Classes="accent" Command="{Binding OpenDetailsCommand}"
IsEnabled="{Binding !IsBusy}"
ToolTip.Tip="View credentials and manage this instance." />
<Button Content="Inspect" Command="{Binding InspectInstanceCommand}" />
<Button Content="Restart Stack" Command="{Binding RestartStackCommand}"
IsEnabled="{Binding !IsBusy}"
ToolTip.Tip="Force-restart all services in the selected stack." />
<Button Content="Delete" Classes="danger" Command="{Binding DeleteInstanceCommand}" />
<Border Width="1" Background="{StaticResource BorderSubtleBrush}" Margin="4,2" />
<Button Content="Rotate DB Password" Command="{Binding RotateMySqlPasswordCommand}"
IsEnabled="{Binding !IsBusy}"
ToolTip.Tip="Generate a new MySQL password, update the Docker secret, and redeploy the stack." />
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="8">
<TextBox Text="{Binding FilterText}" Watermark="Filter by name..." Width="220" />
<Button Content="Search" Command="{Binding LoadInstancesCommand}" />
</StackPanel>
</Grid>
</Border>
<!-- Status -->
<TextBlock DockPanel.Dock="Bottom" Text="{Binding StatusMessage}" Classes="status"
Margin="0,10,0,0" />
<!-- Main content: split into upper (grid + services) and lower (logs) -->
<Grid RowDefinitions="*,Auto,Auto">
<!-- Upper area: instance list + services side panel -->
<Grid Grid.Row="0" ColumnDefinitions="*,Auto">
<!-- Instance list -->
<DataGrid Grid.Column="0"
ItemsSource="{Binding Instances}"
SelectedItem="{Binding SelectedInstance}"
AutoGenerateColumns="False"
IsReadOnly="True"
GridLinesVisibility="Horizontal"
CanUserResizeColumns="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Stack" Binding="{Binding StackName}" Width="150" />
<DataGridTextColumn Header="Abbrev" Binding="{Binding CustomerAbbrev}" Width="70" />
<DataGridTextColumn Header="Services" Binding="{Binding ServiceCount}" Width="70" />
<DataGridTextColumn Header="Host" Binding="{Binding HostLabel}" Width="150" />
</DataGrid.Columns>
</DataGrid>
<!-- Services panel (shown when inspecting) -->
<Border Grid.Column="1" Width="360"
IsVisible="{Binding SelectedServices.Count}"
Classes="card" Margin="16,0,0,0">
<StackPanel Spacing="4">
<TextBlock Text="Stack Services" Classes="sectionTitle"
Foreground="{StaticResource AccentBrush}" Margin="0,0,0,10" />
<ItemsControl ItemsSource="{Binding SelectedServices}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="svc:ServiceInfo">
<Border Background="#232336" CornerRadius="6" Padding="12,10" Margin="0,3"
BorderBrush="{StaticResource BorderSubtleBrush}" BorderThickness="1">
<Grid ColumnDefinitions="*,Auto">
<StackPanel Grid.Column="0" Spacing="3">
<TextBlock Text="{Binding Name}" FontWeight="SemiBold" FontSize="13" />
<TextBlock Text="{Binding Image}" FontSize="11"
Foreground="{StaticResource TextMutedBrush}" />
<TextBlock Text="{Binding Replicas, StringFormat='Replicas: {0}'}"
FontSize="11" Foreground="{StaticResource TextSecondaryBrush}" />
</StackPanel>
<Button Grid.Column="1" Content="Restart"
Command="{Binding $parent[ItemsControl].((vm:InstancesViewModel)DataContext).RestartServiceCommand}"
CommandParameter="{Binding}"
IsEnabled="{Binding $parent[ItemsControl].((vm:InstancesViewModel)DataContext).IsBusy, Converter={x:Static BoolConverters.Not}}"
VerticalAlignment="Center"
FontSize="12" Padding="10,6"
ToolTip.Tip="Force-restart this service" />
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
</Grid>
<!-- Grid splitter between instances and logs -->
<GridSplitter Grid.Row="1" Height="6" HorizontalAlignment="Stretch"
IsVisible="{Binding IsLogsPanelVisible}"
Background="Transparent" />
<!-- Container Logs Panel -->
<Border Grid.Row="2" Classes="card" Margin="0,4,0,0"
IsVisible="{Binding IsLogsPanelVisible}"
MinHeight="180" MaxHeight="400">
<DockPanel>
<!-- Logs toolbar -->
<Grid DockPanel.Dock="Top" ColumnDefinitions="Auto,*,Auto" Margin="0,0,0,8">
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="8"
VerticalAlignment="Center">
<TextBlock Text="Container Logs" Classes="sectionTitle"
Foreground="{StaticResource AccentBrush}" />
<ComboBox ItemsSource="{Binding LogServiceFilter}"
SelectedItem="{Binding SelectedLogService}"
MinWidth="200" FontSize="12"
ToolTip.Tip="Filter logs by service" />
</StackPanel>
<TextBlock Grid.Column="1" Text="{Binding LogsStatusMessage}"
FontSize="11" Foreground="{StaticResource TextMutedBrush}"
VerticalAlignment="Center" HorizontalAlignment="Center" />
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="6"
VerticalAlignment="Center">
<Button Content="Refresh" Command="{Binding RefreshLogsCommand}"
FontSize="11" Padding="8,4"
ToolTip.Tip="Fetch latest logs" />
<ToggleButton IsChecked="{Binding IsLogsAutoRefresh}"
Content="Auto"
FontSize="11" Padding="8,4"
ToolTip.Tip="Toggle auto-refresh (every 5 seconds)"
Command="{Binding ToggleLogsAutoRefreshCommand}" />
<Button Content="✕" Command="{Binding CloseLogsPanelCommand}"
FontSize="11" Padding="6,4"
ToolTip.Tip="Close logs panel" />
</StackPanel>
</Grid>
<!-- Log entries list -->
<Border Background="#1a1a2e" CornerRadius="4" Padding="8"
BorderBrush="{StaticResource BorderSubtleBrush}" BorderThickness="1">
<ScrollViewer VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding LogEntries}"
x:DataType="vm:InstancesViewModel">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="dto:ServiceLogEntry">
<TextBlock Text="{Binding DisplayLine}"
FontFamily="Cascadia Mono,Consolas,Menlo,monospace"
FontSize="11" Padding="0,1"
TextWrapping="NoWrap"
Foreground="#cccccc" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>
</DockPanel>
</Border>
</Grid>
</DockPanel>
</UserControl>