Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 88 additions & 15 deletions apps/roam/src/components/LeftSidebarView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,27 @@ import {
import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle";
import openBlockInSidebar from "roamjs-components/writes/openBlockInSidebar";
import extractRef from "roamjs-components/util/extractRef";
import { getFormattedConfigTree, notify } from "~/utils/discourseConfigRef";
import {
getFormattedConfigTree,
notify,
subscribe,
} from "~/utils/discourseConfigRef";
import type {
LeftSidebarConfig,
LeftSidebarPersonalSectionConfig,
onSettingChange,
settingKeys,
} from "~/components/settings/utils/settingsEmitter";
import {
type LeftSidebarConfig,
type LeftSidebarPersonalSectionConfig,
mergeGlobalSectionWithAccessor,
mergePersonalSectionsWithAccessor,
} from "~/utils/getLeftSidebarSettings";
import {
getGlobalSetting,
getPersonalSetting,
setGlobalSetting,
setPersonalSetting,
} from "~/components/settings/utils/accessors";
import type {
LeftSidebarGlobalSettings,
PersonalSection,
} from "~/components/settings/utils/zodSchema";
import { createBlock } from "roamjs-components/writes";
import deleteBlock from "roamjs-components/writes/deleteBlock";
import getTextByBlockUid from "roamjs-components/queries/getTextByBlockUid";
Expand Down Expand Up @@ -95,12 +107,18 @@ const toggleFoldedState = ({
setIsOpen,
folded,
parentUid,
isGlobal,
sectionIndex,
}: {
isOpen: boolean;
setIsOpen: Dispatch<SetStateAction<boolean>>;
folded: { uid?: string; value: boolean };
parentUid: string;
isGlobal?: boolean;
sectionIndex?: number;
}) => {
const newFolded = !isOpen;

if (isOpen) {
setIsOpen(false);
if (folded.uid) {
Expand All @@ -118,6 +136,17 @@ const toggleFoldedState = ({
folded.uid = newUid;
folded.value = true;
}

if (isGlobal) {
setGlobalSetting(["Left sidebar", "Settings", "Folded"], newFolded);
} else if (sectionIndex !== undefined) {
const sections =
getPersonalSetting<PersonalSection[]>(["Left sidebar"]) || [];
if (sections[sectionIndex]) {
sections[sectionIndex].Settings.Folded = newFolded;
setPersonalSetting(["Left sidebar"], sections);
}
}
};

const SectionChildren = ({
Expand Down Expand Up @@ -160,8 +189,10 @@ const SectionChildren = ({

const PersonalSectionItem = ({
section,
sectionIndex,
}: {
section: LeftSidebarPersonalSectionConfig;
sectionIndex: number;
}) => {
const titleRef = parseReference(section.text);
const blockText = useMemo(
Expand All @@ -182,6 +213,7 @@ const PersonalSectionItem = ({
setIsOpen,
folded: section.settings.folded,
parentUid: section.settings.uid || "",
sectionIndex,
});
};

Expand Down Expand Up @@ -226,9 +258,9 @@ const PersonalSections = ({ config }: { config: LeftSidebarConfig }) => {

return (
<div className="personal-left-sidebar-sections">
{sections.map((section) => (
{sections.map((section, index) => (
<div key={section.uid}>
<PersonalSectionItem section={section} />
<PersonalSectionItem section={section} sectionIndex={index} />
</div>
))}
</div>
Expand All @@ -253,6 +285,7 @@ const GlobalSection = ({ config }: { config: LeftSidebarConfig["global"] }) => {
setIsOpen,
folded: config.settings.folded,
parentUid: config.settings.uid,
isGlobal: true,
});
}}
>
Expand All @@ -276,22 +309,62 @@ const GlobalSection = ({ config }: { config: LeftSidebarConfig["global"] }) => {
);
};

// TODO(ENG-1471): Remove old-system merge when migration complete — just use accessor values directly.
// See mergeGlobalSectionWithAccessor/mergePersonalSectionsWithAccessor for why the merge exists.
const buildConfig = (): LeftSidebarConfig => {
// Read VALUES from accessor (handles flag routing + mismatch detection)
const globalValues = getGlobalSetting<LeftSidebarGlobalSettings>([
"Left sidebar",
]);
const personalValues = getPersonalSetting<PersonalSection[]>([
"Left sidebar",
]);

// Read UIDs from old system (needed for fold CRUD during dual-write)
const oldConfig = getFormattedConfigTree().leftSidebar;

return {
uid: oldConfig.uid,
favoritesMigrated: oldConfig.favoritesMigrated,
sidebarMigrated: oldConfig.sidebarMigrated,
global: mergeGlobalSectionWithAccessor(oldConfig.global, globalValues),
personal: {
uid: oldConfig.personal.uid,
sections: mergePersonalSectionsWithAccessor(
oldConfig.personal.sections,
personalValues,
),
},
allPersonalSections: oldConfig.allPersonalSections,
};
};

export const useConfig = () => {
const [config, setConfig] = useState(
() => getFormattedConfigTree().leftSidebar,
);
const [config, setConfig] = useState(() => buildConfig());
useEffect(() => {
const handleUpdate = () => {
setConfig(getFormattedConfigTree().leftSidebar);
refreshConfigTree();
setConfig(buildConfig());
};
const unsubscribe = subscribe(handleUpdate);
const unsubGlobal = onSettingChange(
settingKeys.globalLeftSidebar,
handleUpdate,
);
const unsubPersonal = onSettingChange(
settingKeys.personalLeftSidebar,
handleUpdate,
);
return () => {
unsubscribe();
unsubGlobal();
unsubPersonal();
};
}, []);
return { config, setConfig };
};

// TODO(ENG-1471): refreshAndNotify still needed by settings panels
// (LeftSidebarGlobalSettings, LeftSidebarPersonalSettings) for old-system CRUD.
// Remove when settings panels also read via accessors + emitter.
export const refreshAndNotify = () => {
refreshConfigTree();
notify();
Expand Down
3 changes: 2 additions & 1 deletion apps/roam/src/components/settings/GeneralSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
GlobalTextPanel,
FeatureFlagPanel,
} from "./components/BlockPropSettingPanels";
import { isNewSettingsStoreEnabled } from "./utils/accessors";
import posthog from "posthog-js";

const DiscourseGraphHome = () => {
Expand Down Expand Up @@ -43,7 +44,7 @@ const DiscourseGraphHome = () => {
uid={settings.leftSidebarEnabled.uid}
parentUid={settings.settingsUid}
onAfterChange={(checked: boolean) => {
if (checked) {
if (checked && !isNewSettingsStoreEnabled()) {
setIsAlertOpen(true);
}
posthog.capture("General Settings: Left Sidebar Toggled", {
Expand Down
23 changes: 17 additions & 6 deletions apps/roam/src/components/settings/LeftSidebarGlobalSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React, { useCallback, useEffect, useMemo, useState, memo } from "react";
import { Button, ButtonGroup, Collapse } from "@blueprintjs/core";
import { GlobalFlagPanel } from "~/components/settings/components/BlockPropSettingPanels";
import { setGlobalSetting } from "~/components/settings/utils/accessors";
import {
setGlobalSetting,
getGlobalSetting,
} from "~/components/settings/utils/accessors";
import type { LeftSidebarGlobalSettings } from "~/components/settings/utils/zodSchema";
import AutocompleteInput from "roamjs-components/components/AutocompleteInput";
import getAllPageNames from "roamjs-components/queries/getAllPageNames";
import createBlock from "roamjs-components/writes/createBlock";
Expand All @@ -11,8 +15,11 @@ import { extractRef, getSubTree } from "roamjs-components/util";
import getPageUidByPageTitle from "roamjs-components/queries/getPageUidByPageTitle";
import discourseConfigRef from "~/utils/discourseConfigRef";
import { DISCOURSE_CONFIG_PAGE_TITLE } from "~/utils/renderNodeConfigPage";
import { getLeftSidebarGlobalSectionConfig } from "~/utils/getLeftSidebarSettings";
import { LeftSidebarGlobalSectionConfig } from "~/utils/getLeftSidebarSettings";
import {
getLeftSidebarGlobalSectionConfig,
mergeGlobalSectionWithAccessor,
type LeftSidebarGlobalSectionConfig,
} from "~/utils/getLeftSidebarSettings";
import { render as renderToast } from "roamjs-components/components/Toast";
import refreshConfigTree from "~/utils/refreshConfigTree";
import { refreshAndNotify } from "~/components/LeftSidebarView";
Expand Down Expand Up @@ -98,6 +105,9 @@ const LeftSidebarGlobalSectionsContent = ({
const initialize = async () => {
setIsInitializing(true);
const globalSectionText = "Global-Section";
const globalValues = getGlobalSetting<LeftSidebarGlobalSettings>([
"Left sidebar",
]);
const config = getLeftSidebarGlobalSectionConfig(leftSidebar.children);

const existingGlobalSection = leftSidebar.children.find(
Expand Down Expand Up @@ -142,9 +152,10 @@ const LeftSidebarGlobalSectionsContent = ({
});
}
} else {
setChildrenUid(config.childrenUid || null);
setPages(config.children || []);
setGlobalSection(config);
const merged = mergeGlobalSectionWithAccessor(config, globalValues);
setChildrenUid(merged.childrenUid || null);
setPages(merged.children || []);
setGlobalSection(merged);
}
setIsInitializing(false);
};
Expand Down
19 changes: 15 additions & 4 deletions apps/roam/src/components/settings/LeftSidebarPersonalSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,19 @@ import createBlock from "roamjs-components/writes/createBlock";
import deleteBlock from "roamjs-components/writes/deleteBlock";
import updateBlock from "roamjs-components/writes/updateBlock";
import type { RoamBasicNode } from "roamjs-components/types";
import { setPersonalSetting } from "~/components/settings/utils/accessors";
import {
setPersonalSetting,
getPersonalSetting,
} from "~/components/settings/utils/accessors";
import type { PersonalSection } from "~/components/settings/utils/zodSchema";
import {
PersonalNumberPanel,
PersonalTextPanel,
} from "~/components/settings/components/BlockPropSettingPanels";
import {
LeftSidebarPersonalSectionConfig,
getLeftSidebarPersonalSectionConfig,
mergePersonalSectionsWithAccessor,
PersonalSectionChild,
} from "~/utils/getLeftSidebarSettings";
import { extractRef, getSubTree } from "roamjs-components/util";
Expand Down Expand Up @@ -507,7 +512,7 @@ const SectionItem = memo(
<PersonalTextPanel
title="Alias"
description="Display name for this item"
settingKeys={["Left sidebar"]}
settingKeys={[]}
initialValue={child.alias?.value ?? ""}
order={0}
uid={child.alias?.uid}
Expand Down Expand Up @@ -599,10 +604,16 @@ const LeftSidebarPersonalSectionsContent = ({
setSections([]);
} else {
setPersonalSectionUid(personalSection.uid);

const personalValues = getPersonalSetting<PersonalSection[]>([
"Left sidebar",
]);
const loadedSections = getLeftSidebarPersonalSectionConfig(
leftSidebar.children,
).sections;
setSections(loadedSections);
setSections(
mergePersonalSectionsWithAccessor(loadedSections, personalValues),
);
}
};

Expand Down Expand Up @@ -786,7 +797,7 @@ const LeftSidebarPersonalSectionsContent = ({
<PersonalNumberPanel
title="Truncate-result?"
description="Maximum characters to display"
settingKeys={["Left sidebar"]}
settingKeys={[]}
initialValue={
activeDialogSection.settings.truncateResult?.value ?? 75
}
Expand Down
6 changes: 5 additions & 1 deletion apps/roam/src/components/settings/utils/accessors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ const getLegacyPersonalLeftSidebarSetting = (): unknown[] => {
return settings.leftSidebar.personal.sections.map((section) => ({
name: section.text,
Children: (section.children || []).map((child) => ({
uid: child.uid,
uid: child.text,
Alias: child.alias?.value || "",
})),
Settings: {
Expand Down Expand Up @@ -724,6 +724,8 @@ export const getGlobalSettings = (): GlobalSettings => {
export const getGlobalSetting = <T = unknown>(
keys: string[],
): T | undefined => {
if (keys.length === 0) return undefined;

if (!isNewSettingsStoreEnabled()) {
return getLegacyGlobalSetting(keys) as T | undefined;
}
Expand Down Expand Up @@ -788,6 +790,8 @@ export const getPersonalSettings = (): PersonalSettings => {
export const getPersonalSetting = <T = unknown>(
keys: string[],
): T | undefined => {
if (keys.length === 0) return undefined;

if (!isNewSettingsStoreEnabled()) {
return getLegacyPersonalSetting(keys) as T | undefined;
}
Expand Down
Loading