@finos/legend-application-marketplace 0.2.3 → 0.2.5

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 (106) hide show
  1. package/lib/__lib__/LegendMarketplaceAppEvent.d.ts +2 -0
  2. package/lib/__lib__/LegendMarketplaceAppEvent.d.ts.map +1 -1
  3. package/lib/__lib__/LegendMarketplaceAppEvent.js +2 -0
  4. package/lib/__lib__/LegendMarketplaceAppEvent.js.map +1 -1
  5. package/lib/__lib__/LegendMarketplaceNavigation.d.ts +7 -1
  6. package/lib/__lib__/LegendMarketplaceNavigation.d.ts.map +1 -1
  7. package/lib/__lib__/LegendMarketplaceNavigation.js +9 -1
  8. package/lib/__lib__/LegendMarketplaceNavigation.js.map +1 -1
  9. package/lib/__lib__/LegendMarketplaceTelemetryHelper.d.ts +2 -1
  10. package/lib/__lib__/LegendMarketplaceTelemetryHelper.d.ts.map +1 -1
  11. package/lib/__lib__/LegendMarketplaceTelemetryHelper.js +10 -2
  12. package/lib/__lib__/LegendMarketplaceTelemetryHelper.js.map +1 -1
  13. package/lib/application/LegendMarketplaceWebApplication.d.ts.map +1 -1
  14. package/lib/application/LegendMarketplaceWebApplication.js +4 -1
  15. package/lib/application/LegendMarketplaceWebApplication.js.map +1 -1
  16. package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.d.ts +22 -0
  17. package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.d.ts.map +1 -0
  18. package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.js +37 -0
  19. package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.js.map +1 -0
  20. package/lib/components/AddToCart/CartDrawer.d.ts.map +1 -1
  21. package/lib/components/AddToCart/CartDrawer.js +36 -4
  22. package/lib/components/AddToCart/CartDrawer.js.map +1 -1
  23. package/lib/components/AddToCart/RecommendedAddOnsModal.d.ts +2 -1
  24. package/lib/components/AddToCart/RecommendedAddOnsModal.d.ts.map +1 -1
  25. package/lib/components/AddToCart/RecommendedAddOnsModal.js +23 -13
  26. package/lib/components/AddToCart/RecommendedAddOnsModal.js.map +1 -1
  27. package/lib/components/AddToCart/RecommendedItemsCard.d.ts +3 -1
  28. package/lib/components/AddToCart/RecommendedItemsCard.d.ts.map +1 -1
  29. package/lib/components/AddToCart/RecommendedItemsCard.js +14 -11
  30. package/lib/components/AddToCart/RecommendedItemsCard.js.map +1 -1
  31. package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.d.ts +23 -0
  32. package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.d.ts.map +1 -0
  33. package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.js +22 -0
  34. package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.js.map +1 -0
  35. package/lib/components/MarketplaceCard/FieldSearchResultListItem.d.ts +25 -0
  36. package/lib/components/MarketplaceCard/FieldSearchResultListItem.d.ts.map +1 -0
  37. package/lib/components/MarketplaceCard/FieldSearchResultListItem.js +58 -0
  38. package/lib/components/MarketplaceCard/FieldSearchResultListItem.js.map +1 -0
  39. package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.d.ts +10 -0
  40. package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.d.ts.map +1 -1
  41. package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.js +2 -2
  42. package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.js.map +1 -1
  43. package/lib/components/ProviderCard/LegendMarketplaceTerminalCard.d.ts.map +1 -1
  44. package/lib/components/ProviderCard/LegendMarketplaceTerminalCard.js +5 -2
  45. package/lib/components/ProviderCard/LegendMarketplaceTerminalCard.js.map +1 -1
  46. package/lib/components/SearchBar/LegendMarketplaceSearchBar.d.ts +2 -1
  47. package/lib/components/SearchBar/LegendMarketplaceSearchBar.d.ts.map +1 -1
  48. package/lib/components/SearchBar/LegendMarketplaceSearchBar.js +20 -7
  49. package/lib/components/SearchBar/LegendMarketplaceSearchBar.js.map +1 -1
  50. package/lib/index.css +2 -2
  51. package/lib/index.css.map +1 -1
  52. package/lib/package.json +1 -1
  53. package/lib/pages/Lakehouse/MarketplaceLakehouseHome.d.ts.map +1 -1
  54. package/lib/pages/Lakehouse/MarketplaceLakehouseHome.js +6 -4
  55. package/lib/pages/Lakehouse/MarketplaceLakehouseHome.js.map +1 -1
  56. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.d.ts +17 -0
  57. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.d.ts.map +1 -0
  58. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.js +126 -0
  59. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.js.map +1 -0
  60. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.d.ts.map +1 -1
  61. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js +8 -3
  62. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js.map +1 -1
  63. package/lib/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.d.ts.map +1 -1
  64. package/lib/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.js +2 -2
  65. package/lib/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.js.map +1 -1
  66. package/lib/pages/__test-utils__/TEST_DATA__LakehouseDataProducts.d.ts.map +1 -1
  67. package/lib/pages/__test-utils__/TEST_DATA__LakehouseDataProducts.js.map +1 -1
  68. package/lib/stores/cart/CartStore.d.ts +10 -3
  69. package/lib/stores/cart/CartStore.d.ts.map +1 -1
  70. package/lib/stores/cart/CartStore.js +66 -42
  71. package/lib/stores/cart/CartStore.js.map +1 -1
  72. package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.d.ts +63 -0
  73. package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.d.ts.map +1 -0
  74. package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.js +228 -0
  75. package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.js.map +1 -0
  76. package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.d.ts.map +1 -1
  77. package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.js +9 -13
  78. package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.js.map +1 -1
  79. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.d.ts +40 -0
  80. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.d.ts.map +1 -0
  81. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.js +84 -0
  82. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.js.map +1 -0
  83. package/package.json +8 -8
  84. package/src/__lib__/LegendMarketplaceAppEvent.ts +2 -0
  85. package/src/__lib__/LegendMarketplaceNavigation.ts +18 -1
  86. package/src/__lib__/LegendMarketplaceTelemetryHelper.ts +17 -1
  87. package/src/application/LegendMarketplaceWebApplication.tsx +13 -0
  88. package/src/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.tsx +67 -0
  89. package/src/components/AddToCart/CartDrawer.tsx +49 -4
  90. package/src/components/AddToCart/RecommendedAddOnsModal.tsx +86 -24
  91. package/src/components/AddToCart/RecommendedItemsCard.tsx +143 -120
  92. package/src/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.tsx +65 -0
  93. package/src/components/MarketplaceCard/FieldSearchResultListItem.tsx +163 -0
  94. package/src/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.tsx +2 -2
  95. package/src/components/ProviderCard/LegendMarketplaceTerminalCard.tsx +7 -0
  96. package/src/components/SearchBar/LegendMarketplaceSearchBar.tsx +44 -3
  97. package/src/pages/Lakehouse/MarketplaceLakehouseHome.tsx +9 -2
  98. package/src/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.tsx +380 -0
  99. package/src/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.tsx +19 -1
  100. package/src/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.tsx +6 -2
  101. package/src/pages/__test-utils__/TEST_DATA__LakehouseDataProducts.ts +3 -2
  102. package/src/stores/cart/CartStore.ts +86 -51
  103. package/src/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.ts +309 -0
  104. package/src/stores/lakehouse/LegendMarketplaceProductViewerStore.ts +23 -30
  105. package/src/stores/lakehouse/fieldSearch/FieldSearchResultState.ts +122 -0
  106. package/tsconfig.json +6 -0
