Skip to content

Commit 8f02648

Browse files
t3dotggNikitaMGrimmclaude
authored
fix(web): Working threads can be dragged into chat as references again (#19697)
Co-authored-by: Nikita Maximilian Grimm <github@nikitagrimm.de> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent ea97e8b commit 8f02648

3 files changed

Lines changed: 32 additions & 3 deletions

File tree

‎apps/web/src/components/Sidebar.logic.test.ts‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,6 +2242,33 @@ describe("Working shelf (beta)", () => {
22422242
expect(resolveSidebarDropVerb("active", "working")).toBeNull();
22432243
});
22442244

2245+
it.each([
2246+
["pinned", "p1"],
2247+
["active", "a2"],
2248+
["settled", "s1"],
2249+
] as const)(
2250+
"does not move a Working thread into %s when its reference drag ends in the sidebar",
2251+
(section, overKey) => {
2252+
const target = resolveSidebarDropTarget(items, "w1", overKey);
2253+
expect(target?.section).toBe(section);
2254+
expect(
2255+
planSidebarThreadDrop({
2256+
activeKey: "w1",
2257+
activeSection: "working",
2258+
target: target!,
2259+
pinnedOrder: ["p1"],
2260+
pinnedKeysById: new Map([["p1", "m"]]),
2261+
activeOrder: ["a1", "a2"],
2262+
activeKeysById: new Map([
2263+
["a1", "f"],
2264+
["a2", "t"],
2265+
]),
2266+
activeTimeOrdered: true,
2267+
}),
2268+
).toEqual({ kind: "none" });
2269+
},
2270+
);
2271+
22452272
it("arranges the rows it can write when another row's server cannot store an order", () => {
22462273
const plan = planSidebarThreadDrop({
22472274
activeKey: "a2",

‎apps/web/src/components/Sidebar.logic.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ export const animateSidebarLayoutChanges: AnimateLayoutChanges = (args) =>
115115

116116
// Snoozed rows can leave the shelf, but dropping into it is not supported
117117
// because snoozing requires a wake time. The Working shelf (beta) follows live
118-
// status, so it is neither a drag source nor a destination.
118+
// status, so its rows only drag out as chat context, never between sidebar
119+
// sections.
119120

120121
export type SidebarSection = "pinned" | "active" | "working" | "snoozed" | "settled";
121122

@@ -290,6 +291,7 @@ export function planSidebarThreadDrop(input: {
290291
activeKeysById,
291292
activeReorderableKeys,
292293
} = input;
294+
if (activeSection === "working") return { kind: "none" };
293295
if (input.supportsSettlement === false && (target.section === "settled" || activeSettled)) {
294296
return { kind: "none" };
295297
}

‎apps/web/src/components/Sidebar.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,7 +3314,8 @@ export default function Sidebar() {
33143314
listMotionRef.current?.update(false);
33153315
};
33163316

3317-
const isContextDrag = dragState?.contextDrag === true;
3317+
// Working rows can supply chat context, but never preview sidebar movement.
3318+
const isContextDrag = dragState?.contextDrag === true || dragState?.activeSection === "working";
33183319
const dragTargetSection = isContextDrag ? null : (dragState?.targetSection ?? null);
33193320
const finishThreadDrag = (started: boolean) => {
33203321
dragSensorRef.current = null;
@@ -4799,7 +4800,6 @@ export default function Sidebar() {
47994800
contextDrag={isContextDrag}
48004801
sortableDisabled={
48014802
renamingThreadKey === threadKey ||
4802-
section === "working" ||
48034803
!draggableThreadKeys.has(threadKey) ||
48044804
optimisticDrop !== null
48054805
}

0 commit comments

Comments
 (0)