From 60086d4bac34e6625c76370e219df2b834dfc2e6 Mon Sep 17 00:00:00 2001 From: bh0fer Date: Wed, 17 Sep 2025 14:28:34 +0200 Subject: [PATCH 1/4] feature: add edit button options for gh, gh-dev and cms --- docusaurus.config.ts | 5 +- src/siteConfig/siteConfig.d.ts | 28 ++++++- src/theme/EditThisPage/index.tsx | 91 +++++++++++++++++++++++ src/theme/EditThisPage/styles.module.scss | 10 +++ 4 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 src/theme/EditThisPage/index.tsx create mode 100644 src/theme/EditThisPage/styles.module.scss diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 1bc3bcdc7..dcc32af0b 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -90,7 +90,10 @@ const config: Config = applyTransformers({ GIT_COMMIT_SHA: GIT_COMMIT_SHA, SENTRY_DSN: process.env.SENTRY_DSN, GH_OAUTH_CLIENT_ID: GH_OAUTH_CLIENT_ID, - PERSONAL_SPACE_DOC_ROOT_ID: siteConfig.personalSpaceDocRootId || '2686fc4e-10e7-4288-bf41-e6175e489b8e' + PERSONAL_SPACE_DOC_ROOT_ID: siteConfig.personalSpaceDocRootId || '2686fc4e-10e7-4288-bf41-e6175e489b8e', + showEditThisPage: siteConfig.showEditThisPage ?? 'teachers', + showEditThisPageOptions: siteConfig.showEditThisPageOptions ?? ['github', 'github-dev', 'cms'], + editThisPageCmsUrl: siteConfig.editThisPageCmsUrl ?? '/cms/', }, future: { v4: true, diff --git a/src/siteConfig/siteConfig.d.ts b/src/siteConfig/siteConfig.d.ts index 68e8f9d4d..b7adf49cb 100644 --- a/src/siteConfig/siteConfig.d.ts +++ b/src/siteConfig/siteConfig.d.ts @@ -5,7 +5,8 @@ import type { DeepPartial } from 'utility-types'; import type { Options as DocsPluginOptions } from '@docusaurus/plugin-content-docs'; import type { Options as BlogPluginOptions } from '@docusaurus/plugin-content-blog'; import type { Options as PagesPluginOptions } from '@docusaurus/plugin-content-pages'; - +export type ShowEditThisPage = 'always' | 'never' | 'loggedIn' | 'teachers' | 'admins'; +export type EditThisPageOption = 'github' | 'github-dev' | 'cms'; export interface SiteConfig { /** The title of the site. */ title?: string; @@ -49,6 +50,31 @@ export interface SiteConfig { /** The document root ID for the "personal space overlay" file system. */ personalSpaceDocRootId?: string; + /** + * wheter to show the "Edit this page" links on docs and blog pages. + */ + showEditThisPage?: ShowEditThisPage; + + /** + * Options for which edit links to show. Only relevant if `showEditThisPage` is not 'never'. + * @default ['github', 'github-dev', 'cms'] + * @example To only show the GitHub edit link: + * ```ts + * showEditThisPageOptions: ['github'] + * ``` + */ + showEditThisPageOptions?: EditThisPageOption[]; + + /** + * the URL to the CMS to edit the page. Defaults to '/cms/', but can be + * redirected to a different path + * @default '/cms/' + * @example 'https://teaching-dev.gbsl.website/cms/' + * + * OrganizationName and ProjectName will be appended automatically. + */ + editThisPageCmsUrl?: string; + /** * the config of the blog plugin. It will be merged with the default options in docusaurus.config.ts * @example ignore the tdev docs (gallery etc.) diff --git a/src/theme/EditThisPage/index.tsx b/src/theme/EditThisPage/index.tsx new file mode 100644 index 000000000..a1d24d216 --- /dev/null +++ b/src/theme/EditThisPage/index.tsx @@ -0,0 +1,91 @@ +import React, { type ReactNode } from 'react'; +import { ThemeClassNames } from '@docusaurus/theme-common'; +import Link from '@docusaurus/Link'; +import styles from './styles.module.scss'; +import siteConfig from '@generated/docusaurus.config'; +import type { Props } from '@theme/EditThisPage'; +import Icon from '@mdi/react'; +import { mdiGithub, mdiInfinity, mdiMicrosoftVisualStudioCode } from '@mdi/js'; +import clsx from 'clsx'; +import { observer } from 'mobx-react-lite'; +import { useStore } from '@tdev-hooks/useStore'; +import { useLocation } from '@docusaurus/router'; +import type { EditThisPageOption, ShowEditThisPage } from '@tdev/siteConfig/siteConfig'; +const { organizationName, projectName, customFields } = siteConfig; +const { showEditThisPage, showEditThisPageOptions, editThisPageCmsUrl } = customFields as { + showEditThisPage: ShowEditThisPage; + showEditThisPageOptions: EditThisPageOption[]; + editThisPageCmsUrl: string; +}; +const DisplayBadgeFor = new Set( + showEditThisPageOptions.length === 0 ? ['github', 'github-dev', 'cms'] : showEditThisPageOptions +); +const GH_EDIT_URL = `https://github.com/${organizationName}/${projectName}/edit/main/`; +const GH_DEV_EDIT_URL = `https://github.dev/${organizationName}/${projectName}/blob/main/`; +const CMS_EDIT_URL = `${editThisPageCmsUrl}${organizationName}/${projectName}/`; + +const EditThisPage = observer(({ editUrl }: Props): ReactNode => { + const userStore = useStore('userStore'); + const location = useLocation(); + const search = new URLSearchParams(location.search); + if (!editUrl || search.has('edit')) { + return; + } + switch (showEditThisPage) { + case 'always': + break; + case 'never': + return null; + case 'loggedIn': + if (!userStore.current) { + return null; + } + break; + case 'teachers': + if (!userStore.current?.hasElevatedAccess) { + return null; + } + break; + case 'admins': + if (!userStore.current?.isAdmin) { + return null; + } + break; + default: + console.warn(`Unknown value for showEditThisPage: ${showEditThisPage}`); + return null; + } + return ( +
+ {DisplayBadgeFor.has('github') && ( + + + Github + + )} + {DisplayBadgeFor.has('github-dev') && ( + + + .dev + + )} + {DisplayBadgeFor.has('cms') && ( + + + cms + + )} +
+ ); +}); + +export default EditThisPage; diff --git a/src/theme/EditThisPage/styles.module.scss b/src/theme/EditThisPage/styles.module.scss new file mode 100644 index 000000000..ea43b396f --- /dev/null +++ b/src/theme/EditThisPage/styles.module.scss @@ -0,0 +1,10 @@ +.editThisPage { + display: flex; + gap: 1rem; + flex-wrap: wrap; + .edit { + display: flex; + align-items: center; + gap: 0.2rem; + } +} From 1eeb96e19de21ab19151f8c135f4fc848707eda8 Mon Sep 17 00:00:00 2001 From: bh0fer Date: Wed, 17 Sep 2025 16:54:32 +0200 Subject: [PATCH 2/4] use better defaults --- docusaurus.config.ts | 5 +++-- src/theme/EditThisPage/index.tsx | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docusaurus.config.ts b/docusaurus.config.ts index dcc32af0b..b0c4cbe1e 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -22,6 +22,7 @@ import path from 'path'; import { recommendedBeforeDefaultRemarkPlugins, recommendedRehypePlugins, recommendedRemarkPlugins } from './src/siteConfig/markdownPluginConfigs'; import { remarkPdfPluginConfig } from '@tdev/remark-pdf'; import { excalidrawPluginConfig } from '@tdev/excalidoc'; +import { EditThisPageOption, ShowEditThisPage } from '@tdev/siteConfig/siteConfig'; const siteConfig = getSiteConfig(); @@ -91,8 +92,8 @@ const config: Config = applyTransformers({ SENTRY_DSN: process.env.SENTRY_DSN, GH_OAUTH_CLIENT_ID: GH_OAUTH_CLIENT_ID, PERSONAL_SPACE_DOC_ROOT_ID: siteConfig.personalSpaceDocRootId || '2686fc4e-10e7-4288-bf41-e6175e489b8e', - showEditThisPage: siteConfig.showEditThisPage ?? 'teachers', - showEditThisPageOptions: siteConfig.showEditThisPageOptions ?? ['github', 'github-dev', 'cms'], + showEditThisPage: siteConfig.showEditThisPage ?? 'always' satisfies ShowEditThisPage, + showEditThisPageOptions: siteConfig.showEditThisPageOptions ?? ['github', 'github-dev', 'cms'] satisfies EditThisPageOption[], editThisPageCmsUrl: siteConfig.editThisPageCmsUrl ?? '/cms/', }, future: { diff --git a/src/theme/EditThisPage/index.tsx b/src/theme/EditThisPage/index.tsx index a1d24d216..22ba227ca 100644 --- a/src/theme/EditThisPage/index.tsx +++ b/src/theme/EditThisPage/index.tsx @@ -31,13 +31,14 @@ const EditThisPage = observer(({ editUrl }: Props): ReactNode => { if (!editUrl || search.has('edit')) { return; } + const isLoggedIn = !!userStore.current; switch (showEditThisPage) { case 'always': break; case 'never': return null; case 'loggedIn': - if (!userStore.current) { + if (!isLoggedIn) { return null; } break; @@ -75,7 +76,7 @@ const EditThisPage = observer(({ editUrl }: Props): ReactNode => { .dev )} - {DisplayBadgeFor.has('cms') && ( + {DisplayBadgeFor.has('cms') && isLoggedIn && ( Date: Wed, 17 Sep 2025 17:07:57 +0200 Subject: [PATCH 3/4] add titles --- src/theme/EditThisPage/index.tsx | 5 ++++- src/theme/EditThisPage/styles.module.scss | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/theme/EditThisPage/index.tsx b/src/theme/EditThisPage/index.tsx index 22ba227ca..232ee1c43 100644 --- a/src/theme/EditThisPage/index.tsx +++ b/src/theme/EditThisPage/index.tsx @@ -62,6 +62,7 @@ const EditThisPage = observer(({ editUrl }: Props): ReactNode => { Github @@ -71,6 +72,7 @@ const EditThisPage = observer(({ editUrl }: Props): ReactNode => { .dev @@ -80,8 +82,9 @@ const EditThisPage = observer(({ editUrl }: Props): ReactNode => { - + cms )} diff --git a/src/theme/EditThisPage/styles.module.scss b/src/theme/EditThisPage/styles.module.scss index ea43b396f..f9371380a 100644 --- a/src/theme/EditThisPage/styles.module.scss +++ b/src/theme/EditThisPage/styles.module.scss @@ -6,5 +6,8 @@ display: flex; align-items: center; gap: 0.2rem; + .cms { + transform: translateY(2px); + } } } From 42f6c7772d377ae477b9b40c0a428c8e2f3a3bae Mon Sep 17 00:00:00 2001 From: bh0fer Date: Thu, 18 Sep 2025 17:06:27 +0200 Subject: [PATCH 4/4] show cms option gtayed out when not logged in... --- src/theme/EditThisPage/index.tsx | 14 +++++++++++--- src/theme/EditThisPage/styles.module.scss | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/theme/EditThisPage/index.tsx b/src/theme/EditThisPage/index.tsx index 232ee1c43..7c6ae1b5a 100644 --- a/src/theme/EditThisPage/index.tsx +++ b/src/theme/EditThisPage/index.tsx @@ -78,11 +78,19 @@ const EditThisPage = observer(({ editUrl }: Props): ReactNode => { .dev )} - {DisplayBadgeFor.has('cms') && isLoggedIn && ( + {DisplayBadgeFor.has('cms') && ( cms diff --git a/src/theme/EditThisPage/styles.module.scss b/src/theme/EditThisPage/styles.module.scss index f9371380a..fcb45bc54 100644 --- a/src/theme/EditThisPage/styles.module.scss +++ b/src/theme/EditThisPage/styles.module.scss @@ -6,6 +6,9 @@ display: flex; align-items: center; gap: 0.2rem; + &.noUser { + --ifm-link-color: var(--ifm-color-gray-600); + } .cms { transform: translateY(2px); }