Take the group's EDIT and DELETE off the heading row

A pair of buttons sat at the end of the GROUPS heading, and the card's own
right-click menu arrived later offering the same two things. Two controls for one
job, and the buttons were the harder of the two to read: a button beside a
heading has no card under a pointer to mean, so it had to work its subject out —
the selected card, or failing that the group the trail ends with, which once a
group is open is not a card on screen at all. The menu never has that problem,
because opening it is what aims it.

The menu is the whole of Edit and Delete on the desktop now. ShowsGroupActions
went with the buttons, since hiding them was all it did. GroupTarget stays: the
menu's two entries read it after the code-behind has selected whatever was
right-clicked, and its fallback to the open group is what makes + NEW HOST open
on the group somebody is standing in rather than on none.

One case changes shape. Opening a group with nothing inside it folds the card
grid away, so from in there nothing can be right-clicked — renaming that group
means pressing the trail back one level, to where it has a card of its own. The
buttons used to cover it through the fallback. The trail was already the way out
of an empty group, and 3.2a says so now.

The test that pressed EDIT through its binding is replaced by one holding that
no button on the screen commands either of them, which is the failure worth
catching: a button coming back is not a compile error, and it would draw itself
in place, aimed at the group the trail ends with. What that test covered — a
command that has to accept an empty parameter, and act on the card the pointer
was on — the two menu tests beside it already do.
This commit is contained in:
2026-08-04 16:39:14 +02:00
parent 742f65c204
commit d02d103569
5 changed files with 63 additions and 85 deletions
+15 -26
View File
@@ -226,25 +226,14 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid ColumnDefinitions="Auto,*,Auto">
<TextBlock Grid.Column="0" Classes="label" Text="GROUPS"
Foreground="{StaticResource TextDim}" VerticalAlignment="Center" />
<!--
The group's own two actions, beside the group cards rather than in the toolbar, because they
act on the card that is selected — and this is where the selection is made. Hidden rather
than disabled while DELETE's question is up, as every other pair in this application is, so
it cannot be pressed twice, and hidden again when there is nothing for them to act on. What
that is, with no card selected, is the group the trail above ends with; see
VaultViewModel.GroupTarget.
-->
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="6">
<Button Classes="ghost" Content="EDIT" Command="{Binding EditGroupCommand}"
IsVisible="{Binding ShowsGroupActions}" />
<Button Classes="ghost" Content="DELETE" Command="{Binding DeleteGroupCommand}"
IsVisible="{Binding ShowsGroupActions}" />
</StackPanel>
</Grid>
<!--
The heading and nothing else. This used to be a row with EDIT and DELETE at the far end of it,
and the card's own menu is where both live now — see the note on it below. They were a second
control for the job that menu already does, and the harder of the two to read: a button beside
a heading has to say which card it means, and with none selected it meant the group the trail
ends with rather than anything on screen.
-->
<TextBlock Classes="label" Text="GROUPS" Foreground="{StaticResource TextDim}" />
<Border Padding="10" Background="{StaticResource DangerWash}" CornerRadius="6"
IsVisible="{Binding IsConfirmingGroupDeletion}">
@@ -269,8 +258,8 @@
◆ THIS IS ONE LEVEL, NOT EVERY GROUP. It binds VisibleGroups: what is inside the group the
trail above ends with, or the outermost groups when it ends at ALL HOSTS. Folded away entirely
at a group with nothing inside it, which is an ordinary thing to open — the trail and the two
buttons stay, because leaving it is a gesture and editing it is a button.
at a group with nothing inside it, which is an ordinary thing to open — the trail stays, and
it is also the way back to the level where that group has a card of its own to be edited from.
◆ THESE CARDS ARE THE DROP TARGET. A host card dragged onto one is filed under that group, and
that is the whole of what a drag does on this screen. It used to be a heading inside the host
@@ -295,11 +284,11 @@
context; the code-behind selects whatever was right-clicked before the menu opens, and
cancels it outright over the space around the cards.
Open is here as well as on the double-click, and Edit and Delete as well as on the two
buttons above, and neither is a duplicate for its own sake: a gesture is unreachable without
a pointer, and the buttons act on GroupTarget — which with no card selected is the group the
trail ends with rather than the one under the pointer. This menu is the one place all three
act on the card that was right-clicked.
Open is here as well as on the double-click, which is not a duplicate for its own sake: a
gesture is unreachable without a pointer. Edit and Delete are here and nowhere else — they
were also a pair of buttons beside the heading above, which acted on GroupTarget and so with
no card selected meant the group the trail ends with rather than any card on screen. All
three act on the card that was right-clicked, which is the whole of what this menu is for.
Only Open takes a parameter, because OpenGroupCommand's null means ALL HOSTS rather than
nothing; Edit and Delete read GroupTarget, which the selection the code-behind has just made