@redocly/theme 0.60.0 → 0.61.0-next.0

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.
Files changed (41) hide show
  1. package/lib/components/Catalog/Catalog.js +12 -2
  2. package/lib/components/Catalog/CatalogEntities.js +18 -2
  3. package/lib/components/Catalog/CatalogEntity/CatalogEntity.js +10 -7
  4. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.d.ts +1 -1
  5. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.js +25 -2
  6. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent.d.ts +2 -1
  7. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent.js +2 -2
  8. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.d.ts +4 -2
  9. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +11 -3
  10. package/lib/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.js +7 -1
  11. package/lib/components/Catalog/CatalogFilter/CatalogFilterContent.d.ts +2 -3
  12. package/lib/components/Catalog/CatalogFilter/CatalogFilterContent.js +4 -43
  13. package/lib/components/Catalog/CatalogSelector.d.ts +3 -4
  14. package/lib/components/Catalog/CatalogSelector.js +2 -3
  15. package/lib/components/Catalog/CatalogTableView/CatalogTableView.d.ts +2 -1
  16. package/lib/components/Catalog/CatalogTableView/CatalogTableView.js +2 -2
  17. package/lib/components/Catalog/CatalogTableView/CatalogTableViewRow.d.ts +2 -1
  18. package/lib/components/Catalog/CatalogTableView/CatalogTableViewRow.js +3 -5
  19. package/lib/core/hooks/catalog/use-catalog-entity-details.d.ts +11 -0
  20. package/lib/core/hooks/catalog/{use-catalog-table-view-row.js → use-catalog-entity-details.js} +9 -9
  21. package/lib/core/hooks/index.d.ts +1 -1
  22. package/lib/core/hooks/index.js +1 -1
  23. package/lib/core/types/catalog.d.ts +23 -10
  24. package/lib/core/types/hooks.d.ts +5 -11
  25. package/package.json +2 -2
  26. package/src/components/Catalog/Catalog.tsx +11 -9
  27. package/src/components/Catalog/CatalogEntities.tsx +24 -3
  28. package/src/components/Catalog/CatalogEntity/CatalogEntity.tsx +21 -9
  29. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable.tsx +27 -0
  30. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent.tsx +3 -0
  31. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +18 -3
  32. package/src/components/Catalog/CatalogFilter/CatalogFilterCheckboxes.tsx +7 -1
  33. package/src/components/Catalog/CatalogFilter/CatalogFilterContent.tsx +6 -17
  34. package/src/components/Catalog/CatalogSelector.tsx +4 -7
  35. package/src/components/Catalog/CatalogTableView/CatalogTableView.tsx +3 -0
  36. package/src/components/Catalog/CatalogTableView/CatalogTableViewRow.tsx +6 -5
  37. package/src/core/hooks/catalog/{use-catalog-table-view-row.ts → use-catalog-entity-details.ts} +11 -15
  38. package/src/core/hooks/index.ts +1 -1
  39. package/src/core/types/catalog.ts +32 -10
  40. package/src/core/types/hooks.ts +6 -24
  41. package/lib/core/hooks/catalog/use-catalog-table-view-row.d.ts +0 -11
@@ -1,10 +1,10 @@
1
1
  import type { AsyncApiRealmUI } from '@redocly/realm-asyncapi-sdk';
2
- import type { BannerConfig, CatalogEntityConfig, PageData, PageProps, ResolvedNavItemWithLink, Version } from '@redocly/config';
2
+ import type { BannerConfig, PageData, PageProps, ResolvedNavItemWithLink, Version } from '@redocly/config';
3
3
  import type { ShikiTransformer } from '@shikijs/types';
4
4
  import type { Callback, TFunction as TFunc } from 'i18next';
5
5
  import type { To, Location, NavigateFunction } from 'react-router-dom';
6
6
  import type { CatalogConfig, ProductUiConfig } from '../../config';
7
- import type { UseCatalogResponse, CatalogApiResults, CatalogApiParams, FilteredCatalog, UseCatalogSortResponse, UseCatalogSearchResponse, CatalogViewMode } from './catalog';
7
+ import type { UseCatalogResponse, FilteredCatalog, UseCatalogSortResponse, UseCatalogSearchResponse, UseCatalogProps, UseCatalogFetchCatalogEntities, UseCatalogFetchCatalogEntitiesRelations } from './catalog';
8
8
  import type { UserMenuData } from './user-menu';
