diff --git a/apps/roam/src/components/Export.tsx b/apps/roam/src/components/Export.tsx index 0f1c350fb..6d96250ac 100644 --- a/apps/roam/src/components/Export.tsx +++ b/apps/roam/src/components/Export.tsx @@ -15,8 +15,9 @@ import { RadioGroup, Radio, FormGroup, + Collapse, } from "@blueprintjs/core"; -import React, { useState, useEffect, useMemo, FormEvent } from "react"; +import React, { useState, useEffect, useMemo, useRef, FormEvent } from "react"; import MenuItemSelect from "roamjs-components/components/MenuItemSelect"; import { saveAs } from "file-saver"; import { Result } from "roamjs-components/types/query-builder"; @@ -91,7 +92,13 @@ import { type NodeUidWithType, } from "~/utils/publishNodesToGroups"; import { getLoggedInClient, getSupabaseContext } from "~/utils/supabaseContext"; -import { isNodeSharingEnabled } from "~/components/settings/utils/accessors"; +import { + bulkReadSettings, + isNodeSharingEnabled, +} from "~/components/settings/utils/accessors"; +import refreshConfigTree from "~/utils/refreshConfigTree"; +import { flushPendingSettingWrites } from "~/utils/pendingSettingWrites"; +import ExportOptions from "./ExportOptions"; const ExportProgress = ({ id }: { id: string }) => { const [progress, setProgress] = useState(0); @@ -225,6 +232,21 @@ const ExportDialog: ExportDialogComponent = ({ if (initialPanel) setSelectedTabId(INITIAL_PANEL_TO_TAB_ID[initialPanel]); }, [initialPanel, sharingEnabled]); const [includeDiscourseContext, setIncludeDiscourseContext] = useState(false); + const [exportOptionsOpen, setExportOptionsOpen] = useState(false); + const exportOptionsOpened = useRef(false); + // Collapse unmounts the panels while closed, so each open seeds them from current values. + const exportGlobalSettings = useMemo( + () => bulkReadSettings().globalSettings, + // eslint-disable-next-line react-hooks/exhaustive-deps + [exportOptionsOpen], + ); + + // Option panels also write legacy config blocks, so refresh the tree as SettingsDialog + // does, but only if they were opened: refreshConfigTree re-reads every node page. + const closeDialog = (): void => { + if (exportOptionsOpened.current) refreshConfigTree(); + onClose(); + }; const [gitHubAccessToken, setGitHubAccessToken] = useState( getSetting("oauth-github", null), ); @@ -756,7 +778,7 @@ const ExportDialog: ExportDialogComponent = ({ }); } finally { setLoading(false); - onClose(); + closeDialog(); } }; @@ -796,7 +818,7 @@ const ExportDialog: ExportDialogComponent = ({ fileCount: files.length, }); } - onClose(); + closeDialog(); } catch (e) { setError("Failed to export files."); posthog.capture("Export Dialog: Export Failed", { @@ -888,7 +910,7 @@ const ExportDialog: ExportDialogComponent = ({ : "success", id: "query-builder-publish-success", }); - if (hasPublishedNodes) onClose(); + if (hasPublishedNodes) closeDialog(); } catch (e) { internalError({ error: e as Error, @@ -951,41 +973,60 @@ const ExportDialog: ExportDialogComponent = ({ /> -
+
+ + { + setIncludeDiscourseContext( + (e.target as HTMLInputElement).checked, + ); + }} + labelElement={ + + Discourse context + + } + /> + +
+
+
+ +
+ +
+
{error} -
-