@seqera/docusaurus-theme-seqera 1.0.29 → 1.0.30-next.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  * Swizzled from docusaurus-theme-search-typesense SearchBar.
8
- * Adds full hierarchy breadcrumbs to the path shown under each modal result.
8
+ * Adds full hierarchy breadcrumbs and product labels to the path shown
9
+ * under each modal result. Product routes are configured via
10
+ * themeConfig.typesense.productRoutes.
9
11
  */
10
12
  export default function SearchBar(): JSX.Element;
@@ -5,7 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  * Swizzled from docusaurus-theme-search-typesense SearchBar.
8
- * Adds full hierarchy breadcrumbs to the path shown under each modal result.
8
+ * Adds full hierarchy breadcrumbs and product labels to the path shown
9
+ * under each modal result. Product routes are configured via
10
+ * themeConfig.typesense.productRoutes.
9
11
  */
10
12
  import React, {useState, useRef, useCallback, useMemo} from 'react';
11
13
  // @ts-ignore
@@ -50,12 +52,22 @@ function ResultsFooter({state, onClose}) {
50
52
  </Link>
51
53
  );
52
54
  }
55
+ /**
56
+ * Resolve a product label from a URL pathname using the configured productRoutes.
57
+ */
58
+ function getProductLabel(pathname, productRoutes) {
59
+ const match = productRoutes.find(([prefix]) => pathname.startsWith(prefix));
60
+ return match ? match[1] : null;
61
+ }
53
62
  /**
54
63
  * Build a breadcrumb string from all ancestor hierarchy levels of a hit.
55
64
  * For lvl2+ and content hits this replaces the single-level hierarchy.lvl1
56
65
  * path with the full parent chain (e.g. "Nextflow › Getting Started › Installation").
66
+ *
67
+ * When productRoutes are provided, the first level (lvl0, typically "Documentation")
68
+ * is replaced with the product name derived from the hit URL.
57
69
  */
