authorgravatar for 118054752+extoci@users.noreply.github.comExotic <118054752+extoci@users.noreply.github.com> 2026-09-07 18:29:02+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-07 10:29:02-05:00
logfe07ffe7c0bf1858ba4d1cd1ce0a67b10802a747
tree04b6c8e11fa6fa1dfe7d1aa3142348e738b6223d
parent8b2838e0e8a73d3fa6476940445c372e47b99db4
signature Signed by PGP key B5690EEEBB952194

fix(web): remove inserted citations on cancel (#10518)


2 files changed, 19 insertions(+), 7 deletions(-)

apps/web/src/components/ComposerCitationNode.tsx+11-6
......@@ -42,6 +42,7 @@ export type ComposerCitationCommentRequest = {
4242export type ComposerCitationCommentTarget = {
4343 nodeKey: NodeKey;
4444 sourceAnchor?: AssistantCitationSourceAnchor;
45 removeOnCancel?: boolean;
4546};
4647
4748export const ComposerCitationCommentContext = createContext<{
......@@ -68,7 +69,11 @@ export function $consumeComposerCitationCommentRequest(requestRef: {
6869 let offset = 0;
6970 for (const node of paragraph.getChildren()) {
7071 if (offset === request.citationStart && node instanceof ComposerCitationNode) {
71 return { nodeKey: node.getKey(), sourceAnchor: request.sourceAnchor };
72 return {
73 nodeKey: node.getKey(),
74 sourceAnchor: request.sourceAnchor,
75 removeOnCancel: true,
76 };
7277 }
7378 offset += node.getTextContentSize();
7479 }
......@@ -78,6 +83,8 @@ export function $consumeComposerCitationCommentRequest(requestRef: {
7883function ComposerCitationDecorator(props: { citation: AssistantCitation; nodeKey: NodeKey }) {
7984 const [editor] = useLexicalComposerContext();
8085 const commentContext = use(ComposerCitationCommentContext);
86 const commentTarget =
87 commentContext.openComment?.nodeKey === props.nodeKey ? commentContext.openComment : null;
8188 const onSaveComment = (comment: string): boolean => {
8289 if (!editor.isEditable()) return false;
8390 let accepted = false;
......@@ -118,15 +125,13 @@ function ComposerCitationDecorator(props: { citation: AssistantCitation; nodeKey
118125 <AssistantCitationChip
119126 citation={props.citation}
120127 commentEditor={{
121 open: commentContext.openComment?.nodeKey === props.nodeKey,
122 sourceAnchor:
123 commentContext.openComment?.nodeKey === props.nodeKey
124 ? commentContext.openComment.sourceAnchor
125 : undefined,
128 open: commentTarget !== null,
129 sourceAnchor: commentTarget?.sourceAnchor,
126130 onOpenChange: (open) => {
127131 if (open && !editor.isEditable()) return;
128132 commentContext.onOpenChange(props.nodeKey, open);
129133 },
134 ...(commentTarget?.removeOnCancel ? { onCancel: onRemove } : {}),
130135 onSave: onSaveComment,
131136 onSaveAndSend: (comment) => {
132137 if (!onSaveComment(comment)) return false;
apps/web/src/components/chat/AssistantCitationChip.tsx+8-1
......@@ -41,6 +41,7 @@ export function AssistantCitationChip({
4141 open: boolean;
4242 sourceAnchor?: AssistantCitationSourceAnchor | undefined;
4343 onOpenChange: (open: boolean) => void;
44 onCancel?: () => void;
4445 onSave: (comment: string) => boolean;
4546 onSaveAndSend?: (comment: string) => boolean;
4647 };
......@@ -168,7 +169,13 @@ export function AssistantCitationChip({
168169 },
169170 }
170171 : {})}
171 onCancel={() => commentEditor.onOpenChange(false)}
172 onCancel={() => {
173 if (commentEditor.onCancel) {
174 commentEditor.onCancel();
175 } else {
176 commentEditor.onOpenChange(false);
177 }
178 }}
172179 />
173180 </PopoverPopup>
174181 ) : null}