feat(v2): enable subcategories (#1021)

* feat(v2): enable subcategories

* nits

* eslint issue https://github.com/prettier/prettier/issues/3734
This commit is contained in:
Endilie Yacop Sucipto 2018-10-08 17:50:28 +08:00 committed by GitHub
parent 954456088c
commit f62029c30e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 150 additions and 43 deletions

View file

@ -9,7 +9,7 @@ module.exports = {
jest: true, jest: true,
node: true, node: true,
}, },
extends: ['airbnb', 'prettier'], extends: ['airbnb', 'prettier', 'prettier/react'],
rules: { rules: {
'no-console': OFF, 'no-console': OFF,
'func-names': OFF, 'func-names': OFF,

View file

@ -151,6 +151,7 @@ module.exports = async function processMetadata(
if (order[id]) { if (order[id]) {
metadata.sidebar = order[id].sidebar; metadata.sidebar = order[id].sidebar;
metadata.category = order[id].category; metadata.category = order[id].category;
metadata.subCategory = order[id].subCategory;
if (order[id].next) { if (order[id].next) {
metadata.next_id = order[id].next; metadata.next_id = order[id].next;
metadata.next = (language ? `${language}-` : '') + order[id].next; metadata.next = (language ? `${language}-` : '') + order[id].next;

View file

@ -9,11 +9,26 @@ module.exports = function createOrder(allSidebars = {}) {
let ids = []; let ids = [];
const categoryOrder = []; const categoryOrder = [];
const subCategoryOrder = [];
Object.keys(categories).forEach(category => { Object.keys(categories).forEach(category => {
ids = ids.concat(categories[category]); if (Array.isArray(categories[category])) {
// eslint-disable-next-line ids = ids.concat(categories[category]);
for (let i = 0; i < categories[category].length; i++) {
categoryOrder.push(category); // eslint-disable-next-line
for (let i = 0; i < categories[category].length; i++) {
categoryOrder.push(category);
subCategoryOrder.push(undefined);
}
} else {
Object.keys(categories[category]).forEach(subCategory => {
ids = ids.concat(categories[category][subCategory]);
// eslint-disable-next-line
for (let i = 0; i < categories[category][subCategory].length; i++) {
categoryOrder.push(category);
subCategoryOrder.push(subCategory);
}
});
} }
}); });
@ -29,6 +44,7 @@ module.exports = function createOrder(allSidebars = {}) {
next, next,
sidebar, sidebar,
category: categoryOrder[i], category: categoryOrder[i],
subCategory: subCategoryOrder[i],
}; };
} }
}); });

View file

@ -12,37 +12,56 @@ function Sidebar(props) {
return null; return null;
} }
const thisSidebar = docsSidebars[sidebar]; const thisSidebar = docsSidebars[sidebar];
const renderItemLink = rawLinkID => {
const linkID = (language ? `${language}-` : '') + rawLinkID;
const linkMetadata = docsMetadatas[linkID];
if (!linkMetadata) {
throw new Error(
`Improper sidebars.json file, document with id '${linkID}' not found.`,
);
}
const activeItem = linkID === thisID;
return (
<li key={linkID}>
<Link
className={classnames(styles.sidebarLink, {
[styles.sidebarLinkActive]: activeItem,
})}
to={linkMetadata.permalink}>
{linkMetadata.sidebar_label || linkMetadata.title}
</Link>
</li>
);
};
const renderCategory = categoryName => {
const category = thisSidebar[categoryName];
return (
<div className={styles.sidebarGroup} key={categoryName}>
<h3 className={styles.sidebarGroupTitle}>{categoryName}</h3>
<ul className={styles.sidebarList}>
{Array.isArray(category)
? category.map(renderItemLink)
: Object.keys(category).map(subCategoryName => (
<div className={styles.sidebarSubGroup} key={subCategoryName}>
<h4 className={styles.sidebarSubGroupTitle}>
{subCategoryName}
</h4>
<ul className={styles.sidebarList}>
{category[subCategoryName].map(renderItemLink)}
</ul>
</div>
))}
</ul>
</div>
);
};
return ( return (
thisSidebar && ( thisSidebar && (
<div className={styles.sidebar}> <div className={styles.sidebar}>
{Object.keys(thisSidebar).map(categoryName => ( {Object.keys(thisSidebar).map(renderCategory)}
<div className={styles.sidebarGroup} key={categoryName}>
<h3 className={styles.sidebarGroupTitle}>{categoryName}</h3>
<ul className={styles.sidebarList}>
{thisSidebar[categoryName].map(rawLinkID => {
const linkID = (language ? `${language}-` : '') + rawLinkID;
const linkMetadata = docsMetadatas[linkID];
if (!linkMetadata) {
throw new Error(
`Improper sidebars.json file, document with id '${linkID}' not found.`,
);
}
const activeItem = linkID === thisID;
return (
<li key={linkID}>
<Link
className={classnames(styles.sidebarLink, {
[styles.sidebarLinkActive]: activeItem,
})}
to={linkMetadata.permalink}>
{linkMetadata.sidebar_label || linkMetadata.title}
</Link>
</li>
);
})}
</ul>
</div>
))}
</div> </div>
) )
); );

View file

@ -7,7 +7,18 @@
margin-bottom: 20px; margin-bottom: 20px;
} }
.sidebarSubGroup {
margin-top: 10px;
margin-left: 10px;
}
.sidebarSubGroupTitle {
font-size: 16px;
margin: 0;
}
.sidebarGroupTitle { .sidebarGroupTitle {
font-size: 18px;
margin: 0; margin: 0;
} }

View file