9
9
  import type { ItemState } from './sidebar';
10
10
  import type { SearchItemData, SearchFacet, SearchFilterItem, SearchFacetQuery, AiSearchConversationItem } from './search';
@@ -12,7 +12,6 @@ import type { SubmitFeedbackParams } from './feedback';
12
12
  import type { TFunction } from './l10n';
13
13
  import type { BreadcrumbItem } from './breadcrumb';
14
14
  import type { DrilldownMenuItemDetails } from './sidebar';
15
- import { BffCatalogEntity, BffCatalogEntityList, BffCatalogRelatedEntity, BffCatalogRelatedEntityList } from './catalog';
16
15
  import { AiSearchError } from '../constants/search';
17
16
  export type ThemeHooks = {
18
17
  useTranslate: () => {
@@ -122,16 +121,11 @@ export type ThemeHooks = {
122
121
  prevPage?: ResolvedNavItemWithLink;
123
122
  nextPage?: ResolvedNavItemWithLink;
124
123
  } | undefined;
125
- useCatalog: (config?: CatalogEntityConfig, serverFilters?: Record<string, {
126
- value: string;
127
- count: number;
128
- }[]>, entitiesCounterInitial?: number, initialViewMode?: CatalogViewMode) => UseCatalogResponse;
124
+ useCatalog: (props?: UseCatalogProps) => UseCatalogResponse;
129
125
  useCatalogSort: () => UseCatalogSortResponse;
130
126
  useCatalogSearch: () => UseCatalogSearchResponse;
131
- useFetchCatalogEntities: (params: CatalogApiParams, initialData?: BffCatalogEntityList) => CatalogApiResults<BffCatalogEntity, BffCatalogEntityList>;
132
- useFetchCatalogEntitiesRelations: (params: CatalogApiParams & {
133
- entityKey: string;
134
- }, initialData?: BffCatalogRelatedEntityList) => CatalogApiResults<BffCatalogRelatedEntity, BffCatalogRelatedEntityList>;
127
+ useFetchCatalogEntities: UseCatalogFetchCatalogEntities;
128
+ useFetchCatalogEntitiesRelations: UseCatalogFetchCatalogEntitiesRelations;
135
129
  useCatalogClassic: (config: CatalogConfig) => FilteredCatalog;
136
130
  useTelemetry: () => Omit<AsyncApiRealmUI.Telemetry, 'init' | 'updateCloudEventData' | 'forceFlush' | 'startSpan' | 'constructCloudEvent' | 'sendToOtelService'>;
137
131
  useUserTeams: () => string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.60.0",
3
+ "version": "0.61.0-next.0",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -63,7 +63,7 @@
63
63
  "vitest": "4.0.10",
64
64
  "vitest-when": "0.6.2",
65
65
  "webpack": "5.94.0",
66
- "@redocly/realm-asyncapi-sdk": "0.6.0"
66
+ "@redocly/realm-asyncapi-sdk": "0.7.0-next.0"
67
67
  },
68
68
  "dependencies": {
69
69
  "@tanstack/react-query": "5.62.3",
@@ -79,12 +79,12 @@ export function Catalog(props: CatalogProps): JSX.Element {
79
79
  onChangeCollapseSidebarClick,
80
80
  layout,
81
81
  collapsedSidebar,
82
- } = useCatalog(
83
- catalogConfig,
82
+ } = useCatalog({
83
+ config: catalogConfig,
84
+ entitiesCounterInitial: initialEntitiesList?.page.total || 0,
84
85
  serverFilters,
85
- initialEntitiesList?.page.total || 0,
86
86
  initialViewMode,
87
- );
87
+ });
88
88
 
89
89
  return (
90
90
  <>
@@ -95,19 +95,21 @@ export function Catalog(props: CatalogProps): JSX.Element {
95
95
  collapsedSidebar ? null : (
96
96
  <CatalogSelector
97
97
  catalogSwitcherItems={catalogSwitcherItems}
98
- setSearchQuery={setSearchQuery}
99
- setSortOption={setSortOption}
98
+ onChange={() => {
99
+ setSearchQuery('');
100
+ setSortOption(null);
101
+ }}
100
102
  />
101
103
  )
102
104
  }
103
105
  menu={
104
106
  <CatalogFilterContent
105
- setFilterTerm={setSearchQuery}
106
107
  filters={filters}
107
108
  filterTerm={searchQuery}
108
- hideSearch={true}
109
- showCounter={true}
110
109
  filterValuesCasing={customCatalogOptionsCasing}
110
+ onClear={() => {
111
+ setSearchQuery('');
112
+ }}
111
113
  />
112
114
  }
113
115
  footer={
@@ -3,7 +3,11 @@ import React, { JSX, useEffect } from 'react';
3
3
  import type { CatalogEntityConfig } from '@redocly/config';
4
4
 
5
5
  import { BffCatalogEntity, BffCatalogEntityList, SortOption } from '@redocly/theme/core/types';
6
- import { useThemeHooks, useCatalogEntities } from '@redocly/theme/core/hooks';
6
+ import {
7
+ useThemeHooks,
8
+ useCatalogEntities,
9
+ useCatalogEntityDetails,
10
+ } from '@redocly/theme/core/hooks';
7
11
  import { ArrowDownIcon } from '@redocly/theme/icons/ArrowDownIcon/ArrowDownIcon';
8
12
  import { CatalogCardView } from '@redocly/theme/components/Catalog/CatalogCardView/CatalogCardView';
9
13
  import { CatalogTableView } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView';
@@ -43,8 +47,11 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
43
47
  isColumnSorted,
44
48
  } = props;
45
49
 
46
- const { useFetchCatalogEntities } = useThemeHooks();
47
-
50
+ const { getEntityDetailsLink } = useCatalogEntityDetails({
51
+ catalogConfig,
52
+ });
53
+ const { useTelemetry, useFetchCatalogEntities } = useThemeHooks();
54
+ const telemetry = useTelemetry();
48
55
  const { initialFilter } = useCatalogEntities({
49
56
  entitiesTypes,
50
57
  excludedEntities,
@@ -67,6 +74,19 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
67
74
  props.initialEntitiesList,
68
75
  );
69
76
 
77
+ const onRowClick = (entity: BffCatalogEntity) => {
78
+ if (searchQuery) {
79
+ telemetry.sendCatalogEntitiesListSearchResultClickedMessage({
80
+ id: entity.id,
81
+ object: 'catalog_entity',
82
+ uri: getEntityDetailsLink(entity),
83
+ query: searchQuery,
84
+ entityKey: entity.key,
85
+ entityType: entity.type,
86
+ });
87
+ }
88
+ };
89
+
70
90
  const shouldShowLoadMore =
71
91
  query.hasNextPage ||
72
92
  (query.isPlaceholderData && entities && entities.length >= LOAD_MORE_THRESHOLD);
@@ -91,6 +111,7 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
91
111
  currentSortOption={sortOption}
92
112
  handleSortClick={handleSortClick}
93
113
  isColumnSorted={isColumnSorted}
114
+ onRowClick={onRowClick}
94
115
  />
95
116
  )}
96
117
 
@@ -48,15 +48,25 @@ const renderFirstColumnEntitySection = (entity: BffCatalogEntity): React.ReactEl
48
48
  }
