a24d49f463
User-facing copy only; internal API names (Backups collection, BackupEntry, list-backups op, etc.) stay the same to avoid churn through the wire protocol and existing on-disk files. The new phrasing makes the auto-snapshot-before-save model more discoverable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
159 lines
9.1 KiB
XML
159 lines
9.1 KiB
XML
<Window x:Class="WebhookServer.Gui.MainWindow"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
xmlns:vm="clr-namespace:WebhookServer.Gui.ViewModels"
|
|
xmlns:models="clr-namespace:WebhookServer.Core.Models;assembly=WebhookServer.Core"
|
|
mc:Ignorable="d"
|
|
Title="Webhook Server" Height="600" Width="1000"
|
|
Icon="/webhook-server.ico"
|
|
d:DataContext="{d:DesignInstance Type=vm:MainViewModel}">
|
|
<Window.InputBindings>
|
|
<KeyBinding Key="N" Modifiers="Control" Command="{Binding AddEndpointCommand}"/>
|
|
</Window.InputBindings>
|
|
<DockPanel LastChildFill="True">
|
|
<StatusBar DockPanel.Dock="Bottom">
|
|
<StatusBarItem>
|
|
<Ellipse Width="10" Height="10"
|
|
Fill="{Binding IsConnected, Converter={StaticResource ConnFill}}"/>
|
|
</StatusBarItem>
|
|
<StatusBarItem>
|
|
<TextBlock Text="{Binding ConnectionStatus}"/>
|
|
</StatusBarItem>
|
|
</StatusBar>
|
|
|
|
<Menu DockPanel.Dock="Top">
|
|
<MenuItem Header="_File">
|
|
<MenuItem Header="_New endpoint…" Command="{Binding AddEndpointCommand}" InputGestureText="Ctrl+N"/>
|
|
<Separator/>
|
|
<MenuItem Header="_Import config…" Command="{Binding ImportConfigCommand}"/>
|
|
<MenuItem Header="_Export config…" Command="{Binding ExportConfigCommand}"/>
|
|
<MenuItem Header="Config _Checkpoints"
|
|
ItemsSource="{Binding Backups}"
|
|
ToolTip="Snapshots taken automatically before each save. Click one to restore."
|
|
SubmenuOpened="OnBackupsSubmenuOpened">
|
|
<MenuItem.ItemContainerStyle>
|
|
<Style TargetType="MenuItem">
|
|
<Setter Property="Header">
|
|
<Setter.Value>
|
|
<MultiBinding StringFormat="{}{0:yyyy-MM-dd HH:mm:ss} ({1:n0} bytes)">
|
|
<Binding Path="SavedAt"/>
|
|
<Binding Path="SizeBytes"/>
|
|
</MultiBinding>
|
|
</Setter.Value>
|
|
</Setter>
|
|
<Setter Property="Command" Value="{Binding DataContext.RestoreBackupCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
|
<Setter Property="CommandParameter" Value="{Binding}"/>
|
|
</Style>
|
|
</MenuItem.ItemContainerStyle>
|
|
</MenuItem>
|
|
<Separator/>
|
|
<MenuItem Header="E_xit" Command="{Binding ExitCommand}"/>
|
|
</MenuItem>
|
|
<MenuItem Header="_Server">
|
|
<MenuItem Header="_Settings…" Command="{Binding EditServerSettingsCommand}"/>
|
|
<Separator/>
|
|
<MenuItem Header="_Restart service" Command="{Binding RestartServiceCommand}"/>
|
|
</MenuItem>
|
|
<MenuItem Header="_Help">
|
|
<MenuItem Header="_About Webhook Server…" Command="{Binding ShowAboutCommand}"/>
|
|
</MenuItem>
|
|
</Menu>
|
|
|
|
<Grid>
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="*"/>
|
|
<RowDefinition Height="5"/>
|
|
<RowDefinition Height="200"/>
|
|
</Grid.RowDefinitions>
|
|
|
|
<DataGrid Grid.Row="0"
|
|
ItemsSource="{Binding Endpoints}"
|
|
SelectedItem="{Binding SelectedEndpoint, Mode=TwoWay}"
|
|
AutoGenerateColumns="False"
|
|
CanUserAddRows="False"
|
|
CanUserDeleteRows="False"
|
|
IsReadOnly="True"
|
|
HeadersVisibility="Column">
|
|
<DataGrid.RowStyle>
|
|
<Style TargetType="DataGridRow">
|
|
<EventSetter Event="MouseDoubleClick" Handler="OnRowDoubleClick"/>
|
|
<Setter Property="ContextMenu">
|
|
<Setter.Value>
|
|
<ContextMenu>
|
|
<MenuItem Header="_Edit…" Command="{Binding DataContext.EditEndpointCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
|
<MenuItem Header="_Copy URL" Command="{Binding DataContext.CopyEndpointUrlCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
|
<Separator/>
|
|
<MenuItem Header="Toggle _enabled"
|
|
Command="{Binding DataContext.ToggleEnabledCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
|
CommandParameter="{Binding}"/>
|
|
<Separator/>
|
|
<MenuItem Header="_Delete…" Command="{Binding DataContext.DeleteEndpointCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
|
|
</ContextMenu>
|
|
</Setter.Value>
|
|
</Setter>
|
|
</Style>
|
|
</DataGrid.RowStyle>
|
|
<DataGrid.Columns>
|
|
<DataGridTemplateColumn Header="Enabled" Width="80">
|
|
<DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate DataType="{x:Type models:EndpointConfig}">
|
|
<CheckBox IsChecked="{Binding Enabled, Mode=OneWay}"
|
|
Command="{Binding DataContext.ToggleEnabledCommand, RelativeSource={RelativeSource AncestorType=Window}}"
|
|
CommandParameter="{Binding}"/>
|
|
</DataTemplate>
|
|
</DataGridTemplateColumn.CellTemplate>
|
|
</DataGridTemplateColumn>
|
|
<DataGridTextColumn Header="Slug" Binding="{Binding Slug}" Width="120"/>
|
|
<DataGridTemplateColumn Header="URL" Width="*">
|
|
<DataGridTemplateColumn.CellTemplate>
|
|
<DataTemplate DataType="{x:Type models:EndpointConfig}">
|
|
<TextBox IsReadOnly="True"
|
|
BorderThickness="0"
|
|
Background="Transparent"
|
|
Padding="0"
|
|
VerticalAlignment="Center">
|
|
<TextBox.Text>
|
|
<MultiBinding Converter="{StaticResource HookUrl}" Mode="OneWay">
|
|
<Binding Path="Slug"/>
|
|
<Binding Path="DataContext.HttpBaseUrl" RelativeSource="{RelativeSource AncestorType=Window}"/>
|
|
</MultiBinding>
|
|
</TextBox.Text>
|
|
</TextBox>
|
|
</DataTemplate>
|
|
</DataGridTemplateColumn.CellTemplate>
|
|
</DataGridTemplateColumn>
|
|
<DataGridTextColumn Header="Auth" Binding="{Binding AuthMode}" Width="80"/>
|
|
<DataGridTextColumn Header="Executor" Binding="{Binding ExecutorType}" Width="140"/>
|
|
<DataGridTextColumn Header="Mode" Binding="{Binding ResponseMode}" Width="80"/>
|
|
<DataGridTextColumn Header="Description" Binding="{Binding Description}" Width="2*"/>
|
|
</DataGrid.Columns>
|
|
</DataGrid>
|
|
|
|
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" Background="#DDD"/>
|
|
|
|
<DockPanel Grid.Row="2">
|
|
<Grid DockPanel.Dock="Top">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
<ColumnDefinition Width="Auto"/>
|
|
</Grid.ColumnDefinitions>
|
|
<TextBlock Text="Recent log entries" FontWeight="Bold" Margin="6,4"/>
|
|
<CheckBox Grid.Column="1" Content="Auto-scroll" IsChecked="{Binding AutoScrollLogs}" VerticalAlignment="Center" Margin="6,2"/>
|
|
<Button Grid.Column="2" Content="Refresh" Command="{Binding RefreshLogTailCommand}" Margin="6,2"/>
|
|
</Grid>
|
|
<TextBox x:Name="LogTailBox"
|
|
Text="{Binding LogTail, Mode=OneWay}"
|
|
IsReadOnly="True"
|
|
FontFamily="Consolas"
|
|
VerticalScrollBarVisibility="Auto"
|
|
HorizontalScrollBarVisibility="Auto"
|
|
TextWrapping="NoWrap"
|
|
TextChanged="OnLogTailChanged"/>
|
|
</DockPanel>
|
|
</Grid>
|
|
</DockPanel>
|
|
</Window>
|