Account · Profile and access: a key's ends stay whole, keys drawn literally

A key's name gives way before its ends, which keep their width. The
ends and a new secret draw through typography::literal. Tests show this
device listing first and the name field emptying after Create.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-09-27 13:38:40 -04:00
1 parent 24e0366e0e
commit 91d939e21e
4 files changed
+36 -10

No files matched your search

+1
View File
@@ -404,3 +404,4 @@ Per-component lines live in `tasks/`. Tags there:
| T35 | 3 | PASS | |
| T36a | 1 | FAIL | Sign in waiting for a password and resting while busy, Create account waiting for a name, the other providers resting, and Send again resting while busy untested |
| T36a | 2 | PASS | |
| T36b | 1 | FAIL | a long key name hid its ends at 280px; the secret and ends skipped typography::literal; this device's place first and the name clearing after Create untested |
+9 -9
View File
@@ -12,7 +12,7 @@ use crate::{
forms::{Enter, Input},
primitives::Severity,
theme::{ActiveTheme, ControlSize, TextSize},
typography::Ellipsis,
typography::{Ellipsis, literal},
};
type OnKey = Rc<dyn Fn(&SharedString, &mut Window, &mut App)>;
@@ -114,7 +114,7 @@ impl RenderOnce for ApiKeyManager {
.gap_2()
.child(
div().flex().child(
div()
literal(div())
.flex_1()
.min_w_0()
.font_family(mono.clone())
@@ -154,19 +154,19 @@ impl RenderOnce for ApiKeyManager {
div()
.flex()
.gap_2()
.child(
div()
.flex_none()
.font_weight(FontWeight::MEDIUM)
.child(each.name.clone()),
)
.child(
div()
.flex_1()
.min_w_0()
.font_weight(FontWeight::MEDIUM)
.child(Ellipsis::new(each.name.clone())),
)
.child(
literal(div())
.flex_none()
.font_family(mono.clone())
.text_color(theme.colors.fg_muted)
.child(Ellipsis::new(each.hint.clone())),
.child(each.hint.clone()),
),
)
.child(
+2
View File
@@ -93,7 +93,9 @@ impl RenderOnce for SessionList {
.into_any_element()
}
};
let tag = format!("session-{}", session.key);
div()
.debug_selector(move || tag)
.flex()
.items_center()
.gap_3()
+24 -1
View File
@@ -104,6 +104,17 @@ fn a_key_is_made_by_name_revoked_on_the_second_press_and_its_secret_dismissed(
write("Deploys", cx);
tap("enter", cx);
assert_eq!(said(&host, cx), ["revoke ci", "make Deploys"]);
cx.executor()
.advance_clock(std::time::Duration::from_secs(10));
settle(cx);
tab(2, cx);
tap("space", cx);
tap("space", cx);
assert_eq!(
said(&host, cx),
["revoke ci", "make Deploys", "revoke ci"],
"the name field emptied, so Create rests and the second stop is Revoke"
);
host.update(cx, |bench, cx| {
bench.sent = true;
cx.notify();
@@ -111,7 +122,10 @@ fn a_key_is_made_by_name_revoked_on_the_second_press_and_its_secret_dismissed(
settle(cx);
tab(2, cx);
tap("space", cx);
assert_eq!(said(&host, cx), ["revoke ci", "make Deploys", "done"]);
assert_eq!(
said(&host, cx),
["revoke ci", "make Deploys", "revoke ci", "done"]
);
}
fn profile() -> Profile {
@@ -223,3 +237,12 @@ fn this_device_alone_offers_no_sign_out(cx: &mut TestAppContext) {
tap("space", cx);
assert!(said(&host, cx).is_empty());
}
/// The phone comes first in what the owner hands over, this device second; this device lists first.
#[gpui::test]
fn this_device_lists_first(cx: &mut TestAppContext) {
let (_, cx) = bench(sessions, cx);
let here = cx.debug_bounds("session-mac").expect("this device");
let phone = cx.debug_bounds("session-phone").expect("the phone");
assert!(here.top() < phone.top(), "{here:?} over {phone:?}");
}