Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(docs,theme): auto-generated category index should not display unlisted content #8319

Merged
merged 2 commits into from
Nov 10, 2022
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React, {type ReactNode} from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import {
findFirstCategoryLink,
findFirstSidebarItemLink,
useDocById,
} from '@docusaurus/theme-common/internal';
import isInternalUrl from '@docusaurus/isInternalUrl';
Expand Down Expand Up @@ -71,7 +71,7 @@ function CardCategory({
}: {
item: PropSidebarItemCategory;
}): JSX.Element | null {
const href = findFirstCategoryLink(item);
const href = findFirstSidebarItemLink(item);

// Unexpected: categories that don't have a link have been filtered upfront
if (!href) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from '@docusaurus/theme-common';
import {
isActiveSidebarItem,
findFirstCategoryLink,
findFirstSidebarItemLink,
useDocSidebarItemsExpandedState,
isSamePath,
} from '@docusaurus/theme-common/internal';
Expand Down Expand Up @@ -67,7 +67,7 @@ function useCategoryHrefWithSSRFallback(
if (isBrowser || !item.collapsible) {
return undefined;
}
return findFirstCategoryLink(item);
return findFirstSidebarItemLink(item);
}, [item, isBrowser]);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/docusaurus-theme-common/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export {
isDocsPluginEnabled,
useDocById,
findSidebarCategory,
findFirstCategoryLink,
findFirstSidebarItemLink,
isActiveSidebarItem,
isVisibleSidebarItem,
useVisibleSidebarItems,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {renderHook} from '@testing-library/react-hooks';
import {StaticRouter} from 'react-router-dom';
import {Context} from '@docusaurus/core/src/client/docusaurusContext';
import {
findFirstCategoryLink,
findFirstSidebarItemLink,
isActiveSidebarItem,
useDocById,
findSidebarCategory,
Expand Down Expand Up @@ -64,6 +64,7 @@ function testVersion(data?: Partial<PropVersionMetadata>): PropVersionMetadata {
docsSidebars: {},
isLast: false,
pluginId: 'default',
noIndex: false,
...data,
};
}
Expand Down Expand Up @@ -163,9 +164,31 @@ describe('findSidebarCategory', () => {
});

describe('findFirstCategoryLink', () => {
it('works with html item', () => {
const htmlItem = {type: 'html', value: '<div/>'} as const;
expect(findFirstSidebarItemLink(htmlItem)).toBeUndefined();
expect(findFirstSidebarItemLink(htmlItem)).toBeUndefined();
});

it('works with link item', () => {
const linkItem = {
type: 'link',
href: '/linkHref',
label: 'Label',
} as const;

expect(findFirstSidebarItemLink(linkItem)).toBe('/linkHref');
expect(
findFirstSidebarItemLink({
...linkItem,
unlisted: true,
}),
).toBeUndefined();
});

it('works with category without link nor child', () => {
expect(
findFirstCategoryLink(
findFirstSidebarItemLink(
testCategory({
href: undefined,
}),
Expand All @@ -175,17 +198,103 @@ describe('findFirstCategoryLink', () => {

it('works with category with link', () => {
expect(
findFirstCategoryLink(
findFirstSidebarItemLink(
testCategory({
href: '/itemPath',
}),
),
).toBe('/itemPath');
});

it('works with category with deeply nested category link', () => {
it('works with deeply nested category', () => {
expect(
findFirstSidebarItemLink(
testCategory({
href: '/category1',
linkUnlisted: true,
items: [
{type: 'html', value: '<p>test1</p>'},
testCategory({
href: '/category2',
linkUnlisted: true,
items: [
{type: 'html', value: '<p>test2</p>'},
testCategory({
href: '/category3',
items: [
{type: 'html', value: '<p>test2</p>'},
testCategory({
href: '/category4',
linkUnlisted: true,
}),
],
}),
],
}),
],
}),
),
).toBe('/category3');
});

it('works with deeply nested link', () => {
expect(
findFirstCategoryLink(
findFirstSidebarItemLink(
testCategory({
href: '/category1',
linkUnlisted: true,
items: [
{
type: 'link',
href: '/itemPathUnlisted',
label: 'Label',
unlisted: true,
},
testCategory({
href: '/category2',
linkUnlisted: true,
items: [
testCategory({
href: '/category3',
linkUnlisted: true,
items: [
{
type: 'link',
href: '/itemPathUnlisted2',
label: 'Label',
unlisted: true,
},
testCategory({
href: '/category4',
linkUnlisted: true,
}),
{
type: 'link',
href: '/itemPathListed1',
label: 'Label',
},
testCategory({
href: '/category5',
}),
{
type: 'link',
href: '/itemPathListed2',
label: 'Label',
unlisted: true,
},
],
}),
],
}),
],
}),
),
).toBe('/itemPathListed1');
});

it('works with category with deeply nested category link unlisted', () => {
expect(
findFirstSidebarItemLink(
testCategory({
href: undefined,
items: [
Expand All @@ -196,29 +305,37 @@ describe('findFirstCategoryLink', () => {
{type: 'html', value: '<p>test2</p>'},
testCategory({
href: '/itemPath',
linkUnlisted: true,
}),
],
}),
],
}),
),
).toBe('/itemPath');
).toBeUndefined();
});

it('works with category with deeply nested link', () => {
it('works with category with deeply nested link unlisted', () => {
expect(
findFirstCategoryLink(
findFirstSidebarItemLink(
testCategory({
href: undefined,
items: [
testCategory({
href: undefined,
items: [{type: 'link', href: '/itemPath', label: 'Label'}],
items: [
{
type: 'link',
href: '/itemPath',
label: 'Label',
unlisted: true,
},
],
}),
],
}),
),
).toBe('/itemPath');
).toBeUndefined();
});
});

Expand Down
38 changes: 25 additions & 13 deletions packages/docusaurus-theme-common/src/utils/docsUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,38 @@ export function findSidebarCategory(
* Best effort to assign a link to a sidebar category. If the category doesn't
* have a link itself, we link to the first sub item with a link.
*/
export function findFirstCategoryLink(
export function findFirstSidebarItemCategoryLink(
item: PropSidebarItemCategory,
): string | undefined {
if (item.href) {
if (item.href && !item.linkUnlisted) {
return item.href;
}

for (const subItem of item.items) {
if (subItem.type === 'link') {
return subItem.href;
} else if (subItem.type === 'category') {
const categoryLink = findFirstCategoryLink(subItem);
if (categoryLink) {
return categoryLink;
}
const link = findFirstSidebarItemLink(subItem);
if (link) {
return link;
}
// Could be "html" items
}
return undefined;
}

/**
* Best effort to assign a link to a sidebar item.
*/
export function findFirstSidebarItemLink(
item: PropSidebarItem,
): string | undefined {
if (item.type === 'link' && !item.unlisted) {
return item.href;
}
if (item.type === 'category') {
return findFirstSidebarItemCategoryLink(item);
}
// Other items types, like "html"
return undefined;
}

/**
* Gets the category associated with the current location. Should only be used
* on category index pages.
Expand Down Expand Up @@ -391,15 +402,16 @@ export function useDocRootMetadata({route}: DocRootProps): null | {
}

/**
* Filter categories that don't have a link.
* Filter items we don't want to display on the doc card list view
* @param items
*/
export function filterDocCardListItems(
items: PropSidebarItem[],
): PropSidebarItem[] {
return items.filter((item) => {
if (item.type === 'category') {
return !!findFirstCategoryLink(item);
const canHaveLink = item.type === 'category' || item.type === 'link';
if (canHaveLink) {
return !!findFirstSidebarItemLink(item);
}
return true;
});
Expand Down
8 changes: 8 additions & 0 deletions website/_dogfooding/_docs tests/tests/visibility/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,11 @@ In production, unlisted items should remain accessible, but be hidden in the sid
- [./some-unlisteds/unlisted1.md](./some-unlisteds/unlisted1.md)
- [./some-unlisteds/unlisted2.md](./some-unlisteds/unlisted2.md)
- [./some-unlisteds/unlisted-subcategory/unlisted3.md](./some-unlisteds/unlisted-subcategory/unlisted3.md)

---

```mdx-code-block
import DocCardList from '@theme/DocCardList';

<DocCardList />
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ tags: [visibility, draft]
# Only Drafts - Subcategory index draft

Doc with draft front matter

```mdx-code-block
import DocCardList from '@theme/DocCardList';

<DocCardList />
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ tags: [visibility, unlisted]
# Only Unlisteds - Subcategory index unlisted

Doc with unlisted front matter

```mdx-code-block
import DocCardList from '@theme/DocCardList';

<DocCardList />
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ tags: [visibility, draft]
# Some Drafts - Subcategory index draft

Doc with draft front matter

```mdx-code-block
import DocCardList from '@theme/DocCardList';

<DocCardList />
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ tags: [visibility, unlisted]
# Some Unlisteds - Subcategory index unlisted

Doc with unlisted front matter

```mdx-code-block
import DocCardList from '@theme/DocCardList';

<DocCardList />
```