Merge branch 'claude/remove-group-edit-delete-buttons-3d38ec'
ci / build and test (push) Successful in 1m31s
ci / android head (push) Failing after 5s
ci / api image (push) Successful in 27s

This commit is contained in:
2026-08-04 16:40:56 +02:00
5 changed files with 63 additions and 85 deletions
@@ -1483,7 +1483,7 @@ internal sealed partial class VaultViewModel(
/// </para>
/// <para>
/// <b>Separate from <see cref="SelectedGroup"/>, and no longer sets it.</b> The two answer different
/// questions — "what is on screen" and "what would EDIT and DELETE act on" — and while one click meant
/// questions — "what is on screen" and "which card is chosen" — and while one click meant
/// both there was no way to name a group without also narrowing the grid to it. Two gestures, two
/// properties; <see cref="GroupTarget"/> is where the two meet.
/// </para>
@@ -2601,26 +2601,23 @@ internal sealed partial class VaultViewModel(
internal bool IsConfirmingGroupDeletion => PendingDeletion?.Target is DeletionTarget.Group;
/// <summary>
/// What the group panel's EDIT and DELETE act on: the card that is selected, or the group that is open.
/// What a group command with no argument acts on: the card that is selected, or the group that is open.
/// </summary>
/// <remarks>
/// Two answers, because a card is no longer where the user is. Selecting one aims the buttons at it,
/// which is what a click has always done; with nothing selected they aim at the group whose contents are
/// on screen — the one the trail ends with. Without that fallback a group with no groups inside it could
/// be opened and then never edited, because opening a group is exactly what takes its own card off the
/// screen. It is also what a file manager does: act on the selection, and on the current folder when
/// there is none.
/// Two answers, because a card is no longer where the user is. Selecting one aims at it, which is what a
/// click has always done; with nothing selected the answer is the group whose contents are on screen —
/// the one the trail ends with. That fallback is what makes + NEW HOST open on the group somebody is
/// standing in rather than on none, and it is what a file manager does: act on the selection, and on the
/// current folder when there is none.
/// <para>
/// The desktop's Edit and Delete reach this through the card menu, which selects whatever was
/// right-clicked first, so the fallback is not what they read — see <c>HostsScreen.OnGroupContextRequested</c>.
/// They used to be a pair of buttons beside the GROUPS heading, which had no card under a pointer to
/// mean and so leaned on it.
/// </para>
/// </remarks>
internal HostGroupRowViewModel? GroupTarget => SelectedGroup ?? GroupFilter;
/// <summary>Whether the group panel's buttons are showing.</summary>
/// <remarks>
/// Hidden with nothing to act on as well as while the question is up. A pair of buttons over a grid of
/// cards nobody has chosen between is a pair whose subject the user has to work out, and the answer
/// would be "neither" — see <see cref="GroupTarget"/>.
/// </remarks>
internal bool ShowsGroupActions => GroupTarget is not null && !IsConfirmingGroupDeletion;
/// <summary>Whether this vault has any groups, which is what makes the sidebar draw headings.</summary>
internal bool HasGroups => Groups.Count > 0;
@@ -4859,8 +4856,9 @@ internal sealed partial class VaultViewModel(
/// <summary>Loads the group being acted on into the box, so saving renames it.</summary>
/// <param name="group">
/// The group to edit, or null for whatever the screen is aimed at — the selected card, or the open group
/// when no card is selected. See <see cref="GroupTarget"/>. The desktop's EDIT button passes nothing and
/// means the second; the phone has no card to select and passes the group its heading names.
/// when no card is selected. See <see cref="GroupTarget"/>. The desktop's card menu passes nothing and
/// means the card that was right-clicked, which opening the menu has already selected; the phone has no
/// card to select and passes the group its heading names.
/// </param>
/// <remarks>
/// Taking it as an argument is what keeps the phone from having to select a group in order to edit one.
@@ -5226,7 +5224,7 @@ internal sealed partial class VaultViewModel(
/// up under the ungrouped heading — so what the user needs to know is exactly how many machines are about
/// to move, and that none of them are going anywhere else.
/// <para>
/// Aims where EDIT does: at the selected card, or at the open group when no card is selected. See
/// Aims where Edit does: at the selected card, which on the desktop is the one the menu opened on. See
/// <see cref="GroupTarget"/>.
/// </para>
/// </remarks>
@@ -8183,7 +8181,6 @@ internal sealed partial class VaultViewModel(
DisarmIfAimedElsewhere(DeletionTarget.Group, GroupTarget?.EntityId);
OnPropertyChanged(nameof(GroupTarget));
OnPropertyChanged(nameof(ShowsGroupActions));
}
/// <remarks>
@@ -8204,7 +8201,6 @@ internal sealed partial class VaultViewModel(
DisarmIfAimedElsewhere(DeletionTarget.Group, GroupTarget?.EntityId);
OnPropertyChanged(nameof(GroupTarget));
OnPropertyChanged(nameof(ShowsGroupActions));
RebuildGroupLevel();
RebuildVisibleHosts();
@@ -8217,7 +8213,6 @@ internal sealed partial class VaultViewModel(
OnPropertyChanged(nameof(IsConfirmingGroupDeletion));
OnPropertyChanged(nameof(ShowsHostActions));
OnPropertyChanged(nameof(ShowsHostPaneActions));
OnPropertyChanged(nameof(ShowsGroupActions));
OnPropertyChanged(nameof(ShowsItemActions));
}