feat(v2): add a banner that links to latest version of documentation (#2916)

* feat(v2): add metadata to indicate the document is old

* feat(v2): add badge that links old versions to latest version

* feat(v2): fix test related to metadata

* feat(v2): fix formatting

* feat(v2): fix formatting

* feat(v2): use Link component instead of anchor tag

* feat(v2): add pramlink to latest docs

* feat(v2): add more vibrant warning message

* feat(v2): position the banner above the article

* feat(v2): link latest version to intro page

* fix(v2): fix some test cases

* feat(v2): fix tests

* feat(v2): change banner to warning orange

* feat(v2): compute root route from sidebar

* style(v2): fix formatting

* feat(v2): use homeid if provided to compute base route

* feat(v2): rename functions and fix a corner case

* feat(v2): fix formating

* feat(v2): compute homepageurl

* style(v2): improve code quality

* style(v2): unbold fullstop for consistency

Co-authored-by: Anshul Goyal <anshulgoel151999@gmail.com>
This commit is contained in:
Teik Jun 2020-06-15 20:31:23 +08:00 committed by GitHub
parent d365b7424b
commit 0c92f5aacd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 2 deletions

View file

@ -163,6 +163,7 @@ describe('simple website', () => {
source: path.join('@site', pluginPath, 'hello.md'), source: path.join('@site', pluginPath, 'hello.md'),
title: 'Hello, World !', title: 'Hello, World !',
description: 'Hi, Endilie here :)', description: 'Hi, Endilie here :)',
latestVersionMainDocPermalink: undefined,
}); });
expect(docsMetadata['foo/bar']).toEqual({ expect(docsMetadata['foo/bar']).toEqual({
@ -176,6 +177,7 @@ describe('simple website', () => {
source: path.join('@site', pluginPath, 'foo', 'bar.md'), source: path.join('@site', pluginPath, 'foo', 'bar.md'),
title: 'Bar', title: 'Bar',
description: 'This is custom description', description: 'This is custom description',
latestVersionMainDocPermalink: undefined,
}); });
expect(docsSidebars).toMatchSnapshot(); expect(docsSidebars).toMatchSnapshot();
@ -335,6 +337,7 @@ describe('versioned website', () => {
title: 'bar', title: 'bar',
permalink: '/docs/foo/bar', permalink: '/docs/foo/bar',
}, },
latestVersionMainDocPermalink: undefined,
}); });
expect(docsMetadata['version-1.0.0/foo/baz']).toEqual({ expect(docsMetadata['version-1.0.0/foo/baz']).toEqual({
id: 'version-1.0.0/foo/baz', id: 'version-1.0.0/foo/baz',

View file

@ -50,6 +50,7 @@ describe('simple site', () => {
source: path.join('@site', routeBasePath, sourceA), source: path.join('@site', routeBasePath, sourceA),
title: 'Bar', title: 'Bar',
description: 'This is custom description', description: 'This is custom description',
latestVersionMainDocPermalink: undefined,
}); });
expect(dataB).toEqual({ expect(dataB).toEqual({
id: 'hello', id: 'hello',
@ -57,6 +58,7 @@ describe('simple site', () => {
source: path.join('@site', routeBasePath, sourceB), source: path.join('@site', routeBasePath, sourceB),
title: 'Hello, World !', title: 'Hello, World !',
description: `Hi, Endilie here :)`, description: `Hi, Endilie here :)`,
latestVersionMainDocPermalink: undefined,
}); });
}); });
@ -85,6 +87,7 @@ describe('simple site', () => {
editUrl: editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/docs/foo/baz.md', 'https://github.com/facebook/docusaurus/edit/master/website/docs/foo/baz.md',
description: 'Images', description: 'Images',
latestVersionMainDocPermalink: undefined,
}); });
}); });
@ -109,6 +112,7 @@ describe('simple site', () => {
title: 'lorem', title: 'lorem',
editUrl: 'https://github.com/customUrl/docs/lorem.md', editUrl: 'https://github.com/customUrl/docs/lorem.md',
description: 'Lorem ipsum.', description: 'Lorem ipsum.',
latestVersionMainDocPermalink: undefined,
}); });
// unrelated frontmatter is not part of metadata // unrelated frontmatter is not part of metadata
@ -140,6 +144,7 @@ describe('simple site', () => {
description: 'Lorem ipsum.', description: 'Lorem ipsum.',
lastUpdatedAt: 1539502055, lastUpdatedAt: 1539502055,
lastUpdatedBy: 'Author', lastUpdatedBy: 'Author',
latestVersionMainDocPermalink: undefined,
}); });
}); });
@ -168,6 +173,7 @@ describe('simple site', () => {
description: 'Lorem ipsum.', description: 'Lorem ipsum.',
lastUpdatedAt: 1539502055, lastUpdatedAt: 1539502055,
lastUpdatedBy: 'Author', lastUpdatedBy: 'Author',
latestVersionMainDocPermalink: undefined,
}); });
}); });

