Files
ClawdDotNet/src/ClawdDotNet.Desktop/Views/BackupPageView.axaml
RichardandClaude Opus 5.5 ad71682c2d i18n: Englisch als Hauptsprache, Sprachpakete fuer Desktop und WebUI (#661)
Umbau durch Gemini Flash, Durchsicht und Nacharbeit durch Claude.

Umfang:
- Desktop: LocalizationManager (JSON-Pakete, Rueckfall auf Englisch,
  Umschalten zur Laufzeit), Localize-Markup-Erweiterung, Sprachwahl in den
  Einstellungen (AppSettings.Language, Vorgabe "en"); 317 Schluessel je Sprache
- WebUI: alle Ansichten auf t()/data-i18n, 656 Schluessel je Sprache
- Agenten-Werkzeuge: Beschreibungen, Schemata und Meldungen auf Englisch
- Tests an die englischen Meldungen angepasst, keine Pruefung abgeschwaecht

Nacharbeit bei der Durchsicht:
- ~25 Kommentarbloecke mit Begruendungen waren ersatzlos entfallen, darunter
  sicherheitsrelevante (NTFS-Datenstrom beim shared:-Praefix, Bremse gegen
  Agentenschleifen, doppelter POST beim Anlegen einer Instanz). Wieder
  eingesetzt: auf Englisch, wo die Datei umgestellt ist, sonst im Wortlaut.
- Drei WebUI-Schluessel fehlten (logs.paused, instances.instanceOfflineError,
  instances.noInstanceActiveError). Weil t() bei fehlendem Schluessel den
  Schluessel selbst liefert, griff der "|| err.message"-Rueckfall nie — die
  Oberflaeche haette den Schluesselnamen angezeigt.

Geprueft: Schluesselgleichheit en/de, Platzhalter je Schluessel, jeder im
Code benutzte Schluessel vorhanden, node --check fuer alle Module,
1.220 Tests gruen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 09:43:51 +02:00

157 lines
8.6 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
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="using:ClawdDotNet.Desktop.ViewModels"
xmlns:ctrl="using:ClawdDotNet.Desktop.Controls"
mc:Ignorable="d" d:DesignWidth="1100" d:DesignHeight="740"
x:Class="ClawdDotNet.Desktop.Views.BackupPageView"
x:DataType="vm:BackupPageViewModel">
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Classes="caption" Margin="0,10,0,0"
Text="{Binding StatusText}" TextWrapping="Wrap" />
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel Spacing="24" MaxWidth="820" HorizontalAlignment="Left">
<!-- ══════════════════ Manuell ══════════════════ -->
<StackPanel Spacing="12">
<TextBlock Classes="kicker" Text="{Binding L[desktop.backup.kickerManual]}" />
<TextBlock Classes="h2" Text="{Binding L[desktop.backup.titleCreate]}" />
<Grid ColumnDefinitions="*,Auto" VerticalAlignment="Bottom">
<StackPanel Grid.Column="0">
<TextBlock Classes="label" Text="{Binding L[desktop.backup.targetFolder]}" />
<TextBox Text="{Binding TargetFolder}"
PlaceholderText="{Binding L[desktop.backup.targetFolderPlaceholder]}" />
</StackPanel>
<Button Grid.Column="1" Content="{Binding L[desktop.backup.browse]}" Click="OnBrowseTargetFolder"
Margin="8,0,0,0" VerticalAlignment="Bottom" />
</Grid>
<StackPanel Spacing="6">
<TextBlock Classes="label" Text="{Binding L[desktop.backup.credentials]}" />
<StackPanel Orientation="Horizontal" Spacing="18">
<RadioButton GroupName="secrets" Content="{Binding L[desktop.backup.credentialsExclude]}"
IsChecked="{Binding SecretsExclude}" />
<RadioButton GroupName="secrets" Content="{Binding L[desktop.backup.credentialsProtect]}"
IsChecked="{Binding SecretsPassphrase}" />
</StackPanel>
</StackPanel>
<StackPanel Spacing="8" Margin="24,0,0,0" IsVisible="{Binding SecretsPassphrase}">
<TextBox Text="{Binding Passphrase}" PasswordChar="•" Width="320"
HorizontalAlignment="Left" PlaceholderText="{Binding L[desktop.backup.passphrase]}" />
<TextBox Text="{Binding PassphraseRepeat}" PasswordChar="•" Width="320"
HorizontalAlignment="Left" PlaceholderText="{Binding L[desktop.backup.passphraseRepeat]}" />
</StackPanel>
<StackPanel Spacing="6">
<TextBlock Classes="label" Text="{Binding L[desktop.backup.scope]}" />
<StackPanel Orientation="Horizontal" Spacing="18">
<CheckBox Content="{Binding L[desktop.backup.scopeChat]}" IsChecked="{Binding IncludeChatHistory}" />
<CheckBox Content="{Binding L[desktop.backup.scopeLogs]}" IsChecked="{Binding IncludeLogs}" />
</StackPanel>
</StackPanel>
<Button Classes="primary" HorizontalAlignment="Left" Margin="0,4,0,0"
Command="{Binding CreateBackupCommand}" IsEnabled="{Binding !IsBusy}">
<StackPanel Orientation="Horizontal" Spacing="6">
<ctrl:StrokeIcon Data="{StaticResource IconPlay}" Width="12" Height="12" IsFilled="True" />
<TextBlock Text="{Binding L[desktop.backup.createNow]}" />
</StackPanel>
</Button>
</StackPanel>
<Border Classes="hr" />
<!-- ══════════════════ Automatik ══════════════════ -->
<StackPanel Spacing="10">
<TextBlock Classes="kicker" Text="{Binding L[desktop.backup.kickerAuto]}" />
<TextBlock Classes="h2" Text="{Binding L[desktop.backup.titleAuto]}" />
<CheckBox Content="{Binding L[desktop.backup.autoDaily]}" IsChecked="{Binding AutoBackupEnabled}" />
<StackPanel Orientation="Horizontal" Spacing="24" Margin="24,0,0,0"
IsEnabled="{Binding AutoBackupEnabled}">
<StackPanel Width="100">
<TextBlock Classes="label" Text="{Binding L[desktop.backup.time]}" />
<TextBox Text="{Binding AutoBackupTime}" PlaceholderText="03:00" />
</StackPanel>
<StackPanel Width="160">
<TextBlock Classes="label" Text="{Binding L[desktop.backup.keep]}" />
<TextBox Text="{Binding KeepCount}" />
</StackPanel>
</StackPanel>
<TextBlock Classes="caption" Margin="24,0,0,0" TextWrapping="Wrap"
Text="{Binding L[desktop.backup.autoHint]}" />
</StackPanel>
<Border Classes="hr" />
<!-- ══════════════════ Bestand ══════════════════ -->
<StackPanel Spacing="10">
<TextBlock Classes="kicker" Text="{Binding L[desktop.backup.kickerExisting]}" />
<DockPanel>
<TextBlock Classes="h2" Text="{Binding L[desktop.backup.titleExisting]}" VerticalAlignment="Center" />
<!-- Mindestabstand zur Ueberschrift links. Vorher stand hier Margin="0" und
der Zwischenraum entstand nur, wenn das Fenster breit genug war; bei
1600 Punkten reichte er gerade nicht, und "Vorhandene Sicherungen"
beruehrte die Schaltflaeche "Aktualisieren". -->
<WrapPanel DockPanel.Dock="Right" HorizontalAlignment="Right" Classes="toolbar"
Margin="16,0,0,0">
<Button Classes="toolbar" Content="{Binding L[desktop.backup.refresh]}"
Command="{Binding RefreshBackupListCommand}" />
<Button Classes="toolbar" Content="{Binding L[desktop.backup.openFolder]}"
Command="{Binding ShowSelectedInFolderCommand}"
IsEnabled="{Binding SelectedBackup, Converter={x:Static ObjectConverters.IsNotNull}}" />
<Button Classes="toolbar" Content="{Binding L[desktop.backup.delete]}"
Command="{Binding DeleteSelectedCommand}"
IsEnabled="{Binding SelectedBackup, Converter={x:Static ObjectConverters.IsNotNull}}" />
<Button Classes="toolbar primary" Content="{Binding L[desktop.backup.restore]}"
Command="{Binding RestoreSelectedCommand}"
IsEnabled="{Binding SelectedBackup, Converter={x:Static ObjectConverters.IsNotNull}}" />
</WrapPanel>
</DockPanel>
<Border Classes="thead">
<Grid ColumnDefinitions="2.6*,1.5*,1.3*,0.9*,1.3*">
<TextBlock Grid.Column="0" Classes="th" Text="{Binding L[desktop.backup.thFilename]}" />
<TextBlock Grid.Column="1" Classes="th" Text="{Binding L[desktop.backup.thCreatedAt]}" />
<TextBlock Grid.Column="2" Classes="th" Text="{Binding L[desktop.backup.thInstance]}" />
<TextBlock Grid.Column="3" Classes="th" Text="{Binding L[desktop.backup.thSize]}" />
<TextBlock Grid.Column="4" Classes="th" Text="{Binding L[desktop.backup.thSecrets]}" />
</Grid>
</Border>
<ListBox Classes="table" MaxHeight="300" Margin="0,-10,0,0"
ItemsSource="{Binding Backups}" SelectedItem="{Binding SelectedBackup}">
<ListBox.ItemTemplate>
<DataTemplate DataType="vm:BackupItemViewModel">
<Border Classes="tr" Padding="7">
<Grid ColumnDefinitions="2.6*,1.5*,1.3*,0.9*,1.3*">
<TextBlock Grid.Column="0" Classes="td" Text="{Binding FileName}" />
<TextBlock Grid.Column="1" Classes="td"
Text="{Binding LastWriteTime, StringFormat='{}{0:dd.MM.yyyy HH:mm}'}" />
<TextBlock Grid.Column="2" Classes="td" Text="{Binding InstanceName}" />
<TextBlock Grid.Column="3" Classes="td" Text="{Binding SizeFormatted}" />
<TextBlock Grid.Column="4" Classes="td dim" Text="{Binding SecretsInfo}" />
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</StackPanel>
</ScrollViewer>
</DockPanel>
</UserControl>