@ -38,7 +38,7 @@
"eslint-config-prettier": "^2.9.0", "eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.12.0", "eslint-plugin-import": "^2.12.0",
"eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.9.1", "eslint-plugin-react": "^7.11.1",
"jest": "^23.4.2", "jest": "^23.4.2",
"prettier": "^1.13.7" "prettier": "^1.13.7"
}, },

View file

@ -1,7 +1,58 @@
import createOrder from '@lib/load/docs/order'; import createOrder from '@lib/load/docs/order';
describe('createOrder', () => { describe('createOrder', () => {
test('should populate docs index from multiple sidebars', () => { test('multiple sidebars with subcategory', () => {
const result = createOrder({
docs: {
Category1: {
'Subcategory 1': ['doc1'],
'Subcategory 2': ['doc2'],
},
Category2: ['doc3', 'doc4'],
},
otherDocs: {
Category1: ['doc5'],
},
});
expect(result).toEqual({
doc1: {
category: 'Category1',
subCategory: 'Subcategory 1',
next: 'doc2',
previous: undefined,
sidebar: 'docs',
},
doc2: {
category: 'Category1',
subCategory: 'Subcategory 2',
next: 'doc3',
previous: 'doc1',
sidebar: 'docs',
},
doc3: {
category: 'Category2',
subCategory: undefined,
next: 'doc4',
previous: 'doc2',
sidebar: 'docs',
},
doc4: {
category: 'Category2',
subCategory: undefined,
next: undefined,
previous: 'doc3',
sidebar: 'docs',
},
doc5: {
category: 'Category1',
subCategory: undefined,
next: undefined,
previous: undefined,
sidebar: 'otherDocs',
},
});
});
test('multiple sidebars without subcategory', () => {
const result = createOrder({ const result = createOrder({
docs: { docs: {
Category1: ['doc1', 'doc2'], Category1: ['doc1', 'doc2'],
@ -14,30 +65,35 @@ describe('createOrder', () => {
expect(result).toEqual({ expect(result).toEqual({
doc1: { doc1: {
category: 'Category1', category: 'Category1',
subCategory: undefined,
next: 'doc2', next: 'doc2',
previous: undefined, previous: undefined,
sidebar: 'docs', sidebar: 'docs',
}, },
doc2: { doc2: {
category: 'Category1', category: 'Category1',
subCategory: undefined,
next: 'doc3', next: 'doc3',
previous: 'doc1', previous: 'doc1',
sidebar: 'docs', sidebar: 'docs',
}, },
doc3: { doc3: {
category: 'Category2', category: 'Category2',
subCategory: undefined,
next: 'doc4', next: 'doc4',
previous: 'doc2', previous: 'doc2',
sidebar: 'docs', sidebar: 'docs',
}, },
doc4: { doc4: {
category: 'Category2', category: 'Category2',
subCategory: undefined,
next: undefined, next: undefined,
previous: 'doc3', previous: 'doc3',
sidebar: 'docs', sidebar: 'docs',
}, },
doc5: { doc5: {
category: 'Category1', category: 'Category1',
subCategory: undefined,
next: undefined, next: undefined,
previous: undefined, previous: undefined,
sidebar: 'otherDocs', sidebar: 'otherDocs',
@ -45,7 +101,7 @@ describe('createOrder', () => {
}); });
}); });
test('should resolve docs from older versions', () => { test('versioned sidebars', () => {
const result = createOrder({ const result = createOrder({
docs: { docs: {
Category1: ['doc1'], Category1: ['doc1'],
@ -58,18 +114,21 @@ describe('createOrder', () => {
expect(result).toEqual({ expect(result).toEqual({
doc1: { doc1: {
category: 'Category1', category: 'Category1',
subCategory: undefined,
next: undefined, next: undefined,
previous: undefined, previous: undefined,
sidebar: 'docs', sidebar: 'docs',
}, },
'version-1.2.3-doc1': { 'version-1.2.3-doc1': {
category: 'Category2', category: 'Category2',
subCategory: undefined,
next: undefined, next: undefined,
previous: 'version-1.2.3-doc2', previous: 'version-1.2.3-doc2',
sidebar: 'version-1.2.3-docs', sidebar: 'version-1.2.3-docs',
}, },
'version-1.2.3-doc2': { 'version-1.2.3-doc2': {
category: 'Category1', category: 'Category1',
subCategory: undefined,
next: 'version-1.2.3-doc1', next: 'version-1.2.3-doc1',
previous: undefined, previous: undefined,
sidebar: 'version-1.2.3-docs', sidebar: 'version-1.2.3-docs',

View file

@ -1,9 +1,9 @@
{ {
"docs": { "docs": {
"Foo": [ "Foo": {
"foo/bar", "bar": ["foo/bar"],
"foo/baz" "baz": ["foo/baz"]
], },
"Endi": [ "Endi": [
"docusaurus", "docusaurus",
"highlight", "highlight",

View file

@ -2527,10 +2527,11 @@ eslint-plugin-jsx-a11y@^6.0.3:
has "^1.0.3" has "^1.0.3"
jsx-ast-utils "^2.0.1" jsx-ast-utils "^2.0.1"
eslint-plugin-react@^7.9.1: eslint-plugin-react@^7.11.1:
version "7.10.0" version "7.11.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.10.0.tgz#af5c1fef31c4704db02098f9be18202993828b50" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c"
dependencies: dependencies:
array-includes "^3.0.3"
doctrine "^2.1.0" doctrine "^2.1.0"
has "^1.0.3" has "^1.0.3"
jsx-ast-utils "^2.0.1" jsx-ast-utils "^2.0.1"