49
49
  };
50
50
 
51
- const renderDataSchemaSection = (
52
- entity: BffCatalogEntity,
53
- relatedEntity: BffCatalogRelatedEntity | null,
51
+ type RenderDataSchemaSectionProps = {
52
+ entity: BffCatalogEntity;
53
+ relatedEntity: BffCatalogRelatedEntity | null;
54
+ catalogConfig: CatalogEntityConfig;
54
55
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
55
- RedocSchema: React.ComponentType<any>,
56
+ RedocSchema: React.ComponentType<any>;
56
57
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
57
- StoreProvider: React.ComponentType<any>,
58
- GraphqlTypeRenderer?: React.ComponentType<{ sdl: string; typeName: string }>,
59
- ): React.ReactElement | null => {
58
+ StoreProvider: React.ComponentType<any>;
59
+ GraphqlTypeRenderer?: React.ComponentType<{ sdl: string; typeName: string }>;
60
+ };
61
+
62
+ const renderDataSchemaSection = ({
63
+ entity,
64
+ relatedEntity,
65
+ catalogConfig,
66
+ RedocSchema,
67
+ StoreProvider,
68
+ GraphqlTypeRenderer,
69
+ }: RenderDataSchemaSectionProps): React.ReactElement | null => {
60
70
  if (entity.type !== 'data-schema') {
61
71
  return null;
62
72
  }
@@ -65,6 +75,7 @@ const renderDataSchemaSection = (
65
75
  <CatalogEntitySchema
66
76
  entity={entity}
67
77
  relatedEntity={relatedEntity}
78
+ catalogConfig={catalogConfig}
68
79
  RedocSchema={RedocSchema}
69
80
  StoreProvider={StoreProvider}
70
81
  GraphqlTypeRenderer={GraphqlTypeRenderer}
@@ -109,13 +120,14 @@ export function CatalogEntity({
109
120
  tag={entity.key}
110
121
  />
111
122
  <CatalogEntityProperties entity={entity} />
112
- {renderDataSchemaSection(
123
+ {renderDataSchemaSection({
113
124
  entity,
114
125
  relatedEntity,
126
+ catalogConfig,
115
127
  RedocSchema,
116
128
  StoreProvider,
117
129
  GraphqlTypeRenderer,
118
- )}
130
+ })}
119
131
  <CatalogTwoColumnsSection>
120
132
  {renderFirstColumnEntitySection(entity)}
121
133
  <CatalogEntityLinks entity={entity} />
@@ -12,6 +12,8 @@ import type {
12
12
  import { CatalogColumn } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTableView';
13
13
  import { CatalogActionsRow } from '@redocly/theme/components/Catalog/CatalogActionsRow';
14
14
  import { CatalogEntityRelationsTableContent } from '@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent';
15
+ import { useCatalogEntityDetails, useThemeHooks } from '@redocly/theme/core/hooks';
16
+ import { reverseRelationMap } from '@redocly/theme/core/constants';
15
17
 
16
18
  export type CatalogEntityRelationsTableProps = {
17
19
  entity: BffCatalogEntity;
@@ -35,6 +37,7 @@ export type CatalogEntityRelationsTableProps = {
35
37
  };
36
38
 
37
39
  export function CatalogEntityRelationsTable({
40
+ entity,
38
41
  entitiesCatalogConfig,
39
42
  catalogConfig,
40
43
  relations,
@@ -50,6 +53,29 @@ export function CatalogEntityRelationsTable({
50
53
  shouldShowLoadMore,
51
54
  listType,
52
55
  }: CatalogEntityRelationsTableProps): JSX.Element {
56
+ const { useTelemetry } = useThemeHooks();
57
+ const telemetry = useTelemetry();
58
+ const { getEntityDetailsLink } = useCatalogEntityDetails({
59
+ catalogConfig,
60
+ entitiesCatalogConfig,
61
+ });
62
+
63
+ const onRowClick = (relatedEntity: BffCatalogRelatedEntity) => {
64
+ if (searchQuery) {
65
+ telemetry.sendCatalogEntitiesRelatedEntitiesListSearchResultClickMessage({
66
+ id: relatedEntity.id,
67
+ object: 'catalog_entity',
68
+ uri: getEntityDetailsLink(relatedEntity),
69
+ query: searchQuery,
70
+ entityKey: entity.key,
71
+ entityType: entity.type,
72
+ relationType: reverseRelationMap[relatedEntity.relationType],
73
+ relatedEntityKey: relatedEntity.key,
74
+ relatedEntityType: relatedEntity.type,
75
+ });
76
+ }
77
+ };
78
+
53
79
  return (
54
80
  <div data-component-name="Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTable">
55
81
  {heading && <Heading>{heading}</Heading>}
@@ -73,6 +99,7 @@ export function CatalogEntityRelationsTable({
73
99
  isColumnSorted={isColumnSorted}
74
100
  shouldShowLoadMore={shouldShowLoadMore}
75
101
  listType={listType}
102
+ onRowClick={onRowClick}
76
103
  />
77
104
  </div>
78
105
  );
@@ -29,6 +29,7 @@ export type CatalogEntityRelationsTableContentProps = {
29
29
  isColumnSorted: (sortKey: string, direction: 'asc' | 'desc') => boolean;
30
30
  shouldShowLoadMore: boolean;
31
31
  listType?: ListType;
32
+ onRowClick: (entity: BffCatalogRelatedEntity) => void;
32
33
  };
33
34
 
34
35
  export function CatalogEntityRelationsTableContent({
@@ -44,6 +45,7 @@ export function CatalogEntityRelationsTableContent({
44
45
  isColumnSorted,
45
46
  shouldShowLoadMore,
46
47
  listType,
48
+ onRowClick,
47
49
  }: CatalogEntityRelationsTableContentProps): JSX.Element {
48
50
  return (
49
51
  <div data-component-name="Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelationsTableContent">
@@ -59,6 +61,7 @@ export function CatalogEntityRelationsTableContent({
59
61
  handleSortClick={handleSortClick}
60
62
  isColumnSorted={isColumnSorted}
61
63
  style={{ marginTop: 0 }}
64
+ onRowClick={onRowClick}
62
65
  />
63
66
  ) : (
64
67
  <CatalogEntitiesEmptyState listType={listType} />
@@ -2,8 +2,10 @@ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
  import * as Sampler from 'openapi-sampler';
4
4
 
5
- import { BffCatalogEntity, BffCatalogRelatedEntity } from '@redocly/theme/core/types';
6
- import { useThemeHooks } from '@redocly/theme/core/hooks';
5
+ import type { CatalogEntityConfig } from '@redocly/config';
6
+ import type { BffCatalogEntity, BffCatalogRelatedEntity } from '@redocly/theme/core/types';
7
+
8
+ import { useCatalogEntityDetails, useThemeHooks } from '@redocly/theme/core/hooks';
7
9
  import { useCatalogEntitySchema } from '@redocly/theme/core/hooks';
8
10
  import { JsonViewer } from '@redocly/theme/components/JsonViewer/JsonViewer';
9
11
  import { CopyButton } from '@redocly/theme/components/Buttons/CopyButton';
@@ -11,6 +13,7 @@ import { CopyButton } from '@redocly/theme/components/Buttons/CopyButton';
11
13
  export type CatalogEntitySchemaProps = {
12
14
  entity: BffCatalogEntity;
13
15
  relatedEntity: BffCatalogRelatedEntity | null;
16
+ catalogConfig: CatalogEntityConfig;
14
17
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
15
18
  RedocSchema: React.ComponentType<any>;
16
19
  /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
@@ -21,15 +24,20 @@ export type CatalogEntitySchemaProps = {
21
24
  export function CatalogEntitySchema({
22
25
  entity,
23
26
  relatedEntity,
27
+ catalogConfig,
24
28
  RedocSchema,
25
29
  StoreProvider,
26
30
  GraphqlTypeRenderer,
27
31
  }: CatalogEntitySchemaProps) {
28
- const { useTranslate } = useThemeHooks();
32
+ const { useTranslate, useTelemetry } = useThemeHooks();
33
+ const telemetry = useTelemetry();
29
34
  const { translate } = useTranslate();
30
35
  const { definition, parsedSchema, rawSchema } = useCatalogEntitySchema({ entity, relatedEntity });
31
36
  const isGraphql = entity.metadata?.specType === 'graphql';
32
37
  const graphqlSDL = entity?.metadata?.sdl;
38
+ const { getEntityDetailsLink } = useCatalogEntityDetails({
39
+ catalogConfig,
40
+ });
33
41
 
34
42
  return (
35
43
  <MetadataWrapper data-component-name="Catalog/CatalogEntity/CatalogEntityMetadata">
@@ -43,6 +51,13 @@ export function CatalogEntitySchema({
43
51
  variant="secondary"
44
52
  iconPosition="right"
45
53
  size="medium"
54
+ onCopyClick={() =>
55
+ telemetry.sendCatalogEntitiesCopyDataSchemaClickedMessage({
56
+ id: entity.id,
57
+ object: 'catalog_entity',
58
+ uri: getEntityDetailsLink(entity),
59
+ })
60
+ }
46
61
  ></CopyButton>
47
62
  )}
48
63
  </HeaderWrapper>
@@ -102,7 +102,13 @@ export function CatalogFilterCheckboxes({
102
102
  role="link"
103
103
  onClick={() => {
104
104
  filter.toggleOption(value);
105
- telemetry.sendFilterCheckboxToggledMessage({ id });
105
+ telemetry.sendCatalogEntitiesFilterCheckboxToggledMessage({
106
+ id: filter.property + '--' + value,
107
+ object: 'checkbox',
108
+ uri: window.location.href,
109
+ category: filter.property,
110
+ value: value,
111
+ });
106
112
  }}
107
113
  >
108
114
  <CheckboxIcon
@@ -1,34 +1,31 @@
1
1
  import React from 'react';
2
- import styled, { css } from 'styled-components';
2
+ import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
5
5
  import type { ResolvedFilter } from '@redocly/theme/core/types';
6
6
  import type { RedoclyConfig } from '@redocly/theme/config';
7
7
 
8
- import { FilterInput } from '@redocly/theme/components/Filter/FilterInput';
9
8
  import { useThemeHooks } from '@redocly/theme/core/hooks';
10
9
  import { Button } from '@redocly/theme/components/Button/Button';
11
10
  import { CatalogFilter } from '@redocly/theme/components/Catalog/CatalogFilter/CatalogFilter';
12
11
  import { isFromToSelectedOptions } from '@redocly/theme/core/utils';
13
12
 
14
13
  export type CatalogFilterContentProps = {
15
- setFilterTerm: (value: string) => void;
14
+ onClear: () => void;
16
15
  filters: ResolvedFilter[];
17
16
  filterTerm: string;
18
17
  filterValuesCasing?:
19
18
  | NonNullable<RedoclyConfig['catalog']>[string]['filterValuesCasing']
20
19
  | ((str: string) => string);
21
- hideSearch?: boolean;
22
20
  showCounter?: boolean;
23
21
  className?: string;
24
22
  };
25
23
 
26
24
  export function CatalogFilterContent({
27
- setFilterTerm,
25
+ onClear,
28
26
  filters,
29
27
  filterTerm,
30
28
  filterValuesCasing,
31
- hideSearch,
32
29
  showCounter = true,
33
30
  className,
34
31
  }: CatalogFilterContentProps): JSX.Element | null {
@@ -50,7 +47,7 @@ export function CatalogFilterContent({
50
47
 
51
48
  const handleClearAll = (): void => {
52
49
  filters.forEach((filter) => filter.selectOption(''));
53
- setFilterTerm('');
50
+ onClear();
54
51
  };
55
52
 
56
53
  if (!filters.length) {
@@ -72,10 +69,7 @@ export function CatalogFilterContent({
72
69
  </Button>
73
70
  ) : null}
74
71
  </FiltersHeader>
75
- {!hideSearch && (
76
- <FilterInput value={filterTerm} onChange={(updatedTerm) => setFilterTerm(updatedTerm)} />
77
- )}
78
- <FilterItems hideSearch={hideSearch}>
72
+ <FilterItems>
79
73
  {filters.map((filter, idx) => (
80
74
  <CatalogFilter
81
75
  filter={filter}
@@ -108,14 +102,9 @@ const FiltersTitle = styled.div`
108
102
  line-height: var(--filter-content-title-line-height);
109
103
  `;
110
104
 
111
- const FilterItems = styled.div<{ hideSearch?: boolean }>`
105
+ const FilterItems = styled.div`
112
106
  height: 100%;
113
107
  display: flex;
114
108
  flex-direction: column;
115
109
  border-top: 1px solid var(--border-color-secondary);
116
- ${({ hideSearch }) =>
117
- hideSearch &&
118
- css`
119
- border-top: none;
120
- `}
121
110
  `;
@@ -3,21 +3,19 @@ import styled from 'styled-components';
3
3
  import { useNavigate } from 'react-router-dom';
4
4
 
5
5
  import { Select } from '@redocly/theme/components/Select/Select';
6
- import { CatalogSwitcherItem, SortOption } from '@redocly/theme/core/types';
6
+ import { CatalogSwitcherItem } from '@redocly/theme/core/types';
7
7
  import { getPathPrefix } from '@redocly/theme/core/utils';
8
8
  import { useThemeHooks } from '@redocly/theme/core/hooks';
9
9
  import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
10
10
 
11
11
  export type CatalogSelectorProps = {
12
12
  catalogSwitcherItems: CatalogSwitcherItem[];
13
- setSearchQuery: (query: string) => void;
14
- setSortOption: (option: SortOption | null) => void;
13
+ onChange: () => void;
15
14
  };
16
15
 
17
16
  export function CatalogSelector({
18
17
  catalogSwitcherItems,
19
- setSearchQuery,
20
- setSortOption,
18
+ onChange,
21
19
  }: CatalogSelectorProps): JSX.Element {
22
20
  const { useTranslate } = useThemeHooks();
23
21
  const { translate } = useTranslate();
@@ -41,8 +39,7 @@ export function CatalogSelector({
41
39
  options={options}
42
40
  onChange={(value) => {
43
41
  navigate(`${pathPrefix}/catalogs/${value}`);
44
- setSearchQuery('');
45
- setSortOption(null);
42
+ onChange();
46
43
  }}
47
44
  icon={<ChevronDownIcon color="var(--catalog-select-icon-color)" />}
48
45
  />
@@ -27,6 +27,7 @@ export type CatalogTableViewProps<T extends BaseEntity> = {
27
27
  columns?: CatalogColumn<T>[];
28
28
  setSortOption: (sortOption: SortOption | null) => void;
29
29
  currentSortOption?: SortOption | null;
30
+ onRowClick?: (entity: T) => void;
30
31
  handleSortClick: (sortKey: string, direction: 'asc' | 'desc') => void;
31
32
  isColumnSorted: (sortKey: string, direction: 'asc' | 'desc') => boolean;
32
33
  style?: React.CSSProperties;
@@ -95,6 +96,7 @@ export const CatalogTableView = <T extends BaseEntity>({
95
96
  columns = baseColumns as CatalogColumn<BaseEntity>[],
96
97
  setSortOption,
97
98
  currentSortOption,
99
+ onRowClick,
98
100
  handleSortClick,
99
101
  isColumnSorted,
100
102
  style,
@@ -124,6 +126,7 @@ export const CatalogTableView = <T extends BaseEntity>({
124
126
  entitiesCatalogConfig={entitiesCatalogConfig}
125
127
  catalogConfig={catalogConfig}
126
128
  columns={columns}
129
+ onRowClick={onRowClick}
127
130
  />
128
131
  ))}
129
132
  </div>
@@ -8,7 +8,7 @@ import { CatalogOwnersCell } from '@redocly/theme/components/Catalog/CatalogTabl
8
8
  import { CatalogDomainsCell } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogDomainsCell';
9
9
  import { CatalogEntityCell } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogEntityCell';
10
10
  import { CatalogTagsCell } from '@redocly/theme/components/Catalog/CatalogTableView/CatalogTagsCell';
11
- import { useCatalogTableViewRow } from '@redocly/theme/core/hooks';
11
+ import { useCatalogEntityDetails } from '@redocly/theme/core/hooks';
12
12
  import { CatalogEntityTypeTag } from '@redocly/theme/components/Catalog/CatalogEntityTypeTag';
13
13
 
14
14
  import { Link } from '../../Link/Link';
@@ -26,6 +26,7 @@ export type CatalogTableViewRowProps<T extends BaseEntity> = {
26
26
  entitiesCatalogConfig?: EntitiesCatalogConfig;
27
27
  catalogConfig: CatalogEntityConfig;
28
28
  columns?: CatalogColumn<T>[];
29
+ onRowClick?: (entity: T) => void;
29
30
  };
30
31
 
31
32
  export type CatalogColumn<T> = {
@@ -89,10 +90,9 @@ export const CatalogTableViewRow = <T extends BaseEntity>({
89
90
  entitiesCatalogConfig,
90
91
  catalogConfig,
91
92
  columns = baseColumns as CatalogColumn<BaseEntity>[],
93
+ onRowClick = () => {},
92
94
  }: CatalogTableViewRowProps<T>) => {
93
- const { getEntityDetailsLink } = useCatalogTableViewRow({
94
- entityKey: entity.key,
95
- entityType: entity.type,
95
+ const { getEntityDetailsLink } = useCatalogEntityDetails({
96
96
  catalogConfig,
97
97
  entitiesCatalogConfig,
98
98
  });
@@ -102,7 +102,8 @@ export const CatalogTableViewRow = <T extends BaseEntity>({
102
102
  key={entity.id}
103
103
  $columnsWidths={columns.map((column) => column.width || '1fr')}
104
104
  $columnsMinWidths={columns.map((column) => column.minWidth || 'auto')}
105
- to={getEntityDetailsLink() + '?search='}
105
+ to={getEntityDetailsLink(entity) + '?search='}
106
+ onClick={() => onRowClick(entity)}
106
107
  style={{ color: 'var(--catalog-page-wrapper-text-color)' }}
107
108
  data-component-name="Catalog/CatalogTableView/CatalogTableViewRow"
108
109
  >
@@ -1,39 +1,35 @@
1
1
  import type { CatalogEntityConfig, EntitiesCatalogConfig } from '@redocly/config';
2
+ import type { BffCatalogEntity } from '@redocly/theme/core/types';
2
3
 
3
4
  import { getPathPrefix } from '../../utils/urls';
4
5
 
5
- type CatalogTableViewRowProps = {
6
- entityKey: string;
7
- entityType: string;
6
+ type Props = {
8
7
  catalogConfig: CatalogEntityConfig;
9
8
  entitiesCatalogConfig?: EntitiesCatalogConfig;
10
9
  };
11
10
 
12
- export function useCatalogTableViewRow({
13
- entityKey,
14
- entityType,
15
- catalogConfig,
16
- entitiesCatalogConfig,
17
- }: CatalogTableViewRowProps) {
18
- const getCatalogSpecificConfigByEntityTypeIncluded = () => {
11
+ type BaseEntity = Pick<BffCatalogEntity, 'key' | 'type'>;
12
+
13
+ export function useCatalogEntityDetails({ catalogConfig, entitiesCatalogConfig }: Props) {
14
+ const getCatalogSpecificConfigByEntityTypeIncluded = (entity: BaseEntity) => {
19
15
  if (!entitiesCatalogConfig) {
20
16
  return;
21
17
  }
22
18
 
23
19
  return Object.values(entitiesCatalogConfig.catalogs ?? {}).find((catalog) => {
24
- return catalog?.includes?.some((include) => include.type === entityType);
20
+ return catalog?.includes?.some((include) => include.type === entity.type);
25
21
  });
26
22
  };
27
23
 
28
- const getEntityDetailsLink = () => {
24
+ const getEntityDetailsLink = (entity: BaseEntity) => {
29
25
  const pathPrefix = getPathPrefix();
30
- const catalogSpecificConfig = getCatalogSpecificConfigByEntityTypeIncluded();
26
+ const catalogSpecificConfig = getCatalogSpecificConfigByEntityTypeIncluded(entity);
31
27
 
32
28
  if (!catalogSpecificConfig || !entitiesCatalogConfig) {
33
- return `${pathPrefix}/catalogs/${catalogConfig.slug}/entities/${entityKey}`;
29
+ return `${pathPrefix}/catalogs/${catalogConfig.slug}/entities/${entity.key}`;
34
30
  }
35
31
 
36
- return `${pathPrefix}/catalogs/${catalogSpecificConfig.slug}/entities/${entityKey}`;
32
+ return `${pathPrefix}/catalogs/${catalogSpecificConfig.slug}/entities/${entity.key}`;
37
33
  };
38
34
 
39
35
  return { getEntityDetailsLink };
@@ -45,6 +45,6 @@ export * from './use-user-teams';
45
45
  export * from './use-page-actions';
46
46
  export * from './use-mcp-config';
47
47
  export * from './use-connect-mcp-button';
48
- export * from './catalog/use-catalog-table-view-row';
48
+ export * from './catalog/use-catalog-entity-details';
49
49
  export * from './catalog/use-catalog-entity-schema';
50
50
  export * from './catalog/use-catalog-table-header-cell-actions';