Give hosts and terminals their own screen, and the rest of the vault another
ci / build and test (ubuntu) (pull_request) Canceled after 0s
ci / build (windows) (pull_request) Canceled after 0s

Rebuilds the client's shell from an imported design: a titlebar and nav rail
it draws itself, real multi-session tabs over the one WebView, a Ctrl+K host
search, and a vault screen that merges keys, passwords and pinned host keys
into one table. Hosts left the vault column for their own screen beside the
terminal, which is what the design asks for and turned out to be the better
split anyway.

Two screens the design shows have nothing behind them yet — file transfer
and teams — and say so plainly rather than rendering invented data; every
other gap between the design and this build is recorded in
docs/design-import-gaps.md.
This commit is contained in:
2026-07-31 08:39:37 +02:00
parent d162271a45
commit 9a76eced14
37 changed files with 4672 additions and 1347 deletions
@@ -0,0 +1,53 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:DodoSSH.Client.App.ViewModels"
x:Class="DodoSSH.Client.App.Views.NavRail"
x:DataType="vm:MainWindowViewModel">
<!--
Five destinations down the left edge.
Two of them — TRANSFERS and TEAM — reach screens that say they are not built. They are in the rail
anyway rather than dropped, and the reasoning is in ShellScreen: the milestones are public, the screens
behind these two say plainly what is missing, and a rail that quietly had three entries would make file
transfer and sharing look like a change of product rather than the next two milestones. Both are
recorded in docs/design-import-gaps.md.
Buttons rather than a TabStrip or a ListBox, for the same reason the vault's category rail is: all three
of those hold the selection themselves, so a click moves the highlight before the shell can decide
anything. Buttons carry no state and cannot disagree with the screen that is showing.
-->
<Border Width="54" Background="{StaticResource Chrome}"
BorderBrush="{StaticResource Border}" BorderThickness="0,0,1,0">
<DockPanel LastChildFill="False">
<StackPanel DockPanel.Dock="Top" Margin="0,8,0,0">
<Button Classes="flat nav" Content="HOSTS" Classes.active="{Binding IsHostsScreen}"
Command="{Binding ShowScreenCommand}"
CommandParameter="{x:Static vm:ShellScreen.Hosts}"
ToolTip.Tip="Your hosts, and the terminals open on them" />
<Button Classes="flat nav" Content="FILES" Classes.active="{Binding IsTransfersScreen}"
Command="{Binding ShowScreenCommand}"
CommandParameter="{x:Static vm:ShellScreen.Transfers}"
ToolTip.Tip="File transfer over SSH. Not built yet — see the screen for what is missing." />
<Button Classes="flat nav" Content="VAULT" Classes.active="{Binding IsVaultScreen}"
Command="{Binding ShowScreenCommand}"
CommandParameter="{x:Static vm:ShellScreen.Vault}"
ToolTip.Tip="SSH keys, stored passwords, and the host keys you have approved" />
<Button Classes="flat nav" Content="TEAM" Classes.active="{Binding IsTeamScreen}"
Command="{Binding ShowScreenCommand}"
CommandParameter="{x:Static vm:ShellScreen.Team}"
ToolTip.Tip="Shared vaults and the people in them. Not built yet — see the screen for what is missing." />
</StackPanel>
<Button DockPanel.Dock="Bottom" Classes="flat nav" Content="PREFS"
Classes.active="{Binding IsPreferencesScreen}"
Command="{Binding ShowScreenCommand}"
CommandParameter="{x:Static vm:ShellScreen.Preferences}"
ToolTip.Tip="Preferences, and this machine's device key" />
</DockPanel>
</Border>
</UserControl>