diff --git a/AWSCLIV2.pkg b/AWSCLIV2.pkg deleted file mode 100644 index cc4804c3e..000000000 Binary files a/AWSCLIV2.pkg and /dev/null differ diff --git a/build.sh b/build.sh index a6d6c317e..fbaa3b4be 100644 --- a/build.sh +++ b/build.sh @@ -20,7 +20,7 @@ fi echo "=======================================================================================================================================================================" echo "========================================================================== Running parser... ==========================================================================" -./snooty-parser/snooty/snooty build $(pwd)/${TESTING_REPO_NAME} --output=./bundle.zip +./snooty-parser/snooty/snooty build $(pwd)/${TESTING_REPO_NAME} --no-caching --output=./bundle.zip echo "========================================================================== Parser complete ============================================================================" echo "=======================================================================================================================================================================" @@ -28,5 +28,9 @@ echo "========================================================================== echo GATSBY_MANIFEST_PATH=$(pwd)/bundle.zip export GATSBY_MANIFEST_PATH=$(pwd)/bundle.zip +if [ -d "docs-worker-pool" ]; then + node --unhandled-rejections=strict docs-worker-pool/modules/persistence/dist/index.js --path bundle.zip --githubUser netlify +fi + # run the site -npm run build:no-prefix +npm run build diff --git a/gatsby-config.js b/gatsby-config.js index f62fbd952..8b8beaeaa 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -32,6 +32,6 @@ const plugins = [ module.exports = { plugins, - pathPrefix, + // pathPrefix, siteMetadata, }; diff --git a/netlify.toml b/netlify.toml index 36075e6bc..4a1a2f161 100644 --- a/netlify.toml +++ b/netlify.toml @@ -6,7 +6,8 @@ publish = "public" command = ". ./build.sh $REPO_NAME $PARSER_VERSION" [build.environment] -ORG_NAME = "mongodb" -REPO_NAME = "docs-landing" +ORG_NAME = "10gen" +REPO_NAME = "cloud-docs" BRANCH_NAME = "master" -PARSER_VERSION = "0.18.9" +PARSER_VERSION = "0.18.11" +PATH_PREFIX="docs/atlas" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d1c52a8bc..575c7f27a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,7 @@ "html-screen-capture-js": "^1.0.50", "https-browserify": "^1.0.0", "immer": "^9.0.6", + "js-toml": "^1.0.1", "json-schema": "^0.4.0", "lodash": "^4.6.0", "minimist": "^1.2.6", @@ -1834,6 +1835,23 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.26.0", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/@babel/runtime/node_modules/regenerator-runtime": { "version": "0.14.1", "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", @@ -1893,6 +1911,40 @@ "partytown": "bin/partytown.cjs" } }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -13732,6 +13784,19 @@ "node": "*" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, "node_modules/chokidar": { "version": "3.5.3", "funding": [ @@ -14350,9 +14415,10 @@ } }, "node_modules/core-js-pure": { - "version": "3.28.0", + "version": "3.39.0", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/core-js-pure/-/core-js-pure-3.39.0.tgz", + "integrity": "sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg==", "hasInstallScript": true, - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -22149,6 +22215,15 @@ "version": "4.0.0", "license": "MIT" }, + "node_modules/js-toml": { + "version": "1.0.1", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/js-toml/-/js-toml-1.0.1.tgz", + "integrity": "sha512-rHd/IolpFm2V5BmHCEY8CckHs8NDsYZZ64H5RNgA6Opsr9vX4QyTiQPplgtqg7b3ztqYShZC38nl6CUg7QuhXg==", + "dependencies": { + "chevrotain": "^11.0.3", + "xregexp": "^5.1.1" + } + }, "node_modules/js-yaml": { "version": "3.14.1", "license": "MIT", @@ -22602,6 +22677,11 @@ "version": "4.17.21", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "license": "MIT" @@ -32114,6 +32194,14 @@ "version": "0.6.1", "license": "MIT" }, + "node_modules/xregexp": { + "version": "5.1.1", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/xregexp/-/xregexp-5.1.1.tgz", + "integrity": "sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==", + "dependencies": { + "@babel/runtime-corejs3": "^7.16.5" + } + }, "node_modules/xstate": { "version": "4.38.3", "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/xstate/-/xstate-4.38.3.tgz", @@ -33265,6 +33353,22 @@ } } }, + "@babel/runtime-corejs3": { + "version": "7.26.0", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", + "requires": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } + } + }, "@babel/template": { "version": "7.25.9", "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@babel/template/-/template-7.25.9.tgz", @@ -33305,6 +33409,40 @@ "@builder.io/partytown": { "version": "0.7.5" }, + "@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "requires": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "requires": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + }, + "@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + }, + "@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" + }, "@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -41916,6 +42054,19 @@ "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" }, + "chevrotain": { + "version": "11.0.3", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "requires": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, "chokidar": { "version": "3.5.3", "requires": { @@ -42326,7 +42477,9 @@ } }, "core-js-pure": { - "version": "3.28.0" + "version": "3.39.0", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/core-js-pure/-/core-js-pure-3.39.0.tgz", + "integrity": "sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg==" }, "core-util-is": { "version": "1.0.3" @@ -47289,6 +47442,15 @@ "js-tokens": { "version": "4.0.0" }, + "js-toml": { + "version": "1.0.1", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/js-toml/-/js-toml-1.0.1.tgz", + "integrity": "sha512-rHd/IolpFm2V5BmHCEY8CckHs8NDsYZZ64H5RNgA6Opsr9vX4QyTiQPplgtqg7b3ztqYShZC38nl6CUg7QuhXg==", + "requires": { + "chevrotain": "^11.0.3", + "xregexp": "^5.1.1" + } + }, "js-yaml": { "version": "3.14.1", "requires": { @@ -47584,6 +47746,11 @@ "lodash": { "version": "4.17.21" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "lodash.clonedeep": { "version": "4.5.0" }, @@ -53709,6 +53876,14 @@ "xmlserializer": { "version": "0.6.1" }, + "xregexp": { + "version": "5.1.1", + "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/xregexp/-/xregexp-5.1.1.tgz", + "integrity": "sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==", + "requires": { + "@babel/runtime-corejs3": "^7.16.5" + } + }, "xstate": { "version": "4.38.3", "resolved": "https://artifactory.corp.mongodb.com/artifactory/api/npm/npm/xstate/-/xstate-4.38.3.tgz", diff --git a/package.json b/package.json index 475c5bbba..9e44650c8 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,7 @@ "html-screen-capture-js": "^1.0.50", "https-browserify": "^1.0.0", "immer": "^9.0.6", + "js-toml": "^1.0.1", "json-schema": "^0.4.0", "lodash": "^4.6.0", "minimist": "^1.2.6", diff --git a/plugins/gatsby-source-snooty-prod/gatsby-node.js b/plugins/gatsby-source-snooty-prod/gatsby-node.js index 2c408bfc4..09e3002b4 100644 --- a/plugins/gatsby-source-snooty-prod/gatsby-node.js +++ b/plugins/gatsby-source-snooty-prod/gatsby-node.js @@ -21,12 +21,16 @@ const { createOpenAPIChangelogNode } = require('../utils/openapi.js'); const { createProductNodes } = require('../utils/products.js'); const { createDocsetNodes } = require('../utils/docsets.js'); const { createBreadcrumbNodes } = require('../utils/breadcrumbs.js'); - +const { createVersionNodes } = require('../utils/versions-toc.js'); +const { generatePathPrefix } = require('../../src/utils/generate-path-prefix.js'); const assets = new Map(); const projectComponents = new Set(); +const { SITE_PREFIXES } = require('../../src/constansts.js'); let db; +const SITE_PREFIX = SITE_PREFIXES[siteMetadata.project]; + // Creates node for RemoteMetadata, mostly used for Embedded Versions. If no associated products // or data are found, the node will be null const createRemoteMetadataNode = async ({ createNode, createNodeId, createContentDigest }, umbrellaProduct) => { @@ -127,6 +131,7 @@ exports.sourceNodes = async ({ actions, createContentDigest, createNodeId, getNo ); process.exit(1); } + const pageIdPrefix = constructPageIdPrefix(siteMetadata); documents.forEach((doc) => { const { page_id, ...rest } = doc; @@ -195,6 +200,8 @@ exports.sourceNodes = async ({ actions, createContentDigest, createNodeId, getNo await createBreadcrumbNodes({ db, createNode, createNodeId, createContentDigest }); + await createVersionNodes({ createNode, createNodeId, createContentDigest }); + if (process.env['OFFLINE_DOCS'] !== 'true') { const umbrellaProduct = await db.realmInterface.getMetadata( { @@ -225,15 +232,19 @@ exports.sourceNodes = async ({ actions, createContentDigest, createNodeId, getNo await saveStaticFiles(staticFiles); } + const snootyMetadata = { + ...metadataMinusStatic, + pathPrefix: generatePathPrefix(siteMetadata), + }; createNode({ children: [], id: createNodeId('metadata'), internal: { - contentDigest: createContentDigest(metadataMinusStatic), + contentDigest: createContentDigest(snootyMetadata), type: 'SnootyMetadata', }, parent: null, - metadata: metadataMinusStatic, + metadata: snootyMetadata, }); }; @@ -275,6 +286,8 @@ exports.createPages = async ({ actions, graphql, reporter }) => { siteBasePrefix: repoInfo.prefix[envKey], }; + console.log('siteBasePrefix: ', repoBranches.siteBasePrefix); + if (repoInfo.groups?.length > 0) { repoBranches.groups = repoInfo.groups; } @@ -336,7 +349,7 @@ exports.createPages = async ({ actions, graphql, reporter }) => { const mainComponentRelativePath = `../../src/components/DocumentBody.js`; createPage({ - path: assertTrailingSlash(slug), + path: path.join(SITE_PREFIX, assertTrailingSlash(slug)), component: path.resolve(__dirname, mainComponentRelativePath), context: { page_id: page.page_id, @@ -389,6 +402,7 @@ exports.createSchemaCustomization = ({ actions }) => { metadata: JSON branch: String project: String + pathPrefix: String } type PagePath implements Node @dontInfer { @@ -420,5 +434,13 @@ exports.createSchemaCustomization = ({ actions }) => { propertyUrl: String } + type TOC implements Node @dontInfer { + tocTree: JSON! + } + + type VersionsData implements Node @dontInfer { + versionsList: JSON! + } + `); }; diff --git a/plugins/utils/versions-toc.js b/plugins/utils/versions-toc.js new file mode 100644 index 000000000..292bab9a3 --- /dev/null +++ b/plugins/utils/versions-toc.js @@ -0,0 +1,27 @@ +const { load } = require('js-toml'); +const fs = require('fs/promises'); + +const createVersionNodes = async ({ createNode, createNodeId, createContentDigest }) => { + // Getting data for all our versioned repos + + try { + const versionsList = (await fs.readFile(`${process.cwd()}/toc_data/versions.toml`)).toString(); + const repo = load(versionsList); + + createNode({ + versionsList: repo, + id: createNodeId('repo'), + internal: { + contentDigest: createContentDigest(repo), + type: 'VersionsData', + }, + parent: null, + }); + } catch (e) { + console.error('error occurred when reading the versions.toml', e); + } +}; + +module.exports = { + createVersionNodes, +}; diff --git a/src/components/Heading.js b/src/components/Heading.js index 47ac473f2..82657237b 100644 --- a/src/components/Heading.js +++ b/src/components/Heading.js @@ -9,6 +9,8 @@ import useScreenSize from '../hooks/useScreenSize'; import { usePageContext } from '../context/page-context'; import { theme } from '../theme/docsTheme'; import { isOfflineDocsBuild } from '../utils/is-offline-docs-build'; +import { useVersionsToml } from '../hooks/use-versions-toml'; +import { getFeatureFlags } from '../utils/feature-flags'; import ComponentFactory from './ComponentFactory'; import TabSelectors from './Tabs/TabSelectors'; import { TabContext } from './Tabs/tab-context'; @@ -17,6 +19,7 @@ import ConditionalWrapper from './ConditionalWrapper'; import Contents from './Contents'; import Permalink from './Permalink'; import { TimeRequired } from './MultiPageTutorials'; +import UnifiedVersionDropdown from './UnifiedSidenav/UnifiedVersionDropdown'; const h2Styling = css` margin-top: 16px; @@ -66,6 +69,10 @@ const Heading = ({ sectionDepth, nodeData, className, as, ...rest }) => { const { page, tabsMainColumn } = usePageContext(); const hasMethodSelector = page?.options?.['has_method_selector']; const shouldShowMobileHeader = !!(isPageTitle && isTabletOrMobile && hasSelectors && !hasMethodSelector); + // Data for versions.toml, if project is in versions.toml that means the repo is versioned. + const versions = useVersionsToml(); + const { isUnifiedToc } = getFeatureFlags(); + const versionData = versions.find((r) => r.repoName === rest.metadata?.project); return ( <> @@ -103,6 +110,12 @@ const Heading = ({ sectionDepth, nodeData, className, as, ...rest }) => { {'Open Interactive Tutorial'} )} + {isUnifiedToc && sectionDepth === 1 && versionData && ( + <> + +
+ + )} {isPageTitle && ( diff --git a/src/components/Link.js b/src/components/Link.js index 5d5eb27de..a105eaa76 100644 --- a/src/components/Link.js +++ b/src/components/Link.js @@ -9,6 +9,7 @@ import ArrowRightIcon from '@leafygreen-ui/icon/dist/ArrowRight'; import { isRelativeUrl } from '../utils/is-relative-url'; import { joinClassNames } from '../utils/join-class-names'; import { validateHTMAttributes } from '../utils/validate-element-attributes'; +import useSnootyMetadata from '../utils/use-snooty-metadata'; /* * Note: This component is not suitable for internal page navigation: @@ -94,8 +95,11 @@ const Link = ({ hideExternalIcon: hideExternalIconProp, showExternalIcon, openInNewTab, + prefix, ...other }) => { + const { pathPrefix } = useSnootyMetadata(); + if (!to) to = ''; const anchor = to.startsWith('#'); @@ -112,13 +116,44 @@ const Link = ({ '' ); - // Use Gatsby Link for internal links, and for others - if (to && isRelativeUrl(to) && !anchor) { + // If prefix, that means we are coming from the UnifiedSideNav and not the old SideNav + if (prefix) { if (!to.startsWith('/')) to = `/${to}`; // Ensure trailing slash to = to.replace(/\/?(\?|#|$)/, '/$1'); + if (pathPrefix.replaceAll('/', '') === prefix.replaceAll('/', '')) { + return ( + + {children} + {decoration} + + ); + } + + // On the Unified SideNav but linking to a different site + const href = `${prefix + to}`; + return ( + + {children} + {decoration} + + ); + } + + // Use Gatsby Link for internal links, and for others + if (to && isRelativeUrl(to) && !anchor && pathPrefix === prefix) { + if (!to.startsWith('/')) to = `/${to}`; + + // Ensure trailing slash + to = to.replace(/\/?(\?|#|$)/, '/$1'); return ( { +const RootProvider = ({ children, headingNodes, slug, repoBranches, remoteMetadata, versionsData }) => { return ( - + {children} diff --git a/src/components/Sidenav/styles/sideNavItem.js b/src/components/Sidenav/styles/sideNavItem.js index ee586e679..e2fccc215 100644 --- a/src/components/Sidenav/styles/sideNavItem.js +++ b/src/components/Sidenav/styles/sideNavItem.js @@ -29,6 +29,30 @@ export const sideNavItemTOCStyling = ({ level = 1 }) => css` } `; +export const sideNavItemUniTOCStyling = ({ level, isStatic = false }) => css` + align-items: flex-start !important; + // TODO: fix this style when design is finalized (DOP-5375) + font-size: ${isStatic ? theme.fontSize.default : theme.fontSize.small}; + text-transform: none; + line-height: 20px !important; + padding-left: calc(16px + ${(level - 1) * 25}px); +`; + +export const sideNavGroupTOCStyling = () => css` + align-items: flex-start !important; + text-transform: none; + line-height: 20px !important; + + // overwrite LG link underlines + // @leafygreen-ui/typography v13.0.0 + :hover { + &:after, + span:after { + display: none; + } + } +`; + export const sideNavItemFontSize = css` font-size: ${theme.fontSize.small}; `; diff --git a/src/components/UnifiedSidenav/UnifiedSidenav.js b/src/components/UnifiedSidenav/UnifiedSidenav.js new file mode 100644 index 000000000..3d11b0bbc --- /dev/null +++ b/src/components/UnifiedSidenav/UnifiedSidenav.js @@ -0,0 +1,434 @@ +import React, { useState, useEffect, useContext } from 'react'; +import styled from '@emotion/styled'; +import { SideNav, SideNavGroup, SideNavItem } from '@leafygreen-ui/side-nav'; +import { css as LeafyCSS, cx } from '@leafygreen-ui/emotion'; +import Icon from '@leafygreen-ui/icon'; +import { palette } from '@leafygreen-ui/palette'; +import { useViewportSize } from '@leafygreen-ui/hooks'; +import { useLocation } from '@gatsbyjs/reach-router'; +import Link from '../Link'; +import { sideNavItemUniTOCStyling, sideNavGroupTOCStyling } from '../Sidenav/styles/sideNavItem'; +import { useUnifiedToc } from '../../hooks/use-unified-toc'; +import { theme } from '../../theme/docsTheme'; +import useScreenSize from '../../hooks/useScreenSize'; +import { isCurrentPage } from '../../utils/is-current-page'; +import { isSelectedTocNode } from '../../utils/is-selected-toc-node'; +import useSnootyMetadata from '../../utils/use-snooty-metadata'; +import { VersionContext } from '../../context/version-context'; +import useStickyTopValues from '../../hooks/useStickyTopValues'; +import { HeaderContext } from '../Header/header-context'; +import { SidenavContext } from '../Sidenav'; +import useViewport from '../../hooks/useViewport'; +import { SIDE_NAV_CONTAINER_ID } from '../../constants'; +import { useSiteMetadata } from '../../hooks/use-site-metadata'; + +const FormatTitle = styled.div` + scroll-margin-bottom: ${theme.size.xxlarge}; +`; + +const overwriteLinkStyle = LeafyCSS` + span { + display: flex; + } +`; + +const chevronStyle = LeafyCSS` + margin-top: 3px; +`; + +const getTopAndHeight = (topValue) => { + return LeafyCSS` + top: max(min(calc(${topValue} - var(--scroll-y))), ${theme.header.actionBarMobileHeight}); + height: calc(100vh - max(min(calc(${topValue} - var(--scroll-y))), ${theme.header.actionBarMobileHeight})); + `; +}; + +const SidenavContainer = ({ topLarge, topMedium, topSmall }) => LeafyCSS` + grid-area: sidenav; + position: sticky; + z-index: ${theme.zIndexes.sidenav}; + top: 0px; + height: calc( + 100vh + ${theme.header.actionBarMobileHeight} - ${topLarge} + + min(calc(${topLarge} - ${theme.header.actionBarMobileHeight}), var(--scroll-y)) + ); + + @media ${theme.screenSize.upToLarge} { + ${getTopAndHeight(topMedium)}; + } + + @media ${theme.screenSize.upToSmall} { + ${getTopAndHeight(topSmall)}; + } +`; + +const sideNavStyle = ({ hideMobile }) => LeafyCSS` + height: 100%; + + + // Mobile & Tablet nav + @media ${theme.screenSize.upToLarge} { + position: absolute; + ${hideMobile && 'display: none;'} + + button[data-testid="side-nav-collapse-toggle"] { + display: none; + } + } + + padding: 0px; + div > ul { + display: flex; + flex-direction: row; + // width: 400px; + // height: 100vh; + // overflow-y: auto; + // position: fixed; + // left: 0; + // top: 0; + + ul { + display: block; + width: 100%; + + li { + a { + justify-content: space-between !important; + } + } + } + + } +`; + +const leftPane = LeafyCSS` + flex: 1; + overflow-y: auto; + background-color: #f8f9fa; + border-right: 3px solid #ddd; +`; + +const rightPane = LeafyCSS` + flex: 2; + overflow-y: auto; +`; + +// we will maybe have to edit this function in the future since if we have double panned side nav in theory two things should be selected at same time +function isSelectedTab(url, slug) { + return isSelectedTocNode(url, slug); +} + +function CollapsibleNavItem({ items, label, url, slug, prefix, level }) { + const [isOpen, setIsOpen] = useState(isActiveTocNode(slug, url, items)); + const chevronType = isOpen ? 'ChevronDown' : 'ChevronRight'; + + const onChevronClick = (event) => { + event.preventDefault(); + setIsOpen(!isOpen); + }; + + const handleClick = () => { + // Allows the collapsed item if the chevron was selected first before + if (!(url !== `/${slug}` && isOpen)) { + setIsOpen(!isOpen); + } + }; + + return ( + <> + + {label} + + + {isOpen && items.map((item) => )} + + ); +} + +function UnifiedTocNavItem({ + label, + group, + url, + collapsible, + items, + isStatic, + prefix, + slug, + activeTabUrl, + isTabletOrMobile, + level, +}) { + // These are the tab items that we dont need to show in the second pane but need to go through recursively + // Unless in Mobile doing Accordion view + if (isStatic) { + if (isTabletOrMobile) { + return ( + <> + + {url === activeTabUrl && + items?.map((tocItem) => ( + + ))} + + ); + } + + return ( + <> + {items?.map((tocItem) => ( + + ))} + + ); + } + + // groups are for adding a static header, these can also be collapsible + if (group) { + return ( + + {items?.map((tocItem) => ( + + ))} + + ); + } + + // collapsible is for items that have nested links + if (collapsible) { + return ( + + ); + } + + return ( + + {label} + + ); +} + +function StaticNavItem({ label, url, slug, items, isStatic, prefix, level = 1 }) { + return ( + + {label} + + ); +} + +// This checks what sidenav should load based on the active Tab +const isActiveTocNode = (currentUrl, slug, children) => { + if (currentUrl === undefined) return false; + if (isCurrentPage(currentUrl, slug)) return true; + if (children) { + return children.reduce((a, b) => a || isActiveTocNode(currentUrl, b.url, b.items), false); + } + return false; +}; + +const replaceVersion = ({ url, currentVersion, versionsData }) => { + // Find the version data for the current content we are in + const noVersion = url.replace(/\$\{([^}]+)\}/g, ''); + const content = versionsData.find((obj) => obj.repoSlug.replaceAll('/', '') === noVersion.replaceAll('/', '')); + if (!content) return; + + const proj = content.repoName; + + // based on the activeVersion, find the correct verion + let ver = content?.version.find((obj) => obj.name === currentVersion[proj]); + if (!ver) { + // If no current version, use first version in the array + ver = content.version[0]; + } + + // input the correct alias into the url + const result = url?.replace(/\$\{([^}]+)\}/g, ver.urlSlug); + + return result; +}; + +// Function that adds a prefix to all the urls +const updateURLs = ({ tree, prefix, activeVersions, versionsData, project, snootyEnv }) => { + return tree?.map((item) => { + // Getting the path prefix and editing it based on the environment so links work correctly + let updatedPrefix = prefix; + if (item.prefix) { + item.prefix = + snootyEnv === 'dotcomprd' + ? `/docs${item.prefix}` + : snootyEnv === 'dotcomstg' + ? `/docs-qa${item.prefix}` + : item.prefix; + const result = replaceVersion({ + url: item.prefix, + currentVersion: activeVersions, + versionsData, + project, + }); + // For incase result is undefined + updatedPrefix = result ? result : item.prefix; + } + + // Edit the url with the correct version path + const newUrl = `${updatedPrefix}${item.url ? item.url : ''}`; + + const items = updateURLs({ + tree: item.items, + prefix: updatedPrefix, + activeVersions, + versionsData, + project, + snootyEnv, + }); + + return { + ...item, + newUrl, + items, + prefix: updatedPrefix, + }; + }); +}; + +export function UnifiedSidenav({ slug, versionsData }) { + const unifiedTocTree = useUnifiedToc(); + const { project } = useSnootyMetadata(); + const { snootyEnv } = useSiteMetadata(); + const { activeVersions } = useContext(VersionContext); + const { hideMobile, setHideMobile } = useContext(SidenavContext); + const viewportSize = useViewportSize(); + const { isTabletOrMobile } = useScreenSize(); + const { bannerContent } = useContext(HeaderContext); + const topValues = useStickyTopValues(false, true, !!bannerContent); + const { pathname } = useLocation(); + + // TODO for testing: Use this tree instead of the unifiedTocTree in the preprd enviroment + const tree = updateURLs({ tree: unifiedTocTree, prefix: '', activeVersions, versionsData, project, snootyEnv }); + console.log('The edited toctree with prefixes is:', tree); + console.log(unifiedTocTree); + + const [activeTabUrl, setActiveTabUrl] = useState(() => { + const activeToc = tree.find((staticTocItem) => { + return isActiveTocNode(slug, staticTocItem.url, staticTocItem.items); + }); + return activeToc?.url; + }); + + useEffect(() => { + setActiveTabUrl(() => { + const activeToc = tree.find((staticTocItem) => { + return isActiveTocNode(slug, staticTocItem.url, staticTocItem.items); + }); + return activeToc?.url; + }); + }, [slug, tree]); + + // close navigation panel on mobile screen, but leaves open if they click on a twisty + useEffect(() => { + setHideMobile(true); + }, [pathname, setHideMobile]); + + // listen for scrolls for mobile and tablet menu + const viewport = useViewport(false); + + // Hide the Sidenav with css while keeping state as open/not collapsed. + // This prevents LG's SideNav component from being seen in its collapsed state on mobile + return ( + <> +
+ +
+ {isTabletOrMobile + ? tree.map((navItems) => { + return ( + + ); + }) + : tree.map((staticTocItem) => { + return ; + })} +
+ {activeTabUrl && !isTabletOrMobile && ( +
+ {tree.map((navItems) => { + if (navItems.url === activeTabUrl) { + return ( + + ); + } + return null; + })} +
+ )} +
+
+ + ); +} diff --git a/src/components/UnifiedSidenav/UnifiedVersionDropdown.js b/src/components/UnifiedSidenav/UnifiedVersionDropdown.js new file mode 100644 index 000000000..85bece2a2 --- /dev/null +++ b/src/components/UnifiedSidenav/UnifiedVersionDropdown.js @@ -0,0 +1,88 @@ +import React, { useCallback, useContext } from 'react'; +import PropTypes from 'prop-types'; +import { cx, css as LeafyCSS } from '@leafygreen-ui/emotion'; +import { Option, Select } from '@leafygreen-ui/select'; +import { useLocation } from '@gatsbyjs/reach-router'; +import { VersionContext } from '../../context/version-context'; +import { useSiteMetadata } from '../../hooks/use-site-metadata'; +import { theme } from '../../theme/docsTheme'; +import useSnootyMetadata from '../../utils/use-snooty-metadata'; +import { isOfflineDocsBuild } from '../../utils/is-offline-docs-build'; + +const selectStyling = LeafyCSS` + margin: ${theme.size.small} ${theme.size.medium} ${theme.size.small} ${theme.size.medium}; + + ${'' /* Render version dropdown text in front of the Sidebar text */} + button { + z-index: 2; + background-color: var(--select-button-bg-color); + color: var(--select-button-color); + + div:last-child svg { + color: var(--select-button-carot); + } + + .dark-theme &:hover { + background-color: var(--gray-dark4); + color: var(--gray-light3); + border-color: var(--gray-base); + box-shadow: var(--gray-dark2) 0px 0px 0px 3px; + } + } + + /* Override LG mobile style of enlarged mobile font */ + @media ${theme.screenSize.upToLarge} { + div, + span { + font-size: ${theme.fontSize.small}; + } + } +`; + +const UnifiedVersionDropdown = ({ versionData }) => { + const { snootyEnv } = useSiteMetadata(); + const { project } = useSnootyMetadata(); + const { activeVersions, onTomlVersion } = useContext(VersionContext); + const location = useLocation(); + + // value is the version we want to switch to + const onSelectChange = useCallback( + (value, key) => { + onTomlVersion(project, value, location.pathname, snootyEnv); + }, + [onTomlVersion, project, location, snootyEnv] + ); + + const unifiedOption = (slug, verName, label) => { + return ( + + ); + }; + + return ( + + ); +}; + +UnifiedVersionDropdown.propTypes = { + slug: PropTypes.string.isRequired, +}; + +export default UnifiedVersionDropdown; diff --git a/src/constants.js b/src/constants.js index 2af0a602e..ce5063239 100644 --- a/src/constants.js +++ b/src/constants.js @@ -17,3 +17,7 @@ export const REF_TARGETS = { }; export const MARIAN_URL = process.env.GATSBY_MARIAN_URL || 'https://docs-search-transport.mongodb.com/'; + +export const SITE_PREFIXES = { + 'cloud-docs': '/docs/atlas', +}; diff --git a/src/context/version-context.js b/src/context/version-context.js index 1875de47e..cf295a0a1 100644 --- a/src/context/version-context.js +++ b/src/context/version-context.js @@ -9,6 +9,7 @@ import { getLocalValue, setLocalValue } from '../utils/browser-storage'; import { fetchDocset, fetchDocument } from '../utils/realm'; import { getUrl } from '../utils/url-utils'; import useSnootyMetadata from '../utils/use-snooty-metadata'; +import { getFeatureFlags } from '../utils/feature-flags'; // <-------------- begin helper functions --------------> const STORAGE_KEY = 'activeVersions'; @@ -31,6 +32,19 @@ const getInitVersions = (branchListByProduct) => { return initState; }; +// Set the inital active version using versions.toml +const getInitVersionsToml = (project, versionsData) => { + const localStorage = getLocalValue(STORAGE_KEY); + const initState = {}; + + if (localStorage) { + initState[project] = localStorage[project]; + return initState; + } + + return getDefaultActiveVersionsToml(project, versionsData); +}; + const findBranchByGit = (gitBranchName, branches) => { if (!branches || !branches.length) { return; @@ -39,8 +53,6 @@ const findBranchByGit = (gitBranchName, branches) => { return branches.find((b) => b.gitBranchName === gitBranchName); }; -// version state reducer helper fn -// overwrite current state with any new state attributes const versionStateReducer = (state, newState) => { return { ...state, @@ -100,6 +112,14 @@ const getDefaultVersions = (metadata, repoBranches, associatedReposInfo) => { return versions; }; +// If repo not saved in local storage use the first version in the array from versions.toml +const getDefaultActiveVersionsToml = (project, versionsData) => { + const initVersion = {}; + const curVersionData = versionsData.find((obj) => obj.repoName === project); + initVersion[project] = curVersionData.version[0].name; + return initVersion; +}; + const getDefaultGroups = (project, repoBranches) => { const groups = {}; const GROUP_KEY = 'groups'; @@ -143,10 +163,12 @@ const VersionContext = createContext({ showEol: false, isAssociatedProduct: false, onVersionSelect: () => {}, + onTomlVersion: () => {}, }); -const VersionContextProvider = ({ repoBranches, slug, children }) => { +const VersionContextProvider = ({ repoBranches, slug, children, versionsData }) => { const siteMetadata = useSiteMetadata(); + const { isUnifiedToc } = getFeatureFlags(); const associatedProductNames = useAllAssociatedProducts(); const docsets = useAllDocsets(); const { project } = useSnootyMetadata(); @@ -171,9 +193,11 @@ const VersionContextProvider = ({ repoBranches, slug, children }) => { }, [siteMetadata, project]); const mountRef = useRef(true); + // TODO: Might need to update this once we use this branch on a stitched project (DOP-5243 dependent) // TODO check whats going on here for 404 pages // tracks active versions across app const [activeVersions, setActiveVersions] = useReducer(versionStateReducer, metadata, getDefaultActiveVersions); + // update local storage when active versions change useEffect(() => { const existing = getLocalValue(STORAGE_KEY); @@ -199,7 +223,9 @@ const VersionContextProvider = ({ repoBranches, slug, children }) => { if (!mountRef.current) { return; } - setActiveVersions(getInitVersions(versions)); + isUnifiedToc + ? setActiveVersions(getInitVersionsToml(project, versionsData)) + : setActiveVersions(getInitVersions(versions)); setAvailableGroups(groups); setAvailableVersions(versions); setShowEol(hasEolBranches); @@ -247,6 +273,24 @@ const VersionContextProvider = ({ repoBranches, slug, children }) => { [availableVersions, metadata, repoBranches, slug] ); + // handler for a versions.toml dropdown + const onTomlVersion = useCallback( + (targetProject, versionName, location, snootyEnv) => { + // store previous version + const prevVersion = activeVersions[targetProject]; + + // update to new version + const updatedVersion = {}; + updatedVersion[targetProject] = versionName; + setActiveVersions(updatedVersion); + + // navigate to location replacing old version with new version + let newlocation = location.replace(prevVersion, versionName); + if (snootyEnv === 'development') newlocation = newlocation + 'index.html'; + navigate(newlocation); + }, + [activeVersions] + ); // attempts to find branch by given url alias. can be alias, urlAliases, or gitBranchName const findBranchByAlias = useCallback( (alias) => { @@ -275,12 +319,12 @@ const VersionContextProvider = ({ repoBranches, slug, children }) => { console.error(`url <${currentUrlSlug}> does not correspond to any current branch`); return; } - if (activeVersions[metadata.project] !== currentBranch.gitBranchName) { + if (activeVersions[metadata.project] !== currentBranch.gitBranchName && !isUnifiedToc) { const newState = { ...activeVersions }; newState[metadata.project] = currentBranch.gitBranchName; setActiveVersions(newState); } - }, [activeVersions, currentUrlSlug, findBranchByAlias, metadata.project, setActiveVersions]); + }, [activeVersions, currentUrlSlug, findBranchByAlias, metadata.project, setActiveVersions, isUnifiedToc]); return ( { availableGroups, showVersionDropdown, onVersionSelect, + onTomlVersion, isAssociatedProduct, showEol, }} diff --git a/src/hooks/use-canonical-url.js b/src/hooks/use-canonical-url.js index 4bbbbb018..5760fffce 100644 --- a/src/hooks/use-canonical-url.js +++ b/src/hooks/use-canonical-url.js @@ -10,6 +10,7 @@ export const useCanonicalUrl = (meta, metadata, slug, repoBranches) => { const urlSlug = repoBranches?.branches.find((branch) => branch.gitBranchName === parserBranch)?.urlSlug ?? parserBranch; const siteBasePrefix = repoBranches?.siteBasePrefix; + console.log('siteBasePrefix: ', repoBranches.siteBasePrefix); const pathPrefix = generateVersionedPrefix(urlSlug, siteBasePrefix); // Use default logic assuming there is no canonical provided from the meta directive diff --git a/src/hooks/use-unified-toc.js b/src/hooks/use-unified-toc.js new file mode 100644 index 000000000..edbf5aeae --- /dev/null +++ b/src/hooks/use-unified-toc.js @@ -0,0 +1,5 @@ +import { tocData } from '../../toc_data/toc'; + +export function useUnifiedToc() { + return tocData(); +} diff --git a/src/hooks/use-versions-toml.js b/src/hooks/use-versions-toml.js new file mode 100644 index 000000000..cc43a29b0 --- /dev/null +++ b/src/hooks/use-versions-toml.js @@ -0,0 +1,14 @@ +const { useStaticQuery, graphql } = require('gatsby'); + +export function useVersionsToml() { + const data = useStaticQuery( + graphql` + query versionsData { + versionsData { + versionsList + } + } + ` + ); + return data.versionsData.versionsList.repo ?? []; +} diff --git a/src/layouts/index.js b/src/layouts/index.js index 1e83b5df8..35d9ef2b7 100644 --- a/src/layouts/index.js +++ b/src/layouts/index.js @@ -13,6 +13,9 @@ import { theme } from '../theme/docsTheme'; import useSnootyMetadata from '../utils/use-snooty-metadata'; import { useRemoteMetadata } from '../hooks/use-remote-metadata'; import { getAllLocaleCssStrings } from '../utils/locale'; +import { UnifiedSidenav } from '../components/UnifiedSidenav/UnifiedSidenav'; +import { getFeatureFlags } from '../utils/feature-flags'; +import { useVersionsToml } from '../hooks/use-versions-toml'; // TODO: Delete this as a part of the css cleanup // Currently used to preserve behavior and stop legacy css @@ -94,9 +97,10 @@ export const StyledContentContainer = styled('div')` const DefaultLayout = ({ children, data: { page }, pageContext: { slug, repoBranches, template } }) => { const { sidenav } = getTemplate(template); const { chapters, guides, slugToTitle, toctree, eol, project } = useSnootyMetadata(); + const { isUnifiedToc } = getFeatureFlags(); const remoteMetadata = useRemoteMetadata(); - const isInPresentationMode = usePresentationMode()?.toLocaleLowerCase() === 'true'; + const versionsData = useVersionsToml(); const pageTitle = React.useMemo( () => page?.ast?.options?.title || slugToTitle?.[slug === '/' ? 'index' : slug], @@ -112,10 +116,13 @@ const DefaultLayout = ({ children, data: { page }, pageContext: { slug, repoBran headingNodes={page?.ast?.options?.headings} remoteMetadata={remoteMetadata} project={project} + versionsData={versionsData} > {!isInPresentationMode ?
:
} - {sidenav && !isInPresentationMode ? ( + {isUnifiedToc ? ( + + ) : sidenav && !isInPresentationMode ? ( { // If user specified a PATH_PREFIX environment variable, ensure it begins with a prefix and use if (pathPrefix) { @@ -8,21 +6,6 @@ const generatePathPrefix = ({ commitHash, parserBranch, patchId, pathPrefix, pro } return `/${pathPrefix}`; } - - let prefix = ''; - if (commitHash) prefix += `${commitHash}`; - if (patchId) prefix += `/${patchId}`; - - // Include the Snooty branch in pathPrefix for Snooty developers. mut automatically - // includes the git branch of the repo where it is called, so this parameter must - // be present in the URL's path prefix in order to be mut-compatible. - // - // TODO: Simplify this logic when Snooty development is staged in integration environment - const base = `${project}/${user}`; - const path = process.env.GATSBY_SNOOTY_DEV - ? `/${prefix}/${parserBranch}/${base}/${snootyBranch}` - : `/${prefix}/${base}/${parserBranch}`; - return normalizePath(path); }; // TODO: switch to ES6 export syntax if Gatsby implements support for ES6 module imports diff --git a/toc_data/toc.ts b/toc_data/toc.ts new file mode 100644 index 000000000..2f5fd78c9 --- /dev/null +++ b/toc_data/toc.ts @@ -0,0 +1,245 @@ +interface TocItem { + label: string; + glyph?: string; + url?: string; + group?: boolean; + prefix?: string; + collapsible?: boolean; + items?: TocItem[]; +} + +const DOCS = 'docs'; +const ATLAS_PREFIX = 'atlas'; + +export const tocData = (): TocItem[] => { + const toc: TocItem[] = [ + { + label: "(Won't work) C# Quick Start", + url: '/c-sharp', + glyph: 'Bulb', + prefix: '/drivers/c-sharp', + items: [ + { + label: 'C# Documentation', + group: true, + items: [ + { + label: 'Quick Reference', + url: '/quick-reference/', + }, + { + label: 'Usage Examples', + url: '/usage-examples', + collapsible: true, + items: [ + { + label: 'Find a Document', + url: '/usage-examples/findOne/', + }, + { + label: 'Find Multiple Documents', + url: '/usage-examples/findMany/', + }, + { + label: 'Insert a Document', + url: '/usage-examples/insertOne', + }, + ], + }, + { + label: "What's New", + url: '/whats-new', + }, + ], + }, + { + label: 'Fundamentals', + group: true, + items: [ + { + label: 'Operations with Builders', + url: '/fundamentals/builders', + }, + { + label: 'Databases and Collections', + url: '/fundamentals/database-collection', + collapsible: true, + items: [ + { + label: 'Run a Database Command', + url: '/fundamentals/databases-collections/run-command', + }, + ], + }, + ], + }, + { + label: 'Connect to cloud', + group: true, + prefix: '/master/cloud-docs/bianca.laube/DOP-5343', + items: [ + { + label: 'Manage Clusters', + url: '/manage-database-deployments', + collapsible: true, + items: [ + { + label: 'Storage', + url: '/customize-storage', + }, + { + label: 'Auto-Scaling', + url: '/cluster-autoscaling', + }, + ], + }, + ], + }, + ], + }, + { + label: 'Get Started', + url: '/getting-started', + glyph: 'LightningBolt', + items: [ + { + label: 'Get Started', + group: true, + prefix: '/docs/atlas', + items: [ + { + label: 'Create Account', + url: `/${DOCS}/${ATLAS_PREFIX}/tutorial/create-atlas-account/`, + }, + { + label: 'Deploy a Free Cluster', + prefix: '/docs/atlas', + url: '/docs/atlas/tutorial/deploy-free-tier-cluster/', + }, + { + label: 'Manage Database Users', + prefix: '/docs/atlas', + url: '/tutorial/create-mongodb-user-for-cluster/', + }, + { + label: "(Won't work) Manage the IP Access List", + url: '/tutorial/access-list/', + }, + { + label: 'Connect to the Cluster', + prefix: '/docs/atlas', + url: '/tutorial/connect-to-your-cluster/', + }, + { + label: "(Won't work) Insert and View a Document", + url: '/tutorial/insert-and-view', + }, + { + label: "(Won't work) Load Sample Data", + url: '/tutorial/load-data', + }, + { + label: "(Won't work) Generate Synthetic Data", + url: '/tutorial/generate-data', + }, + ], + }, + { + label: "(Won't work) Docs Compass", + prefix: '/master/compass/bianca.laube/DOP-5343', + group: true, + items: [ + { + label: 'Overview', + url: '/', + }, + { + label: 'Import and export', + url: '/import-export', + }, + ], + }, + ], + }, + { + label: 'Application Development', + url: '/create-connect-deployments', + glyph: 'Code', + prefix: '/master/cloud-docs/bianca.laube/DOP-5343', + items: [ + { + label: 'Application Development', + group: true, + items: [ + { + label: 'Connect to Clusters', + url: '/connect-to-database-deployment', + collapsible: true, + items: [ + { + label: 'Drivers', + url: '/driver-connection', + }, + { + label: 'Compass', + url: '/compass-connection', + }, + { + label: 'mongosh', + url: '/mongo-shell-connection', + }, + { + collapsible: true, + label: 'BI Connector', + url: '/bi-connection', + items: [ + { + label: 'Transition to Atlas SQL', + url: '/tutorial/transition-bic-to-atlas-sql', + }, + { + label: 'System DSN', + url: '/tutorial/create-system-dsn', + }, + ], + }, + ], + }, + { + label: 'Command Line Tools', + url: '/command-line-tools', + }, + { + label: 'VS Code', + url: '/mongodb-for-vscode', + }, + ], + }, + { + label: 'Security', + group: true, + items: [ + { + label: 'Authentication', + url: '/authentication', + }, + { + label: 'Auditing', + url: '/auditing', + }, + { + label: 'Encryption', + url: '/encryption', + }, + { + label: 'Support Access', + url: '/support-acces', + }, + ], + }, + ], + }, + ]; + + return toc; +}; diff --git a/toc_data/toc.yaml b/toc_data/toc.yaml new file mode 100644 index 000000000..d61e25419 --- /dev/null +++ b/toc_data/toc.yaml @@ -0,0 +1,85 @@ +toc: + - label: Get Started + url: /getting-started + glyph: LightningBolt + items: + - label: Get Started + group: true + items: + - label: Create Account + url: /tutorial/create-atlas-account + - label: Deploy a Free Cluster + url: /tutorial/deploy-free-tier-cluster + - label: Manage Database Users + url: /tutorial/manage-users + - label: Manage the IP Access List + url: /tutorial/access-list + - label: Connect to the Cluster + url: /tutorial/connect-to-the-cluster + - label: Insert and View a Document + url: /tutorial/insert-and-view + - label: Load Sample Data + url: /tutorial/load-data + - label: Generate Synthetic Data + url: /tutorial/generate-data + + - label: Application Development + url: /application-development + glyph: Code + items: + - label: Application Development + group: true + items: + - label: link test + url: /link + - label: Connect to Clusters + url: /connect-to-clusters + collapsible: true + items: + - label: Drivers + url: /drivers + - label: Compass + url: /compass + - label: mongosh + url: /mongosh + - collapsible: true + label: BI Connector + url: /bi-connector + items: + - label: Transition to Atlas SQL + url: /transition-atlas-sql + - label: System DSN + url: /system-dsn + - label: Excel + url: /excel + - label: Tableau Desktop + url: /tableau + - label: Qlik Sense + url: /qlik-sense + - label: MySQL Workbench + url: /mysql-workbench + - label: Power BI Desktop + url: /power-bi-desktop + - label: Command Line Tools + url: /cli-tools + - label: VS Code + url: /vs-code + - label: AWS Lambda + url: /aws-lambda + - label: Azure Functions + url: /azure-functions + - label: Google Cloud Functions + url: /google-cloud-functions + - label: Troubleshoot + url: /troubleshoot + - label: Security + group: true + items: + - label: Authentication + url: /authenticatio + - label: Auditing + url: /auditing + - label: Encryption + url: /encryption + - label: Support Access + url: /support-acces diff --git a/toc_data/toc_example.js b/toc_data/toc_example.js new file mode 100644 index 000000000..75bb4bc3f --- /dev/null +++ b/toc_data/toc_example.js @@ -0,0 +1,145 @@ +export const tocData = () => { + const toc = { + toc: [ + { + prefix: '/drivers/csharp/version', // this will be item one + label: 'C# Quick Start', + url: '/quick-start', + items: [ + { + label: 'Overview', + url: '/', + }, + { + label: 'Get Started', + group: true, + items: [ + { + label: 'Quick Reference', + url: '/quick-reference/', + }, + { + label: "What's new", + url: '/whats-new/', + }, + { + label: 'FAQ', + url: '/faq', + }, + ], + }, + ], + }, + { + prefix: '/csharp/version', // this will be item 2 + label: 'Fundamentals', + url: '/fundamentals', + items: [ + { + label: 'Connection', + group: true, + items: [ + { + label: 'Connection Guide', + url: '/fundamentals/connection/connect/', + }, + { + label: 'Connection Options', + url: '/fundamentals/connection/connection-options/', + }, + { + label: 'Network Compression', + url: '/fundamentals/connection/network-compression/', + }, + ], + }, + { + label: 'CRUD Operations', + group: true, + items: [ + { + label: 'Operations with Builders', + url: '/fundamentals/builders/', + }, + { + label: 'Write', + url: '/fundamentals/crud/write-operations/', + collapsible: true, + items: [ + { + label: 'Insert', + url: '/fundamentals/crud/write-operations/insert/', + }, + { + label: 'Replace', + url: '/fundamentals/crud/write-operations/replace/', + }, + { + label: 'Update Many', + url: '/fundamentals/crud/write-operations/update-many/', + collapsible: true, + items: [ + { + label: 'Fields', + url: '/fundamentals/crud/write-operations/update-many/fields', + }, + { + label: 'Arrays', + url: '/fundamentals/crud/write-operations/update-many/arrays', + }, + ], + }, + ], + }, + { + label: 'Read', + url: '/fundamentals/crud/read-operations/', + collapsible: true, + items: [ + { + label: 'Retrieve Data', + url: '/fundamentals/crud/read-operations/retrieve/', + }, + { + label: 'Specify Fields to Return', + url: '/fundamentals/crud/read-operations/project/', + }, + ], + }, + ], + }, + ], + }, + { + label: 'Examples', // this will be item 3 + url: '/usage-examples/', + items: [ + { + label: 'Updating Documents', + group: true, + items: [ + { + label: 'Find a document', + url: '/usage-examples/findOne/', + }, + { + label: 'Insert a Document', + url: '/usage-examples/insertOne/', + }, + { + label: 'Update a document', + url: '/usage-examples/updateOne/', + }, + { + label: 'Issues and Help', + url: '/issues-and-help/', + }, + ], + }, + ], + }, + ], + }; + + return toc; +}; diff --git a/toc_data/toc_example.json b/toc_data/toc_example.json new file mode 100644 index 000000000..e7b8ca769 --- /dev/null +++ b/toc_data/toc_example.json @@ -0,0 +1,141 @@ +{ + "toc": [ + { + "prefix": "/drivers/csharp/${version}", + "label": "C# Quick Start", + "url": "/quick-start", + "items": [ + { + "label": "Overview", + "url": "/" + }, + { + "label": "Get Started", + "group": true, + "items": [ + { + "label": "Quick Reference", + "url": "/quick-reference/" + }, + { + "label": "What's new", + "url": "/whats-new/" + }, + { + "label": "FAQ", + "url": "/faq" + } + ] + } + ] + }, + { + "prefix": "/csharp/${version}", + "label": "Fundamentals", + "url": "/fundamentals", + "items": [ + { + "label": "Connection", + "group": true, + "items": [ + { + "label": "Connection Guide", + "url": "/fundamentals/connection/connect/" + }, + { + "label": "Connection Options", + "url": "/fundamentals/connection/connection-options/" + }, + { + "label": "Network Compression", + "url": "/fundamentals/connection/network-compression/" + } + ] + }, + { + "label": "CRUD Operations", + "group": true, + "items": [ + { + "label": "Operations with Builders", + "url": "/fundamentals/builders/" + }, + { + "label": "Write", + "url": "/fundamentals/crud/write-operations/", + "collapsible": true, + "items": [ + { + "label": "Insert", + "url": "/fundamentals/crud/write-operations/insert/" + }, + { + "label": "Replace", + "url": "/fundamentals/crud/write-operations/replace/" + }, + { + "label": "Update Many", + "url": "/fundamentals/crud/write-operations/update-many/", + "collapsible": true, + "items": [ + { + "label": "Fields", + "url": "/fundamentals/crud/write-operations/update-many/fields" + }, + { + "label": "Arrays", + "url": "/fundamentals/crud/write-operations/update-many/arrays" + } + ] + } + ] + }, + { + "label": "Read", + "url": "/fundamentals/crud/read-operations/", + "collapsible": true, + "items": [ + { + "label": "Retrieve Data", + "url": "/fundamentals/crud/read-operations/retrieve/" + }, + { + "label": "Specify Fields to Return", + "url": "/fundamentals/crud/read-operations/project/" + } + ] + } + ] + } + ] + }, + { + "label": "Examples", + "url": "/usage-examples/", + "items": [ + { + "label": "Updating Documents", + "group": true, + "items": [ + { + "label": "Find a document", + "url": "/usage-examples/findOne/" + }, + { + "label": "Insert a Document", + "url": "/usage-examples/insertOne/" + }, + { + "label": "Update a document", + "url": "/usage-examples/updateOne/" + }, + { + "label": "Issues and Help", + "url": "/issues-and-help/" + } + ] + } + ] + } + ] +} diff --git a/toc_data/toc_example.toml b/toc_data/toc_example.toml new file mode 100644 index 000000000..0bcab7917 --- /dev/null +++ b/toc_data/toc_example.toml @@ -0,0 +1,100 @@ +# tab item 1 +[[toc]] +prefix = '/drivers/csharp/${version}' +label = "C# Quick Start" +url = "/quick-start" + +[[toc.items]] +label = 'Overview' +url = '/' + +[[toc.items]] +label = 'Get Started' +group = true +[[toc.items.items]] +label = 'Quick Reference' +url = '/quick-reference/' +[[toc.items.items]] +label = "What's new" +url = '/whats-new/' +[[toc.items.items]] +label = 'FAQ' +url = '/faq' + +# tab item 2 +[[toc]] +prefix = '/csharp/${version}' +label = "Fundamentals" +url = "/fundamentals" + +[[toc.items]] +label = "Connection" +group = true +[[toc.items.items]] +label = "Connection Guide" +url = "/fundamentals/connection/connect/" +[[toc.items.items]] +label = "Connection Options" +url = "/fundamentals/connection/connection-options/" +[[toc.items.items]] +label = "Network Compression" +url = "/fundamentals/connection/network-compression/" + +[[toc.items]] +label = "CRUD Operations" +group = true +[[toc.items.items]] +label = "Operations with Builders" +url = "/fundamentals/builders/" +[[toc.items.items]] +label = "Write" +url = '/fundamentals/crud/write-operations/' +collapsible = true +[[toc.items.items.items]] +label = "Insert" +url = '/fundamentals/crud/write-operations/insert/' +[[toc.items.items.items]] +label = "Replace" +url = '/fundamentals/crud/write-operations/replace/' +[[toc.items.items.items]] +label = "Update Many" +url = '/fundamentals/crud/write-operations/update-many/' +collapsible = true +[[toc.items.items.items.items]] +label = "Fields" +url = '/fundamentals/crud/write-operations/update-many/fields' +[[toc.items.items.items.items]] +label = "Arrays" +url = '/fundamentals/crud/write-operations/update-many/arrays' +[[toc.items.items]] +label = "Read" +url = '/fundamentals/crud/read-operations/' +collapsible = true +[[toc.items.items.items]] +label = "Retrieve Data" +url = '/fundamentals/crud/read-operations/retrieve/' +[[toc.items.items.items]] +label = "Specify Fields to Return" +url = '/fundamentals/crud/read-operations/project/' + + +# tab item 3 +[[toc]] +label = "Examples" +url = "/usage-examples/" + +[[toc.items]] +label = "Updating Documents" +group = true +[[toc.items.items]] +label = "Find a document" +url = "/usage-examples/findOne/" +[[toc.items.items]] +label = "Insert a Document" +url = "/usage-examples/insertOne/" +[[toc.items.items]] +label = "Update a document" +url = "/usage-examples/updateOne/" +[[toc.items.items]] +label = "Issues and Help" +url = "/issues-and-help/" \ No newline at end of file diff --git a/toc_data/toc_example.ts b/toc_data/toc_example.ts new file mode 100644 index 000000000..886b33105 --- /dev/null +++ b/toc_data/toc_example.ts @@ -0,0 +1,161 @@ +interface TocItem { + label: string; + url?: string; + group?: boolean; + prefix?: string; + collapsible?: boolean; + items?: TocItem[]; +} + +interface TocData { + toc: TocItem[]; +} + +export const tocData = (): TocData => { + const toc: TocData = { + toc: [ + { + prefix: '/drivers/csharp/version', // this will be item one + label: 'C# Quick Start', + url: '/quick-start', + items: [ + { + label: 'Overview', + url: '/', + }, + { + label: 'Get Started', + group: true, + items: [ + { + label: 'Quick Reference', + url: '/quick-reference/', + }, + { + label: "What's new", + url: '/whats-new/', + }, + { + label: 'FAQ', + url: '/faq', + }, + ], + }, + ], + }, + { + prefix: '/csharp/version', // this will be item 2 + label: 'Fundamentals', + url: '/fundamentals', + items: [ + { + label: 'Connection', + group: true, + items: [ + { + label: 'Connection Guide', + url: '/fundamentals/connection/connect/', + }, + { + label: 'Connection Options', + url: '/fundamentals/connection/connection-options/', + }, + { + label: 'Network Compression', + url: '/fundamentals/connection/network-compression/', + }, + ], + }, + { + label: 'CRUD Operations', + group: true, + items: [ + { + label: 'Operations with Builders', + url: '/fundamentals/builders/', + }, + { + label: 'Write', + url: '/fundamentals/crud/write-operations/', + collapsible: true, + items: [ + { + label: 'Insert', + url: '/fundamentals/crud/write-operations/insert/', + }, + { + label: 'Replace', + url: '/fundamentals/crud/write-operations/replace/', + }, + { + label: 'Update Many', + url: '/fundamentals/crud/write-operations/update-many/', + collapsible: true, + items: [ + { + label: 'Fields', + url: '/fundamentals/crud/write-operations/update-many/fields', + }, + { + label: 'Arrays', + url: '/fundamentals/crud/write-operations/update-many/arrays', + }, + ], + }, + ], + }, + { + label: 'Read', + url: '/fundamentals/crud/read-operations/', + collapsible: true, + items: [ + { + label: 'Retrieve Data', + url: '/fundamentals/crud/read-operations/retrieve/', + }, + { + label: 'Specify Fields to Return', + url: '/fundamentals/crud/read-operations/project/', + }, + ], + }, + ], + }, + ], + }, + { + label: 'Examples', // this will be item 3 + url: '/usage-examples/', + items: [ + { + label: 'Updating Documents', + group: true, + items: [ + { + label: 'Find a document', + url: '/usage-examples/findOne/', + }, + { + label: 'Insert a Document', + url: '/usage-examples/insertOne/', + }, + { + label: 'Update a document', + url: '/usage-examples/updateOne/', + }, + { + label: 'Issues and Help', + url: '/issues-and-help/', + }, + { + label: 'Issues and Help', + }, + ], + }, + ], + }, + ], + }; + + return toc; +}; diff --git a/toc_data/toc_example.yaml b/toc_data/toc_example.yaml new file mode 100644 index 000000000..903d3181e --- /dev/null +++ b/toc_data/toc_example.yaml @@ -0,0 +1,72 @@ +toc: + - prefix: /drivers/csharp/${version} + label: C# Quick Start + url: /quick-start + items: + - label: Overview + url: / + - label: Get Started + group: true + items: + - label: Quick Reference + url: /quick-reference/ + - label: What's new + url: /whats-new/ + - label: FAQ + url: /faq + - prefix: /csharp/${version} + label: Fundamentals + url: /fundamentals + items: + - label: Connection + group: true + items: + - label: Connection Guide + url: /fundamentals/connection/connect/ + - label: Connection Options + url: /fundamentals/connection/connection-options/ + - label: Network Compression + url: /fundamentals/connection/network-compression/ + - label: CRUD Operations + group: true + items: + - label: Operations with Builders + url: /fundamentals/builders/ + - label: Write + url: /fundamentals/crud/write-operations/ + collapsible: true + items: + - label: Insert + url: /fundamentals/crud/write-operations/insert/ + - label: Replace + url: /fundamentals/crud/write-operations/replace/ + - label: Update Many + url: /fundamentals/crud/write-operations/update-many/ + collapsible: true + items: + - label: Fields + url: /fundamentals/crud/write-operations/update-many/fields + - label: Arrays + url: /fundamentals/crud/write-operations/update-many/arrays + - label: Read + url: /fundamentals/crud/read-operations/ + collapsible: true + items: + - label: Retrieve Data + url: /fundamentals/crud/read-operations/retrieve/ + - label: Specify Fields to Return + url: /fundamentals/crud/read-operations/project/ + - label: Examples + url: /usage-examples/ + items: + - label: Updating Documents + group: true + items: + - label: Find a document + url: /usage-examples/findOne/ + - label: Insert a Document + url: /usage-examples/insertOne/ + - label: Update a document + url: /usage-examples/updateOne/ + - label: Issues and Help + url: /issues-and-help/ diff --git a/toc_data/versions.toml b/toc_data/versions.toml new file mode 100644 index 000000000..c2583cead --- /dev/null +++ b/toc_data/versions.toml @@ -0,0 +1,70 @@ + +[[repo]] +repoName = "docs-atlas-cli" +repoSlug = 'atlas/cli/' +[[repo.version]] +# name is what is saved in activeVersion +name = 'master' +urlAliases = ['1.36', 'upcoming', 'master'] +urlSlug = 'upcoming' +versionSelectorLabel = '1.36 (upcoming)' +isStableBranch = false +# do we want to do publishOriginalBranchName +[[repo.version]] +name = 'v1.35' +urlAliases = ['1.35', 'current'] +urlSlug = 'current' +versionSelectorLabel = '1.35' +isStableBranch = true +[[repo.version]] +name = 'v1.34' +urlAliases = ['1.34'] +urlSlug = 'v1.34' +versionSelectorLabel = '1.34' +isStableBranch = false + +[[repo]] +repoName = "docs-atlas-operator" +repoSlug = "atlas/operator/" +[[repo.version]] +name = 'master' +urlAliases = ['upcoming'] +urlSlug = 'upcoming' +versionSelectorLabel = 'upcoming' +isStableBranch = false +[[repo.version]] +name = 'v2.6' +urlAliases = ['current', 'v2.6'] +urlSlug = 'v2.6' +versionSelectorLabel = 'v2.6' +isStableBranch = true +[[repo.version]] +name = 'v2.5' +urlAliases = ['v2.5'] +urlSlug = 'v2.5' +versionSelectorLabel = 'v2.5' +isStableBranch = true + +[[repo]] +repoName = "csharp" +# repoSlug = 'drivers/csharp/' +repoSlug = 'csharp/bianca.laube/DOP-5343' +[[repo.version]] +name = 'master' +urlAliases = ['upcoming'] +# urlSlug = "upcoming" +urlSlug = "master" +versionSelectorLabel = 'upcoming' +isStableBranch = false +[[repo.version]] +name = 'v2.23' +urlAliases = ['v2.23'] +urlSlug = 'v2.23' +versionSelectorLabel = 'v2.23 (current)' +isStableBranch = true +[[repo.version]] +name = 'v2.22' +urlAliases = ['v2.22'] +urlSlug = 'v2.22' +versionSelectorLabel = 'v2.22' +isStableBranch = false