Public Access
Give the hosts board its vaults, and the Hetzner import a vault and a key
Six things, all of them answers to a question a screen was deciding on somebody's behalf. The board draws a heading per vault and sorts each vault's hosts by that vault's own groups. A group is an item of one vault, so drawing every group of every vault in one run flattened away containment that already exists: two vaults each holding a "production" were two headings with the same word on them, told apart by a small grey name beside each. Single- vault sessions are unchanged. There is now one "No group" heading per vault, so the folded set is keyed on SidebarGroupHeader.CollapseKey rather than on GroupId ?? Guid.Empty, which had one vault's unfiled hosts folding every other vault's away with them. A Ctrl-click starts its set with the card the board has lit. The board always has a selection — a fresh unlock lights the first host so CONNECT has something under it — so "one card lit, nothing ticked" is the state this screen opens in, and ticking a second card there produced a set of one: the machine the user was looking at was left out of the count and out of everything Delete, Move and Change group then ran over. The card tooltip says the host's name as well as its address. 214 pixels of card trims the name, and the tooltip was the one place it was not said in full. The card's floor drops from 120 to 104. A card with no tags measures about 87, so the mock's number was thirty pixels of air under every card on a board that is scrolled. "Move to another vault…" joins the board's context menu for one host. Moving one machine meant opening its pane and finding the menu inside it, while moving six was a right click away — the one-host case was the harder of the two. And the Hetzner import asks which vault and which key. A project belongs to a team more often than to a person, so forty servers landing wherever the session happens to be standing is the wrong default; ImportHostsAsync takes the target vault, and the ssh_config importer passes null and is unchanged. The key is the half Hetzner cannot supply and the keychain usually already holds — the public half went to Hetzner when the servers were made — so the import points every host at it rather than bringing one. It defaults to no key rather than guessing, and says so when the key it was given lives in a different vault from the hosts.
This commit is contained in:
1 parent
ed936380b3
commit
c859705b83
9 files changed
+926
-84
No files matched your search
@@ -250,12 +250,19 @@ public sealed class HostGridTests : IAsyncLifetime
|
||||
/// way down rather than acted on as it bubbles.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// ◆ <b>And the set the first Ctrl-click starts has the lit card in it.</b> The board always has a
|
||||
/// selection — a fresh unlock lights the first host so CONNECT has something under it — so "one card
|
||||
/// lit, nothing ticked" is the state this screen opens in. A Ctrl-click there used to produce a set of
|
||||
/// one, leaving the machine the user was looking at out of the count and out of everything Delete, Move
|
||||
/// and Change group then acted on. See <c>VaultViewModel.ExtendHostChoice</c>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// And a plain click is the way out, which is the other half of the same rule: after one, exactly one
|
||||
/// card is in play and every command on this screen is about the same host.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
[Fact]
|
||||
public async Task CtrlClickingCardsTicksThemWithoutMovingTheSelection()
|
||||
public async Task CtrlClickingCardsTicksThemAndTheLitCardWithoutMovingTheSelection()
|
||||
{
|
||||
await OnTheBoardAsync((screen, window) =>
|
||||
{
|
||||
@@ -267,16 +274,19 @@ public sealed class HostGridTests : IAsyncLifetime
|
||||
|
||||
Click(CardFor(screen, second), window, RawInputModifiers.Control);
|
||||
|
||||
vault.ChosenHostCount.ShouldBe(1);
|
||||
vault.ChosenHostCount.ShouldBe(2, "the card the board had lit is in the set the Ctrl-click began");
|
||||
first.IsChosen.ShouldBeTrue("which is the half that used to be left out of it");
|
||||
second.IsChosen.ShouldBeTrue("the tick is drawn on the card");
|
||||
vault.SelectedHost.ShouldBeSameAs(first, "ticking a card is not selecting it");
|
||||
vault.SelectedSidebarRow.ShouldBeSameAs(first, "and the section lists were never told otherwise");
|
||||
|
||||
Click(CardFor(screen, first), window, RawInputModifiers.Control);
|
||||
vault.ChosenHostCount.ShouldBe(2);
|
||||
|
||||
vault.ChosenHostCount.ShouldBe(1, "the same click again takes the tick off");
|
||||
first.IsChosen.ShouldBeFalse("the lit card is not folded back in over a set that already exists");
|
||||
|
||||
Click(CardFor(screen, first), window, RawInputModifiers.Control);
|
||||
vault.ChosenHostCount.ShouldBe(1, "the same click again takes the tick off");
|
||||
vault.ChosenHostCount.ShouldBe(2);
|
||||
|
||||
Click(CardFor(screen, first), window);
|
||||
|
||||
@@ -387,6 +397,12 @@ public sealed class HostGridTests : IAsyncLifetime
|
||||
|
||||
var tickedCard = CardFor(screen, ticked);
|
||||
|
||||
// Lit first, and it matters: a Ctrl-click folds the lit card into the set it starts — see
|
||||
// ExtendHostChoice — so ticking one card while another is lit would leave no card outside the
|
||||
// set for the second half of this test to right-click.
|
||||
vault.SelectedHost = ticked;
|
||||
Dispatcher.UIThread.RunJobs();
|
||||
|
||||
Click(tickedCard, window, RawInputModifiers.Control);
|
||||
|
||||
RightClick(tickedCard, window);
|
||||
|
||||
Reference in new issue
Block a user