Skip to content

Commit 076bf8a

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 419faad commit 076bf8a

3 files changed

Lines changed: 35 additions & 8 deletions

File tree

apps/obsidian/src/components/ModifyNodeModal.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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,7 @@ export const ModifyNodeForm = ({
8384
const [selectedRelationshipKey, setSelectedRelationshipKey] = useState<
8485
string | undefined
8586
>(undefined);
87+
const [insertBacklink, setInsertBacklink] = useState(!!initialTitle);
8688
const queryEngine = useRef(new QueryEngine(plugin.app));
8789
const titleInputRef = useRef<HTMLTextAreaElement>(null);
8890
const popoverRef = useRef<HTMLDivElement>(null);
@@ -278,6 +280,7 @@ export const ModifyNodeForm = ({
278280
setSelectedExistingNode(file);
279281
setQuery(file.basename);
280282
setTitle(file.basename);
283+
setInsertBacklink(true);
281284
// Auto-detect node type from the selected file's frontmatter
282285
const nodeTypeId = await getNodeTypeIdForFile(plugin, file);
283286
if (nodeTypeId && selectedFileRef.current === file) {
@@ -291,12 +294,13 @@ export const ModifyNodeForm = ({
291294
const handleClearSelection = useCallback(() => {
292295
selectedFileRef.current = null;
293296
setSelectedExistingNode(null);
297+
setInsertBacklink(!!initialTitle);
294298
setQuery("");
295299
setTitle("");
296300
setTimeout(() => {
297301
titleInputRef.current?.focus();
298302
}, 50);
299-
}, []);
303+
}, [initialTitle]);
300304

301305
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
302306
if (selectedExistingNode) {
@@ -391,6 +395,7 @@ export const ModifyNodeForm = ({
391395
selectedExistingNode: selectedExistingNode || undefined,
392396
relationshipId: selectedRel?.uniqueKey || undefined,
393397
relationshipTargetFile: currentFile || undefined,
398+
insertBacklink,
394399
});
395400
onCancel();
396401
} catch (error) {
@@ -418,6 +423,7 @@ export const ModifyNodeForm = ({
418423
selectedRelationshipKey,
419424
currentFile,
420425
availableRelationships,
426+
insertBacklink,
421427
]);
422428

423429
return (
@@ -568,6 +574,20 @@ export const ModifyNodeForm = ({
568574
</div>
569575
)}
570576

577+
{!isEditMode && (
578+
<div className="setting-item">
579+
<div className="setting-item-name">Insert backlink</div>
580+
<div className="setting-item-control">
581+
<input
582+
type="checkbox"
583+
checked={insertBacklink}
584+
onChange={(e) => setInsertBacklink(e.target.checked)}
585+
disabled={isSubmitting}
586+
/>
587+
</div>
588+
</div>
589+
)}
590+
571591
<div className="modal-button-container mt-5 flex justify-end gap-2">
572592
<button
573593
type="button"
@@ -606,6 +626,7 @@ type ModifyNodeModalProps = {
606626
selectedExistingNode?: TFile;
607627
relationshipId?: string;
608628
relationshipTargetFile?: TFile;
629+
insertBacklink: boolean;
609630
}) => Promise<void>;
610631
initialTitle?: string;
611632
initialNodeType?: DiscourseNode;
@@ -622,6 +643,7 @@ class ModifyNodeModal extends Modal {
622643
selectedExistingNode?: TFile;
623644
relationshipId?: string;
624645
relationshipTargetFile?: TFile;
646+
insertBacklink: boolean;
625647
}) => Promise<void>;
626648
private root: Root | null = null;
627649
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/registerCommands.ts

Lines changed: 4 additions & 2 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,9 +35,10 @@ export const createModifyNodeModalSubmitHandler = (
3435
selectedExistingNode,
3536
relationshipId,
3637
relationshipTargetFile,
38+
insertBacklink,
3739
}: ModifyNodeSubmitParams) => {
3840
if (selectedExistingNode) {
39-
if (editor && editor.somethingSelected()) {
41+
if (insertBacklink && editor && editor.somethingSelected()) {
4042
editor?.replaceSelection(`[[${selectedExistingNode.basename}]]`);
4143
}
4244
await addRelationIfRequested(plugin, selectedExistingNode, {
@@ -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)