View file

@ -65,6 +65,22 @@ const DEFAULT_OPTIONS: PluginOptions = {
admonitions: {}, admonitions: {},
}; };
function getFirstDocLinkOfSidebar(
sidebarItems: DocsSidebarItem[],
): string | null {
for (let sidebarItem of sidebarItems) {
if (sidebarItem.type === 'category') {
const url = getFirstDocLinkOfSidebar(sidebarItem.items);
if (url) {
return url;
}
} else {
return sidebarItem.href;
}
}
return null;
}
export default function pluginContentDocs( export default function pluginContentDocs(
context: LoadContext, context: LoadContext,
opts: Partial<PluginOptions>, opts: Partial<PluginOptions>,
@ -320,7 +336,6 @@ Available document ids=
}, },
{}, {},
); );
return { return {
docsMetadata, docsMetadata,
docsDir, docsDir,
@ -368,7 +383,6 @@ Available document ids=
const isDocsHomePage = const isDocsHomePage =
metadataItem.id.replace(versionsRegex, '').replace(/^\//, '') === metadataItem.id.replace(versionsRegex, '').replace(/^\//, '') ===
options.homePageId; options.homePageId;
if (isDocsHomePage) { if (isDocsHomePage) {
const versionDocsPathPrefix = const versionDocsPathPrefix =
(metadataItem?.version === versioning.latestVersion (metadataItem?.version === versioning.latestVersion
@ -384,6 +398,7 @@ Available document ids=
homePageDocsRoutePath, homePageDocsRoutePath,
versionDocsPathPrefix, versionDocsPathPrefix,
]); ]);
const docsBaseMetadataPath = await createData( const docsBaseMetadataPath = await createData(
`${docuHash(metadataItem.source)}-base.json`, `${docuHash(metadataItem.source)}-base.json`,
JSON.stringify(docsBaseMetadata, null, 2), JSON.stringify(docsBaseMetadata, null, 2),
@ -461,6 +476,22 @@ Available document ids=
Object.values(content.docsMetadata), Object.values(content.docsMetadata),
'version', 'version',
); );
const rootUrl =
options.homePageId && content.docsMetadata[options.homePageId]
? normalizeUrl([baseUrl, routeBasePath])
: getFirstDocLinkOfSidebar(
content.docsSidebars[
`version-${versioning.latestVersion}/docs`
],
);
if (!rootUrl) {
throw new Error('Bad sidebars file. No document linked');
}
Object.values(content.docsMetadata).forEach((docMetadata) => {
if (docMetadata.version !== versioning.latestVersion) {
docMetadata.latestVersionMainDocPermalink = rootUrl;
}
});
await Promise.all( await Promise.all(
Object.keys(docsMetadataByVersion).map(async (version) => { Object.keys(docsMetadataByVersion).map(async (version) => {
const routes: RouteConfig[] = await genRoutes( const routes: RouteConfig[] = await genRoutes(

View file

@ -118,6 +118,7 @@ export interface MetadataRaw extends LastUpdateData {
sidebar_label?: string; sidebar_label?: string;
editUrl?: string; editUrl?: string;
version?: string; version?: string;
latestVersionMainDocPermalink?: string;
} }
export interface Paginator { export interface Paginator {

View file

@ -12,6 +12,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
import DocPaginator from '@theme/DocPaginator'; import DocPaginator from '@theme/DocPaginator';
import useTOCHighlight from '@theme/hooks/useTOCHighlight'; import useTOCHighlight from '@theme/hooks/useTOCHighlight';
import Link from '@docusaurus/Link';
import clsx from 'clsx'; import clsx from 'clsx';
import styles from './styles.module.css'; import styles from './styles.module.css';
@ -68,6 +69,7 @@ function DocItem(props) {
lastUpdatedAt, lastUpdatedAt,
lastUpdatedBy, lastUpdatedBy,
version, version,
latestVersionMainDocPermalink,
} = metadata; } = metadata;
const { const {
frontMatter: { frontMatter: {
@ -108,6 +110,33 @@ function DocItem(props) {
className={clsx('col', { className={clsx('col', {
[styles.docItemCol]: !hideTableOfContents, [styles.docItemCol]: !hideTableOfContents,
})}> })}>
{latestVersionMainDocPermalink && (
<div
className="alert alert--warning margin-bottom--md"
role="alert">
{version === 'next' ? (
<div>
This is unreleased documentation for {siteTitle}{' '}
<strong>{version}</strong> version.
</div>
) : (
<div>
This is archived documentation for {siteTitle}{' '}
<strong>v{version}</strong>, which is no longer actively
maintained.
</div>
)}
<div className="margin-top--md">
For up-to-date documentation, see the{' '}
<strong>
<Link to={latestVersionMainDocPermalink}>
latest version
</Link>
</strong>
.
</div>
</div>
)}
<div className={styles.docItemContainer}> <div className={styles.docItemContainer}>
<article> <article>
{version && ( {version && (