58
- function buildBreadcrumb(item) {
70
+ function buildBreadcrumb(item, productRoutes) {
59
71
  const {type} = item;
60
72
  const maxLevel =
61
73
  type === 'content' ? 7 : parseInt(type.replace('lvl', ''), 10);
@@ -64,9 +76,26 @@ function buildBreadcrumb(item) {
64
76
  const val = item[`hierarchy.lvl${i}`];
65
77
  if (val) parts.push(val);
66
78
  }
79
+ // Replace lvl0 (typically "Documentation") with the product label
80
+ if (parts.length > 0 && productRoutes.length > 0) {
81
+ try {
82
+ const pathname = new URL(item.url).pathname;
83
+ const product = getProductLabel(pathname, productRoutes);
84
+ if (product) {
85
+ parts[0] = product;
86
+ }
87
+ } catch {
88
+ // URL parsing failed — keep the original lvl0 value
89
+ }
90
+ }
67
91
  return parts.length > 1 ? parts.join(' › ') : null;
68
92
  }
69
- function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
93
+ function DocSearch({
94
+ contextualSearch,
95
+ externalUrlRegex,
96
+ productRoutes = [],
97
+ ...props
98
+ }) {
70
99
  const contextualSearchFacetFilters = useTypesenseContextualFilters();
71
100
  const configFacetFilters = props.typesenseSearchParameters?.filter_by ?? '';
72
101
  const facetFilters = contextualSearch
@@ -144,7 +173,7 @@ function DocSearch({contextualSearch, externalUrlRegex, ...props}) {
144
173
  };
145
174
  // Overwrite hierarchy.lvl1 with the full ancestor breadcrumb so the
146
175
  // DocSearch-Hit-path slot shows the complete path for lvl2+ results.
147
- const breadcrumb = buildBreadcrumb(withRelativeUrl);
176
+ const breadcrumb = buildBreadcrumb(withRelativeUrl, productRoutes);
148
177
  if (!breadcrumb) return withRelativeUrl;
149
178
  return {
150
179
  ...withRelativeUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seqera/docusaurus-theme-seqera",
3
- "version": "1.0.29",
3
+ "version": "1.0.30-next.99",
4
4
  "description": "Seqera docs theme for Docusaurus",
5
5
  "author": "Seqera docs team <education@seqera.io>",
6
6
  "license": "Apache-2.0",
@@ -5,7 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  * Swizzled from docusaurus-theme-search-typesense SearchBar.
8
- * Adds full hierarchy breadcrumbs to the path shown under each modal result.
8
+ * Adds full hierarchy breadcrumbs and product labels to the path shown
9
+ * under each modal result. Product routes are configured via
10
+ * themeConfig.typesense.productRoutes.
9
11
  */
10
12
 
11
13
  import React, {useState, useRef, useCallback, useMemo} from 'react';
@@ -48,6 +50,7 @@ type DocSearchProps = Omit<
48
50
  contextualSearch?: string;
49
51
  externalUrlRegex?: string;
50
52
  searchPagePath: boolean | string;
53
+ productRoutes?: [string, string, string | null, string | null][];
51
54
  };
52
55
 
53
56
  let DocSearchModal: typeof DocSearchModalType | null = null;
@@ -86,13 +89,30 @@ function ResultsFooter({state, onClose}: ResultsFooterProps) {
86
89
  );
87
90
  }
88
91
 
92
+ /**
93
+ * Resolve a product label from a URL pathname using the configured productRoutes.
94
+ */
95
+ function getProductLabel(
96
+ pathname: string,
97
+ productRoutes: [string, string, string | null, string | null][],
98
+ ): string | null {
99
+ const match = productRoutes.find(([prefix]) =>
100
+ pathname.startsWith(prefix),
101
+ );
102
+ return match ? match[1] : null;
103
+ }
104
+
89
105
  /**
90
106
  * Build a breadcrumb string from all ancestor hierarchy levels of a hit.
91
107
  * For lvl2+ and content hits this replaces the single-level hierarchy.lvl1
92
108
  * path with the full parent chain (e.g. "Nextflow › Getting Started › Installation").
109
+ *
110
+ * When productRoutes are provided, the first level (lvl0, typically "Documentation")
111
+ * is replaced with the product name derived from the hit URL.
93
112
  */
94
113
  function buildBreadcrumb(
95
114
  item: InternalDocSearchHit | StoredDocSearchHit,
115
+ productRoutes: [string, string, string | null, string | null][],
96
116
  ): string | null {
97
117
  const {type} = item;
98
118
  const maxLevel =
@@ -106,12 +126,26 @@ function buildBreadcrumb(
106
126
  if (val) parts.push(val);
107
127
  }
108
128
 
129
+ // Replace lvl0 (typically "Documentation") with the product label
130
+ if (parts.length > 0 && productRoutes.length > 0) {
131
+ try {
132
+ const pathname = new URL(item.url).pathname;
133
+ const product = getProductLabel(pathname, productRoutes);
134
+ if (product) {
135
+ parts[0] = product;
136
+ }
137
+ } catch {
138
+ // URL parsing failed — keep the original lvl0 value
139
+ }
140
+ }
141
+
109
142
  return parts.length > 1 ? parts.join(' › ') : null;
110
143
  }
111
144
 
112
145
  function DocSearch({
113
146
  contextualSearch,
114
147
  externalUrlRegex,
148
+ productRoutes = [],
115
149
  ...props
116
150
  }: DocSearchProps) {
117
151
  const contextualSearchFacetFilters =
@@ -207,7 +241,7 @@ function DocSearch({
207
241
 
208
242
  // Overwrite hierarchy.lvl1 with the full ancestor breadcrumb so the
209
243
  // DocSearch-Hit-path slot shows the complete path for lvl2+ results.
210
- const breadcrumb = buildBreadcrumb(withRelativeUrl);
244
+ const breadcrumb = buildBreadcrumb(withRelativeUrl, productRoutes);
211
245
  if (!breadcrumb) return withRelativeUrl;
212
246
 
213
247
  return {