diff --git a/apps/p2/plugins/sessions/web.tsx b/apps/p2/plugins/sessions/web.tsx index c11cd2821..3786cd3f1 100644 --- a/apps/p2/plugins/sessions/web.tsx +++ b/apps/p2/plugins/sessions/web.tsx @@ -178,12 +178,20 @@ function Sidebar() { ); const renamed = renaming && list?.find((each) => each.id === renaming.session); const branch = renamed?.branches.find((each) => each.conversation === renaming?.conversation); - const { setChoice } = useNewSessionState(); + const { setChoice, setLocation } = useNewSessionState(); const onNew = useCallback(() => { setChoice(undefined); navigate({}); setTimeout(() => document.querySelector(".composer textarea")?.focus(), 50); }, [setChoice]); + // A folder's "+": the new session starts in that folder's location. + const onNewIn = useCallback( + (env: string | null, cwd: string) => { + setLocation({ env, cwd }); + onNew(); + }, + [setLocation, onNew], + ); return ( <> void; onNew: () => void; + /** Starts a new session in a sidebar folder's location; absent: folders have no "+". */ + onNewIn?: (env: string | null, cwd: string) => void; onCollapse: () => void; onProviders: () => void; onEnvs: () => void; @@ -412,45 +415,62 @@ export const Drawer = memo(function Drawer({ />
- {ordered.map(([location, list]) => ( -
-

- {location} -

- {list.map((session) => ( - - + )} + + {list.map((session) => ( + - - {session.pinned && } - {session.title} - - - {session.worker.error && ( - - Worker failed - - )} - - {archived ? "Tap to restore" : ago(session.updatedAt)} - - - - ))} -
- ))} + + + ))} + + ); + })} {results && results.messages.length > 0 && (

Messages

diff --git a/apps/p2/src/web/style.css b/apps/p2/src/web/style.css index 0080b4cb0..d83bcd44e 100644 --- a/apps/p2/src/web/style.css +++ b/apps/p2/src/web/style.css @@ -2830,6 +2830,25 @@ button.diff-number:hover { letter-spacing: 0; white-space: nowrap; } +.group-label { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; +} +.group-new { + display: inline-flex; + flex: none; + align-items: center; + justify-content: center; + width: var(--control-sm); + height: var(--control-sm); + margin: calc(-1 * var(--s1)) 0; + color: var(--faint); +} +.group-new:hover:not(:disabled) { + color: var(--text); +} .session-main { min-height: var(--control); padding-top: var(--s1); diff --git a/apps/p2/test/p2/ui-drawer.test.ts b/apps/p2/test/p2/ui-drawer.test.ts index 96ff39a3a..045be32c6 100644 --- a/apps/p2/test/p2/ui-drawer.test.ts +++ b/apps/p2/test/p2/ui-drawer.test.ts @@ -146,6 +146,16 @@ describe("drawer and new-session parity", { skip: !browserTests }, () => { "Pinned parent", "Recent sibling", ]); + // A folder's "+" opens a new session in that folder. + const label = await browser.evaluate( + `document.querySelector('.session-scroll .group h3 .group-label').textContent`, + ); + await browser.click(".session-scroll .group h3 .group-new"); + await browser.wait( + `location.pathname==='/' && document.querySelector('.cwd-pick span')?.textContent===${JSON.stringify(label)}`, + ); + await browser.open(`http://127.0.0.1:${fixture.server.port}/s/${pinned.id}`); + await browser.wait(`[...document.querySelectorAll('.session-title')].some(e=>e.textContent==='Pinned parent')`); const chat = await holdIn(owner, Chat, { session: pinned.id, conversation: 1 }, "participant"); await chat.send({ text: "subagent", requestId: "drawer-child" }, BACKGROUND_CONTEXT); const agents = await holdIn(owner, Subagents, {}, "reader");