diff --git a/_docs/latest/util/data/nav.yml b/_docs/latest/util/data/nav.yml new file mode 100644 index 0000000000..b560b771db --- /dev/null +++ b/_docs/latest/util/data/nav.yml @@ -0,0 +1,582 @@ +categories: + - name: "Analytics" + pages: + - name: "Getting started" + url: "/learn/metabase-basics/getting-started" + - name: "Metabase concepts" + url: "/learn/metabase-basics/overview/concepts" + - name: Queries and charts + url: "questions/start" + pages: + - name: "Introduction" + url: "questions/introduction" + - name: "Query builder" + pages: + - name: "Editor" + url: "questions/query-builder/editor" + - name: "Filtering" + url: "questions/query-builder/filters" + - name: "Summarizing and grouping" + url: "questions/query-builder/summarizing-and-grouping" + - name: "Joining data" + url: "questions/query-builder/join" + - name: "Custom expressions" + url: "questions/query-builder/expressions" + - name: "List of expressions" + url: "questions/query-builder/expressions-list" + - name: "SQL and native queries" + pages: + - name: "SQL editor" + url: "questions/native-editor/writing-sql" + - name: "SQL parameters" + url: "questions/native-editor/sql-parameters" + - name: "Field filters" + url: "questions/native-editor/field-filters" + - name: "Basic SQL parameters" + url: "questions/native-editor/basic-sql-parameters" + - name: "Time grouping parameters" + url: "questions/native-editor/time-grouping-parameters" + - name: "Table variables" + url: "questions/native-editor/table-variables" + - name: "Optional variables" + url: "questions/native-editor/optional-variables" + - name: "Filter widgets" + url: "questions/native-editor/filter-widgets" + - name: "Referencing models and questions" + url: "questions/native-editor/referencing-saved-questions-in-queries" + - name: "Snippets" + url: "questions/native-editor/snippets" + - name: "Snippet folder permissions" + url: "permissions/snippets" + - name: "Visualizations" + pages: + - name: "Overview" + url: "questions/visualizations/visualizing-results" + - name: "Box plot" + url: "questions/visualizations/box-plot" + - name: "Combo chart" + url: "questions/visualizations/combo-chart" + - name: "Details chart" + url: "questions/visualizations/detail" + - name: "Funnel chart" + url: "questions/visualizations/funnel" + - name: "Gauge chart" + url: "questions/visualizations/gauge" + - name: "Line, bar, and area charts" + url: "questions/visualizations/line-bar-and-area-charts" + - name: "Maps" + url: "questions/visualizations/map" + - name: "Number chart" + url: "questions/visualizations/numbers" + - name: "Pie and sunburst charts" + url: "questions/visualizations/pie-or-donut-chart" + - name: "Pivot tables" + url: "questions/visualizations/pivot-table" + - name: "Progress bar" + url: "questions/visualizations/progress-bar" + - name: "Sankey chart" + url: "questions/visualizations/sankey" + - name: "Scatterplot" + url: "questions/visualizations/scatterplot-or-bubble-chart" + - name: "Table" + url: "questions/visualizations/table" + - name: "Treemap" + url: "questions/visualizations/treemap" + - name: "Trend chart" + url: "questions/visualizations/trend" + - name: "Waterfall chart" + url: "questions/visualizations/waterfall-chart" + - name: "Tooltips" + url: "questions/visualizations/tooltips" + - name: "Custom visualizations" + url: "questions/visualizations/custom" + - name: "Drill-through" + url: "questions/visualizations/drill-through" + + - name: "Metrics explorer" + url: "questions/metrics-explorer" + - name: "Alerts" + url: "questions/alerts" + - name: "Exporting data" + url: "questions/exporting-results" + - name: "Dashboards" + url: "dashboards/start" + pages: + - name: "Overview" + url: "dashboards/introduction" + - name: "Dashboard heading and text cards" + url: "dashboards/dashboard-markdown" + - name: "Format text with Markdown" + url: "dashboards/markdown" + - name: "Dashboard filters" + url: "dashboards/filters" + - name: "Linked filters" + url: "dashboards/linked-filters" + - name: "Dashboard interactivity" + url: "dashboards/interactive" + - name: "Charts with multiple series" + url: "dashboards/multiple-series" + - name: "Dashboard subscriptions" + url: "dashboards/subscriptions" + - name: "Actions on dashboards" + url: "dashboards/actions" + + - name: "Documents" + url: "documents/start" + pages: + - name: "Overview" + url: "documents/introduction" + + - name: "AI" + url: "ai/start" + pages: + - name: "Overview" + url: "ai/overview" + - name: "Metabot" + url: "ai/metabot" + - name: "Metabot in Slack" + url: "ai/metabot-slack" + - name: "Settings" + url: "ai/settings" + - name: "MCP server" + url: "ai/mcp" + - name: "Agent API" + url: "ai/agent-api" + - name: "Agent-driven development" + url: "ai/file-based-development" + - name: "Customization" + url: "ai/customization" + - name: "System prompts" + url: "ai/system-prompts" + - name: "Usage auditing" + url: "ai/usage-auditing" + - name: "Usage controls" + url: "ai/usage-controls" + - name: "AI privacy" + url: "ai/privacy" + + - name: "Data modeling" + url: "data-modeling/start" + pages: + - name: "Models" + url: "data-modeling/models" + - name: "Model persistence" + url: "data-modeling/model-persistence" + - name: "Metrics" + url: "data-modeling/metrics" + - name: "Table metadata settings" + url: "data-modeling/metadata-editing" + - name: "Data and semantic types" + url: "data-modeling/semantic-types" + - name: "Editable tables" + url: "data-modeling/editable-tables" + - name: "Formatting defaults" + url: "data-modeling/formatting" + - name: "Working with JSON" + url: "data-modeling/json-unfolding" + - name: "Segments" + url: "data-modeling/segments" + - name: "Actions" + pages: + - name: "Overview" + url: "actions/introduction" + - name: "Basic actions" + url: "actions/basic" + - name: "Custom actions" + url: "actions/custom" + + - name: "Data Studio" + url: "data-studio/overview" + pages: + - name: "Overview" + url: "data-studio/overview" + - name: "Library" + url: "data-studio/library" + - name: "Managing tables" + url: "data-studio/managing-tables" + - name: "Measures" + url: "data-studio/measures" + - name: "Segments" + url: "data-studio/segments" + - name: "Glossary" + url: "exploration-and-organization/data-model-reference#glossary" + - name: "Dependencies" + pages: + - name: "Dependency graph" + url: "data-studio/dependencies/graph" + - name: "Dependency diagnostics" + url: "data-studio/dependencies/diagnostics" + - name: "Replace data sources" + url: "data-studio/dependencies/replace-data-sources" + - name: "Transforms" + pages: + - name: "Overview" + url: "data-studio/transforms/transforms-overview" + - name: "Query transforms" + url: "data-studio/transforms/query-transforms" + - name: "Python transforms" + url: "data-studio/transforms/python-transforms" + - name: "Python runner" + url: "data-studio/transforms/python-runner" + - name: "Jobs and runs" + url: "data-studio/transforms/jobs-and-runs" + - name: "Transform inspector" + url: "data-studio/transforms/transform-inspector" + - name: "Add-ons" + url: "data-studio/transforms/addons" + + - name: "Organization" + url: "exploration-and-organization/start" + pages: + - name: "Basic exploration" + url: "exploration-and-organization/exploration" + - name: "Keyboard shortcuts" + url: "exploration-and-organization/keyboard-shortcuts" + - name: "Collections" + url: "exploration-and-organization/collections" + - name: "Data reference" + url: "exploration-and-organization/data-model-reference" + - name: "Events and timelines" + url: "exploration-and-organization/events-and-timelines" + - name: "X-rays" + url: "exploration-and-organization/x-rays" + - name: "Content verification" + url: "exploration-and-organization/content-verification" + - name: "History" + url: "exploration-and-organization/history" + - name: "Delete and restore" + url: "exploration-and-organization/delete-and-restore" + + - name: "Embedding" + url: "embedding/start" + pages: + - name: "Overview" + url: "embedding/introduction" + - name: "Modular embedding" + pages: + - name: "Overview" + url: "embedding/modular-embedding" + - name: "Components" + url: "embedding/components" + - name: "Filters and parameters" + url: "embedding/parameters" + - name: "Appearance" + url: "embedding/appearance" + - name: "Authentication" + url: "embedding/authentication" + - name: "Tenants" + url: "embedding/tenants" + - name: "Modular embedding SDK" + pages: + - name: "Overview" + url: "embedding/sdk/introduction" + - name: "Quickstarts" + url: "embedding/sdk/introduction#quickstarts" + - name: "Components" + pages: + - name: "Questions" + url: "embedding/sdk/questions" + - name: "Dashboards" + url: "embedding/sdk/dashboards" + - name: "AI chat" + url: "embedding/sdk/ai-chat" + - name: "Collections" + url: "embedding/sdk/collections" + - name: "Plugins" + url: "embedding/sdk/plugins" + - name: "Configuration" + pages: + - name: "Provider config" + url: "embedding/sdk/config" + - name: "Working with Next.js" + url: "embedding/sdk/next-js" + - name: "Versioning" + url: "embedding/sdk/version" + - name: "Upgrading" + url: "embedding/sdk/upgrade" + - name: "API" + url: "embedding/sdk/api/" + - name: "Guest embedding" + url: "embedding/guest-embedding" + - name: "Translate embeds" + url: "embedding/translations" + - name: "Full app embedding" + pages: + - name: "Overview" + url: "embedding/full-app-embedding" + - name: "Quickstart" + url: "embedding/full-app-embedding-quick-start-guide" + - name: "Full app UI components" + url: "embedding/full-app-ui-components" + - name: "Public links and embeds" + url: "embedding/public-links" + - name: "Securing embeds" + url: "embedding/securing-embeds" + - name: "AI agent resources" + url: "embedding/ai-agent-resources" + + - name: "Administration" + pages: + - name: "Installation" + url: "installation-and-operation/start" + pages: + - name: "Installing Metabase" + pages: + - name: "Installation overview" + url: "installation-and-operation/installing-metabase" + - name: "Metabase Cloud" + url: "cloud/start" + - name: "Running the JAR file" + url: "installation-and-operation/running-the-metabase-jar-file" + - name: "Running in Docker" + url: "installation-and-operation/running-metabase-on-docker" + - name: "Other installation options" + url: "installation-and-operation/installing-metabase#other-installation-options" + - name: "Upgrading Metabase" + url: "installation-and-operation/upgrading-metabase" + - name: "Configuring the Metabase application database" + url: "installation-and-operation/configuring-application-database" + - name: "Activating Enterprise features" + url: "installation-and-operation/activating-the-enterprise-edition" + - name: "Migrating to a production application database" + url: "installation-and-operation/migrating-from-h2" + - name: "Data sources" + url: "databases/start" + pages: + - name: "Adding and managing databases" + url: "databases/connecting" + - name: "Supported databases" + pages: + - name: "Athena" + url: "databases/connections/athena" + - name: "Amazon RDS" + url: "databases/connections/aws-rds" + - name: "BigQuery" + url: "databases/connections/bigquery" + - name: "ClickHouse" + url: "databases/connections/clickhouse" + - name: "Databricks" + url: "databases/connections/databricks" + - name: "Druid" + url: "databases/connections/druid" + - name: "MariaDB" + url: "databases/connections/mariadb" + - name: "MongoDB" + url: "databases/connections/mongodb" + - name: "MySQL" + url: "databases/connections/mysql" + - name: "Oracle" + url: "databases/connections/oracle" + - name: "PostgreSQL" + url: "databases/connections/postgresql" + - name: "Presto" + url: "databases/connections/presto" + - name: "Redshift" + url: "databases/connections/redshift" + - name: "Snowflake" + url: "databases/connections/snowflake" + - name: "SQL Server" + url: "databases/connections/sql-server" + - name: "SQLite" + url: "databases/connections/sqlite" + - name: "Spark SQL" + url: "databases/connections/sparksql" + - name: "Starburst" + url: "databases/connections/starburst" + - name: "Vertica" + url: "databases/connections/vertica" + - name: "Community drivers" + url: "developers-guide/community-drivers" + + - name: "Database users, roles, and privileges" + url: "databases/users-roles-privileges" + - name: "Writable connection" + url: "databases/writable-connection" + - name: "Syncing and scanning databases" + url: "databases/sync-scan" + - name: "Encrypting your database connection" + url: "databases/encrypting-details-at-rest" + - name: "SSH tunneling" + url: "databases/ssh-tunnel" + - name: "SSL certificate" + url: "databases/ssl-certificates" + - name: "Setting up data uploads" + url: "databases/uploads" + - name: "Uploading data" + url: "exploration-and-organization/uploads" + - name: "Metabase Cloud Storage" + url: "cloud/storage" + - name: "Sync Google Sheets" + url: "cloud/google-sheets" + - name: "Configuration" + url: "configuring-metabase/start" + pages: + - name: "Setting up Metabase" + url: "configuring-metabase/setting-up-metabase" + - name: "General settings" + url: "configuring-metabase/settings" + - name: "Set up email" + url: "configuring-metabase/email" + - name: "Set up Slack" + url: "configuring-metabase/slack" + - name: "Webhooks" + url: "configuring-metabase/webhooks" + - name: "Environment variables" + url: "configuring-metabase/environment-variables" + - name: "Configuration file" + url: "configuring-metabase/config-file" + - name: "Config file template" + url: "configuring-metabase/config-template" + - name: "Metabase log configuration" + url: "configuring-metabase/log-configuration" + - name: "Timezones" + url: "configuring-metabase/timezones" + - name: "Languages and localization" + url: "configuring-metabase/localization" + - name: "Appearance" + url: "configuring-metabase/appearance" + - name: "Fonts" + url: "configuring-metabase/fonts" + - name: "Caching query results" + url: "configuring-metabase/caching" + - name: "Custom maps" + url: "configuring-metabase/custom-maps" + - name: "Customizing the Metabase Jetty webserver" + url: "configuring-metabase/customizing-jetty-webserver" + - name: "Operations and monitoring" + url: "installation-and-operation/start" + pages: + - name: "Backing up Metabase" + url: "installation-and-operation/backing-up-metabase-application-data" + - name: "Development instances" + url: "installation-and-operation/development-instance" + - name: "Monitoring your Metabase" + url: "installation-and-operation/monitoring-metabase" + - name: "Observability with Prometheus" + url: "installation-and-operation/observability-with-prometheus" + - name: "Serialization" + url: "installation-and-operation/serialization" + - name: "Remote Sync" + url: "installation-and-operation/remote-sync" + - name: "Commands" + url: "installation-and-operation/commands" + - name: "Metabase CLI" + url: "installation-and-operation/metabase-cli" + - name: "Usage analytics" + url: "usage-and-performance-tools/usage-analytics" + - name: "Security center" + url: "installation-and-operation/security-center" + - name: "Admin tools" + url: "usage-and-performance-tools/tools" + - name: "Authentication" + url: "people-and-groups/start" + pages: + - name: "Account settings" + url: "people-and-groups/account-settings" + - name: "Password complexity" + url: "people-and-groups/changing-password-complexity" + - name: "Session expiration" + url: "people-and-groups/changing-session-expiration" + - name: "Google Sign-In" + url: "people-and-groups/google-sign-in" + - name: "LDAP" + url: "people-and-groups/ldap" + - name: "User provisioning" + url: "people-and-groups/user-provisioning" + - name: "API keys" + url: "people-and-groups/api-keys" + - name: "Paid SSO options" + url: "people-and-groups/start" + pages: + - name: "JWT-based authentication" + url: "people-and-groups/authenticating-with-jwt" + - name: "SAML-based authentication" + url: "people-and-groups/authenticating-with-saml" + - name: "SAML with Auth0" + url: "people-and-groups/saml-auth0" + - name: "SAML with Microsoft Entra ID" + url: "people-and-groups/saml-azure" + - name: "SAML with Google" + url: "people-and-groups/saml-google" + - name: "SAML with Keycloak" + url: "people-and-groups/saml-keycloak" + - name: "SAML with Okta" + url: "people-and-groups/saml-okta" + - name: "OIDC-based authentication" + url: "people-and-groups/authenticating-with-oidc" + - name: "OIDC with Keycloak" + url: "people-and-groups/oidc-keycloak" + - name: "Permissions" + url: "permissions/start" + pages: + - name: "Permissions introduction" + url: "permissions/introduction" + - name: "Managing people and groups" + url: "people-and-groups/managing" + - name: "Data permissions" + url: "permissions/data" + - name: "Data isolation methods" + url: "permissions/data-isolation-methods" + - name: "Collection permissions" + url: "permissions/collections" + - name: "Application permissions" + url: "permissions/application" + - name: "Row and column security" + url: "permissions/row-and-column-security" + - name: "Row and column security examples" + url: "permissions/row-and-column-security-examples" + - name: "Database routing" + url: "permissions/database-routing" + - name: "Impersonation" + url: "permissions/impersonation" + - name: "Snippets folder permissions" + url: "permissions/snippets" + - name: "Notification permissions" + url: "permissions/notifications" + - name: "Configuring permissions for embedding" + url: "permissions/embedding" + + - name: Other resources + pages: + - name: "API" + url: "api" + - name: "Metabase Cloud" + url: "cloud/start" + pages: + - name: "Cloud vs self-hosted" + url: "cloud/cloud-vs-self-hosting" + - name: "Custom domain" + url: "cloud/custom-domain" + - name: "Cloud limitations" + url: "cloud/limitations" + - name: "Change region" + url: "cloud/change-region" + - name: "IP addresses to whitelist" + url: "cloud/ip-addresses-to-whitelist" + - name: "Migrate from self-hosted to Cloud" + url: "cloud/migrate/guide" + - name: "Migrate from Cloud to self-hosted" + url: "cloud/migrate/cloud-to-self-hosted" + - name: "Migrate from Heroku" + url: "cloud/migrate/heroku" + - name: "Billing" + url: "https://www.metabase.com/how-billing-works" + pages: + - name: "How billing works" + url: "cloud/how-billing-works" + - name: "Accounts and billing" + url: "cloud/accounts-and-billing" + - name: "Troubleshooting" + url: "troubleshooting-guide/" + - name: "Developer guide" + url: "developers-guide/start" + - name: "Pro and Enterprise features" + url: "/paid-features/" + - name: "Accessibility" + url: "installation-and-operation/accessibility" + - name: "Supported browsers" + url: "installation-and-operation/supported-browsers" + - name: "Privacy" + url: "installation-and-operation/privacy" + - name: "About the anonymous usage data we collect" + url: "installation-and-operation/information-collection" diff --git a/_includes/docs/left-sidebar.html b/_includes/docs/left-sidebar.html deleted file mode 100644 index e84e27e1b9..0000000000 --- a/_includes/docs/left-sidebar.html +++ /dev/null @@ -1,21 +0,0 @@ - diff --git a/_includes/learn/left-nav.html b/_includes/learn/left-nav.html deleted file mode 100644 index c78e237ee9..0000000000 --- a/_includes/learn/left-nav.html +++ /dev/null @@ -1,147 +0,0 @@ -{% assign cleanPageURL = page.url | replace: '/index', '' %} - -{% for category in include.categories %} -
{{category.name}}
- - -{% endfor %} diff --git a/copy-navs-from-mb.sh b/copy-navs-from-mb.sh new file mode 100644 index 0000000000..310bf81156 --- /dev/null +++ b/copy-navs-from-mb.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash +# Companion to https://github.com/metabase/metabase/pull/81703 +# 1. Run the #81703 script first to populate the metabase branches with nav.yml files from this repo. +# 2. Then merge all the PRs it generated. +# 3. Then run this script to populate this feature branch with the new structure/contents. +# 4. Then delete this file + delete _data/docs. +# 5. Merge this branch. +# 6. Job done. Nav data source of truth is in the metabase repo; nav.yml +# files will get automatically copied via script/docs (and no additional +# processing is needed since the /docs// prefixes are added in +# getNavForVersion). +# +# For each version v0.44 - v0.63 plus latest (master), sparse-checkout only +# docs/util/data/nav.yml from the metabase/metabase repo into a throwaway +# worktree, copy that file out to _docs//util/data/nav.yml, then +# remove the worktree. +# +# v0.44 - v0.63 use the release-x.NN.x branch; latest uses master. +set -euo pipefail + +METABASE_REPO_URL="${METABASE_REPO_URL:-https://github.com/metabase/metabase.git}" + +REPO_ROOT="$(git rev-parse --show-toplevel)" + +TMP_ROOT="$REPO_ROOT/tmp" +mkdir -p "$TMP_ROOT" + +# A full clone (even with --filter=blob:none) still walks the commit/tree +# history of every branch and tag in the repo, which is most of the cost for +# a repo this size. We only need ~20 specific refs, so instead: resolve each +# ref remotely with ls-remote (cheap, no clone) and shallow-fetch just that +# one commit (--depth=1 --filter=tree:0) into an initially-empty repo. +# sparse-checkout then lazily pulls only the docs/util/data blobs for that commit. +CLONE_DIR="$TMP_ROOT/metabase-metabase" +if [[ ! -d "$CLONE_DIR" ]]; then + echo "Initializing ${CLONE_DIR}" + git init -q --bare "$CLONE_DIR" + git -C "$CLONE_DIR" remote add origin "$METABASE_REPO_URL" +fi + +# Resolve every ref up front from one bulk ls-remote call instead of one per +# version, then fetch them all in a single batched `git fetch`. This turns +# ~20 sequential network round trips into 2. +echo "Listing remote refs" +all_heads="$(git ls-remote --heads "$METABASE_REPO_URL")" + +labels=() +refs=() + +for nn in $(seq 44 63); do + ref="release-x.${nn}.x" + if ! grep -q "refs/heads/${ref}\$" <<< "$all_heads"; then + echo "Skipping v0.${nn}: no such remote branch (release-x.${nn}.x)" + continue + fi + labels+=("v0.${nn}") + refs+=("$ref") +done + +if grep -q "refs/heads/master\$" <<< "$all_heads"; then + labels+=("latest") + refs+=("master") +else + echo "Skipping latest: no such remote branch (master)" +fi + +refspecs=() +for ref in "${refs[@]}"; do + refspecs+=("refs/heads/${ref}:refs/remotes/origin/${ref}") +done + +echo "Fetching ${#refspecs[@]} refs" +git -C "$CLONE_DIR" fetch -q --depth=1 --filter=tree:0 origin "${refspecs[@]}" + +for i in "${!labels[@]}"; do + label="${labels[i]}" + ref="${refs[i]}" + worktree_dir="$TMP_ROOT/wt_metabase_${label}" + dest_dir="$REPO_ROOT/_docs/${label}" + + echo "Adding worktree for ${ref} at ${worktree_dir}" + git -C "$CLONE_DIR" worktree add --no-checkout -B "${ref}" "$worktree_dir" "origin/${ref}" + + git -C "$worktree_dir" sparse-checkout init --cone + git -C "$worktree_dir" sparse-checkout set docs/util/data + git -C "$worktree_dir" checkout "${ref}" + + src_file="$worktree_dir/docs/util/data/nav.yml" + if [[ ! -f "$src_file" ]]; then + echo "Skipping ${label}: no docs/util/data/nav.yml at ${ref}" + else + mkdir -p "$dest_dir/util/data" + cp "$src_file" "$dest_dir/util/data/nav.yml" + fi + + git -C "$CLONE_DIR" worktree remove "$worktree_dir" --force + git -C "$CLONE_DIR" branch -D "${ref}" +done + +echo "Removing ${TMP_ROOT}" +rm -rf "$TMP_ROOT" + +echo "Done." diff --git a/src/components/chrome/LeftSidebar.astro b/src/components/chrome/LeftSidebar.astro new file mode 100644 index 0000000000..f900e41f11 --- /dev/null +++ b/src/components/chrome/LeftSidebar.astro @@ -0,0 +1,26 @@ +--- +import NavItem from "@/components/chrome/NavItem.astro"; +import { getNavForVersion } from "@/lib/docs/nav"; + +type Props = { + url: string; + version?: string; +}; + +const { url: pageUrl, version = "latest" } = Astro.props; +--- + + diff --git a/src/components/chrome/NavItem.astro b/src/components/chrome/NavItem.astro new file mode 100644 index 0000000000..8236493274 --- /dev/null +++ b/src/components/chrome/NavItem.astro @@ -0,0 +1,39 @@ +--- +import NavItem from "@/components/chrome/NavItem.astro"; +import Chevron from "@/icons/chevron.svg"; +import { containsUrl, type NavNode } from "@/lib/docs/nav"; + +type Props = { + node: NavNode; + pageUrl: string; +}; + +const { node, pageUrl } = Astro.props; + +const hasChildren = Boolean(node.pages && node.pages.length > 0); +const expanded = containsUrl(node, pageUrl); +--- + +
  • + + {node.name} + + { + hasChildren && ( +
    + +
    + ) + } +
    + + { + hasChildren && ( +
      + {node.pages!.map((child) => ( + + ))} +
    + ) + } +
  • diff --git a/src/icons/chevron.svg b/src/icons/chevron.svg new file mode 100644 index 0000000000..a0ec40d6ac --- /dev/null +++ b/src/icons/chevron.svg @@ -0,0 +1,17 @@ + + + diff --git a/src/layouts/NewDocsLayout.astro b/src/layouts/NewDocsLayout.astro index 5b159be21b..f4385c99da 100644 --- a/src/layouts/NewDocsLayout.astro +++ b/src/layouts/NewDocsLayout.astro @@ -1,4 +1,5 @@ --- +import LeftSidebar from "@/components/chrome/LeftSidebar.astro"; import LiquidInclude from "@/components/LiquidInclude.astro"; import { UNIFY_ENABLED_PAGES } from "@/constants"; import { getLiquidRenderer } from "@/lib/liquid/liquidRenderer"; @@ -9,6 +10,8 @@ type Props = { title: string; url: string; category?: string; + version?: string; + latest?: string; }; dirname: string; }; @@ -27,7 +30,7 @@ const unify = UNIFY_ENABLED_PAGES.includes(page.url);
    - +
    + n.url === targetUrl || + (n.pages?.some((child) => containsUrl(child, targetUrl)) ?? false); + +const isRelativeUrl = (url: string) => !/^(\/|[a-z][a-z0-9+.-]*:)/i.test(url); + +const navCache: Record = {}; + +export const getNavForVersion = (version: string): Nav => { + const resolveUrls = (node: NavNode): NavNode => ({ + ...node, + url: + node.url && isRelativeUrl(node.url) + ? `/docs/${version}/${node.url}` + : node.url, + pages: node.pages?.map(resolveUrls), + }); + + const computeNav = (): Nav => { + const navPath = path.resolve( + process.cwd(), + DOCS_SRC_ROOT, + METABASE_REPO_PATH ? "" : version, + "util/data/nav.yml", + ); + const navRaw: Nav = fs.existsSync(navPath) + ? YAML.parse(fs.readFileSync(navPath, "utf8")) + : { categories: [] }; + return { categories: navRaw.categories.map(resolveUrls) }; + }; + + const shouldCache = import.meta.env.MODE !== "development"; + return shouldCache ? (navCache[version] ??= computeNav()) : computeNav(); +};