Conversation
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
| export const QuerySettingsSchema = z.object({ | ||
| "Hide query metadata": z.boolean().default(false), | ||
| "Hide query metadata": z.boolean().default(true), | ||
| "Default page size": z.number().default(10), | ||
| "Query pages": z.array(z.string()).default([]), | ||
| "Query pages": z.array(z.string()).default(["discourse-graph/queries/*"]), |
There was a problem hiding this comment.
🟡 Changed QuerySettingsSchema defaults corrupt legacy-path fallbacks
The QuerySettingsSchema defaults were changed ("Hide query metadata" from false → true, "Query pages" from [] → ["discourse-graph/queries/*"]). These new defaults propagate into DEFAULT_PERSONAL_SETTINGS (computed at module load via PersonalSettingsSchema.parse({}) at accessors.ts:165), which is then used as the fallback value in getLegacyPersonalSetting().
Root cause and impact
In getLegacyPersonalSetting (accessors.ts:212-251), when a mapped key is found, the fallback default is read from DEFAULT_PERSONAL_SETTINGS:
return getSetting<unknown>(
mappedOldKey,
readPathValue(DEFAULT_PERSONAL_SETTINGS, keys),
);For keys = ["Query", "Hide query metadata"], this resolves to getSetting("hide-metadata", true). If the user has never explicitly set this value, getSetting returns true (the new default) instead of false (the old default). The intent of the legacy path is backward compatibility with the old system, but the fallback now returns different values than the old system provided.
Concretely:
- Users who never explicitly set "Hide query metadata" will see query metadata hidden when it was previously shown.
- Users who never explicitly set "Query pages" will get
["discourse-graph/queries/*"]instead of[].
The getters aren't called yet (being built in this PR), but when they are wired up, the legacy path will silently change behavior for users who haven't explicitly configured these settings.
Was this helpful? React with 👍 or 👎 to provide feedback.
| getGlobalSetting<boolean>([ | ||
| "Suggestive mode", | ||
| "Include current page relations", | ||
| ]) ?? false; | ||
| const shouldGrabParentChildContext = | ||
| (extensionAPI.settings.get( | ||
| "context-grab-parent-child-context", | ||
| ) as boolean) ?? true; | ||
| getGlobalSetting<boolean>([ | ||
| "Suggestive mode", | ||
| "Include parent and child blocks", | ||
| ]) ?? false; |
There was a problem hiding this comment.
🔴 Hyde search defaults changed from true to false, degrading suggestive mode search quality
In hyde.ts, the old code read shouldGrabFromReferencedPages and shouldGrabParentChildContext from phantom extensionAPI keys (context-grab-from-referenced-pages, context-grab-parent-child-context) that were never written anywhere in the codebase. Since the keys never existed, extensionAPI.settings.get(...) always returned undefined, and the ?? true fallback ensured both flags were always true. The new code reads from the global accessor with a ?? false fallback. The schema defaults for "Include current page relations" and "Include parent and child blocks" are also false. This means for users who never explicitly configured these settings (which is everyone, since the UI writes to different keys), the behavior silently changes from always including referenced pages and parent/child blocks in the search to never including them. This degrades suggestive mode hyde search results.
Was this helpful? React with 👍 or 👎 to provide feedback.
* ENG-1454: Enable dual read feature flag * add caller * resolve merge conflicts * review * example fix * review
* ENG-1455: Dual-read from old-system settings and from blockprops * remove console.logs * address review * prettier * add comment describing why we do it like this * reviewed * rebase, review * address review * explicit throw, now zodschema default reads * replace throw with warn, throw was too strong, with warn we test if legacy and block props are same
…ult reads (#813) * ENG-1472: Refactor BlockPropSettingPanels to add accessor-backed default reads (with initialValue fallback) * review, fix
* ENG-1473: Rebase onto updated eng-1472, resolve conflicts and fix missing import * ENG-1473: Review fixes — remove dead extensionAPI params, fix type casts * ENG-1473: Fix restrict-template-expressions warnings in query utils * rename persistQueryPages → setQueryPages, setQueryPages → setInitialQueryPages * restore legacy type coercion for query-pages
* ENG-1467: Port global setting consumer reads (→ getGlobalSetting) * prettier * rebase onto updated eng-1472, resolve conflicts and fix tsc
* ENG-1479: Port suggestive mode settings to dual-read Add dual-read routing to getFeatureFlag for flags with legacy counterparts. FEATURE_FLAG_LEGACY_MAP maps "Suggestive mode enabled" and "Enable left sidebar" to their config tree reads, gated by isNewSettingsStoreEnabled(). Flags without legacy entries go straight to block props (no behavior change). Migrate value reads from getFormattedConfigTree() / extensionAPI.settings to accessors: - index.ts: getUidAndBooleanSetting → getFeatureFlag (accessor handles legacy fallback now) - AdminPanel: suggestiveModeEnabled.value → getFeatureFlag in both FeatureFlagsTab and main component. Removed unused useMemo. - SuggestiveModeSettings: includePageRelations state init → getGlobalSetting. Dropped initialValue from both GlobalFlagPanels. - hyde.ts: orphan extensionAPI.settings.get() reads → getGlobalSetting. Fixes bug where sync config toggles had no runtime effect (keys were never written by any code). Structural UIDs remain with getFormattedConfigTree(). pageGroups.groups NOT migrated — type mismatch (legacy PageGroup has UIDs, Zod PageGroup does not). Deferred to ENG-1470. * Align hyde.ts fallback defaults with Zod schema * Fix eslint naming-convention warnings in FEATURE_FLAG_LEGACY_MAP * Add TODO(ENG-1484) for suggestive mode reactivity
* Rebase ENG-1468 onto eng-1472 (fresh redo) * Remove unnecessary lazy initializer from complement useState * Break circular dep: inline DISCOURSE_CONFIG_PAGE_TITLE * Address review: case-insensitive attribute lookup, empty-string fallback, move DISCOURSE_CONFIG_PAGE_TITLE to data/constants
…er-based reactivity - Extract mergeGlobalSectionWithAccessor/mergePersonalSectionsWithAccessor to getLeftSidebarSettings.ts (used by LeftSidebarView, GlobalSettings, PersonalSettings) - Settings panels now actually use accessor values (not fire-and-forget) - Replace setLeftSidebarFlagHandler with settingsEmitter pub/sub - useConfig subscribes to emitter instead of old subscribe() - Wire up global/personal/flag handlers in pullWatchers to emit - Remove dead newValue===oldValue guard (hasPropChanged already checks) - Remove dead ?./?? in personal merge (Zod defaults guarantee values)
toggleFoldedState mutates folded.uid in-place then dual-writes to block props, triggering pull watch → emitter → buildConfig(). Without refreshConfigTree(), buildConfig() reads stale UIDs from the cached tree, overwriting the in-place mutation and orphaning Roam blocks.
21b6000 to
3b4c80a
Compare
…on personal panels
…d from block props
initSingleDiscourseNode was writing backedBy: "default" which caused nodes to be filtered out of the settings panel when the flag is ON. Also fixes up existing graphs that already stored the wrong value.
…l-and-personal-left-sidebar-to-dual-readers-v2 ENG-1478: Port left sidebar to dual-readers + reactivity
…courserelations-and-getdiscoursenodes-to-read ENG-1469: Refactor getDiscourseRelations and getDiscourseNodes to read from block props
…m settingKeys.ts Replaces all raw string literals used as block-prop accessor paths in consumer files with typed constants from settingKeys.ts. Adds TEMPLATE_SETTING_KEYS constant and tightens KeyboardShortcutInput blockPropKey prop from string to keyof PersonalSettings.
…blockprop-key-pairs-to-shared-constant-or ENG-1499: Convert legacy-blockprop key pairs to shared constant or typed key
…-of-getformattedconfigtree ENG-1503: Replace getFormattedConfigTree consumers with direct helper calls
…cy-to-blockprops-migration
…props-migration ENG-1519: Add legacy-to-blockprops migration, remove backedBy from schemea
…ettings-pages ENG-735: Remove inline settings UI from config pages
There was a problem hiding this comment.
🟡 Inverted fold/unfold logic: isOpen state and block CRUD are backwards
In toggleFoldedState, when isOpen is true (section is currently open/expanded), the code calls setIsOpen(false) and deletes the "Folded" block — meaning it unfolds by removing the folded marker. But when isOpen is false, it calls setIsOpen(true) and creates a "Folded" block. This means the isOpen React state tracks whether the section is collapsed (folded), not whether it is open. The newFolded value at LeftSidebarView.tsx:130 is computed as !isOpen, so when isOpen=true (collapsed/folded), newFolded=false — and this is the value written to the new settings store. However, the old-system block CRUD on lines 132-148 does the opposite: when isOpen=true it deletes the Folded block (setting folded=false), and when isOpen=false it creates the Folded block (setting folded=true). So both systems agree on the final folded value.
The actual bug is that the newFolded value written to the new settings store at lines 150-166 is !isOpen, but the old-system block operations establish that isOpen=true means "currently folded" (since the Folded block exists). When the section is currently folded (isOpen=true), newFolded = !true = false → correct (we're unfolding). When the section is currently expanded (isOpen=false), newFolded = !false = true → correct (we're folding). So the value is actually correct.
However, looking at PersonalSectionItem at line 223, isOpen is initialized from !!section.settings?.folded.value, meaning isOpen=true when folded=true. This means isOpen actually represents "is folded", not "is open". The Collapse isOpen={isOpen} at line 262 will then show content when folded=true and hide content when folded=false — which is the opposite of expected behavior. The section is shown expanded when the folded flag is true, and collapsed when it's false.
(Refers to lines 223-224)
Was this helpful? React with 👍 or 👎 to provide feedback.
…nch' into eng-1484-reactive-settings-some-settings-require-reloading-the-graph # Conflicts: # apps/roam/src/index.ts # apps/roam/src/utils/initializeObserversAndListeners.ts
…gs-some-settings-require-reloading-the-graph ENG-1484: reactive settings for triggers and suggestive mode overlay
| const getLegacyRelationsSetting = (): Record<string, unknown> => { | ||
| const settingsUid = getPageUidByPageTitle(DG_BLOCK_PROP_SETTINGS_PAGE_TITLE); | ||
| if (!settingsUid) return DEFAULT_GLOBAL_SETTINGS.Relations; | ||
|
|
||
| const configTree = getBasicTreeByParentUid(settingsUid); | ||
| const grammarChildren = getSubTree({ | ||
| tree: configTree, | ||
| key: "grammar", | ||
| }).children; | ||
| const relationNodes = getSubTree({ | ||
| tree: grammarChildren, | ||
| key: "relations", | ||
| }).children; | ||
| if (relationNodes.length === 0) return DEFAULT_GLOBAL_SETTINGS.Relations; |
There was a problem hiding this comment.
🔴 getLegacyRelationsSetting reads relations from the block-props settings page instead of the legacy config page
getLegacyRelationsSetting at apps/roam/src/components/settings/utils/accessors.ts:284 reads a grammar > relations subtree from DG_BLOCK_PROP_SETTINGS_PAGE_TITLE (the new block-props settings page). However, the legacy grammar/relations tree actually lives on DISCOURSE_CONFIG_PAGE_TITLE ("roam/js/discourse-graph"), as shown by getDiscourseRelations.ts reading from discourseConfigRef.tree. Since the block-props settings page has no grammar subtree, getSubTree returns empty children, relationNodes is empty, and the function falls back to DEFAULT_GLOBAL_SETTINGS.Relations.
This causes two downstream problems:
- Migration data loss:
migrateGraphLevel→readAllLegacyGlobalSettings()→getLegacyGlobalSetting(["Relations"])reads defaults instead of actual legacy relations, then overwrites correctly-initialized block props (init.ts+reconcileRelationKeys) with those defaults. - Spurious dual-read warnings: When
isNewSettingsStoreEnabled()is true,getGlobalSetting(["Relations", ...])compares block-props values against defaults (not actual legacy data), generating incorrect mismatch warnings.
Expected fix
Read from `discourseConfigRef.tree` (or `DISCOURSE_CONFIG_PAGE_TITLE`) instead of `DG_BLOCK_PROP_SETTINGS_PAGE_TITLE`:const getLegacyRelationsSetting = (): Record<string, unknown> => {
const tree = discourseConfigRef.tree;
const grammarChildren = getSubTree({ tree, key: "grammar" }).children;
const relationNodes = getSubTree({ tree: grammarChildren, key: "relations" }).children;
...
};
Prompt for agents
In apps/roam/src/components/settings/utils/accessors.ts, the function getLegacyRelationsSetting (starting around line 283) reads from DG_BLOCK_PROP_SETTINGS_PAGE_TITLE, which is the new block-props settings page. It should instead read from the legacy discourse config tree where the grammar/relations data actually lives.
Change:
const settingsUid = getPageUidByPageTitle(DG_BLOCK_PROP_SETTINGS_PAGE_TITLE);
if (!settingsUid) return DEFAULT_GLOBAL_SETTINGS.Relations;
const configTree = getBasicTreeByParentUid(settingsUid);
To:
const configTree = discourseConfigRef.tree;
if (!configTree || configTree.length === 0) return DEFAULT_GLOBAL_SETTINGS.Relations;
This ensures the legacy relations are read from 'roam/js/discourse-graph' (via discourseConfigRef.tree) where they are actually stored, matching how getDiscourseRelations.ts reads them.
Was this helpful? React with 👍 or 👎 to provide feedback.
Resolved 11 conflicts:
- Replaced getFeatureFlag("Reified relation triples") with getStoredRelationsEnabled()
(main moved reified relations from FeatureFlags to PersonalSettings)
- Removed "Reified relation triples" from FeatureFlagsSchema, kept "Use new settings store"
- Kept toDiscourseNode + added migrateNodeBlockProps in accessors.ts (both needed)
- Dropped MigrationTab from AdminPanel (moved to HomePersonalSettings on main)
- Migrated DiscourseContextOverlay score validation to use accessors instead of
legacy tree reads (getSubTree/getSettingValueFromTree/getBasicTreeByParentUid)
- Removed dead legacy imports (getSetting, AUTO_CANVAS_RELATIONS_KEY from Tldraw.tsx;
USE_REIFIED_RELATIONS from accessors.ts)
- Zero net increase in legacy reader call sites
…ing-branch Resolved 2 import conflicts in canvas files — keep both sides (accessor imports + new canvas sync/posthog imports).
#DO NOT MERGE - until all the other prs are