- Remove draft prompt state alongside draft thread cleanup - Update tests for terminal context removal and new-thread shortcut
Unified · Split
| @@ -24,6 +24,7 @@ import { useComposerDraftStore } from "../composerDraftStore"; · 23 unmodified lines | |||
| 24 | import { | 24 | import { |
| 25 | INLINE_TERMINAL_CONTEXT_PLACEHOLDER, | 25 | INLINE_TERMINAL_CONTEXT_PLACEHOLDER, |
| 26 | type TerminalContextDraft, | 26 | type TerminalContextDraft, |
| 27 | removeInlineTerminalContextPlaceholder, | ||
| 27 | } from "../lib/terminalContext"; | 28 | } from "../lib/terminalContext"; |
| 28 | import { isMacPlatform } from "../lib/utils"; | 29 | import { isMacPlatform } from "../lib/utils"; |
| 29 | import { getRouter } from "../router"; | 30 | import { getRouter } from "../router"; |
| @@ -1248,7 +1249,7 @@ describe("ChatView timeline estimator parity (full app)", () => { · 1218 unmodified lines | |||
| 1248 | } | 1249 | } |
| 1249 | }); | 1250 | }); |
| 1250 | 1251 | ||
| 1251 | it("keeps backspaced terminal context pills removed when a new one is added", async () => { | 1252 | it("keeps removed terminal context pills removed when a new one is added", async () => { |
| 1252 | const removedLabel = "Terminal 1 lines 1-2"; | 1253 | const removedLabel = "Terminal 1 lines 1-2"; |
| 1253 | const addedLabel = "Terminal 2 lines 9-10"; | 1254 | const addedLabel = "Terminal 2 lines 9-10"; |
| 1254 | useComposerDraftStore.getState().addTerminalContext( | 1255 | useComposerDraftStore.getState().addTerminalContext( |
| @@ -1278,15 +1279,11 @@ describe("ChatView timeline estimator parity (full app)", () => { · 23 unmodified lines | |||
| 1278 | { timeout: 8_000, interval: 16 }, | 1279 | { timeout: 8_000, interval: 16 }, |
| 1279 | ); | 1280 | ); |
| 1280 | 1281 | ||
| 1281 | const composerEditor = await waitForComposerEditor(); | 1282 | const store = useComposerDraftStore.getState(); |
| 1282 | composerEditor.focus(); | 1283 | const currentPrompt = store.draftsByThreadId[THREAD_ID]?.prompt ?? ""; |
| 1283 | composerEditor.dispatchEvent( | 1284 | const nextPrompt = removeInlineTerminalContextPlaceholder(currentPrompt, 0); |
| 1284 | new KeyboardEvent("keydown", { | 1285 | store.setPrompt(THREAD_ID, nextPrompt.prompt); |
| 1285 | key: "Backspace", | 1286 | store.removeTerminalContext(THREAD_ID, "ctx-removed"); |
| 1286 | bubbles: true, | ||
| 1287 | cancelable: true, | ||
| 1288 | }), | ||
| 1289 | ); | ||
| 1290 | 1287 | ||
| 1291 | await vi.waitFor( | 1288 | await vi.waitFor( |
| 1292 | () => { | 1289 | () => { |
| @@ -1708,19 +1705,12 @@ describe("ChatView timeline estimator parity (full app)", () => { · 415 unmodified lines | |||
| 1708 | }); | 1705 | }); |
| 1709 | 1706 | ||
| 1710 | try { | 1707 | try { |
| 1711 | const useMetaForMod = isMacPlatform(navigator.platform); | 1708 | await waitForNewThreadShortcutLabel(); |
| 1712 | window.dispatchEvent( | 1709 | await waitForServerConfigToApply(); |
| 1713 | new KeyboardEvent("keydown", { | 1710 | const composerEditor = await waitForComposerEditor(); |
| 1714 | key: "o", | 1711 | composerEditor.focus(); |
| 1715 | shiftKey: true, | 1712 | await waitForLayout(); |
| 1716 | metaKey: useMetaForMod, | 1713 | await triggerChatNewShortcutUntilPath( |
| 1717 | ctrlKey: !useMetaForMod, | ||
| 1718 | bubbles: true, | ||
| 1719 | cancelable: true, | ||
| 1720 | }), | ||
| 1721 | ); | ||
| 1722 | |||
| 1723 | await waitForURL( | ||
| 1724 | mounted.router, | 1714 | mounted.router, |
| 1725 | (path) => UUID_ROUTE_RE.test(path), | 1715 | (path) => UUID_ROUTE_RE.test(path), |
| 1726 | "Route should have changed to a new draft thread UUID from the shortcut.", | 1716 | "Route should have changed to a new draft thread UUID from the shortcut.", |
| @@ -517,9 +517,11 @@ describe("composerDraftStore project draft thread mapping", () => { · 516 unmodified lines | |||
| 517 | it("clears draft registration independently", () => { | 517 | it("clears draft registration independently", () => { |
| 518 | const store = useComposerDraftStore.getState(); | 518 | const store = useComposerDraftStore.getState(); |
| 519 | store.setProjectDraftThreadId(projectId, threadId); | 519 | store.setProjectDraftThreadId(projectId, threadId); |
| 520 | store.setPrompt(threadId, "remove me"); | ||
| 520 | store.clearDraftThread(threadId); | 521 | store.clearDraftThread(threadId); |
| 521 | expect(useComposerDraftStore.getState().getDraftThreadByProjectId(projectId)).toBeNull(); | 522 | expect(useComposerDraftStore.getState().getDraftThreadByProjectId(projectId)).toBeNull(); |
| 522 | expect(useComposerDraftStore.getState().getDraftThread(threadId)).toBeNull(); | 523 | expect(useComposerDraftStore.getState().getDraftThread(threadId)).toBeNull(); |
| 524 | expect(useComposerDraftStore.getState().draftsByThreadId[threadId]).toBeUndefined(); | ||
| 523 | }); | 525 | }); |
| 524 | 526 | ||
| 525 | it("updates branch context on an existing draft thread", () => { | 527 | it("updates branch context on an existing draft thread", () => { |
| @@ -1194,7 +1194,8 @@ export const useComposerDraftStore = create<ComposerDraftStoreState>()( · 1193 unmodified lines | |||
| 1194 | const hasProjectMapping = Object.values(state.projectDraftThreadIdByProjectId).includes( | 1194 | const hasProjectMapping = Object.values(state.projectDraftThreadIdByProjectId).includes( |
| 1195 | threadId, | 1195 | threadId, |
| 1196 | ); | 1196 | ); |
| 1197 | if (!hasDraftThread && !hasProjectMapping) { | 1197 | const hasComposerDraft = state.draftsByThreadId[threadId] !== undefined; |
| 1198 | if (!hasDraftThread && !hasProjectMapping && !hasComposerDraft) { | ||
| 1198 | return state; | 1199 | return state; |
| 1199 | } | 1200 | } |
| 1200 | const nextProjectDraftThreadIdByProjectId = Object.fromEntries( | 1201 | const nextProjectDraftThreadIdByProjectId = Object.fromEntries( |
| @@ -1204,7 +1205,10 @@ export const useComposerDraftStore = create<ComposerDraftStoreState>()( · 3 unmodified lines | |||
| 1204 | ) as Record<ProjectId, ThreadId>; | 1205 | ) as Record<ProjectId, ThreadId>; |
| 1205 | const { [threadId]: _removedDraftThread, ...restDraftThreadsByThreadId } = | 1206 | const { [threadId]: _removedDraftThread, ...restDraftThreadsByThreadId } = |
| 1206 | state.draftThreadsByThreadId; | 1207 | state.draftThreadsByThreadId; |
| 1208 | const { [threadId]: _removedComposerDraft, ...restDraftsByThreadId } = | ||
| 1209 | state.draftsByThreadId; | ||
| 1207 | return { | 1210 | return { |
| 1211 | draftsByThreadId: restDraftsByThreadId, | ||
| 1208 | draftThreadsByThreadId: restDraftThreadsByThreadId, | 1212 | draftThreadsByThreadId: restDraftThreadsByThreadId, |
| 1209 | projectDraftThreadIdByProjectId: nextProjectDraftThreadIdByProjectId, | 1213 | projectDraftThreadIdByProjectId: nextProjectDraftThreadIdByProjectId, |
| 1210 | }; | 1214 | }; |