From 49140883156f265f4ca64cce12d32459434fe4ae Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 19 Jun 2026 16:58:39 +0000 Subject: [PATCH 1/2] Remove legacy anchor-backed discourse node type support - Remove anchor-backed discourse node creation from getDiscourseNodes - Remove anchor selection logic from getDiscourseContextResults - Preserve existing context selection behavior This removes unused legacy functionality where relations with 'anchor' in their triples would generate discourse nodes. Per the issue, this feature is no longer used and has no place to surface in the current discourse context UI. --- .../src/utils/getDiscourseContextResults.ts | 6 - apps/roam/src/utils/getDiscourseNodes.ts | 121 +++++++----------- 2 files changed, 46 insertions(+), 81 deletions(-) diff --git a/apps/roam/src/utils/getDiscourseContextResults.ts b/apps/roam/src/utils/getDiscourseContextResults.ts index 179c7ee2b..fc42934ce 100644 --- a/apps/roam/src/utils/getDiscourseContextResults.ts +++ b/apps/roam/src/utils/getDiscourseContextResults.ts @@ -50,12 +50,6 @@ const buildSelections = ({ label: "context", text: `node:${conditionUid}-Context`, }); - } else if (r.triples.some((t) => t.some((a) => /anchor/i.test(a)))) { - selections.push({ - uid: window.roamAlphaAPI.util.generateUID(), - label: "anchor", - text: `node:${conditionUid}-Anchor`, - }); } return selections; diff --git a/apps/roam/src/utils/getDiscourseNodes.ts b/apps/roam/src/utils/getDiscourseNodes.ts index 765d12422..537d5522b 100644 --- a/apps/roam/src/utils/getDiscourseNodes.ts +++ b/apps/roam/src/utils/getDiscourseNodes.ts @@ -115,83 +115,54 @@ const getDiscourseNodes = ( const newStoreEnabled = snapshot ? snapshot.featureFlags["Use new settings store"] : isNewSettingsStoreEnabled(); - const configuredNodes = ( - newStoreEnabled - ? getAllDiscourseNodes() - : Object.entries(discourseConfigRef.nodes).map( - ([type, { text, children }]): DiscourseNode => { - const suggestiveRules = getSubTree({ - tree: children, - key: "Suggestive Rules", - }); - const embeddingBlockRef = getSubTree({ - tree: suggestiveRules.children, - key: "Embedding Block Ref", - }); + const configuredNodes = newStoreEnabled + ? getAllDiscourseNodes() + : Object.entries(discourseConfigRef.nodes).map( + ([type, { text, children }]): DiscourseNode => { + const suggestiveRules = getSubTree({ + tree: children, + key: "Suggestive Rules", + }); + const embeddingBlockRef = getSubTree({ + tree: suggestiveRules.children, + key: "Embedding Block Ref", + }); - return { - format: getSettingValueFromTree({ - tree: children, - key: "format", - }), - text, - shortcut: getSettingValueFromTree({ - tree: children, - key: "shortcut", - }), - tag: getSettingValueFromTree({ tree: children, key: "tag" }), - type, - specification: getSpecification(children), - backedBy: "user", - canvasSettings: Object.fromEntries( - getSubTree({ tree: children, key: "canvas" }).children.map( - (c) => [c.text, c.children[0]?.text || ""] as const, - ), + return { + format: getSettingValueFromTree({ + tree: children, + key: "format", + }), + text, + shortcut: getSettingValueFromTree({ + tree: children, + key: "shortcut", + }), + tag: getSettingValueFromTree({ tree: children, key: "tag" }), + type, + specification: getSpecification(children), + backedBy: "user", + canvasSettings: Object.fromEntries( + getSubTree({ tree: children, key: "canvas" }).children.map( + (c) => [c.text, c.children[0]?.text || ""] as const, ), - graphOverview: - children.filter((c) => c.text === "Graph Overview").length > 0, - description: getSettingValueFromTree({ - tree: children, - key: "description", - }), - template: getSubTree({ tree: children, key: "template" }) - .children, - embeddingRef: embeddingBlockRef?.children?.[0]?.text, - embeddingRefUid: embeddingBlockRef?.uid, - isFirstChild: getUidAndBooleanSetting({ - tree: suggestiveRules.children, - text: "First Child", - }), - }; - }, - ) - ).concat( - resolvedRelations - .filter((r) => r.triples.some((t) => t.some((n) => /anchor/i.test(n)))) - .map((r) => ({ - format: "", - text: r.label, - type: r.id, - shortcut: r.label.slice(0, 1), - tag: "", - specification: r.triples.map(([source, relation, target]) => ({ - type: "clause", - source: /anchor/i.test(source) ? r.label : source, - relation, - target: - target === "source" - ? r.source - : target === "destination" - ? r.destination - : /anchor/i.test(target) - ? r.label - : target, - uid: window.roamAlphaAPI.util.generateUID(), - })), - backedBy: "relation", - canvasSettings: {}, - })), - ); + ), + graphOverview: + children.filter((c) => c.text === "Graph Overview").length > 0, + description: getSettingValueFromTree({ + tree: children, + key: "description", + }), + template: getSubTree({ tree: children, key: "template" }).children, + embeddingRef: embeddingBlockRef?.children?.[0]?.text, + embeddingRefUid: embeddingBlockRef?.uid, + isFirstChild: getUidAndBooleanSetting({ + tree: suggestiveRules.children, + text: "First Child", + }), + }; + }, + ); const configuredNodeTexts = new Set(configuredNodes.map((n) => n.text)); const defaultNodes = DEFAULT_NODES.filter( (n) => !configuredNodeTexts.has(n.text), From 62de57d3b680637bc3960fa897424f75240b6834 Mon Sep 17 00:00:00 2001 From: Michael Gartner Date: Sun, 21 Jun 2026 23:13:46 -0600 Subject: [PATCH 2/2] Refactor getDiscourseNodes to remove legacy relations parameter - Updated getDiscourseNodes to only accept settingsSnapshot, removing the relations parameter. - Adjusted multiple components and utility functions to align with the new getDiscourseNodes signature. - Ensured consistent behavior across the application by standardizing how discourse nodes are retrieved. --- apps/roam/src/components/DiscourseContext.tsx | 212 +----------------- .../components/DiscourseContextOverlay.tsx | 2 +- .../roam/src/components/DiscourseNodeMenu.tsx | 4 +- apps/roam/src/components/Export.tsx | 2 +- apps/roam/src/components/SuggestionsBody.tsx | 2 +- apps/roam/src/components/canvas/Tldraw.tsx | 4 +- .../src/utils/deriveDiscourseNodeAttribute.ts | 2 +- apps/roam/src/utils/findDiscourseNode.ts | 2 +- .../src/utils/getDiscourseContextResults.ts | 2 +- apps/roam/src/utils/getDiscourseNodes.ts | 9 +- apps/roam/src/utils/getExportTypes.ts | 2 +- apps/roam/src/utils/getRelationData.ts | 2 +- .../src/utils/initializeDiscourseNodes.ts | 4 +- .../utils/initializeObserversAndListeners.ts | 6 +- .../roam/src/utils/pageRefObserverHandlers.ts | 5 +- .../registerDiscourseDatalogTranslators.ts | 2 +- 16 files changed, 27 insertions(+), 235 deletions(-) diff --git a/apps/roam/src/components/DiscourseContext.tsx b/apps/roam/src/components/DiscourseContext.tsx index fa4a213f9..8cef59811 100644 --- a/apps/roam/src/components/DiscourseContext.tsx +++ b/apps/roam/src/components/DiscourseContext.tsx @@ -1,24 +1,6 @@ -import { - Button, - Icon, - Portal, - Switch, - Tabs, - Tab, - Tooltip, - Spinner, -} from "@blueprintjs/core"; -import React, { - useCallback, - useEffect, - useMemo, - useState, - useRef, -} from "react"; -import getPageTitleByPageUid from "roamjs-components/queries/getPageTitleByPageUid"; -import getShallowTreeByParentUid from "roamjs-components/queries/getShallowTreeByParentUid"; +import { Switch, Tabs, Tab, Spinner } from "@blueprintjs/core"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import { Result } from "roamjs-components/types/query-builder"; -import nanoId from "nanoid"; import getDiscourseContextResults from "~/utils/getDiscourseContextResults"; import ResultsView from "./results-view/ResultsView"; import posthog from "posthog-js"; @@ -34,188 +16,12 @@ type Props = { overlayRefresh?: () => void; }; -const ExtraColumnRow = (r: Result) => { - const [contextOpen, setContextOpen] = useState(false); - const [contextRowReady, setContextRowReady] = useState(false); - const contextId = useMemo(() => `td-${nanoId()}`, []); - const anchorId = useMemo(() => `td-${nanoId()}`, []); - const [anchorOpen, setAnchorOpen] = useState(false); - const [anchorRowReady, setAnchorRowReady] = useState(false); - const containerRef = useRef(null); - const contextPageTitle = useMemo( - () => - r["context-uid"] && getPageTitleByPageUid(r["context-uid"].toString()), - [r["context-uid"]], - ); - const contextBreadCrumbs = useMemo( - () => - r["context-uid"] - ? window.roamAlphaAPI - .q( - `[:find (pull ?p [:node/title :block/string :block/uid]) :where - [?b :block/uid "${r["context-uid"]}"] - [?b :block/parents ?p] - ]`, - ) - .map( - (a) => a[0] as { string?: string; title?: string; uid: string }, - ) - .map((a) => ({ uid: a.uid, text: a.string || a.title || "" })) - : [], - [r["context-uid"]], - ); - const contextChildren = useMemo( - () => - r["context-uid"] && contextPageTitle - ? getShallowTreeByParentUid(r["context-uid"].toString()).map( - ({ uid }) => uid, - ) - : [r["context-uid"].toString()], - [r["context-uid"], contextPageTitle, r.uid], - ); - useEffect(() => { - if (contextOpen && containerRef.current) { - const row = containerRef.current.closest("tr"); - const contextElement = document.createElement("tr"); - const contextTd = document.createElement("td"); - contextTd.colSpan = row?.childElementCount || 0; - contextElement.id = contextId; - row?.parentElement?.insertBefore(contextElement, row.nextElementSibling); - contextElement.append(contextTd); - setContextRowReady(true); - } else { - setContextRowReady(false); - document.getElementById(contextId)?.remove(); - } - }, [contextOpen, setContextRowReady, contextId]); - useEffect(() => { - if (contextRowReady) { - setTimeout(() => { - contextChildren.forEach((uid) => { - const el = document.querySelector( - `tr#${contextId} div[data-uid="${uid}"]`, - ); - if (el) - window.roamAlphaAPI.ui.components.renderBlock({ - uid, - el, - }); - }); - }, 1); - } - }, [contextRowReady]); - useEffect(() => { - if (anchorOpen) { - const row = containerRef.current?.closest("tr"); - const anchorElement = document.createElement("tr"); - const anchorTd = document.createElement("td"); - anchorTd.colSpan = row?.childElementCount || 0; - anchorElement.id = anchorId; - row?.parentElement?.insertBefore(anchorElement, row.nextElementSibling); - anchorElement.append(anchorTd); - setAnchorRowReady(true); - } else { - setAnchorRowReady(false); - document.getElementById(anchorId)?.remove(); - } - }, [anchorOpen, setAnchorRowReady, anchorId]); - return ( - - {r["context-uid"] && ( - -