@redocly/theme 0.19.1 → 0.19.2

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.
@@ -27,10 +27,13 @@ exports.useCatalog = void 0;
27
27
  const React = __importStar(require("react"));
28
28
  const react_router_dom_1 = require("react-router-dom");
29
29
  const telemetry_1 = require("../../mocks/telemetry");
30
+ const usePageData_1 = require("../../mocks/hooks/usePageData");
30
31
  const utils_1 = require("../../utils");
31
32
  function useCatalog(items, config) {
33
+ var _a;
32
34
  const location = (0, react_router_dom_1.useLocation)();
33
35
  const navigate = (0, react_router_dom_1.useNavigate)();
36
+ const pageData = (0, usePageData_1.usePageData)();
34
37
  const searchParams = useSearchParams(location);
35
38
  const [filtersState, setFiltersState] = React.useState(() => {
36
39
  var _a;
@@ -47,7 +50,8 @@ function useCatalog(items, config) {
47
50
  });
48
51
  const [filterTerm, setFilterTerm] = React.useState(() => searchParams.get('filter') || '');
49
52
  const filtersWithOptions = React.useMemo(() => collectFilterOptions(items, config.filters), [items, config.filters]);
50
- const normalizedItems = React.useMemo(() => normalizeItems(items, config), [items, config]);
53
+ const customFields = (_a = pageData === null || pageData === void 0 ? void 0 : pageData.props) === null || _a === void 0 ? void 0 : _a.customFields;
54
+ const normalizedItems = React.useMemo(() => normalizeItems(items, config, customFields || {}), [items, config, customFields]);
51
55
  const toggleOption = React.useCallback((filterIdx, option) => {
52
56
  setFiltersState((prev) => {
53
57
  const newFilterOptions = prev[filterIdx] ? prev[filterIdx] : new Set();
@@ -178,7 +182,7 @@ function groupByFirstFilter(filters, filteredItems) {
178
182
  function useSearchParams(location) {
179
183
  return React.useMemo(() => new URLSearchParams(location.search), [location.search]);
180
184
  }
181
- function normalizeItems(items, config) {
185
+ function normalizeItems(items, config, customFields) {
182
186
  // because of RBAC some versions can be missing so we need to pick up other default version
183
187
  const hasDeafultVersion = {};
184
188
  for (const item of items) {
@@ -203,9 +207,10 @@ function normalizeItems(items, config) {
203
207
  return items.map((item) => {
204
208
  var _a, _b, _c;
205
209
  const metadata = item.metadata || {};
210
+ const apiCustomFields = customFields[item.fsPath || ''] || {};
206
211
  const link = item.link || ((_a = (0, utils_1.findDeepFirst)(item.items || [], (i) => 'link' in i && !!i.link)) === null || _a === void 0 ? void 0 : _a.link);
207
212
  const firstSidebarItem = (_b = item.sidebar) === null || _b === void 0 ? void 0 : _b[0];
208
- return Object.assign(Object.assign({}, metadata), { publishedAt: metadata.publishedAt || metadata.createdAt, title: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.title) || item.label || 'Untitled', description: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.description), link: (_c = (0, utils_1.withoutHash)(link)) !== null && _c !== void 0 ? _c : '#', docsLink: (0, utils_1.withoutHash)(firstSidebarItem === null || firstSidebarItem === void 0 ? void 0 : firstSidebarItem.link), image: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.image) });
213
+ return Object.assign(Object.assign(Object.assign({}, metadata), apiCustomFields), { publishedAt: metadata.publishedAt || metadata.createdAt, title: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.title) || item.label || 'Untitled', description: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.description), link: (_c = (0, utils_1.withoutHash)(link)) !== null && _c !== void 0 ? _c : '#', docsLink: (0, utils_1.withoutHash)(firstSidebarItem === null || firstSidebarItem === void 0 ? void 0 : firstSidebarItem.link), image: (0, utils_1.toStringIfDefined)(metadata === null || metadata === void 0 ? void 0 : metadata.image) });
209
214
  });
210
215
  }
211
216
  function collectFilterParents(filtersWithOptions) {
@@ -2,4 +2,5 @@ import type { ResolvedNavLinkItem } from '../../types/portal';
2
2
  export declare function usePageData(): {
3
3
  prevPage: ResolvedNavLinkItem | null;
4
4
  nextPage: ResolvedNavLinkItem | null;
5
+ props?: any;
5
6
  } | null;
@@ -17,6 +17,7 @@ export type ResolvedNavLinkItem = {
17
17
  httpVerb?: string;
18
18
  separatorLine?: boolean;
19
19
  routeSlug?: string;
20
+ fsPath?: string;
20
21
  active?: boolean;
21
22
  icon?: string;
22
23
  srcSet?: string;
@@ -41,6 +42,7 @@ export type ResolvedNavGroupItem = {
41
42
  menuStyle?: MenuStyle;
42
43
  separatorLine?: boolean;
43
44
  routeSlug?: string;
45
+ fsPath?: string;
44
46
  active?: boolean;
45
47
  icon?: string;
46
48
  srcSet?: string;
@@ -52,6 +54,7 @@ export type ResolvedNavItem = ResolvedNavLinkItem | ResolvedNavGroupItem | {
52
54
  label?: string;
53
55
  labelTranslationKey?: string;
54
56
  routeSlug?: never;
57
+ fsPath?: never;
55
58
  version?: string;
56
59
  isDefault?: boolean;
57
60
  versionFolderId?: string;
@@ -70,6 +73,7 @@ export type ResolvedNavItem = ResolvedNavLinkItem | ResolvedNavGroupItem | {
70
73
  versionFolderId?: string;
71
74
  metadata?: Record<string, unknown>;
72
75
  routeSlug?: never;
76
+ fsPath?: never;
73
77
  label: string;
74
78
  labelTranslationKey?: string;
75
79
  link?: undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.19.1",
3
+ "version": "0.19.2",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -4,6 +4,7 @@ import { useLocation, useNavigate } from 'react-router-dom';
4
4
  import type { Location } from 'react-router-dom';
5
5
 
6
6
  import { telemetry } from '@portal/telemetry';
7
+ import { usePageData } from '@portal/hooks/usePageData';
7
8
  import type { ResolvedNavItem } from '@theme/types/portal';
8
9
  import type {
9
10
  CatalogItem,
@@ -16,6 +17,7 @@ import type { CatalogConfig, CatalogFilterConfig } from '@theme/config';
16
17
  export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): FilteredCatalog {
17
18
  const location = useLocation();
18
19
  const navigate = useNavigate();
20
+ const pageData = usePageData();
19
21
  const searchParams = useSearchParams(location);
20
22
  const [filtersState, setFiltersState] = React.useState(() =>
21
23
  (config.filters ?? []).map((f) => {
@@ -33,7 +35,12 @@ export function useCatalog(items: ResolvedNavItem[], config: CatalogConfig): Fil
33
35
  () => collectFilterOptions(items, config.filters),
34
36
  [items, config.filters],
35
37
  );
36
- const normalizedItems = React.useMemo(() => normalizeItems(items, config), [items, config]);
38
+
39
+ const customFields = pageData?.props?.customFields;
40
+ const normalizedItems = React.useMemo(
41
+ () => normalizeItems(items, config, customFields || ({} as any)),
42
+ [items, config, customFields],
43
+ );
37
44
 
38
45
  const toggleOption = React.useCallback((filterIdx, option) => {
39
46
  setFiltersState((prev) => {
@@ -198,7 +205,11 @@ function useSearchParams(location: Location) {
198
205
  return React.useMemo(() => new URLSearchParams(location.search), [location.search]);
199
206
  }
200
207
 
201
- function normalizeItems(items: ResolvedNavItem[], config: CatalogConfig): CatalogItem[] {
208
+ function normalizeItems(
209
+ items: ResolvedNavItem[],
210
+ config: CatalogConfig,
211
+ customFields: Record<string, Record<string, unknown>>,
212
+ ): CatalogItem[] {
202
213
  // because of RBAC some versions can be missing so we need to pick up other default version
203
214
  const hasDeafultVersion: Record<string, boolean> = {};
204
215
  for (const item of items) {
@@ -223,10 +234,12 @@ function normalizeItems(items: ResolvedNavItem[], config: CatalogConfig): Catalo
223
234
 
224
235
  return items.map((item) => {
225
236
  const metadata = item.metadata || {};
237
+ const apiCustomFields = customFields[item.fsPath || ''] || {};
226
238
  const link = item.link || findDeepFirst(item.items || [], (i) => 'link' in i && !!i.link)?.link;
227
239
  const firstSidebarItem = (item as any).sidebar?.[0];
228
240
  return {
229
241
  ...metadata,
242
+ ...apiCustomFields,
230
243
  publishedAt: metadata.publishedAt || metadata.createdAt,
231
244
  title: toStringIfDefined(metadata?.title) || item.label || 'Untitled',
232
245
  description: toStringIfDefined(metadata?.description),
@@ -3,6 +3,7 @@ import type { ResolvedNavLinkItem } from '@theme/types/portal';
3
3
  export function usePageData(): {
4
4
  prevPage: ResolvedNavLinkItem | null;
5
5
  nextPage: ResolvedNavLinkItem | null;
6
+ props?: any;
6
7
  } | null {
7
8
  return {
8
9
  prevPage: { label: 'Intro', type: 'link', link: '#prev' },
@@ -20,6 +20,7 @@ export type ResolvedNavLinkItem = {
20
20
  httpVerb?: string;
21
21
  separatorLine?: boolean;
22
22
  routeSlug?: string;
23
+ fsPath?: string
23
24
  active?: boolean;
24
25
  icon?: string;
25
26
  srcSet?: string;
@@ -47,6 +48,7 @@ export type ResolvedNavGroupItem = {
47
48
  menuStyle?: MenuStyle;
48
49
  separatorLine?: boolean;
49
50
  routeSlug?: string;
51
+ fsPath?: string
50
52
  active?: boolean;
51
53
  icon?: string;
52
54
  srcSet?: string;
@@ -62,6 +64,7 @@ export type ResolvedNavItem =
62
64
  label?: string;
63
65
  labelTranslationKey?: string;
64
66
  routeSlug?: never;
67
+ fsPath?: never
65
68
 
66
69
  version?: string;
67
70
  isDefault?: boolean;
@@ -84,6 +87,7 @@ export type ResolvedNavItem =
84
87
  versionFolderId?: string;
85
88
  metadata?: Record<string, unknown>;
86
89
  routeSlug?: never;
90
+ fsPath?: never
87
91
 
88
92
  label: string;
89
93
  labelTranslationKey?: string;