From 9dfde0af5b0c1673a918f18d71a47a5acd6f6993 Mon Sep 17 00:00:00 2001 From: bh0fer Date: Wed, 15 Oct 2025 22:46:04 +0200 Subject: [PATCH 1/6] feature: provide progress state of page to sidebar --- docusaurus.config.ts | 24 +++++++++++++--- src/theme/DocSidebarItem/index.tsx | 31 +++++++++++++++++++++ src/theme/DocSidebarItem/styles.module.scss | 8 ++++++ 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/theme/DocSidebarItem/index.tsx create mode 100644 src/theme/DocSidebarItem/styles.module.scss diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 490ce5134..58380e457 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -23,6 +23,7 @@ import { recommendedBeforeDefaultRemarkPlugins, recommendedRehypePlugins, recomm import { remarkPdfPluginConfig } from '@tdev/remark-pdf'; import { excalidrawPluginConfig } from '@tdev/excalidoc'; import { EditThisPageOption, ShowEditThisPage } from '@tdev/siteConfig/siteConfig'; +import type { ParseFrontMatterResult } from '@docusaurus/types/src/markdown'; const siteConfig = getSiteConfig(); @@ -48,6 +49,21 @@ const PROJECT_NAME = siteConfig.gitHub?.projectName ?? 'teaching-dev'; const GH_OAUTH_CLIENT_ID = process.env.GH_OAUTH_CLIENT_ID; const DEFAULT_TEST_USER = process.env.DEFAULT_TEST_USER?.trim(); +/** + * exposes the `page_id` frontmatter as `pid` in `sidebar_custom_props` + * this way the sidebar can access the page_id without additional plugins + * and we can use it to access the page model for the current page in the sidebar + */ +const exposePidToSidebar = (fm: ParseFrontMatterResult) => { + if (!('sidebar_custom_props' in fm.frontMatter)) { + fm.frontMatter.sidebar_custom_props = {}; + } + if (!('pid' in (fm.frontMatter as any).sidebar_custom_props) && ('page_id' in fm.frontMatter)) { + (fm.frontMatter.sidebar_custom_props as any).pid = fm.frontMatter.page_id; + } + return fm; +}; + const config: Config = applyTransformers({ title: TITLE, tagline: siteConfig.tagline ?? 'Eine Plattform zur Gestaltung interaktiver Lernerlebnisse', @@ -137,7 +153,7 @@ const config: Config = applyTransformers({ parseFrontMatter: async (params) => { const result = await params.defaultParseFrontMatter(params); if (process.env.NODE_ENV === 'production') { - return result; + return exposePidToSidebar(result); } /** * don't add frontmatter to partials @@ -145,13 +161,13 @@ const config: Config = applyTransformers({ const fileName = path.basename(params.filePath); if (fileName.startsWith('_')) { // it is a partial, don't add frontmatter - return result; + return exposePidToSidebar(result); } /** * don't edit blogs frontmatter */ if (params.filePath.startsWith(`${BUILD_LOCATION}/blog/`)) { - return result; + return exposePidToSidebar(result); } if (process.env.NODE_ENV !== 'production') { let needsRewrite = false; @@ -181,7 +197,7 @@ const config: Config = applyTransformers({ ) } } - return result; + return exposePidToSidebar(result); }, mermaid: true, hooks: { diff --git a/src/theme/DocSidebarItem/index.tsx b/src/theme/DocSidebarItem/index.tsx new file mode 100644 index 000000000..cf49c77eb --- /dev/null +++ b/src/theme/DocSidebarItem/index.tsx @@ -0,0 +1,31 @@ +import React, { type ReactNode } from 'react'; +import DocSidebarItem from '@theme-original/DocSidebarItem'; +import type DocSidebarItemType from '@theme/DocSidebarItem'; +import type { WrapperProps } from '@docusaurus/types'; +import { observer } from 'mobx-react-lite'; +import { useStore } from '@tdev-hooks/useStore'; +import Icon from '@mdi/react'; +import { mdiCheck, mdiCheckCircle, mdiProgressQuestion } from '@mdi/js'; +import clsx from 'clsx'; +import styles from './styles.module.scss'; + +type Props = WrapperProps; + +const DocSidebarItemWrapper = observer((props: Props): ReactNode => { + const pageStore = useStore('pageStore'); + const { pid } = (props.item.customProps || {}) as { pid?: string }; + const page = pageStore.find(pid); + return ( +
+ + +
+ ); +}); + +export default DocSidebarItemWrapper; diff --git a/src/theme/DocSidebarItem/styles.module.scss b/src/theme/DocSidebarItem/styles.module.scss new file mode 100644 index 000000000..70b5b8da8 --- /dev/null +++ b/src/theme/DocSidebarItem/styles.module.scss @@ -0,0 +1,8 @@ +.item { + position: relative; + .icon { + position: absolute; + right: 0px; + top: 12px; + } +} From a1a499a0c4ec3ffe4539f052c673eef39bd39eea Mon Sep 17 00:00:00 2001 From: bh0fer Date: Wed, 15 Oct 2025 23:05:16 +0200 Subject: [PATCH 2/6] make linter happy --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 288fd5121..e0f7af2de 100644 --- a/package.json +++ b/package.json @@ -127,4 +127,4 @@ "engines": { "node": ">=22.15" } -} \ No newline at end of file +} From 3464f524195982e7cbe32f53b325be9fb1402739 Mon Sep 17 00:00:00 2001 From: bh0fer Date: Sun, 19 Oct 2025 14:58:39 +0200 Subject: [PATCH 3/6] basic exporter --- src/.page-index/.gitignore | 1 + src/.page-index/.gitkeep | 0 src/plugins/remark-page/plugin.ts | 33 ++++++++++++++++++++--- src/siteConfig/markdownPluginConfigs.ts | 36 ++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 src/.page-index/.gitignore create mode 100644 src/.page-index/.gitkeep diff --git a/src/.page-index/.gitignore b/src/.page-index/.gitignore new file mode 100644 index 000000000..94a2dd146 --- /dev/null +++ b/src/.page-index/.gitignore @@ -0,0 +1 @@ +*.json \ No newline at end of file diff --git a/src/.page-index/.gitkeep b/src/.page-index/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/src/plugins/remark-page/plugin.ts b/src/plugins/remark-page/plugin.ts index 709756319..1becf1d41 100644 --- a/src/plugins/remark-page/plugin.ts +++ b/src/plugins/remark-page/plugin.ts @@ -1,21 +1,48 @@ import type { Plugin, Transformer } from 'unified'; import type { MdxJsxFlowElement } from 'mdast-util-mdx'; -import type { Root } from 'mdast'; +import type { Node, Root } from 'mdast'; import { toJsxAttribute } from '../helpers'; +import path from 'path'; +import { promises as fs } from 'fs'; + +export interface PluginOptions { + extractors: { test: (node: Node) => boolean; getDocumentRootIds: (node: Node) => string[] }[]; + exportDir: string; +} /** * A remark plugin that adds a ` elements at the top of the current page. * This is useful to initialize a page model on page load and to trigger side-effects on page display, * as to load models attached to the `page_id`'s root document. */ -const plugin: Plugin = function plugin(): Transformer { +const plugin: Plugin = function plugin( + options = { extractors: [], exportDir: './.page-index' } +): Transformer { return async (root, file) => { const { visit, EXIT } = await import('unist-util-visit'); const { page_id } = (file.data?.frontMatter || {}) as { page_id?: string }; if (!page_id) { return; } - visit(root, (node, index, parent) => { + const index: Set = new Set(); + visit(root, (node, idx, parent) => { + const extractor = options.extractors.find((ext) => ext.test(node)); + if (!extractor) { + return; + } + const docRootIds = extractor.getDocumentRootIds(node); + docRootIds.forEach((id) => index.add(id)); + }); + if (index.size > 0) { + await fs.writeFile( + path.join(options.exportDir, `${page_id}.json`), + JSON.stringify([...index], null, 2), + { + encoding: 'utf-8' + } + ); + } + visit(root, (node, idx, parent) => { /** add the MdxPage exactly once at the top of the document and exit */ if (root === node && !parent) { const loaderNode: MdxJsxFlowElement = { diff --git a/src/siteConfig/markdownPluginConfigs.ts b/src/siteConfig/markdownPluginConfigs.ts index cbd602295..ae2640bbe 100644 --- a/src/siteConfig/markdownPluginConfigs.ts +++ b/src/siteConfig/markdownPluginConfigs.ts @@ -1,5 +1,7 @@ import type { Node } from 'mdast'; +import path from 'path'; import type { LeafDirective } from 'mdast-util-directive'; +import type { MdxJsxFlowElement, MdxJsxTextElement } from 'mdast-util-mdx-jsx'; import strongPlugin, { transformer as captionVisitor } from '../plugins/remark-strong/plugin'; import deflistPlugin from '../plugins/remark-deflist/plugin'; import mdiPlugin from '../plugins/remark-mdi/plugin'; @@ -129,7 +131,39 @@ export const enumerateAnswersPluginConfig = [ export const pdfPluginConfig = pdfPlugin; -export const pagePluginConfig = pagePlugin; +const cwd = process.cwd(); +const indexPath = path.resolve(cwd, './src/.page-index'); +const ComponentsWithId = new Set(['TaskState', 'ProgressState']); +const AnswerTypes = new Set(['state', 'progress']); +export const pagePluginConfig = [ + pagePlugin, + { + exportDir: indexPath, + extractors: [ + { + test: (_node: Node) => { + if (_node.type !== 'mdxJsxFlowElement') { + return false; + } + const node = _node as MdxJsxFlowElement; + const name = node.name as string; + return ( + ComponentsWithId.has(name) || + node.attributes.some( + (a) => + (a as { name?: string }).name === 'type' && AnswerTypes.has(a.value as string) + ) + ); + }, + getDocumentRootIds: (node: Node) => { + const jsxNode = node as MdxJsxFlowElement; + const idAttr = jsxNode.attributes.find((attr) => (attr as any).name === 'id'); + return idAttr ? [idAttr.value] : []; + } + } + ] + } +]; export const graphvizPluginConfig = graphvizPlugin; export const commentPluginConfig = [ From 2cd2a9fb633e4dbbb4fc0fbe1f2e8a46ce81620f Mon Sep 17 00:00:00 2001 From: bh0fer Date: Mon, 20 Oct 2025 11:44:03 +0200 Subject: [PATCH 4/6] account border width in html sandbox --- .../documents/CodeEditor/HtmlEditor/HtmlSandbox.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/documents/CodeEditor/HtmlEditor/HtmlSandbox.tsx b/src/components/documents/CodeEditor/HtmlEditor/HtmlSandbox.tsx index 8d0446235..aa839987a 100644 --- a/src/components/documents/CodeEditor/HtmlEditor/HtmlSandbox.tsx +++ b/src/components/documents/CodeEditor/HtmlEditor/HtmlSandbox.tsx @@ -42,9 +42,11 @@ function sendHeight() { if (scrollHeight !== clientHeight) { parent.postMessage({id: '${id}', type: 'resize', height: scrollHeight}, "*"); } else { + const borderTopWidth = parseFloat(getComputedStyle(document.body).borderTopWidth); + const borderBottomWidth = parseFloat(getComputedStyle(document.body).borderBottomWidth); const mTop = parseFloat(getComputedStyle(document.body).marginTop); const mBottom = parseFloat(getComputedStyle(document.body).marginBottom); - const total = mTop + mBottom; + const total = mTop + mBottom + borderTopWidth + borderBottomWidth; if (scrollHeight > document.body.clientHeight + total) { parent.postMessage({id: '${id}', type: 'resize', height: document.body.clientHeight + total}, "*"); } From b114f15fa858975d76d21d627996e0392facc8a8 Mon Sep 17 00:00:00 2001 From: bh0fer Date: Mon, 20 Oct 2025 12:08:54 +0200 Subject: [PATCH 5/6] fix missing null check --- src/components/Admin/EditUser/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Admin/EditUser/index.tsx b/src/components/Admin/EditUser/index.tsx index 418195018..65db66e68 100644 --- a/src/components/Admin/EditUser/index.tsx +++ b/src/components/Admin/EditUser/index.tsx @@ -219,7 +219,7 @@ const EditUser = observer((props: Props) => { authClient.admin .setUserPassword({ userId: user.id, newPassword: password }) .then((res) => { - if (res.data) { + if (res?.data) { setPwState('success'); } else { setPwState('error'); @@ -284,7 +284,7 @@ const EditUser = observer((props: Props) => { setSpinState('deleting'); authClient.admin.removeUser({ userId: user.id }).then( action((res) => { - if (res.data?.success) { + if (res?.data?.success) { userStore.removeFromStore(user.id); props.close(); } From 7f89fafe8dc37eeece51c40c9e0ce2a8662eac3d Mon Sep 17 00:00:00 2001 From: bh0fer Date: Mon, 3 Nov 2025 10:02:03 +0100 Subject: [PATCH 6/6] add experiments --- packages/tdev/page-progress-state/.gitignore | 1 + .../page-progress-state/assets}/.gitignore | 0 .../tdev/page-progress-state/package.json | 15 +++ .../remark-plugin/index.ts | 95 +++++++++++++++++++ .../tdev/page-progress-state/tsconfig.json | 3 + src/.page-index/.gitkeep | 0 src/plugins/remark-page/plugin.ts | 29 +----- src/siteConfig/markdownPluginConfigs.ts | 10 +- src/stores/PageStore.ts | 32 +++++++ src/stores/rootStore.ts | 1 + src/theme/DocItem/Content/index.tsx | 7 ++ src/theme/DocSidebarItem/index.tsx | 2 +- 12 files changed, 163 insertions(+), 32 deletions(-) create mode 100644 packages/tdev/page-progress-state/.gitignore rename {src/.page-index => packages/tdev/page-progress-state/assets}/.gitignore (100%) create mode 100644 packages/tdev/page-progress-state/package.json create mode 100644 packages/tdev/page-progress-state/remark-plugin/index.ts create mode 100644 packages/tdev/page-progress-state/tsconfig.json delete mode 100644 src/.page-index/.gitkeep diff --git a/packages/tdev/page-progress-state/.gitignore b/packages/tdev/page-progress-state/.gitignore new file mode 100644 index 000000000..3a03a092e --- /dev/null +++ b/packages/tdev/page-progress-state/.gitignore @@ -0,0 +1 @@ +.assets \ No newline at end of file diff --git a/src/.page-index/.gitignore b/packages/tdev/page-progress-state/assets/.gitignore similarity index 100% rename from src/.page-index/.gitignore rename to packages/tdev/page-progress-state/assets/.gitignore diff --git a/packages/tdev/page-progress-state/package.json b/packages/tdev/page-progress-state/package.json new file mode 100644 index 000000000..9723aad76 --- /dev/null +++ b/packages/tdev/page-progress-state/package.json @@ -0,0 +1,15 @@ +{ + "name": "@tdev/page-progress-state", + "version": "1.0.0", + "main": "remark-plugin/index.ts", + "types": "remark-plugin/index.ts", + "dependencies": {}, + "devDependencies": { + "vitest": "*", + "@docusaurus/module-type-aliases": "*", + "@docusaurus/core": "*" + }, + "peerDependencies": { + "@tdev/core": "1.0.0" + } +} \ No newline at end of file diff --git a/packages/tdev/page-progress-state/remark-plugin/index.ts b/packages/tdev/page-progress-state/remark-plugin/index.ts new file mode 100644 index 000000000..f564a55b3 --- /dev/null +++ b/packages/tdev/page-progress-state/remark-plugin/index.ts @@ -0,0 +1,95 @@ +import type { Plugin, Transformer } from 'unified'; +import type { Node, Root } from 'mdast'; +import path from 'path'; +import { promises as fs, accessSync, mkdirSync, writeFileSync, readFileSync } from 'fs'; + +export interface PluginOptions { + extractors: { test: (node: Node) => boolean; getDocumentRootIds: (node: Node) => string[] }[]; +} + +const projectRoot = process.cwd(); + +/** + * + * sidebar: + * { + * "1f6db0ee-aa48-44c7-af43-4b66843f665e": [ ... document root ids ] + * } + * + * structure: + * { + * "path" : { + * "to": { + * "doc": + * }, + * } + * } + */ + +const ensureFile = async (indexPath: string) => { + const assetsDir = path.dirname(indexPath); + try { + accessSync(assetsDir); + } catch { + mkdirSync(assetsDir, { recursive: true }); + } + try { + accessSync(indexPath); + } catch { + writeFileSync(indexPath, JSON.stringify({}, null, 2), { + encoding: 'utf-8' + }); + } +}; + +/** + * A remark plugin that adds a ` elements at the top of the current page. + * This is useful to initialize a page model on page load and to trigger side-effects on page display, + * as to load models attached to the `page_id`'s root document. + */ +const remarkPlugin: Plugin = function plugin( + options = { extractors: [] } +): Transformer { + const index = new Map(); + const structurePath = path.resolve(__dirname, '../assets/', 'structure.json'); + const indexPath = path.resolve(__dirname, '../assets/', 'index.json'); + ensureFile(indexPath); + ensureFile(structurePath); + try { + const content = readFileSync(indexPath, { encoding: 'utf-8' }); + const parsed = JSON.parse(content) as { [key: string]: string[] }; + for (const [key, values] of Object.entries(parsed)) { + index.set(key, values); + } + } catch { + console.log('Error parsing existing index file, starting fresh.'); + } + + return async (root, file) => { + const { visit, EXIT } = await import('unist-util-visit'); + const { page_id } = (file.data?.frontMatter || {}) as { page_id?: string }; + if (!page_id) { + return; + } + const filePath = path + .relative(projectRoot, file.path) + .replace(/\/(index|README)\.mdx?$/i, '') + .replace(/\.mdx?$/i, ''); + console.log('file', filePath); + const pageIndex = new Set([]); + visit(root, (node, idx, parent) => { + const extractor = options.extractors.find((ext) => ext.test(node)); + if (!extractor) { + return; + } + const docRootIds = extractor.getDocumentRootIds(node); + docRootIds.forEach((id) => pageIndex.add(id)); + }); + index.set(page_id, [...pageIndex]); + await fs.writeFile(indexPath, JSON.stringify(Object.fromEntries(index), null, 2), { + encoding: 'utf-8' + }); + }; +}; + +export default remarkPlugin; diff --git a/packages/tdev/page-progress-state/tsconfig.json b/packages/tdev/page-progress-state/tsconfig.json new file mode 100644 index 000000000..ea56794f8 --- /dev/null +++ b/packages/tdev/page-progress-state/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../../tsconfig.json" +} diff --git a/src/.page-index/.gitkeep b/src/.page-index/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/plugins/remark-page/plugin.ts b/src/plugins/remark-page/plugin.ts index 1becf1d41..90d748676 100644 --- a/src/plugins/remark-page/plugin.ts +++ b/src/plugins/remark-page/plugin.ts @@ -2,46 +2,19 @@ import type { Plugin, Transformer } from 'unified'; import type { MdxJsxFlowElement } from 'mdast-util-mdx'; import type { Node, Root } from 'mdast'; import { toJsxAttribute } from '../helpers'; -import path from 'path'; -import { promises as fs } from 'fs'; - -export interface PluginOptions { - extractors: { test: (node: Node) => boolean; getDocumentRootIds: (node: Node) => string[] }[]; - exportDir: string; -} /** * A remark plugin that adds a ` elements at the top of the current page. * This is useful to initialize a page model on page load and to trigger side-effects on page display, * as to load models attached to the `page_id`'s root document. */ -const plugin: Plugin = function plugin( - options = { extractors: [], exportDir: './.page-index' } -): Transformer { +const plugin: Plugin = function plugin(): Transformer { return async (root, file) => { const { visit, EXIT } = await import('unist-util-visit'); const { page_id } = (file.data?.frontMatter || {}) as { page_id?: string }; if (!page_id) { return; } - const index: Set = new Set(); - visit(root, (node, idx, parent) => { - const extractor = options.extractors.find((ext) => ext.test(node)); - if (!extractor) { - return; - } - const docRootIds = extractor.getDocumentRootIds(node); - docRootIds.forEach((id) => index.add(id)); - }); - if (index.size > 0) { - await fs.writeFile( - path.join(options.exportDir, `${page_id}.json`), - JSON.stringify([...index], null, 2), - { - encoding: 'utf-8' - } - ); - } visit(root, (node, idx, parent) => { /** add the MdxPage exactly once at the top of the document and exit */ if (root === node && !parent) { diff --git a/src/siteConfig/markdownPluginConfigs.ts b/src/siteConfig/markdownPluginConfigs.ts index ae2640bbe..c725b99b4 100644 --- a/src/siteConfig/markdownPluginConfigs.ts +++ b/src/siteConfig/markdownPluginConfigs.ts @@ -15,6 +15,7 @@ import linkAnnotationPlugin from '../plugins/remark-link-annotation/plugin'; import mediaPlugin from '../plugins/remark-media/plugin'; import detailsPlugin from '../plugins/remark-details/plugin'; import pagePlugin from '../plugins/remark-page/plugin'; +import pageProgressStatePlugin from '@tdev/page-progress-state/remark-plugin'; import graphvizPlugin from '@tdev/remark-graphviz/remark-plugin'; import pdfPlugin from '@tdev/remark-pdf/remark-plugin'; import codeAsAttributePlugin from '../plugins/remark-code-as-attribute/plugin'; @@ -135,10 +136,11 @@ const cwd = process.cwd(); const indexPath = path.resolve(cwd, './src/.page-index'); const ComponentsWithId = new Set(['TaskState', 'ProgressState']); const AnswerTypes = new Set(['state', 'progress']); -export const pagePluginConfig = [ - pagePlugin, +export const pagePluginConfig = [pagePlugin, {}]; + +export const pageProgressStatePluginConfig = [ + pageProgressStatePlugin, { - exportDir: indexPath, extractors: [ { test: (_node: Node) => { @@ -164,6 +166,7 @@ export const pagePluginConfig = [ ] } ]; + export const graphvizPluginConfig = graphvizPlugin; export const commentPluginConfig = [ @@ -203,6 +206,7 @@ export const recommendedRemarkPlugins = [ enumerateAnswersPluginConfig, pdfPluginConfig, pagePluginConfig, + pageProgressStatePluginConfig, commentPluginConfig, linkAnnotationPluginConfig, codeAsAttributePluginConfig diff --git a/src/stores/PageStore.ts b/src/stores/PageStore.ts index 059fb283c..fbd74e8fb 100644 --- a/src/stores/PageStore.ts +++ b/src/stores/PageStore.ts @@ -4,6 +4,9 @@ import { RootStore } from '@tdev-stores/rootStore'; import Page from '@tdev-models/Page'; import { computedFn } from 'mobx-utils'; import { allDocuments as apiAllDocuments } from '@tdev-api/document'; +import type { useDocsSidebar } from '@docusaurus/plugin-content-docs/client'; +import { PropSidebarItem } from '@docusaurus/plugin-content-docs'; +type PageIndex = { [key: string]: string[] }; export class PageStore extends iStore { readonly root: RootStore; @@ -13,11 +16,40 @@ export class PageStore extends iStore { @observable accessor currentPageId: string | undefined = undefined; @observable accessor runningTurtleScriptId: string | undefined = undefined; + @observable.ref accessor pageIndex: PageIndex = {}; + sidebars = observable.map>([], { deep: false }); + constructor(store: RootStore) { super(); this.root = store; } + @action + configureSidebar(id: string, sidebar: ReturnType) { + if (this.sidebars.has(id) || !sidebar) { + return; + } + this.sidebars.set(id, sidebar); + sidebar.items.forEach((item) => { + if (item.type !== 'category') { + return; + } + item.items; + }); + } + + @action + load() { + return import('@tdev/page-progress-state/assets/index.json').then((mod) => { + this.updatePageIndex(mod.default as PageIndex); + }); + } + + @action + updatePageIndex(newIndex: PageIndex) { + this.pageIndex = newIndex; + } + find = computedFn( function (this: PageStore, id?: string): Page | undefined { if (!id) { diff --git a/src/stores/rootStore.ts b/src/stores/rootStore.ts index b2b623e50..7c8a6a5de 100644 --- a/src/stores/rootStore.ts +++ b/src/stores/rootStore.ts @@ -55,6 +55,7 @@ export class RootStore { * load stores */ this.userStore.load(); + this.pageStore.load(); this.studentGroupStore.load(); this.cmsStore.initialize(); if (user.hasElevatedAccess) { diff --git a/src/theme/DocItem/Content/index.tsx b/src/theme/DocItem/Content/index.tsx index 12295d8d1..54581cc7f 100644 --- a/src/theme/DocItem/Content/index.tsx +++ b/src/theme/DocItem/Content/index.tsx @@ -6,10 +6,17 @@ import { observer } from 'mobx-react-lite'; import { useStore } from '@tdev-hooks/useStore'; import { useLocation } from '@docusaurus/router'; type Props = WrapperProps; +import { useDocsSidebar } from '@docusaurus/plugin-content-docs/client'; const ContentWrapper = observer((props: Props): React.ReactNode => { const pageStore = useStore('pageStore'); const location = useLocation(); + const sidebar = useDocsSidebar(); + React.useEffect(() => { + if (sidebar?.name) { + pageStore.configureSidebar(sidebar.name, sidebar); + } + }, [sidebar, pageStore]); React.useEffect(() => { if (pageStore.current) { diff --git a/src/theme/DocSidebarItem/index.tsx b/src/theme/DocSidebarItem/index.tsx index cf49c77eb..1f674eeac 100644 --- a/src/theme/DocSidebarItem/index.tsx +++ b/src/theme/DocSidebarItem/index.tsx @@ -8,9 +8,9 @@ import Icon from '@mdi/react'; import { mdiCheck, mdiCheckCircle, mdiProgressQuestion } from '@mdi/js'; import clsx from 'clsx'; import styles from './styles.module.scss'; +import { useDocsSidebar } from '@docusaurus/plugin-content-docs/client'; type Props = WrapperProps; - const DocSidebarItemWrapper = observer((props: Props): ReactNode => { const pageStore = useStore('pageStore'); const { pid } = (props.item.customProps || {}) as { pid?: string };