fix(team): keep member launch labels consistent
This commit is contained in:
parent
0821b182e2
commit
e8ebe68576
6 changed files with 49 additions and 8 deletions
|
|
@ -126,6 +126,10 @@ export const MemberCard = ({
|
|||
const spawnCardClass = launchPresentation.cardClass;
|
||||
const launchVisualState = launchPresentation.launchVisualState;
|
||||
const launchStatusLabel = launchPresentation.launchStatusLabel;
|
||||
const displayPresenceLabel =
|
||||
launchVisualState === 'runtime_pending' || launchVisualState === 'permission_pending'
|
||||
? (launchStatusLabel ?? presenceLabel)
|
||||
: presenceLabel;
|
||||
const colors = getTeamColorSet(memberColor);
|
||||
const { isLight } = useTheme();
|
||||
const pending = taskCounts?.pending ?? 0;
|
||||
|
|
@ -155,8 +159,7 @@ export const MemberCard = ({
|
|||
(presenceLabel === 'starting' ||
|
||||
presenceLabel === 'connecting' ||
|
||||
launchVisualState === 'runtime_pending');
|
||||
const launchBadgeLabel =
|
||||
presenceLabel === 'starting' ? presenceLabel : (launchStatusLabel ?? presenceLabel);
|
||||
const launchBadgeLabel = presenceLabel === 'starting' ? presenceLabel : displayPresenceLabel;
|
||||
const showRuntimeAdvisoryBadge =
|
||||
!isRemoved &&
|
||||
Boolean(runtimeAdvisoryLabel) &&
|
||||
|
|
@ -201,7 +204,7 @@ export const MemberCard = ({
|
|||
</div>
|
||||
<span
|
||||
className={`absolute -bottom-0.5 -right-0.5 size-2.5 rounded-full border-2 border-[var(--color-surface)] ${dotClass}`}
|
||||
aria-label={presenceLabel}
|
||||
aria-label={displayPresenceLabel}
|
||||
/>
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
|
|
@ -295,7 +298,7 @@ export const MemberCard = ({
|
|||
variant="secondary"
|
||||
className="shrink-0 bg-red-500/15 px-1.5 py-0.5 text-[10px] font-normal leading-none text-red-400"
|
||||
>
|
||||
{presenceLabel}
|
||||
{displayPresenceLabel}
|
||||
</Badge>
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
|
|
@ -325,7 +328,7 @@ export const MemberCard = ({
|
|||
className={`shrink-0 px-1.5 py-0.5 text-[10px] font-normal leading-none ${isRemoved ? 'bg-zinc-600 text-zinc-300' : 'text-[var(--color-text-muted)]'}`}
|
||||
title={isRemoved ? 'This member has been removed' : activityTitle}
|
||||
>
|
||||
{isRemoved ? 'removed' : presenceLabel}
|
||||
{isRemoved ? 'removed' : displayPresenceLabel}
|
||||
</Badge>
|
||||
) : null}
|
||||
{showStartingSkeleton ? (
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ export const MemberDetailHeader = ({
|
|||
/>
|
||||
<span
|
||||
className={`absolute -bottom-0.5 -right-0.5 size-3 rounded-full border-2 border-[var(--color-surface)] ${dotClass}`}
|
||||
aria-label={presenceLabel}
|
||||
aria-label={badgeLabel}
|
||||
/>
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ export const MemberHoverCard = ({
|
|||
/>
|
||||
<span
|
||||
className={`absolute -bottom-0.5 -right-0.5 size-3 rounded-full border-2 border-[var(--color-surface)] ${dotClass}`}
|
||||
aria-label={presenceLabel}
|
||||
aria-label={badgeLabel}
|
||||
/>
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
|
|
|
|||
|
|
@ -201,6 +201,41 @@ describe('MemberCard starting-state visuals', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('keeps runtime-pending accessibility copy honest even when launch badge is hidden by an active task', async () => {
|
||||
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
||||
const host = document.createElement('div');
|
||||
document.body.appendChild(host);
|
||||
const root = createRoot(host);
|
||||
|
||||
await act(async () => {
|
||||
root.render(
|
||||
React.createElement(MemberCard, {
|
||||
member: {
|
||||
...member,
|
||||
currentTaskId: currentTask.id,
|
||||
},
|
||||
memberColor: 'blue',
|
||||
currentTask,
|
||||
isTeamAlive: true,
|
||||
isTeamProvisioning: false,
|
||||
spawnStatus: 'online',
|
||||
spawnLaunchState: 'runtime_pending_bootstrap',
|
||||
spawnRuntimeAlive: true,
|
||||
spawnLivenessSource: 'process',
|
||||
})
|
||||
);
|
||||
await Promise.resolve();
|
||||
});
|
||||
|
||||
expect(host.textContent).not.toContain('online');
|
||||
expect(host.querySelector('[aria-label="connecting"]')).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
await Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps the starting treatment and runtime summary visible while a runtime is still joining', async () => {
|
||||
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
|
||||
const host = document.createElement('div');
|
||||
|
|
@ -258,7 +293,7 @@ describe('MemberCard starting-state visuals', () => {
|
|||
});
|
||||
|
||||
expect(host.textContent).toContain('awaiting permission');
|
||||
expect(host.querySelector('[aria-label="connecting"]')).not.toBeNull();
|
||||
expect(host.querySelector('[aria-label="awaiting permission"]')).not.toBeNull();
|
||||
expect(host.querySelector('.member-waiting-shimmer')).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ describe('MemberDetailHeader spawn-aware presence', () => {
|
|||
|
||||
expect(host.textContent).toContain('connecting');
|
||||
expect(host.textContent).not.toContain('online');
|
||||
expect(host.querySelector('[aria-label="connecting"]')).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ describe('MemberHoverCard spawn-aware presence', () => {
|
|||
|
||||
expect(host.textContent).toContain('connecting');
|
||||
expect(host.textContent).not.toContain('online');
|
||||
expect(host.querySelector('[aria-label="connecting"]')).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
|
|
@ -225,6 +226,7 @@ describe('MemberHoverCard spawn-aware presence', () => {
|
|||
|
||||
expect(host.textContent).toContain('connecting');
|
||||
expect(host.textContent).not.toContain('online');
|
||||
expect(host.querySelector('[aria-label="connecting"]')).not.toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
root.unmount();
|
||||
|
|
|
|||
Loading…
Reference in a new issue