Skip to content

Commit e633543

Browse files
author
Donovan Yohan
committed
fix(frontend): bound mobile topic activity status
1 parent 5c60171 commit e633543

2 files changed

Lines changed: 47 additions & 4 deletions

File tree

frontend/src/components/TopicSidebarShell.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ type TopicSendInput = typeof sendSessionInput;
7272

7373
const DISCONNECTED_SESSION_CONTROL_REASON =
7474
'session offline/disconnected — controls unavailable until reconnect';
75+
const TOPIC_LATEST_STATUS_MAX_LENGTH = 96;
76+
77+
function boundedTopicLatestStatus(value: string): string {
78+
const trimmed = value.trim();
79+
return trimmed.length > TOPIC_LATEST_STATUS_MAX_LENGTH
80+
? `${trimmed.slice(0, TOPIC_LATEST_STATUS_MAX_LENGTH - 3)}...`
81+
: trimmed;
82+
}
7583

7684
function topicPrimarySession(
7785
item: TopicNavItem
@@ -158,20 +166,23 @@ function topicPrimaryAction(item: TopicNavItem): {
158166
function topicLatestStatus(item: TopicNavItem): string {
159167
const session = topicPrimarySession(item);
160168
if (session?.agentState === 'permission-prompt') {
161-
return session.currentActivity?.detail
169+
const status = session.currentActivity?.detail
162170
? `${item.statusLabel} · ${session.currentActivity.detail}`
163171
: item.statusLabel;
172+
return boundedTopicLatestStatus(status);
164173
}
165174
if (session?.currentActivity) {
166175
const detail = session.currentActivity.detail
167176
? ` · ${session.currentActivity.detail}`
168177
: '';
169-
return `${session.currentActivity.tool}${detail}`;
178+
return boundedTopicLatestStatus(`${session.currentActivity.tool}${detail}`);
170179
}
171180
if (item.surfaces.length > 0) {
172-
return `${item.statusLabel} · ${item.surfaces[0]!.label}`;
181+
return boundedTopicLatestStatus(
182+
`${item.statusLabel} · ${item.surfaces[0]!.label}`
183+
);
173184
}
174-
return item.routingLabel ?? item.statusLabel;
185+
return boundedTopicLatestStatus(item.routingLabel ?? item.statusLabel);
175186
}
176187

177188
function TopicBadge({ item }: { item: TopicNavItem }) {

test/topic-sidebar-shell.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,38 @@ describe('TopicSidebarView', () => {
243243
expect(mobileRows[1]?.textContent).toContain('Routine lane');
244244
});
245245

246+
it('bounds mobile topic latest status from raw activity text', async () => {
247+
const longToolName = 'tool-name-'.repeat(30);
248+
await renderView({
249+
topics: [
250+
makeTopic({
251+
linkedRefs: { sessionIds: ['waiting-session'] },
252+
}),
253+
],
254+
sessions: [
255+
makeSession({
256+
id: 'waiting-session',
257+
displayName: 'waiting lane',
258+
agentState: 'waiting-for-input',
259+
currentActivity: { tool: longToolName },
260+
}),
261+
],
262+
surfaces: [],
263+
});
264+
265+
const mobileRowStatus = container.querySelector(
266+
'.topic-mobile-row__status'
267+
)?.textContent;
268+
const mobileDetailLatest = container.querySelector(
269+
'.topic-mobile-detail__latest'
270+
)?.textContent;
271+
272+
expect(mobileRowStatus).toBe(`${longToolName.slice(0, 93)}...`);
273+
expect(mobileDetailLatest).toBe(`${longToolName.slice(0, 93)}...`);
274+
expect(mobileRowStatus?.length).toBeLessThanOrEqual(96);
275+
expect(mobileDetailLatest?.length).toBeLessThanOrEqual(96);
276+
});
277+
246278
it('uses the bounded topic search as the only mobile search surface', async () => {
247279
await renderView();
248280

0 commit comments

Comments
 (0)