diff --git a/nx-dev/data-access-documents/src/lib/documents.api.ts b/nx-dev/data-access-documents/src/lib/documents.api.ts index 6fe750ec7f..5a0e66363b 100644 --- a/nx-dev/data-access-documents/src/lib/documents.api.ts +++ b/nx-dev/data-access-documents/src/lib/documents.api.ts @@ -1,4 +1,8 @@ -import { DocumentData, DocumentMetadata } from '@nrwl/nx-dev/models-document'; +import { + createDocumentMetadata, + DocumentData, + DocumentMetadata, +} from '@nrwl/nx-dev/models-document'; import { MenuItem } from '@nrwl/nx-dev/models-menu'; import { parseMarkdown } from '@nrwl/nx-dev/ui-markdoc'; import { readFileSync } from 'fs'; @@ -30,19 +34,19 @@ export class DocumentsApi { (x) => x.itemList ) as DocumentMetadata[]; - this.documents = { + this.documents = createDocumentMetadata({ id: 'documents', name: 'documents', itemList: !!this.options.addAncestor ? [ - { + createDocumentMetadata({ id: this.options.addAncestor.id, name: this.options.addAncestor.name, itemList, - }, + }), ] : itemList, - }; + }); // this.allDocuments = options.allDocuments; } diff --git a/nx-dev/data-access-menu/src/lib/menu.api.ts b/nx-dev/data-access-menu/src/lib/menu.api.ts index a45b20d45a..df26b0d580 100644 --- a/nx-dev/data-access-menu/src/lib/menu.api.ts +++ b/nx-dev/data-access-menu/src/lib/menu.api.ts @@ -45,6 +45,12 @@ export class MenuApi { id: 'packages', name: 'Packages', itemList: packageDocuments, + path: '', + packageName: '', + isExternal: false, + description: '', + file: '', + tags: [], }; const items = createMenuItems(documents); diff --git a/nx-dev/data-access-menu/src/lib/menu.utils.ts b/nx-dev/data-access-menu/src/lib/menu.utils.ts index a10688d1ce..bbd368821d 100644 --- a/nx-dev/data-access-menu/src/lib/menu.utils.ts +++ b/nx-dev/data-access-menu/src/lib/menu.utils.ts @@ -16,7 +16,10 @@ export function createMenuItems(root: DocumentMetadata): MenuItem[] { ); } - return pathData; + return { + ...pathData, + disableCollapsible: false, + } as MenuItem; }; return items?.map((item) => createPathMetadata(item)) ?? []; } @@ -65,6 +68,7 @@ export function getDeepDiveSection(items: MenuItem[]): MenuSection { return { id: 'deep-dive', name: 'Deep Dive', + hideSectionHeader: false, itemList: items .filter( (m) => @@ -104,6 +108,7 @@ export function getPackageApiSection(items: MenuItem[]): MenuSection { return { id: 'official-packages', name: 'Reference', + hideSectionHeader: false, itemList: items .filter( (m) => @@ -116,6 +121,7 @@ export function getPackageApiSection(items: MenuItem[]): MenuSection { ) .map((m) => ({ ...m, + disableCollapsible: true, itemList: [ { id: m.id + '-guides', @@ -159,6 +165,7 @@ export function getDeepDiveNxCloudSection(items: MenuItem[]): MenuSection { return { id: 'deep-dive', name: 'Deep Dive', + hideSectionHeader: false, itemList: items .filter((m) => m.id === 'private-cloud' || m.id === 'reference') .map((m) => ({ diff --git a/nx-dev/data-access-packages/src/lib/packages.api.ts b/nx-dev/data-access-packages/src/lib/packages.api.ts index a802806638..cc0dc7d2ee 100644 --- a/nx-dev/data-access-packages/src/lib/packages.api.ts +++ b/nx-dev/data-access-packages/src/lib/packages.api.ts @@ -1,4 +1,7 @@ -import { DocumentMetadata } from '@nrwl/nx-dev/models-document'; +import { + createDocumentMetadata, + DocumentMetadata, +} from '@nrwl/nx-dev/models-document'; import { PackageMetadata, SchemaMetadata } from '@nrwl/nx-dev/models-package'; import { readFileSync } from 'fs'; @@ -81,43 +84,46 @@ export class PackagesApi { // For production build, the packages files are missing so need this try-catch. // TODO(jack): Look at handling this without try-catch. try { - return { + return createDocumentMetadata({ id: 'packages', name: 'packages', - itemList: this.options.packagesIndex.map((p) => ({ - id: p.name, - name: p.name.replace(/-/gi, ' '), - description: p.description, - packageName: p.packageName, - path: `/packages/${p.name}`, - itemList: this.getPackage(p.name) - .documentation.map((d) => ({ - id: d.id, - name: d.name, - path: d.path, - })) - .concat( - p.schemas.executors.map((e) => ({ - id: e, - name: e, - path: `/packages/${p.name}/executors/${e}`, + itemList: this.options.packagesIndex.map((p) => + createDocumentMetadata({ + id: p.name, + name: p.name.replace(/-/gi, ' '), + description: p.description, + packageName: p.packageName, + path: `/packages/${p.name}`, + itemList: this.getPackage(p.name) + .documentation.map((d) => ({ + id: d.id, + name: d.name, + path: d.path, })) - ) - .concat( - p.schemas.generators.map((g) => ({ - id: g, - name: g, - path: `/packages/${p.name}/generators/${g}`, - })) - ), - })), - }; + .concat( + p.schemas.executors.map((e) => ({ + id: e, + name: e, + path: `/packages/${p.name}/executors/${e}`, + })) + ) + .concat( + p.schemas.generators.map((g) => ({ + id: g, + name: g, + path: `/packages/${p.name}/generators/${g}`, + })) + ) + .map((x) => createDocumentMetadata(x)), + }) + ), + }); } catch { - return { + return createDocumentMetadata({ id: 'packages', name: 'packages', itemList: [], - }; + }); } } diff --git a/nx-dev/models-document/src/index.ts b/nx-dev/models-document/src/index.ts index e6fdfbe110..d9ec959376 100644 --- a/nx-dev/models-document/src/index.ts +++ b/nx-dev/models-document/src/index.ts @@ -1 +1,2 @@ export * from './lib/documents.models'; +export * from './lib/documents.transformers'; diff --git a/nx-dev/models-document/src/lib/documents.models.ts b/nx-dev/models-document/src/lib/documents.models.ts index 5669292223..fdea836c47 100644 --- a/nx-dev/models-document/src/lib/documents.models.ts +++ b/nx-dev/models-document/src/lib/documents.models.ts @@ -6,12 +6,12 @@ export interface DocumentData { export interface DocumentMetadata { id: string; - name?: string; - description?: string; - packageName?: string; - file?: string; - path?: string; - isExternal?: boolean; - itemList?: DocumentMetadata[]; - tags?: string[]; + name: string; + description: string; + packageName: string; + file: string; + path: string; + isExternal: boolean; + itemList: DocumentMetadata[]; + tags: string[]; } diff --git a/nx-dev/models-document/src/lib/documents.transformers.ts b/nx-dev/models-document/src/lib/documents.transformers.ts new file mode 100644 index 0000000000..22fb73b057 --- /dev/null +++ b/nx-dev/models-document/src/lib/documents.transformers.ts @@ -0,0 +1,44 @@ +import { DocumentMetadata } from './documents.models'; + +export function createDocumentMetadata( + defaults: Partial = {} +): DocumentMetadata { + if (!defaults.id) throw new Error('A document entry requires an "id".'); + + return Object.assign( + {}, + { + id: 'fake-id', + name: '', + description: '', + file: '', + itemList: [], + isExternal: false, + packageName: '', + path: '', + tags: [], + }, + defaults + ); +} + +export function convertToDocumentMetadata( + target: Partial +): DocumentMetadata { + if (!target.id) throw new Error('A document entry requires an "id".'); + + if (target.itemList) + target.itemList.map((item) => convertToDocumentMetadata(item)); + + return { + id: target.id, + name: target.name ?? '', + description: target.description ?? '', + file: target.file ?? '', + itemList: target.itemList ?? [], + isExternal: target.isExternal ?? false, + packageName: target.packageName ?? '', + path: target.path ?? '', + tags: target.tags ?? [], + }; +} diff --git a/nx-dev/models-menu/src/lib/menu.models.ts b/nx-dev/models-menu/src/lib/menu.models.ts index aded16cbec..fb30746465 100644 --- a/nx-dev/models-menu/src/lib/menu.models.ts +++ b/nx-dev/models-menu/src/lib/menu.models.ts @@ -8,11 +8,11 @@ export interface MenuSection { id: string; name: string; itemList: MenuItem[]; - hideSectionHeader?: boolean; + hideSectionHeader: boolean; } export interface MenuItem extends DocumentMetadata { - path?: string; - itemList?: MenuItem[]; - disableCollapsible?: boolean; + path: string; + itemList: MenuItem[]; + disableCollapsible: boolean; } diff --git a/nx-dev/nx-dev/lib/api.ts b/nx-dev/nx-dev/lib/api.ts index 5f2e407f05..a08183a7a4 100644 --- a/nx-dev/nx-dev/lib/api.ts +++ b/nx-dev/nx-dev/lib/api.ts @@ -1,7 +1,10 @@ import { DocumentsApi } from '@nrwl/nx-dev/data-access-documents/node-only'; import { MenuApi } from '@nrwl/nx-dev/data-access-menu'; import { PackagesApi } from '@nrwl/nx-dev/data-access-packages/node-only'; -import { DocumentMetadata } from '@nrwl/nx-dev/models-document'; +import { + convertToDocumentMetadata, + DocumentMetadata, +} from '@nrwl/nx-dev/models-document'; import { getBasicNxCloudSection, getBasicSection, @@ -21,9 +24,15 @@ export const packagesApi = new PackagesApi({ export const nxDocumentsApi = new DocumentsApi({ publicDocsRoot: 'nx-dev/nx-dev/public/documentation', documentSources: [ - documents.find((x) => x.id === 'nx-documentation'), - documents.find((x) => x.id === 'additional-api-references'), - ].filter((x) => !!x) as DocumentMetadata[], + documents.find( + (x) => x.id === 'nx-documentation' + ) as Partial, + documents.find( + (x) => x.id === 'additional-api-references' + ) as Partial, + ] + .filter((x) => !!x) + .map((x) => convertToDocumentMetadata(x)), addAncestor: null, }); export const nxRecipesApi = new DocumentsApi({ @@ -36,14 +45,18 @@ export const nxRecipesApi = new DocumentsApi({ export const nxCloudDocumentsApi = new DocumentsApi({ publicDocsRoot: 'nx-dev/nx-dev/public/documentation', documentSources: [ - documents.find((x) => x.id === 'nx-cloud-documentation'), - ].filter((x) => !!x) as DocumentMetadata[], + documents.find( + (x) => x.id === 'nx-cloud-documentation' + ) as Partial, + ] + .filter((x) => !!x) + .map((x) => convertToDocumentMetadata(x)), addAncestor: { id: 'nx-cloud', name: 'Nx Cloud' }, }); export const nxMenuApi = new MenuApi( nxDocumentsApi.getDocuments(), - packagesApi.getPackageDocuments().itemList as DocumentMetadata[], + packagesApi.getPackageDocuments().itemList, [getBasicSection] ); export const nxRecipesMenuApi = new MenuApi( diff --git a/nx-dev/nx-dev/pages/[...segments].tsx b/nx-dev/nx-dev/pages/[...segments].tsx index 113407f32e..5231e69f9a 100644 --- a/nx-dev/nx-dev/pages/[...segments].tsx +++ b/nx-dev/nx-dev/pages/[...segments].tsx @@ -5,7 +5,7 @@ import { import { sortCorePackagesFirst } from '@nrwl/nx-dev/data-access-packages'; import { DocViewer } from '@nrwl/nx-dev/feature-doc-viewer'; import { DocumentData } from '@nrwl/nx-dev/models-document'; -import { Menu, MenuItem } from '@nrwl/nx-dev/models-menu'; +import { Menu, MenuItem, MenuSection } from '@nrwl/nx-dev/models-menu'; import { PackageMetadata } from '@nrwl/nx-dev/models-package'; import { DocumentationHeader, SidebarContainer } from '@nrwl/nx-dev/ui-common'; import type { GetStaticPaths, GetStaticProps } from 'next'; @@ -65,7 +65,7 @@ export default function DocumentationPage( const { menu, document, pkg, schemaRequest } = props; - const vm: { entryComponent: JSX.Element; menu: { sections: MenuItem[] } } = { + const vm: { entryComponent: JSX.Element; menu: Menu } = { entryComponent: , menu: { sections: menu.sections.filter((x) => x.id !== 'official-packages'), @@ -73,23 +73,17 @@ export default function DocumentationPage( }; if (!!pkg) { + const reference: MenuSection | null = + menu.sections.find((x) => x.id === 'official-packages') ?? null; + if (!reference) + throw new Error('Could not find menu section for "official-packages".'); vm.menu = { - sections: sortCorePackagesFirst( - menu.sections.filter((x) => x.id === 'official-packages')[0]?.itemList + sections: sortCorePackagesFirst(reference.itemList).map( + (x) => ({ ...x, hideSectionHeader: false }) ), }; - vm.entryComponent = ( - - ); - } - if (!!pkg && !!schemaRequest) { - vm.menu = { - sections: sortCorePackagesFirst( - menu.sections.filter((x) => x.id === 'official-packages')[0]?.itemList - ), - }; - vm.entryComponent = ( + vm.entryComponent = !!schemaRequest ? ( + ) : ( + ); } diff --git a/nx-dev/ui-common/src/lib/sidebar-container.tsx b/nx-dev/ui-common/src/lib/sidebar-container.tsx index db10059f0b..a442822c2f 100644 --- a/nx-dev/ui-common/src/lib/sidebar-container.tsx +++ b/nx-dev/ui-common/src/lib/sidebar-container.tsx @@ -1,6 +1,13 @@ +import { Menu } from '@nrwl/nx-dev/models-menu'; import { Sidebar, SidebarMobile } from '@nrwl/nx-dev/ui-common'; -export function SidebarContainer({ menu, navIsOpen }: any): JSX.Element { +export function SidebarContainer({ + menu, + navIsOpen, +}: { + menu: Menu; + navIsOpen: boolean; +}): JSX.Element { return (