Skip to content

Commit 98af9b1

Browse files
trangdoan982claude
andcommitted
ENG-1693 Add insert backlink checkbox to ModifyNodeModal with smart defaults
- Add "Insert backlink" checkbox to ModifyNodeModal (create mode only) - Default true when pre-filled text exists (user had text selected) or existing node is chosen; false otherwise - Gate backlink insertion in canvas flow and editor command flow on checkbox value Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3b34820 commit 98af9b1

4 files changed

Lines changed: 40 additions & 11 deletions

File tree

apps/obsidian/src/components/ModifyNodeModal.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { App, Modal, Notice, TFile } from "obsidian";
1+
import { App, MarkdownView, Modal, Notice, TFile } from "obsidian";
22
import { createRoot, Root } from "react-dom/client";
33
import {
44
StrictMode,
@@ -49,6 +49,7 @@ type ModifyNodeFormProps = {
4949
/** DiscourseRelation.id; when set, relation is created with currentFile as the other end. */
5050
relationshipId?: string;
5151
relationshipTargetFile?: TFile;
52+
insertBacklink: boolean;
5253
}) => Promise<void>;
5354
onCancel: () => void;
5455
initialTitle?: string;
@@ -83,6 +84,9 @@ export const ModifyNodeForm = ({
8384
const [selectedRelationshipKey, setSelectedRelationshipKey] = useState<
8485
string | undefined
8586
>(undefined);
87+
const hasEditorContext =
88+
plugin.app.workspace.activeLeaf?.view instanceof MarkdownView;
89+
const [insertBacklink, setInsertBacklink] = useState(!!initialTitle);
8690
const queryEngine = useRef(new QueryEngine(plugin.app));
8791
const titleInputRef = useRef<HTMLTextAreaElement>(null);
8892
const popoverRef = useRef<HTMLDivElement>(null);
@@ -278,6 +282,7 @@ export const ModifyNodeForm = ({
278282
setSelectedExistingNode(file);
279283
setQuery(file.basename);
280284
setTitle(file.basename);
285+
setInsertBacklink(true);
281286
// Auto-detect node type from the selected file's frontmatter
282287
const nodeTypeId = await getNodeTypeIdForFile(plugin, file);
283288
if (nodeTypeId && selectedFileRef.current === file) {
@@ -291,12 +296,13 @@ export const ModifyNodeForm = ({
291296
const handleClearSelection = useCallback(() => {
292297
selectedFileRef.current = null;
293298
setSelectedExistingNode(null);
299+
setInsertBacklink(!!initialTitle);
294300
setQuery("");
295301
setTitle("");
296302
setTimeout(() => {
297303
titleInputRef.current?.focus();
298304
}, 50);
299-
}, []);
305+
}, [initialTitle]);
300306

301307
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
302308
if (selectedExistingNode) {
@@ -391,6 +397,7 @@ export const ModifyNodeForm = ({
391397
selectedExistingNode: selectedExistingNode || undefined,
392398
relationshipId: selectedRel?.uniqueKey || undefined,
393399
relationshipTargetFile: currentFile || undefined,
400+
insertBacklink,
394401
});
395402
onCancel();
396403
} catch (error) {
@@ -418,6 +425,7 @@ export const ModifyNodeForm = ({
418425
selectedRelationshipKey,
419426
currentFile,
420427
availableRelationships,
428+
insertBacklink,
421429
]);
422430

423431
return (
@@ -568,6 +576,20 @@ export const ModifyNodeForm = ({
568576
</div>
569577
)}
570578

579+
{!isEditMode && hasEditorContext && (
580+
<div className="setting-item">
581+
<div className="setting-item-name">Insert backlink</div>
582+
<div className="setting-item-control">
583+
<input
584+
type="checkbox"
585+
checked={insertBacklink}
586+
onChange={(e) => setInsertBacklink(e.target.checked)}
587+
disabled={isSubmitting}
588+
/>
589+
</div>
590+
</div>
591+
)}
592+
571593
<div className="modal-button-container mt-5 flex justify-end gap-2">
572594
<button
573595
type="button"
@@ -606,6 +628,7 @@ type ModifyNodeModalProps = {
606628
selectedExistingNode?: TFile;
607629
relationshipId?: string;
608630
relationshipTargetFile?: TFile;
631+
insertBacklink: boolean;
609632
}) => Promise<void>;
610633
initialTitle?: string;
611634
initialNodeType?: DiscourseNode;
@@ -622,6 +645,7 @@ class ModifyNodeModal extends Modal {
622645
selectedExistingNode?: TFile;
623646
relationshipId?: string;
624647
relationshipTargetFile?: TFile;
648+
insertBacklink: boolean;
625649
}) => Promise<void>;
626650
private root: Root | null = null;
627651
private initialTitle?: string;

apps/obsidian/src/components/canvas/utils/nodeCreationFlow.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const openCreateDiscourseNodeAt = (args: CreateNodeAtArgs): void => {
3232
selectedExistingNode,
3333
relationshipId,
3434
relationshipTargetFile,
35+
insertBacklink,
3536
}) => {
3637
try {
3738
// If user selected an existing node, use it instead of creating a new one
@@ -54,11 +55,13 @@ export const openCreateDiscourseNodeAt = (args: CreateNodeAtArgs): void => {
5455
});
5556
}
5657

57-
const src = await addWikilinkBlockrefForFile({
58-
app: plugin.app,
59-
canvasFile,
60-
linkedFile: fileToUse,
61-
});
58+
const src = insertBacklink
59+
? await addWikilinkBlockrefForFile({
60+
app: plugin.app,
61+
canvasFile,
62+
linkedFile: fileToUse,
63+
})
64+
: undefined;
6265

6366
let preloadedImageSrc: string | undefined = undefined;
6467
if (selectedNodeType.keyImage) {

apps/obsidian/src/utils/createNode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ export const createDiscourseNode = async ({
134134
nodeType,
135135
});
136136

137-
if (newFile && editor && editor.somethingSelected()) {
137+
if (newFile && editor) {
138138
editor.replaceSelection(`[[${formattedNodeName}]]`);
139139
}
140140

apps/obsidian/src/utils/registerCommands.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type ModifyNodeSubmitParams = {
2222
selectedExistingNode?: TFile;
2323
relationshipId?: string;
2424
relationshipTargetFile?: TFile;
25+
insertBacklink: boolean;
2526
};
2627

2728
export const createModifyNodeModalSubmitHandler = (
@@ -34,10 +35,11 @@ export const createModifyNodeModalSubmitHandler = (
3435
selectedExistingNode,
3536
relationshipId,
3637
relationshipTargetFile,
38+
insertBacklink,
3739
}: ModifyNodeSubmitParams) => {
3840
if (selectedExistingNode) {
39-
if (editor && editor.somethingSelected()) {
40-
editor?.replaceSelection(`[[${selectedExistingNode.basename}]]`);
41+
if (insertBacklink && editor) {
42+
editor.replaceSelection(`[[${selectedExistingNode.basename}]]`);
4143
}
4244
await addRelationIfRequested(plugin, selectedExistingNode, {
4345
relationshipId,
@@ -48,7 +50,7 @@ export const createModifyNodeModalSubmitHandler = (
4850
plugin,
4951
nodeType,
5052
text: title,
51-
editor,
53+
editor: insertBacklink ? editor : undefined,
5254
});
5355
if (newFile) {
5456
await addRelationIfRequested(plugin, newFile, {

0 commit comments

Comments
 (0)