Public Access
195 lines
12 KiB
XML
195 lines
12 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:DodoSSH.Client.Shell.ViewModels"
|
|
xmlns:views="using:DodoSSH.Client.App.Views"
|
|
x:Class="DodoSSH.Client.App.Views.SettingsGroupsPage"
|
|
x:DataType="vm:MainWindowViewModel"
|
|
x:Name="Root">
|
|
|
|
<!--
|
|
v5c-2: Groups, against Settings-Groups.dc.html — a real management page over VaultViewModel's own group
|
|
commands (Groups, NewGroup, EditGroup, DeleteGroup), given its own row here rather than only living inside
|
|
the hosts board's sidebar. DataContext.Vault (VaultViewModel) is nullable — locked, or the settings mode
|
|
reached before an unlock — so every binding below is {Binding Vault.*}, and the empty-vault caption covers
|
|
the null case the same way the vaults page's own does.
|
|
|
|
── THE INTRO SENTENCE IS NOT THE MOCK'S ────────────────────────────────────────────────────────────────
|
|
The design says "the order here is the order there" and draws drag handles to back it up. Neither is true:
|
|
HostGroupRowViewModel — see VaultViewModel.RebuildGroups — orders groups by the vault new items go into
|
|
first, then by vault name, then by label; there is no manual order to drag into and nothing this page
|
|
could do would make one real. The sentence below says what is actually true instead, and there are no
|
|
drag handles.
|
|
|
|
── EDIT AND DELETE ──────────────────────────────────────────────────────────────────────────────────────
|
|
EditGroupCommand and DeleteGroupCommand already take the row as their argument — see
|
|
VaultViewModel.EditGroup and VaultViewModel.EditGroupFromHeading's own remark on why — so this card's
|
|
buttons bind straight to them with CommandParameter="{Binding}"; no wrapper commands were needed the way
|
|
the tags page needs one. Editing opens the same drawer form the hosts board's own GROUPS section does
|
|
(HostDrawer.axaml's IsEditingGroup panel); it is not reproduced here as a second form, on the reasoning
|
|
the vaults page gives for reusing VaultsViewModel's commands rather than rebuilding them: one set of
|
|
fields, one place they can drift from what SaveGroupCommand actually writes.
|
|
|
|
── THE "NO GROUP" FOOTER ────────────────────────────────────────────────────────────────────────────────
|
|
Real, all three facts: VaultViewModel.UngroupedHostCount counts hosts whose group has gone or was never
|
|
set, "always listed first" is true of both FlattenIntoSections call sites (RebuildSidebarRows passes
|
|
ungroupedFirst: false — it is drawn last there — but the desktop's own board, RebuildHostSections, passes
|
|
true), and it genuinely cannot be renamed or deleted: there is no HostGroupSecret behind it for either
|
|
command to act on.
|
|
-->
|
|
|
|
<ScrollViewer>
|
|
<StackPanel MaxWidth="1100" Margin="40" HorizontalAlignment="Stretch">
|
|
|
|
<Grid ColumnDefinitions="*,Auto">
|
|
<StackPanel Grid.Column="0" Orientation="Horizontal" Spacing="14" VerticalAlignment="Center">
|
|
<TextBlock Classes="settingstitle" Text="Groups" />
|
|
<Border Background="{StaticResource Chip}" CornerRadius="9" MinWidth="34" Height="30"
|
|
IsVisible="{Binding Vault, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<TextBlock Text="{Binding Vault.Groups.Count}" FontSize="13.5" FontWeight="SemiBold"
|
|
Foreground="{StaticResource TextFaint}" Margin="8,0"
|
|
HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
</Border>
|
|
</StackPanel>
|
|
<Button Grid.Column="1" Classes="accent" Height="40" Content="+ NEW GROUP"
|
|
Command="{Binding Vault.NewGroupCommand}"
|
|
IsEnabled="{Binding Vault, Converter={x:Static ObjectConverters.IsNotNull}}" />
|
|
</Grid>
|
|
|
|
<TextBlock Classes="settingsrowcaption" Margin="0,12,0,0" TextWrapping="Wrap"
|
|
Text="Groups order by which vault new items go into, then by vault, then by label — there is no manual order to set." />
|
|
|
|
<!-- The group editor, in place: HostDrawer's own IsEditingGroup form, restyled into this page's card
|
|
idiom rather than duplicated. Opened by + NEW GROUP above or an EDIT icon below. -->
|
|
<Border Classes="settingscard" Margin="0,20,0,0" Padding="20"
|
|
IsVisible="{Binding Vault.IsEditingGroup}">
|
|
<StackPanel Spacing="10">
|
|
<TextBlock Classes="settingsrowtitle" Text="{Binding Vault.DrawerTitle}" />
|
|
<TextBlock Classes="settingsrowcaption"
|
|
Text="A heading for the hosts board, and the defaults every host under it inherits when it says nothing itself." />
|
|
<TextBox PlaceholderText="group name" Text="{Binding Vault.GroupEditorLabel}" />
|
|
<StackPanel Spacing="4" IsVisible="{Binding Vault.ShowsGroupEditorVaultChoice}">
|
|
<ComboBox HorizontalAlignment="Stretch" ItemsSource="{Binding Vault.GroupEditorVaultChoices}"
|
|
SelectedItem="{Binding Vault.GroupEditorSelectedVault}">
|
|
<ComboBox.ItemTemplate>
|
|
<DataTemplate x:DataType="vm:VaultChoiceViewModel">
|
|
<TextBlock Text="{Binding Display}" FontSize="12" />
|
|
</DataTemplate>
|
|
</ComboBox.ItemTemplate>
|
|
</ComboBox>
|
|
</StackPanel>
|
|
<ComboBox HorizontalAlignment="Stretch" ItemsSource="{Binding Vault.GroupEditorParentChoices}"
|
|
SelectedItem="{Binding Vault.GroupEditorSelectedParent}">
|
|
<ComboBox.ItemTemplate>
|
|
<DataTemplate x:DataType="vm:GroupChoice">
|
|
<TextBlock Text="{Binding Label}" />
|
|
</DataTemplate>
|
|
</ComboBox.ItemTemplate>
|
|
</ComboBox>
|
|
<Grid ColumnDefinitions="*,8,*">
|
|
<NumericUpDown Grid.Column="0" Value="{Binding Vault.GroupEditorDefaultPort}" Minimum="1"
|
|
Maximum="65535" FormatString="0" ShowButtonSpinner="False"
|
|
PlaceholderText="default port" />
|
|
<TextBox Grid.Column="2" Text="{Binding Vault.GroupEditorDefaultUsername}"
|
|
PlaceholderText="default username" />
|
|
</Grid>
|
|
<ComboBox HorizontalAlignment="Stretch" ItemsSource="{Binding Vault.GroupEditorAuthenticationChoices}"
|
|
SelectedItem="{Binding Vault.GroupEditorSelectedAuthentication}">
|
|
<ComboBox.ItemTemplate>
|
|
<DataTemplate x:DataType="vm:AuthenticationChoice">
|
|
<TextBlock Text="{Binding Label}" />
|
|
</DataTemplate>
|
|
</ComboBox.ItemTemplate>
|
|
</ComboBox>
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
<Button Classes="accent" Height="36" Content="{Binding Vault.GroupSaveLabel}"
|
|
Command="{Binding Vault.SaveGroupCommand}" />
|
|
<Button Classes="ghost" Height="36" Content="CANCEL"
|
|
Command="{Binding Vault.CancelGroupEditCommand}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- The delete confirmation, in place. The same control the hosts board's GROUPS section and the
|
|
vaults page both reuse. -->
|
|
<Border Margin="0,20,0,0" Padding="20" CornerRadius="12"
|
|
Background="{StaticResource DangerWash}" BorderBrush="{StaticResource DangerSoft}"
|
|
BorderThickness="1"
|
|
IsVisible="{Binding Vault.PendingDeletion, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<views:ConfirmDeleteCard DataContext="{Binding Vault}" />
|
|
</Border>
|
|
|
|
<StackPanel Margin="0,24,0,40" Spacing="10">
|
|
<ItemsControl ItemsSource="{Binding Vault.Groups}">
|
|
<ItemsControl.ItemsPanel>
|
|
<ItemsPanelTemplate>
|
|
<StackPanel Spacing="10" />
|
|
</ItemsPanelTemplate>
|
|
</ItemsControl.ItemsPanel>
|
|
<ItemsControl.ItemTemplate>
|
|
<DataTemplate x:DataType="vm:HostGroupRowViewModel">
|
|
<Border Classes="settingscard" Padding="20,16">
|
|
<Grid ColumnDefinitions="Auto,*,Auto,Auto">
|
|
|
|
<Border Grid.Column="0" Width="38" Height="38" CornerRadius="10"
|
|
Background="{StaticResource AvatarGradient}">
|
|
<TextBlock Text="{Binding Initial}" FontWeight="Bold" FontSize="14"
|
|
Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
|
|
</Border>
|
|
|
|
<StackPanel Grid.Column="1" Spacing="5" Margin="14,0" VerticalAlignment="Center">
|
|
<TextBlock Text="{Binding Label}" FontSize="15" FontWeight="Bold" LetterSpacing="-0.2"
|
|
Foreground="{StaticResource Text}" TextTrimming="CharacterEllipsis" />
|
|
<TextBlock Classes="mono" FontSize="11.5" Foreground="{StaticResource TextFaint}"
|
|
Text="{Binding Description}" />
|
|
</StackPanel>
|
|
|
|
<Border Grid.Column="2" Classes="chip" Margin="0,0,14,0" VerticalAlignment="Center"
|
|
IsVisible="{Binding HasVaultBadge}">
|
|
<TextBlock Text="{Binding VaultBadge}" />
|
|
</Border>
|
|
|
|
<StackPanel Grid.Column="3" Orientation="Horizontal" Spacing="8" VerticalAlignment="Center">
|
|
<Button Classes="paneicon" Width="34" Height="34" FontSize="15"
|
|
Command="{Binding #Root.((vm:MainWindowViewModel)DataContext).Vault.EditGroupCommand}"
|
|
CommandParameter="{Binding}" ToolTip.Tip="Rename this group or change what its hosts inherit.">
|
|
<TextBlock FontFamily="{StaticResource IconFont}" Text="" />
|
|
</Button>
|
|
<Button Classes="paneicon danger" Width="34" Height="34" FontSize="15"
|
|
Command="{Binding #Root.((vm:MainWindowViewModel)DataContext).Vault.DeleteGroupCommand}"
|
|
CommandParameter="{Binding}" ToolTip.Tip="Delete this group. The hosts filed under it are asked about separately.">
|
|
<TextBlock FontFamily="{StaticResource IconFont}" Text="" />
|
|
</Button>
|
|
</StackPanel>
|
|
|
|
</Grid>
|
|
</Border>
|
|
</DataTemplate>
|
|
</ItemsControl.ItemTemplate>
|
|
</ItemsControl>
|
|
|
|
<!-- The "No group" footer row. Always drawn, even with zero groups, because it is true whether or
|
|
not any group exists — it is just as often the only row on this page. -->
|
|
<Border Classes="settingscard" Padding="20,16" Opacity="0.7"
|
|
IsVisible="{Binding Vault, Converter={x:Static ObjectConverters.IsNotNull}}">
|
|
<StackPanel Orientation="Horizontal" Spacing="14">
|
|
<TextBlock FontFamily="{StaticResource IconFont}" FontSize="17" Text=""
|
|
Foreground="{StaticResource TextGhost}" VerticalAlignment="Center" />
|
|
<StackPanel Spacing="5">
|
|
<TextBlock Text="No group" FontSize="14" FontWeight="SemiBold" LetterSpacing="-0.2"
|
|
Foreground="{StaticResource TextFaint}" />
|
|
<TextBlock Classes="mono" FontSize="11.5" Foreground="{StaticResource TextGhost}"
|
|
Text="{Binding Vault.UngroupedHostCount, StringFormat='{}{0} hosts · always listed first · cannot be renamed or deleted'}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<TextBlock Classes="settingsrowcaption" TextWrapping="Wrap"
|
|
IsVisible="{Binding Vault, Converter={x:Static ObjectConverters.IsNull}}"
|
|
Text="Unlock your keychain to see and manage your groups." />
|
|
</StackPanel>
|
|
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
|
|
</UserControl>
|