@@ -63,13 +63,18 @@ export interface Vendor {
63
63
 
64
64
  export const LegendMarketplaceSearchBar = observer(
65
65
  (props: {
66
- onSearch?: (query: string | undefined, useProducerSearch: boolean) => void;
66
+ onSearch?: (
67
+ query: string | undefined,
68
+ useProducerSearch: boolean,
69
+ useFieldSearch: boolean,
70
+ ) => void;
67
71
  stateSearchQuery?: string | undefined;
68
72
  placeholder?: string;
69
73
  onChange?: (query: string) => void;
70
74
  className?: string | undefined;
71
75
  showSettings?: boolean;
72
76
  stateUseProducerSearch?: boolean | undefined;
77
+ stateUseFieldSearch?: boolean;
73
78
  enableAutosuggest?: boolean;
74
79
  }): JSX.Element => {
75
80
  const {
@@ -80,6 +85,7 @@ export const LegendMarketplaceSearchBar = observer(
80
85
  className,
81
86
  showSettings,
82
87
  stateUseProducerSearch,
88
+ stateUseFieldSearch,
83
89
  enableAutosuggest = true,
84
90
  } = props;
85
91
 
@@ -92,6 +98,9 @@ export const LegendMarketplaceSearchBar = observer(
92
98
  const [useProducerSearch, setUseProducerSearch] = useState(
93
99
  stateUseProducerSearch ?? false,
94
100
  );
101
+ const [useFieldSearch, setUseFieldSearch] = useState(
102
+ stateUseFieldSearch ?? false,
103
+ );
95
104
  const [searchMenuAnchorEl, setSearchMenuAnchorEl] =
96
105
  useState<HTMLElement | null>();
97
106
  const [suggestions, setSuggestions] = useState<SearchSuggestion[]>([]);
@@ -181,6 +190,10 @@ export const LegendMarketplaceSearchBar = observer(
181
190
  setUseProducerSearch(stateUseProducerSearch ?? false);
182
191
  }, [stateUseProducerSearch]);
183
192
 
193
+ useEffect(() => {
194
+ setUseFieldSearch(stateUseFieldSearch ?? false);
195
+ }, [stateUseFieldSearch]);
196
+
184
197
  useEffect(() => {
185
198
  const abortController = new AbortController();
186
199
 
@@ -241,7 +254,7 @@ export const LegendMarketplaceSearchBar = observer(
241
254
  selectedSuggestion.type === SearchSuggestionType.SEARCH_QUERY ||
242
255
  selectedSuggestion.type === SearchSuggestionType.DEFAULT
243
256
  ) {
244
- onSearch?.(selectedQuery, useProducerSearch);
257
+ onSearch?.(selectedQuery, useProducerSearch, useFieldSearch);
245
258
  LegendMarketplaceTelemetryHelper.logEvent_SearchAutosuggestSelection(
246
259
  applicationStore.telemetryService,
247
260
  selectedQuery,
@@ -274,7 +287,7 @@ export const LegendMarketplaceSearchBar = observer(
274
287
 
275
288
  const handleSubmit = (event: React.FormEvent): void => {
276
289
  event.preventDefault();
277
- onSearch?.(searchQuery, useProducerSearch);
290
+ onSearch?.(searchQuery, useProducerSearch, useFieldSearch);
278
291
  };
279
292
 
280
293
  const getOptionLabel = (option: SearchSuggestion | string): string =>
@@ -525,6 +538,9 @@ export const LegendMarketplaceSearchBar = observer(
525
538
  checked={useProducerSearch}
526
539
  onChange={(event) => {
527
540
  setUseProducerSearch(event.target.checked);
541
+ if (event.target.checked) {
542
+ setUseFieldSearch(false);
543
+ }
528
544
  LegendMarketplaceTelemetryHelper.logEvent_ToggleProducerSearch(
529
545
  applicationStore.telemetryService,
530
546
  event.target.checked,
@@ -540,6 +556,31 @@ export const LegendMarketplaceSearchBar = observer(
540
556
  }
541
557
  />
542
558
  </MenuItem>
559
+ <MenuItem>
560
+ <FormControlLabel
561
+ control={
562
+ <Switch
563
+ checked={useFieldSearch}
564
+ onChange={(event) => {
565
+ setUseFieldSearch(event.target.checked);
566
+ if (event.target.checked) {
567
+ setUseProducerSearch(false);
568
+ }
569
+ LegendMarketplaceTelemetryHelper.logEvent_ToggleFieldSearch(
570
+ applicationStore.telemetryService,
571
+ event.target.checked,
572
+ );
573
+ }}
574
+ />
575
+ }
576
+ label={
577
+ <>
578
+ Field Search{' '}
579
+ <LegendMarketplaceInfoTooltip title="Use this search to discover data products and datasets that contain a specific field" />
580
+ </>
581
+ }
582
+ />
583
+ </MenuItem>
543
584
  </Menu>
544
585
  )}
545
586
  </form>
@@ -25,7 +25,10 @@ import {
25
25
  CubesLoadingIndicator,
26
26
  CubesLoadingIndicatorIcon,
27
27
  } from '@finos/legend-art';
28
- import { generateLakehouseSearchResultsRoute } from '../../__lib__/LegendMarketplaceNavigation.js';
28
+ import {
29
+ generateFieldSearchResultsRoute,
30
+ generateLakehouseSearchResultsRoute,
31
+ } from '../../__lib__/LegendMarketplaceNavigation.js';
29
32
  import {
30
33
  assertErrorThrown,
31
34
  isNonEmptyString,
@@ -217,16 +220,20 @@ export const MarketplaceLakehouseHome = observer(() => {
217
220
  const handleSearch = (
218
221
  _query: string | undefined,
219
222
  _useProducerSearch: boolean,
223
+ _useFieldSearch: boolean,
220
224
  ): void => {
221
225
  if (isNonEmptyString(_query)) {
222
226
  applicationStore.navigationService.navigator.goToLocation(
223
- generateLakehouseSearchResultsRoute(_query, _useProducerSearch),
227
+ _useFieldSearch
228
+ ? generateFieldSearchResultsRoute(_query)
229
+ : generateLakehouseSearchResultsRoute(_query, _useProducerSearch),
224
230
  );
225
231
  LegendMarketplaceTelemetryHelper.logEvent_SearchQuery(
226
232
  applicationStore.telemetryService,
227
233
  _query,
228
234
  _useProducerSearch,
229
235
  LEGEND_MARKETPLACE_PAGE.HOME_PAGE,
236
+ _useFieldSearch,
230
237
  );
231
238
  }
232
239
  };
@@ -0,0 +1,380 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { Container, Paper, Typography } from '@mui/material';
18
+ import { observer } from 'mobx-react-lite';
19
+ import { flowResult } from 'mobx';
20
+ import { useCallback, useEffect, useRef } from 'react';
21
+ import { useSyncStateAndSearchParam } from '@finos/legend-application';
22
+ import { useSearchParams } from '@finos/legend-application/browser';
23
+ import { isNonEmptyString } from '@finos/legend-shared';
24
+ import {
25
+ CubesLoadingIndicator,
26
+ CubesLoadingIndicatorIcon,
27
+ } from '@finos/legend-art';
28
+ import { DATAPRODUCT_TYPE } from '@finos/legend-extension-dsl-data-product';
29
+ import {
30
+ LEGEND_MARKETPLACE_FIELD_SEARCH_RESULTS_QUERY_PARAM_TOKEN,
31
+ generateLakehouseSearchResultsRoute,
32
+ } from '../../../__lib__/LegendMarketplaceNavigation.js';
33
+ import {
34
+ LEGEND_MARKETPLACE_PAGE,
35
+ LegendMarketplaceTelemetryHelper,
36
+ } from '../../../__lib__/LegendMarketplaceTelemetryHelper.js';
37
+ import {
38
+ useLegendMarketplaceFieldSearchResultsStore,
39
+ withLegendMarketplaceFieldSearchResultsStore,
40
+ } from '../../../application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.js';
41
+ import { FieldSearchFiltersPanel } from '../../../components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.js';
42
+ import { FieldSearchResultListRow } from '../../../components/MarketplaceCard/FieldSearchResultListItem.js';
43
+ import { LegendMarketplaceSearchBar } from '../../../components/SearchBar/LegendMarketplaceSearchBar.js';
44
+ import { PaginationControls } from '../../../components/Pagination/PaginationControls.js';
45
+ import { LegendMarketplacePage } from '../../LegendMarketplacePage.js';
46
+ import { DataProductTypeFilter } from '../../../stores/lakehouse/LegendMarketplaceSearchResultsStore.js';
47
+ import type { LegendMarketplaceFieldSearchResultsStore } from '../../../stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.js';
48
+ import { type FieldSearchDataProductEntry } from '../../../stores/lakehouse/fieldSearch/FieldSearchResultState.js';
49
+
50
+ const FieldSearchResultsContent = observer(
51
+ (props: {
52
+ fieldSearchResultsStore: LegendMarketplaceFieldSearchResultsStore;
53
+ handlePageChange: (page: number) => void;
54
+ handleItemsPerPageChange: (itemsPerPage: number) => void;
55
+ handleToggleExpandRow: (rowId: string) => void;
56
+ handleOpenDataProduct: (dataProduct: FieldSearchDataProductEntry) => void;
57
+ }) => {
58
+ const {
59
+ fieldSearchResultsStore,
60
+ handlePageChange,
61
+ handleItemsPerPageChange,
62
+ handleToggleExpandRow,
63
+ handleOpenDataProduct,
64
+ } = props;
65
+
66
+ if (fieldSearchResultsStore.isLoading) {
67
+ return (
68
+ <div className="marketplace-lakehouse-search-results__loading-container">
69
+ <CubesLoadingIndicator isLoading={true}>
70
+ <CubesLoadingIndicatorIcon />
71
+ </CubesLoadingIndicator>
72
+ </div>
73
+ );
74
+ }
75
+
76
+ if (fieldSearchResultsStore.hasFailed) {
77
+ return (
78
+ <div className="marketplace-lakehouse-search-results__empty-state">
79
+ <Typography
80
+ variant="h5"
81
+ className="marketplace-lakehouse-search-results__empty-state__title"
82
+ >
83
+ Field search failed
84
+ </Typography>
85
+ <Typography
86
+ variant="body1"
87
+ className="marketplace-lakehouse-search-results__empty-state__message"
88
+ >
89
+ {fieldSearchResultsStore.errorMessage}
90
+ </Typography>
91
+ </div>
92
+ );
93
+ }
94
+
95
+ if (
96
+ fieldSearchResultsStore.hasActiveFilters &&
97
+ fieldSearchResultsStore.totalItems === 0
98
+ ) {
99
+ return (
100
+ <div className="marketplace-lakehouse-search-results__empty-state">
101
+ <Typography
102
+ variant="h5"
103
+ className="marketplace-lakehouse-search-results__empty-state__title"
104
+ >
105
+ No fields match the current filters
106
+ </Typography>
107
+ <Typography
108
+ variant="body1"
109
+ className="marketplace-lakehouse-search-results__empty-state__message"
110
+ >
111
+ Clear one or more filters to see results again.
112
+ </Typography>
113
+ </div>
114
+ );
115
+ }
116
+
117
+ if (
118
+ !fieldSearchResultsStore.hasActiveFilters &&
119
+ isNonEmptyString(fieldSearchResultsStore.searchQuery) &&
120
+ fieldSearchResultsStore.totalItems === 0
121
+ ) {
122
+ return (
123
+ <div className="marketplace-lakehouse-search-results__empty-state">
124
+ <Typography
125
+ variant="h5"
126
+ className="marketplace-lakehouse-search-results__empty-state__title"
127
+ >
128
+ No fields found
129
+ </Typography>
130
+ <Typography
131
+ variant="body1"
132
+ className="marketplace-lakehouse-search-results__empty-state__message"
133
+ >
134
+ Try a broader query or switch back to product search.
135
+ </Typography>
136
+ </div>
137
+ );
138
+ }
139
+
140
+ if (fieldSearchResultsStore.tableRows.length === 0) {
141
+ return null;
142
+ }
143
+
144
+ return (
145
+ <>
146
+ <Paper
147
+ elevation={1}
148
+ className="marketplace-lakehouse-field-search-results__list"
149
+ >
150
+ <div className="marketplace-lakehouse-field-search-results__list-header">
151
+ <Typography className="marketplace-lakehouse-field-search-results__list-header-cell">
152
+ Field Name
153
+ </Typography>
154
+ <Typography className="marketplace-lakehouse-field-search-results__list-header-cell">
155
+ Type
156
+ </Typography>
157
+ <Typography className="marketplace-lakehouse-field-search-results__list-header-cell">
158
+ Description
159
+ </Typography>
160
+ <Typography className="marketplace-lakehouse-field-search-results__list-header-cell">
161
+ Data Products
162
+ </Typography>
163
+ </div>
164
+ <div className="marketplace-lakehouse-field-search-results__list-body">
165
+ {fieldSearchResultsStore.tableRows.map((row) => (
166
+ <FieldSearchResultListRow
167
+ key={row.id}
168
+ fieldSearchResultState={row}
169
+ expanded={fieldSearchResultsStore.isRowExpanded(row.id)}
170
+ onToggleExpanded={handleToggleExpandRow}
171
+ onOpenDataProduct={handleOpenDataProduct}
172
+ />
173
+ ))}
174
+ </div>
175
+ </Paper>
176
+ <PaginationControls
177
+ totalItems={fieldSearchResultsStore.totalItems}
178
+ itemsPerPage={fieldSearchResultsStore.itemsPerPage}
179
+ page={fieldSearchResultsStore.page}
180
+ onPageChange={handlePageChange}
181
+ onItemsPerPageChange={handleItemsPerPageChange}
182
+ disabled={fieldSearchResultsStore.isLoading}
183
+ />
184
+ </>
185
+ );
186
+ },
187
+ );
188
+
189
+ const LegendMarketplaceFieldSearchResultsPage = observer(() => {
190
+ const fieldSearchResultsStore = useLegendMarketplaceFieldSearchResultsStore();
191
+ const marketplaceBaseStore = fieldSearchResultsStore.marketplaceBaseStore;
192
+ const applicationStore = marketplaceBaseStore.applicationStore;
193
+ const [searchParams, setSearchParams] = useSearchParams();
194
+ const pageRef = useRef<HTMLDivElement>(null);
195
+
196
+ useSyncStateAndSearchParam(
197
+ fieldSearchResultsStore.searchQuery,
198
+ useCallback(
199
+ (val: string | null) => {
200
+ if (val === null) {
201
+ return;
202
+ }
203
+ fieldSearchResultsStore.setSearchQuery(val);
204
+ },
205
+ [fieldSearchResultsStore],
206
+ ),
207
+ LEGEND_MARKETPLACE_FIELD_SEARCH_RESULTS_QUERY_PARAM_TOKEN.QUERY,
208
+ searchParams.get(
209
+ LEGEND_MARKETPLACE_FIELD_SEARCH_RESULTS_QUERY_PARAM_TOKEN.QUERY,
210
+ ),
211
+ setSearchParams,
212
+ useCallback(() => true, []),
213
+ );
214
+
215
+ useEffect(() => {
216
+ flowResult(fieldSearchResultsStore.executeSearch()).catch(
217
+ applicationStore.alertUnhandledError,
218
+ );
219
+ }, [
220
+ applicationStore,
221
+ fieldSearchResultsStore,
222
+ fieldSearchResultsStore.searchQuery,
223
+ ]);
224
+
225
+ const handlePageChange = useCallback(
226
+ (page: number) => {
227
+ pageRef.current?.scrollIntoView({ behavior: 'smooth' });
228
+ flowResult(fieldSearchResultsStore.changePageAndFetch(page)).catch(
229
+ applicationStore.alertUnhandledError,
230
+ );
231
+ },
232
+ [fieldSearchResultsStore, applicationStore],
233
+ );
234
+
235
+ const handleItemsPerPageChange = useCallback(
236
+ (itemsPerPage: number) => {
237
+ flowResult(
238
+ fieldSearchResultsStore.changeItemsPerPageAndFetch(itemsPerPage),
239
+ ).catch(applicationStore.alertUnhandledError);
240
+ },
241
+ [fieldSearchResultsStore, applicationStore],
242
+ );
243
+
244
+ const handleToggleProductType = useCallback(
245
+ (productType: DataProductTypeFilter) => {
246
+ flowResult(
247
+ fieldSearchResultsStore.toggleProductTypeAndFetch(productType),
248
+ ).catch(applicationStore.alertUnhandledError);
249
+ },
250
+ [fieldSearchResultsStore, applicationStore],
251
+ );
252
+
253
+ const handleClearFilters = useCallback(() => {
254
+ flowResult(fieldSearchResultsStore.clearAllFiltersAndFetch()).catch(
255
+ applicationStore.alertUnhandledError,
256
+ );
257
+ }, [fieldSearchResultsStore, applicationStore]);
258
+
259
+ const handleSearch = useCallback(
260
+ (
261
+ query: string | undefined,
262
+ useProducerSearch: boolean,
263
+ useFieldSearch: boolean,
264
+ ) => {
265
+ if (!isNonEmptyString(query)) {
266
+ return;
267
+ }
268
+ if (!useFieldSearch) {
269
+ applicationStore.navigationService.navigator.goToLocation(
270
+ generateLakehouseSearchResultsRoute(query, useProducerSearch),
271
+ );
272
+ return;
273
+ }
274
+ fieldSearchResultsStore.setSearchQuery(query);
275
+ LegendMarketplaceTelemetryHelper.logEvent_SearchQuery(
276
+ applicationStore.telemetryService,
277
+ query,
278
+ false,
279
+ LEGEND_MARKETPLACE_PAGE.SEARCH_RESULTS_PAGE,
280
+ true,
281
+ );
282
+ },
283
+ [applicationStore, fieldSearchResultsStore],
284
+ );
285
+
286
+ const handleOpenDataProduct = useCallback(
287
+ (dataProduct: FieldSearchDataProductEntry) => {
288
+ LegendMarketplaceTelemetryHelper.logEvent_ClickingDataProductCard(
289
+ applicationStore.telemetryService,
290
+ {
291
+ origin:
292
+ dataProduct.productType === DataProductTypeFilter.LEGACY
293
+ ? {
294
+ type: DATAPRODUCT_TYPE.SDLC,
295
+ groupId: dataProduct.groupId,
296
+ artifactId: dataProduct.artifactId,
297
+ versionId: dataProduct.versionId,
298
+ path: dataProduct.entityPath,
299
+ }
300
+ : {
301
+ type: DATAPRODUCT_TYPE.ADHOC,
302
+ },
303
+ dataProductId: dataProduct.dataProductId,
304
+ name: dataProduct.name,
305
+ deploymentId: dataProduct.deploymentId,
306
+ },
307
+ LEGEND_MARKETPLACE_PAGE.SEARCH_RESULTS_PAGE,
308
+ );
309
+ applicationStore.navigationService.navigator.visitAddress(
310
+ applicationStore.navigationService.navigator.generateAddress(
311
+ dataProduct.path,
312
+ ),
313
+ );
314
+ },
315
+ [applicationStore],
316
+ );
317
+
318
+ const handleToggleExpandRow = useCallback(
319
+ (rowId: string) => {
320
+ fieldSearchResultsStore.toggleExpandRow(rowId);
321
+ },
322
+ [fieldSearchResultsStore],
323
+ );
324
+
325
+ return (
326
+ <LegendMarketplacePage className="marketplace-lakehouse-search-results marketplace-lakehouse-field-search-results">
327
+ <div ref={pageRef} />
328
+ <Container className="marketplace-lakehouse-search-results__search-container">
329
+ <LegendMarketplaceSearchBar
330
+ showSettings={true}
331
+ onSearch={handleSearch}
332
+ stateSearchQuery={fieldSearchResultsStore.searchQuery}
333
+ stateUseProducerSearch={false}
334
+ stateUseFieldSearch={true}
335
+ placeholder="Search Marketplace fields"
336
+ className="marketplace-lakehouse-search-results__search-bar"
337
+ enableAutosuggest={false}
338
+ />
339
+ </Container>
340
+ <div className="legend-marketplace-search-results__sort-bar">
341
+ <div className="legend-marketplace-search-results__sort-bar__container">
342
+ <Typography
343
+ variant="h4"
344
+ className="marketplace-lakehouse-search-results__subtitles"
345
+ >
346
+ {fieldSearchResultsStore.totalFieldMatches} Fields
347
+ </Typography>
348
+ </div>
349
+ </div>
350
+ <Container
351
+ maxWidth="xxxl"
352
+ className="marketplace-lakehouse-search-results__results-container"
353
+ >
354
+ <div className="marketplace-lakehouse-search-results__results-layout">
355
+ <div className="marketplace-lakehouse-search-results__sidebar">
356
+ <FieldSearchFiltersPanel
357
+ store={fieldSearchResultsStore}
358
+ onToggleProductType={handleToggleProductType}
359
+ onClearFilters={handleClearFilters}
360
+ />
361
+ </div>
362
+ <div className="marketplace-lakehouse-search-results__main-content">
363
+ <FieldSearchResultsContent
364
+ fieldSearchResultsStore={fieldSearchResultsStore}
365
+ handlePageChange={handlePageChange}
366
+ handleItemsPerPageChange={handleItemsPerPageChange}
367
+ handleToggleExpandRow={handleToggleExpandRow}
368
+ handleOpenDataProduct={handleOpenDataProduct}
369
+ />
370
+ </div>
371
+ </div>
372
+ </Container>
373
+ </LegendMarketplacePage>
374
+ );
375
+ });
376
+
377
+ export const LegendMarketplaceFieldSearchResults =
378
+ withLegendMarketplaceFieldSearchResultsStore(
379
+ LegendMarketplaceFieldSearchResultsPage,
380
+ );
@@ -45,7 +45,10 @@ import {
45
45
  SearchResultsViewMode,
46
46
  type LegendMarketplaceSearchResultsStore,
47
47
  } from '../../../stores/lakehouse/LegendMarketplaceSearchResultsStore.js';
48
- import { LEGEND_MARKETPLACE_LAKEHOUSE_SEARCH_RESULTS_QUERY_PARAM_TOKEN } from '../../../__lib__/LegendMarketplaceNavigation.js';
48
+ import {
49
+ generateFieldSearchResultsRoute,
50
+ LEGEND_MARKETPLACE_LAKEHOUSE_SEARCH_RESULTS_QUERY_PARAM_TOKEN,
51
+ } from '../../../__lib__/LegendMarketplaceNavigation.js';
49
52
  import { LegendMarketplaceSearchBar } from '../../../components/SearchBar/LegendMarketplaceSearchBar.js';
50
53
  import { LegendMarketplacePage } from '../../LegendMarketplacePage.js';
51
54
  import { useAuth } from 'react-oidc-context';
@@ -265,8 +268,22 @@ export const LegendMarketplaceSearchResults =
265
268
  const handleSearch = (
266
269
  _query: string | undefined,
267
270
  _useProducerSearch: boolean,
271
+ _useFieldSearch: boolean,
268
272
  ): void => {
269
273
  if (isNonEmptyString(_query)) {
274
+ if (_useFieldSearch) {
275
+ applicationStore.navigationService.navigator.goToLocation(
276
+ generateFieldSearchResultsRoute(_query),
277
+ );
278
+ LegendMarketplaceTelemetryHelper.logEvent_SearchQuery(
279
+ applicationStore.telemetryService,
280
+ _query,
281
+ false,
282
+ LEGEND_MARKETPLACE_PAGE.SEARCH_RESULTS_PAGE,
283
+ true,
284
+ );
285
+ return;
286
+ }
270
287
  searchResultsStore.setSearchQuery(_query);
271
288
  searchResultsStore.setUseProducerSearch(_useProducerSearch);
272
289
  LegendMarketplaceTelemetryHelper.logEvent_SearchQuery(
@@ -349,6 +366,7 @@ export const LegendMarketplaceSearchResults =
349
366
  onSearch={handleSearch}
350
367
  stateSearchQuery={searchResultsStore.searchQuery}
351
368
  stateUseProducerSearch={searchResultsStore.useProducerSearch}
369
+ stateUseFieldSearch={false}
352
370
  placeholder="Search Legend Marketplace"
353
371
  className="marketplace-lakehouse-search-results__search-bar"
354
372
  enableAutosuggest={false}
@@ -311,10 +311,14 @@ export const LegendMarketplaceVendorData = withLegendMarketplaceVendorDataStore(
311
311
  setUserValue={(_user: LegendUser): void => {
312
312
  if (!_user.id) {
313
313
  marketPlaceVendorDataStore.resetSelectedUser();
314
- cartStore.setTargetUser(undefined);
314
+ flowResult(cartStore.setTargetUser(undefined)).catch(
315
+ marketplaceStore.applicationStore.alertUnhandledError,
316
+ );
315
317
  } else {
316
318
  marketPlaceVendorDataStore.setSelectedUser(_user);
317
- cartStore.setTargetUser(_user.id);
319
+ flowResult(cartStore.setTargetUser(_user.id)).catch(
320
+ marketplaceStore.applicationStore.alertUnhandledError,
321
+ );
318
322
  }
319
323
  }}
320
324
  userSearchService={marketplaceStore.userSearchService}
@@ -18,6 +18,7 @@ import {
18
18
  type V1_EntitlementsDataProductDetailsResponse,
19
19
  CORE_PURE_PATH,
20
20
  V1_AppDirLevel,
21
+ type V1_AppDirNode,
21
22
  V1_EntitlementsLakehouseEnvironmentType,
22
23
  } from '@finos/legend-graph';
23
24
  import type { Entity } from '@finos/legend-storage';
@@ -53,7 +54,7 @@ export const mockEntitlementsSDLCDataProduct: V1_EntitlementsDataProductDetailsR
53
54
  owner: {
54
55
  appDirId: 12345,
55
56
  level: V1_AppDirLevel.DEPLOYMENT,
56
- },
57
+ } as V1_AppDirNode,
57
58
  },
58
59
  fullPath: 'com::example::analytics::Mock_SDLC_DataProduct',
59
60
  },
@@ -164,7 +165,7 @@ export const mockEntitlementsAdHocDataProduct: V1_EntitlementsDataProductDetails
164
165
  owner: {
165
166
  appDirId: 22222,
166
167
  level: V1_AppDirLevel.DEPLOYMENT,
167
- },
168
+ } as V1_AppDirNode,
168
169
  },
169
170
  fullPath: 'com::example::analytics::Mock_AdHoc_DataProduct',
170
171
  },