@finos/legend-application-marketplace 0.2.3 → 0.2.4
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.
- package/lib/__lib__/LegendMarketplaceAppEvent.d.ts +2 -0
- package/lib/__lib__/LegendMarketplaceAppEvent.d.ts.map +1 -1
- package/lib/__lib__/LegendMarketplaceAppEvent.js +2 -0
- package/lib/__lib__/LegendMarketplaceAppEvent.js.map +1 -1
- package/lib/__lib__/LegendMarketplaceNavigation.d.ts +7 -1
- package/lib/__lib__/LegendMarketplaceNavigation.d.ts.map +1 -1
- package/lib/__lib__/LegendMarketplaceNavigation.js +9 -1
- package/lib/__lib__/LegendMarketplaceNavigation.js.map +1 -1
- package/lib/__lib__/LegendMarketplaceTelemetryHelper.d.ts +2 -1
- package/lib/__lib__/LegendMarketplaceTelemetryHelper.d.ts.map +1 -1
- package/lib/__lib__/LegendMarketplaceTelemetryHelper.js +10 -2
- package/lib/__lib__/LegendMarketplaceTelemetryHelper.js.map +1 -1
- package/lib/application/LegendMarketplaceWebApplication.d.ts.map +1 -1
- package/lib/application/LegendMarketplaceWebApplication.js +4 -1
- package/lib/application/LegendMarketplaceWebApplication.js.map +1 -1
- package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.d.ts +22 -0
- package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.d.ts.map +1 -0
- package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.js +37 -0
- package/lib/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.js.map +1 -0
- package/lib/components/AddToCart/CartDrawer.d.ts.map +1 -1
- package/lib/components/AddToCart/CartDrawer.js +36 -4
- package/lib/components/AddToCart/CartDrawer.js.map +1 -1
- package/lib/components/AddToCart/RecommendedAddOnsModal.d.ts +2 -1
- package/lib/components/AddToCart/RecommendedAddOnsModal.d.ts.map +1 -1
- package/lib/components/AddToCart/RecommendedAddOnsModal.js +23 -13
- package/lib/components/AddToCart/RecommendedAddOnsModal.js.map +1 -1
- package/lib/components/AddToCart/RecommendedItemsCard.d.ts +3 -1
- package/lib/components/AddToCart/RecommendedItemsCard.d.ts.map +1 -1
- package/lib/components/AddToCart/RecommendedItemsCard.js +14 -11
- package/lib/components/AddToCart/RecommendedItemsCard.js.map +1 -1
- package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.d.ts +23 -0
- package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.d.ts.map +1 -0
- package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.js +22 -0
- package/lib/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.js.map +1 -0
- package/lib/components/MarketplaceCard/FieldSearchResultListItem.d.ts +25 -0
- package/lib/components/MarketplaceCard/FieldSearchResultListItem.d.ts.map +1 -0
- package/lib/components/MarketplaceCard/FieldSearchResultListItem.js +58 -0
- package/lib/components/MarketplaceCard/FieldSearchResultListItem.js.map +1 -0
- package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.d.ts +10 -0
- package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.d.ts.map +1 -1
- package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.js +2 -2
- package/lib/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.js.map +1 -1
- package/lib/components/ProviderCard/LegendMarketplaceTerminalCard.d.ts.map +1 -1
- package/lib/components/ProviderCard/LegendMarketplaceTerminalCard.js +5 -2
- package/lib/components/ProviderCard/LegendMarketplaceTerminalCard.js.map +1 -1
- package/lib/components/SearchBar/LegendMarketplaceSearchBar.d.ts +2 -1
- package/lib/components/SearchBar/LegendMarketplaceSearchBar.d.ts.map +1 -1
- package/lib/components/SearchBar/LegendMarketplaceSearchBar.js +20 -7
- package/lib/components/SearchBar/LegendMarketplaceSearchBar.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/pages/Lakehouse/MarketplaceLakehouseHome.d.ts.map +1 -1
- package/lib/pages/Lakehouse/MarketplaceLakehouseHome.js +6 -4
- package/lib/pages/Lakehouse/MarketplaceLakehouseHome.js.map +1 -1
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.d.ts +17 -0
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.d.ts.map +1 -0
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.js +126 -0
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.js.map +1 -0
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.d.ts.map +1 -1
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js +8 -3
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js.map +1 -1
- package/lib/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.d.ts.map +1 -1
- package/lib/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.js +2 -2
- package/lib/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.js.map +1 -1
- package/lib/stores/cart/CartStore.d.ts +10 -3
- package/lib/stores/cart/CartStore.d.ts.map +1 -1
- package/lib/stores/cart/CartStore.js +66 -42
- package/lib/stores/cart/CartStore.js.map +1 -1
- package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.d.ts +63 -0
- package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.d.ts.map +1 -0
- package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.js +228 -0
- package/lib/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.js.map +1 -0
- package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.d.ts.map +1 -1
- package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.js +9 -13
- package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.js.map +1 -1
- package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.d.ts +40 -0
- package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.d.ts.map +1 -0
- package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.js +84 -0
- package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.js.map +1 -0
- package/package.json +8 -8
- package/src/__lib__/LegendMarketplaceAppEvent.ts +2 -0
- package/src/__lib__/LegendMarketplaceNavigation.ts +18 -1
- package/src/__lib__/LegendMarketplaceTelemetryHelper.ts +17 -1
- package/src/application/LegendMarketplaceWebApplication.tsx +13 -0
- package/src/application/providers/LegendMarketplaceFieldSearchResultsStoreProvider.tsx +67 -0
- package/src/components/AddToCart/CartDrawer.tsx +49 -4
- package/src/components/AddToCart/RecommendedAddOnsModal.tsx +86 -24
- package/src/components/AddToCart/RecommendedItemsCard.tsx +143 -120
- package/src/components/FieldSearchFiltersPanel/FieldSearchFiltersPanel.tsx +65 -0
- package/src/components/MarketplaceCard/FieldSearchResultListItem.tsx +163 -0
- package/src/components/MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.tsx +2 -2
- package/src/components/ProviderCard/LegendMarketplaceTerminalCard.tsx +7 -0
- package/src/components/SearchBar/LegendMarketplaceSearchBar.tsx +44 -3
- package/src/pages/Lakehouse/MarketplaceLakehouseHome.tsx +9 -2
- package/src/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.tsx +380 -0
- package/src/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.tsx +19 -1
- package/src/pages/TerminalsAddons/LegendMarketplaceTerminalsAddons.tsx +6 -2
- package/src/stores/cart/CartStore.ts +86 -51
- package/src/stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.ts +309 -0
- package/src/stores/lakehouse/LegendMarketplaceProductViewerStore.ts +23 -30
- package/src/stores/lakehouse/fieldSearch/FieldSearchResultState.ts +122 -0
- package/tsconfig.json +6 -0
|
@@ -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 {
|
|
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}
|
|
@@ -14,7 +14,14 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
makeObservable,
|
|
19
|
+
observable,
|
|
20
|
+
action,
|
|
21
|
+
flow,
|
|
22
|
+
flowResult,
|
|
23
|
+
computed,
|
|
24
|
+
} from 'mobx';
|
|
18
25
|
import {
|
|
19
26
|
LogEvent,
|
|
20
27
|
type GeneratorFn,
|
|
@@ -22,6 +29,7 @@ import {
|
|
|
22
29
|
ActionState,
|
|
23
30
|
} from '@finos/legend-shared';
|
|
24
31
|
import {
|
|
32
|
+
TerminalItemType,
|
|
25
33
|
type CartItem,
|
|
26
34
|
type CartItemRequest,
|
|
27
35
|
type CartItemResponse,
|
|
@@ -64,8 +72,10 @@ export class CartStore {
|
|
|
64
72
|
businessReason: observable,
|
|
65
73
|
open: observable,
|
|
66
74
|
cartSummary: observable,
|
|
75
|
+
cartUser: computed,
|
|
76
|
+
cartItemIds: computed,
|
|
67
77
|
setOpen: action,
|
|
68
|
-
setTargetUser:
|
|
78
|
+
setTargetUser: flow,
|
|
69
79
|
setBusinessReason: action,
|
|
70
80
|
initialize: flow,
|
|
71
81
|
submitOrder: flow,
|
|
@@ -81,12 +91,50 @@ export class CartStore {
|
|
|
81
91
|
return this.baseStore.applicationStore.identityService.currentUser;
|
|
82
92
|
}
|
|
83
93
|
|
|
94
|
+
get cartUser(): string {
|
|
95
|
+
return this.targetUser ?? this.currentUser;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
get cartItemIds(): Set<number> {
|
|
99
|
+
const ids = new Set<number>();
|
|
100
|
+
for (const vendorProfileId in this.items) {
|
|
101
|
+
if (Object.prototype.hasOwnProperty.call(this.items, vendorProfileId)) {
|
|
102
|
+
const cartItems = this.items[Number(vendorProfileId)];
|
|
103
|
+
if (cartItems) {
|
|
104
|
+
for (const item of cartItems) {
|
|
105
|
+
ids.add(item.id);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return ids;
|
|
111
|
+
}
|
|
112
|
+
|
|
84
113
|
setOpen(val: boolean): void {
|
|
85
114
|
this.open = val;
|
|
86
115
|
}
|
|
87
116
|
|
|
88
|
-
setTargetUser(val: string | undefined): void {
|
|
117
|
+
*setTargetUser(val: string | undefined): GeneratorFn<void> {
|
|
118
|
+
this.loadingState.inProgress();
|
|
89
119
|
this.targetUser = val;
|
|
120
|
+
this.items = {};
|
|
121
|
+
this.cartSummary = {
|
|
122
|
+
total_items: 0,
|
|
123
|
+
total_cost: 0,
|
|
124
|
+
formatted_total_cost: '$0.00',
|
|
125
|
+
};
|
|
126
|
+
this.businessReason = undefined;
|
|
127
|
+
try {
|
|
128
|
+
yield flowResult(this.refresh());
|
|
129
|
+
this.loadingState.complete();
|
|
130
|
+
} catch (error) {
|
|
131
|
+
assertErrorThrown(error);
|
|
132
|
+
this.baseStore.applicationStore.logService.error(
|
|
133
|
+
LogEvent.create(APPLICATION_EVENT.IDENTITY_AUTO_FETCH__FAILURE),
|
|
134
|
+
`Failed to load cart for user: ${error.message}`,
|
|
135
|
+
);
|
|
136
|
+
this.loadingState.fail();
|
|
137
|
+
}
|
|
90
138
|
}
|
|
91
139
|
|
|
92
140
|
setBusinessReason(val: string | undefined): void {
|
|
@@ -94,23 +142,39 @@ export class CartStore {
|
|
|
94
142
|
}
|
|
95
143
|
|
|
96
144
|
isItemInCart(itemId: number): boolean {
|
|
145
|
+
return this.cartItemIds.has(itemId);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Returns the add-on items that depend on the given cart item.
|
|
150
|
+
* When a Terminal is deleted, its associated add-ons (same vendor) must also be removed.
|
|
151
|
+
*/
|
|
152
|
+
getDependentAddOns(cartId: number): CartItem[] {
|
|
97
153
|
for (const vendorProfileId in this.items) {
|
|
98
154
|
if (Object.prototype.hasOwnProperty.call(this.items, vendorProfileId)) {
|
|
99
155
|
const cartItems = this.items[Number(vendorProfileId)];
|
|
100
|
-
if (cartItems
|
|
101
|
-
|
|
156
|
+
if (cartItems) {
|
|
157
|
+
const target = cartItems.find((item) => item.cartId === cartId);
|
|
158
|
+
if (target && target.category === TerminalItemType.TERMINAL) {
|
|
159
|
+
return cartItems.filter(
|
|
160
|
+
(item) =>
|
|
161
|
+
item.cartId !== cartId &&
|
|
162
|
+
item.category === TerminalItemType.ADD_ON,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
102
165
|
}
|
|
103
166
|
}
|
|
104
167
|
}
|
|
105
|
-
return
|
|
168
|
+
return [];
|
|
106
169
|
}
|
|
107
170
|
|
|
108
171
|
*addToCartWithAPI(cartItemData: CartItemRequest): GeneratorFn<{
|
|
109
172
|
success: boolean;
|
|
110
173
|
recommendations?: TerminalResult[];
|
|
111
174
|
message: string;
|
|
175
|
+
totalCount?: number | null;
|
|
112
176
|
}> {
|
|
113
|
-
const user = this.
|
|
177
|
+
const user = this.cartUser;
|
|
114
178
|
|
|
115
179
|
if (!user) {
|
|
116
180
|
const message = 'User not authenticated';
|
|
@@ -125,11 +189,6 @@ export class CartStore {
|
|
|
125
189
|
cartItemData,
|
|
126
190
|
)) as CartItemResponse;
|
|
127
191
|
|
|
128
|
-
this.cartSummary =
|
|
129
|
-
(yield this.baseStore.marketplaceServerClient.getCartSummary(
|
|
130
|
-
user,
|
|
131
|
-
)) as CartSummary;
|
|
132
|
-
|
|
133
192
|
yield flowResult(this.refresh());
|
|
134
193
|
|
|
135
194
|
const responseMessage: string = response.message;
|
|
@@ -159,6 +218,7 @@ export class CartStore {
|
|
|
159
218
|
success: true,
|
|
160
219
|
recommendations,
|
|
161
220
|
message: responseMessage,
|
|
221
|
+
totalCount: response.total_count,
|
|
162
222
|
};
|
|
163
223
|
} catch (error) {
|
|
164
224
|
assertErrorThrown(error);
|
|
@@ -195,7 +255,7 @@ export class CartStore {
|
|
|
195
255
|
}
|
|
196
256
|
this.initState.inProgress();
|
|
197
257
|
try {
|
|
198
|
-
this.refresh();
|
|
258
|
+
yield flowResult(this.refresh());
|
|
199
259
|
this.initState.complete();
|
|
200
260
|
} catch (error) {
|
|
201
261
|
assertErrorThrown(error);
|
|
@@ -208,7 +268,7 @@ export class CartStore {
|
|
|
208
268
|
}
|
|
209
269
|
|
|
210
270
|
*refresh(): GeneratorFn<void> {
|
|
211
|
-
const user = this.
|
|
271
|
+
const user = this.cartUser;
|
|
212
272
|
if (!user) {
|
|
213
273
|
return;
|
|
214
274
|
}
|
|
@@ -231,31 +291,6 @@ export class CartStore {
|
|
|
231
291
|
}
|
|
232
292
|
}
|
|
233
293
|
|
|
234
|
-
*getCartSummary(): GeneratorFn<void> {
|
|
235
|
-
const user = this.currentUser;
|
|
236
|
-
if (!user) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
try {
|
|
240
|
-
const cartSummary =
|
|
241
|
-
(yield this.baseStore.marketplaceServerClient.getCartSummary(
|
|
242
|
-
user,
|
|
243
|
-
)) as CartSummary;
|
|
244
|
-
this.cartSummary = cartSummary;
|
|
245
|
-
} catch (error) {
|
|
246
|
-
assertErrorThrown(error);
|
|
247
|
-
this.cartSummary = {
|
|
248
|
-
total_items: 0,
|
|
249
|
-
total_cost: 0,
|
|
250
|
-
formatted_total_cost: '$0.00',
|
|
251
|
-
};
|
|
252
|
-
this.baseStore.applicationStore.logService.error(
|
|
253
|
-
LogEvent.create(APPLICATION_EVENT.IDENTITY_AUTO_FETCH__FAILURE),
|
|
254
|
-
`Failed to get cart summary: ${error.message}`,
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
294
|
*submitOrder(): GeneratorFn<void> {
|
|
260
295
|
if (!this.businessReason) {
|
|
261
296
|
toastManager.warning(
|
|
@@ -277,18 +312,16 @@ export class CartStore {
|
|
|
277
312
|
try {
|
|
278
313
|
const orderData: OrderDetails = {
|
|
279
314
|
ordered_by: user,
|
|
280
|
-
kerberos: this.
|
|
315
|
+
kerberos: this.cartUser,
|
|
281
316
|
order_items: this.items,
|
|
282
317
|
business_justification: this.businessReason,
|
|
283
318
|
};
|
|
284
319
|
|
|
285
320
|
yield this.baseStore.marketplaceServerClient.submitOrder(user, orderData);
|
|
286
321
|
|
|
287
|
-
this.getCartSummary();
|
|
288
|
-
|
|
289
322
|
toastManager.notify('Order created successfully!', 'success');
|
|
290
323
|
|
|
291
|
-
this.refresh();
|
|
324
|
+
yield flowResult(this.refresh());
|
|
292
325
|
this.setBusinessReason(undefined);
|
|
293
326
|
this.open = false;
|
|
294
327
|
this.submitState.complete();
|
|
@@ -301,7 +334,7 @@ export class CartStore {
|
|
|
301
334
|
}
|
|
302
335
|
|
|
303
336
|
*clearCart(): GeneratorFn<void> {
|
|
304
|
-
const user = this.
|
|
337
|
+
const user = this.cartUser;
|
|
305
338
|
if (!user) {
|
|
306
339
|
toastManager.error('User not authenticated');
|
|
307
340
|
return;
|
|
@@ -310,8 +343,7 @@ export class CartStore {
|
|
|
310
343
|
this.loadingState.inProgress();
|
|
311
344
|
try {
|
|
312
345
|
yield this.baseStore.marketplaceServerClient.clearCart(user);
|
|
313
|
-
this.refresh();
|
|
314
|
-
this.getCartSummary();
|
|
346
|
+
yield flowResult(this.refresh());
|
|
315
347
|
toastManager.success('Cart cleared successfully');
|
|
316
348
|
this.loadingState.complete();
|
|
317
349
|
} catch (error) {
|
|
@@ -322,8 +354,8 @@ export class CartStore {
|
|
|
322
354
|
}
|
|
323
355
|
}
|
|
324
356
|
|
|
325
|
-
*deleteCartItem(cartId: number): GeneratorFn<void> {
|
|
326
|
-
const user = this.
|
|
357
|
+
*deleteCartItem(cartId: number, confirmDelete?: boolean): GeneratorFn<void> {
|
|
358
|
+
const user = this.cartUser;
|
|
327
359
|
if (!user) {
|
|
328
360
|
toastManager.error('User not authenticated');
|
|
329
361
|
return;
|
|
@@ -331,10 +363,13 @@ export class CartStore {
|
|
|
331
363
|
|
|
332
364
|
this.loadingState.inProgress();
|
|
333
365
|
try {
|
|
334
|
-
yield this.baseStore.marketplaceServerClient.deleteCartItem(
|
|
366
|
+
yield this.baseStore.marketplaceServerClient.deleteCartItem(
|
|
367
|
+
user,
|
|
368
|
+
cartId,
|
|
369
|
+
confirmDelete,
|
|
370
|
+
);
|
|
335
371
|
|
|
336
|
-
this.
|
|
337
|
-
this.refresh();
|
|
372
|
+
yield flowResult(this.refresh());
|
|
338
373
|
toastManager.success('Item removed successfully');
|
|
339
374
|
this.loadingState.complete();
|
|
340
375
|
} catch (error) {
|