@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.
- 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/pages/__test-utils__/TEST_DATA__LakehouseDataProducts.d.ts.map +1 -1
- package/lib/pages/__test-utils__/TEST_DATA__LakehouseDataProducts.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/pages/__test-utils__/TEST_DATA__LakehouseDataProducts.ts +3 -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
|
@@ -19,8 +19,15 @@ import {
|
|
|
19
19
|
RecommendationSource,
|
|
20
20
|
type TerminalResult,
|
|
21
21
|
} from '@finos/legend-server-marketplace';
|
|
22
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
Box,
|
|
24
|
+
Button,
|
|
25
|
+
CircularProgress,
|
|
26
|
+
Tooltip,
|
|
27
|
+
Typography,
|
|
28
|
+
} from '@mui/material';
|
|
23
29
|
import { flowResult } from 'mobx';
|
|
30
|
+
import { observer } from 'mobx-react-lite';
|
|
24
31
|
import { useState } from 'react';
|
|
25
32
|
import { assertErrorThrown } from '@finos/legend-shared';
|
|
26
33
|
import { toastManager } from '../Toast/CartToast.js';
|
|
@@ -33,166 +40,182 @@ interface RecommendedItemsCardProps {
|
|
|
33
40
|
selectedItemId?: number | undefined;
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
export const RecommendedItemsCard = (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
legendMarketplaceBaseStore.cartStore.isItemInCart(
|
|
42
|
-
|
|
43
|
+
export const RecommendedItemsCard = observer(
|
|
44
|
+
(props: RecommendedItemsCardProps) => {
|
|
45
|
+
const { recommendedItem, onSelect, isSelecting, selectedItemId } = props;
|
|
46
|
+
const legendMarketplaceBaseStore = useLegendMarketplaceBaseStore();
|
|
47
|
+
const [isAddingToCart, setIsAddingToCart] = useState(false);
|
|
48
|
+
const inCart = legendMarketplaceBaseStore.cartStore.isItemInCart(
|
|
49
|
+
recommendedItem.id,
|
|
50
|
+
);
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
const isAssociationFlow = onSelect !== undefined;
|
|
53
|
+
const isCurrentlySelecting =
|
|
54
|
+
isAssociationFlow &&
|
|
55
|
+
Boolean(isSelecting) &&
|
|
56
|
+
selectedItemId === recommendedItem.id;
|
|
57
|
+
const isMarketplaceItem =
|
|
58
|
+
recommendedItem.source === RecommendationSource.MARKETPLACE;
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
const handleAddAddonToCart = (addon: TerminalResult) => {
|
|
61
|
+
setIsAddingToCart(true);
|
|
62
|
+
const cartItemRequest =
|
|
63
|
+
legendMarketplaceBaseStore.cartStore.providerToCartRequest(addon);
|
|
56
64
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
);
|
|
71
|
-
setIsAddingToCart(false);
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const renderAction = () => {
|
|
76
|
-
if (isAssociationFlow) {
|
|
77
|
-
if (recommendedItem.isOwned) {
|
|
78
|
-
return (
|
|
79
|
-
<Box className="recommended-addons-modal__owned-badge">
|
|
80
|
-
<CheckCircleIcon />
|
|
81
|
-
<Typography variant="body2">Owned</Typography>
|
|
82
|
-
</Box>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
65
|
+
flowResult(
|
|
66
|
+
legendMarketplaceBaseStore.cartStore.addToCartWithAPI(cartItemRequest),
|
|
67
|
+
)
|
|
68
|
+
.catch((error) => {
|
|
69
|
+
assertErrorThrown(error);
|
|
70
|
+
toastManager.error(
|
|
71
|
+
`Failed to add ${addon.productName} to cart: ${error.message}`,
|
|
72
|
+
);
|
|
73
|
+
})
|
|
74
|
+
.finally(() => {
|
|
75
|
+
setIsAddingToCart(false);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
85
78
|
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
const renderAction = () => {
|
|
80
|
+
if (isAssociationFlow) {
|
|
81
|
+
if (recommendedItem.isOwned) {
|
|
88
82
|
return (
|
|
89
|
-
<Box className="recommended-addons-
|
|
90
|
-
<Typography variant="body2">In Cart</Typography>
|
|
83
|
+
<Box className="recommended-addons-modal__owned-badge">
|
|
91
84
|
<CheckCircleIcon />
|
|
85
|
+
<Typography variant="body2">Owned</Typography>
|
|
92
86
|
</Box>
|
|
93
87
|
);
|
|
94
88
|
}
|
|
89
|
+
|
|
90
|
+
if (isMarketplaceItem) {
|
|
91
|
+
if (inCart) {
|
|
92
|
+
return (
|
|
93
|
+
<Box className="recommended-addons-modal__in-cart-badge">
|
|
94
|
+
<Typography variant="body2">In Cart</Typography>
|
|
95
|
+
<CheckCircleIcon />
|
|
96
|
+
</Box>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
return (
|
|
100
|
+
<Button
|
|
101
|
+
variant="outlined"
|
|
102
|
+
onClick={() => onSelect(recommendedItem)}
|
|
103
|
+
disabled={Boolean(isSelecting)}
|
|
104
|
+
size="small"
|
|
105
|
+
className="recommended-addons-modal__add-btn"
|
|
106
|
+
>
|
|
107
|
+
{isCurrentlySelecting ? (
|
|
108
|
+
<>
|
|
109
|
+
Adding...
|
|
110
|
+
<CircularProgress size={14} />
|
|
111
|
+
</>
|
|
112
|
+
) : (
|
|
113
|
+
<>
|
|
114
|
+
Add to Cart
|
|
115
|
+
<PlusIcon />
|
|
116
|
+
</>
|
|
117
|
+
)}
|
|
118
|
+
</Button>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
95
122
|
return (
|
|
96
123
|
<Button
|
|
97
124
|
variant="outlined"
|
|
98
125
|
onClick={() => onSelect(recommendedItem)}
|
|
99
126
|
disabled={Boolean(isSelecting)}
|
|
100
127
|
size="small"
|
|
101
|
-
className="recommended-addons-
|
|
128
|
+
className="recommended-addons-modal__select-btn"
|
|
102
129
|
>
|
|
103
130
|
{isCurrentlySelecting ? (
|
|
104
131
|
<>
|
|
105
|
-
|
|
132
|
+
Selecting...
|
|
106
133
|
<CircularProgress size={14} />
|
|
107
134
|
</>
|
|
108
135
|
) : (
|
|
109
136
|
<>
|
|
110
|
-
|
|
111
|
-
<
|
|
137
|
+
Select
|
|
138
|
+
<CheckIcon />
|
|
112
139
|
</>
|
|
113
140
|
)}
|
|
114
141
|
</Button>
|
|
115
142
|
);
|
|
116
143
|
}
|
|
117
144
|
|
|
118
|
-
|
|
145
|
+
const button = (
|
|
119
146
|
<Button
|
|
120
147
|
variant="outlined"
|
|
121
|
-
onClick={() =>
|
|
122
|
-
disabled={
|
|
148
|
+
onClick={() => handleAddAddonToCart(recommendedItem)}
|
|
149
|
+
disabled={inCart || isAddingToCart}
|
|
123
150
|
size="small"
|
|
124
|
-
className=
|
|
151
|
+
className={clsx('recommended-addons-modal__add-btn', {
|
|
152
|
+
'recommended-addons-modal__add-btn--added': inCart,
|
|
153
|
+
})}
|
|
125
154
|
>
|
|
126
|
-
{
|
|
155
|
+
{isAddingToCart ? (
|
|
127
156
|
<>
|
|
128
|
-
|
|
157
|
+
Adding...
|
|
129
158
|
<CircularProgress size={14} />
|
|
130
159
|
</>
|
|
160
|
+
) : inCart ? (
|
|
161
|
+
'Added to Cart'
|
|
131
162
|
) : (
|
|
132
163
|
<>
|
|
133
|
-
|
|
134
|
-
<
|
|
164
|
+
Add to Cart
|
|
165
|
+
<PlusIcon />
|
|
135
166
|
</>
|
|
136
167
|
)}
|
|
137
168
|
</Button>
|
|
138
169
|
);
|
|
139
|
-
}
|
|
140
170
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
) : inCart ? (
|
|
157
|
-
'Added to Cart'
|
|
158
|
-
) : (
|
|
159
|
-
<>
|
|
160
|
-
Add to Cart
|
|
161
|
-
<PlusIcon />
|
|
162
|
-
</>
|
|
163
|
-
)}
|
|
164
|
-
</Button>
|
|
165
|
-
);
|
|
166
|
-
};
|
|
171
|
+
if (inCart) {
|
|
172
|
+
return (
|
|
173
|
+
<Tooltip
|
|
174
|
+
title={
|
|
175
|
+
recommendedItem.isMandatory
|
|
176
|
+
? 'This is a mandatory item which needs to be associated with this order.'
|
|
177
|
+
: 'This item is already in your cart.'
|
|
178
|
+
}
|
|
179
|
+
arrow={true}
|
|
180
|
+
placement="top"
|
|
181
|
+
>
|
|
182
|
+
<span>{button}</span>
|
|
183
|
+
</Tooltip>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
167
186
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
187
|
+
return button;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return (
|
|
191
|
+
<Box className="recommended-addons-modal__list-item">
|
|
192
|
+
<Typography
|
|
193
|
+
variant="body1"
|
|
194
|
+
className="recommended-addons-modal__item-name"
|
|
195
|
+
>
|
|
196
|
+
{recommendedItem.productName}
|
|
197
|
+
</Typography>
|
|
198
|
+
<Typography
|
|
199
|
+
variant="body2"
|
|
200
|
+
className="recommended-addons-modal__item-provider"
|
|
201
|
+
>
|
|
202
|
+
{recommendedItem.providerName}
|
|
203
|
+
</Typography>
|
|
204
|
+
<Typography
|
|
205
|
+
variant="body2"
|
|
206
|
+
className="recommended-addons-modal__item-price"
|
|
207
|
+
>
|
|
208
|
+
{recommendedItem.price.toLocaleString('en-US', {
|
|
209
|
+
style: 'currency',
|
|
210
|
+
currency: 'USD',
|
|
211
|
+
minimumFractionDigits: 2,
|
|
212
|
+
maximumFractionDigits: 2,
|
|
213
|
+
})}
|
|
214
|
+
</Typography>
|
|
215
|
+
<Box className="recommended-addons-modal__item-action">
|
|
216
|
+
{renderAction()}
|
|
217
|
+
</Box>
|
|
195
218
|
</Box>
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
219
|
+
);
|
|
220
|
+
},
|
|
221
|
+
);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026-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 { observer } from 'mobx-react-lite';
|
|
18
|
+
import { Typography } from '@mui/material';
|
|
19
|
+
import { DataProductTypeFilter } from '../../stores/lakehouse/LegendMarketplaceSearchResultsStore.js';
|
|
20
|
+
import type { LegendMarketplaceFieldSearchResultsStore } from '../../stores/lakehouse/LegendMarketplaceFieldSearchResultsStore.js';
|
|
21
|
+
import {
|
|
22
|
+
FilterCheckboxOption,
|
|
23
|
+
FilterSection,
|
|
24
|
+
} from '../MarketplaceSearchFiltersPanel/MarketplaceSearchFiltersPanel.js';
|
|
25
|
+
|
|
26
|
+
export const FieldSearchFiltersPanel: React.FC<{
|
|
27
|
+
store: LegendMarketplaceFieldSearchResultsStore;
|
|
28
|
+
onToggleProductType: (productType: DataProductTypeFilter) => void;
|
|
29
|
+
onClearFilters: () => void;
|
|
30
|
+
}> = observer(({ store, onToggleProductType, onClearFilters }) => (
|
|
31
|
+
<div className="marketplace-search-filters-panel">
|
|
32
|
+
<div className="marketplace-search-filters-panel__header">
|
|
33
|
+
<Typography className="marketplace-search-filters-panel__header__title">
|
|
34
|
+
Filters
|
|
35
|
+
</Typography>
|
|
36
|
+
{store.hasActiveFilters && (
|
|
37
|
+
<button
|
|
38
|
+
type="button"
|
|
39
|
+
className="marketplace-search-filters-panel__header__clear"
|
|
40
|
+
onClick={onClearFilters}
|
|
41
|
+
>
|
|
42
|
+
Clear all
|
|
43
|
+
</button>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
46
|
+
<div className="marketplace-search-filters-panel__content">
|
|
47
|
+
<FilterSection title="Data Product Type">
|
|
48
|
+
<FilterCheckboxOption
|
|
49
|
+
label="Lakehouse"
|
|
50
|
+
checked={store.selectedProductTypes.has(
|
|
51
|
+
DataProductTypeFilter.LAKEHOUSE,
|
|
52
|
+
)}
|
|
53
|
+
count={store.lakehouseCount}
|
|
54
|
+
onChange={() => onToggleProductType(DataProductTypeFilter.LAKEHOUSE)}
|
|
55
|
+
/>
|
|
56
|
+
<FilterCheckboxOption
|
|
57
|
+
label="Legacy"
|
|
58
|
+
checked={store.selectedProductTypes.has(DataProductTypeFilter.LEGACY)}
|
|
59
|
+
count={store.legacyCount}
|
|
60
|
+
onChange={() => onToggleProductType(DataProductTypeFilter.LEGACY)}
|
|
61
|
+
/>
|
|
62
|
+
</FilterSection>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
));
|
|
@@ -0,0 +1,163 @@
|
|
|
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 { observer } from 'mobx-react-lite';
|
|
18
|
+
import { useState } from 'react';
|
|
19
|
+
import { Chip, Typography } from '@mui/material';
|
|
20
|
+
import { DatasetIcon, PackageIcon } from '@finos/legend-art';
|
|
21
|
+
import type {
|
|
22
|
+
FieldSearchDataProductEntry,
|
|
23
|
+
FieldSearchResultState,
|
|
24
|
+
} from '../../stores/lakehouse/fieldSearch/FieldSearchResultState.js';
|
|
25
|
+
import { LegendMarketplaceListItem } from '../MarketplaceCard/LegendMarketplaceListItem.js';
|
|
26
|
+
|
|
27
|
+
enum FieldSearchResultListItemLabel {
|
|
28
|
+
SHOW_LESS = 'Show Less',
|
|
29
|
+
MORE_SUFFIX = 'More',
|
|
30
|
+
DATASET_SEPARATOR = '|',
|
|
31
|
+
EMPTY_VALUE = '-',
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
enum FieldSearchResultListItemValue {
|
|
35
|
+
COLLAPSED_VISIBLE_DATA_PRODUCTS = 2,
|
|
36
|
+
MAX_DESCRIPTION_LENGTH = 150,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const FieldSearchResultListRow = observer(
|
|
40
|
+
(props: {
|
|
41
|
+
fieldSearchResultState: FieldSearchResultState;
|
|
42
|
+
expanded: boolean;
|
|
43
|
+
onToggleExpanded: (rowId: string) => void;
|
|
44
|
+
onOpenDataProduct: (dataProduct: FieldSearchDataProductEntry) => void;
|
|
45
|
+
}): React.ReactNode => {
|
|
46
|
+
const {
|
|
47
|
+
fieldSearchResultState,
|
|
48
|
+
expanded,
|
|
49
|
+
onToggleExpanded,
|
|
50
|
+
onOpenDataProduct,
|
|
51
|
+
} = props;
|
|
52
|
+
|
|
53
|
+
const [descriptionExpanded, setDescriptionExpanded] = useState(false);
|
|
54
|
+
const description = fieldSearchResultState.fieldDescription;
|
|
55
|
+
const isDescriptionTruncatable =
|
|
56
|
+
description.length >
|
|
57
|
+
FieldSearchResultListItemValue.MAX_DESCRIPTION_LENGTH;
|
|
58
|
+
const displayDescription =
|
|
59
|
+
!descriptionExpanded && isDescriptionTruncatable
|
|
60
|
+
? `${description.substring(0, FieldSearchResultListItemValue.MAX_DESCRIPTION_LENGTH)}...`
|
|
61
|
+
: description;
|
|
62
|
+
|
|
63
|
+
const visibleDataProducts = expanded
|
|
64
|
+
? fieldSearchResultState.dataProducts
|
|
65
|
+
: fieldSearchResultState.dataProducts.slice(
|
|
66
|
+
0,
|
|
67
|
+
FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS,
|
|
68
|
+
);
|
|
69
|
+
const hiddenDataProductCount = Math.max(
|
|
70
|
+
0,
|
|
71
|
+
fieldSearchResultState.dataProducts.length -
|
|
72
|
+
FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS,
|
|
73
|
+
);
|
|
74
|
+
const toggleLabel = expanded
|
|
75
|
+
? FieldSearchResultListItemLabel.SHOW_LESS
|
|
76
|
+
: `+${hiddenDataProductCount} ${FieldSearchResultListItemLabel.MORE_SUFFIX}`;
|
|
77
|
+
|
|
78
|
+
const content = (
|
|
79
|
+
<div className="marketplace-lakehouse-field-search-results__list-item-grid">
|
|
80
|
+
<div className="marketplace-lakehouse-field-search-results__field-name-cell">
|
|
81
|
+
<Typography className="marketplace-lakehouse-field-search-results__list-item-text marketplace-lakehouse-field-search-results__list-item-text--primary">
|
|
82
|
+
{fieldSearchResultState.fieldName}
|
|
83
|
+
</Typography>
|
|
84
|
+
</div>
|
|
85
|
+
<div className="marketplace-lakehouse-field-search-results__type-cell">
|
|
86
|
+
<Typography className="marketplace-lakehouse-field-search-results__list-item-text">
|
|
87
|
+
{fieldSearchResultState.fieldType}
|
|
88
|
+
</Typography>
|
|
89
|
+
</div>
|
|
90
|
+
<div className="marketplace-lakehouse-field-search-results__description-cell">
|
|
91
|
+
<Typography className="marketplace-lakehouse-field-search-results__list-item-text">
|
|
92
|
+
{displayDescription}
|
|
93
|
+
</Typography>
|
|
94
|
+
{isDescriptionTruncatable && (
|
|
95
|
+
<button
|
|
96
|
+
className="marketplace-lakehouse-field-search-results__description-toggle"
|
|
97
|
+
onClick={(e) => {
|
|
98
|
+
e.stopPropagation();
|
|
99
|
+
setDescriptionExpanded(!descriptionExpanded);
|
|
100
|
+
}}
|
|
101
|
+
>
|
|
102
|
+
{descriptionExpanded ? 'Show less' : 'Show more'}
|
|
103
|
+
</button>
|
|
104
|
+
)}
|
|
105
|
+
</div>
|
|
106
|
+
<div className="marketplace-lakehouse-field-search-results__data-products-cell">
|
|
107
|
+
{fieldSearchResultState.dataProducts.length > 0 ? (
|
|
108
|
+
<>
|
|
109
|
+
{visibleDataProducts.map((dataProduct) => (
|
|
110
|
+
<Chip
|
|
111
|
+
key={`${fieldSearchResultState.id}-${dataProduct.path}-${dataProduct.datasetName ?? ''}`}
|
|
112
|
+
clickable={true}
|
|
113
|
+
label={
|
|
114
|
+
<span className="marketplace-lakehouse-field-search-results__chip-label">
|
|
115
|
+
<PackageIcon className="marketplace-lakehouse-field-search-results__chip-icon" />
|
|
116
|
+
<span>{dataProduct.name}</span>
|
|
117
|
+
{dataProduct.datasetName && (
|
|
118
|
+
<span className="marketplace-lakehouse-field-search-results__chip-secondary">
|
|
119
|
+
<span className="marketplace-lakehouse-field-search-results__chip-separator">
|
|
120
|
+
{FieldSearchResultListItemLabel.DATASET_SEPARATOR}
|
|
121
|
+
</span>
|
|
122
|
+
<DatasetIcon className="marketplace-lakehouse-field-search-results__chip-icon" />
|
|
123
|
+
<span className="marketplace-lakehouse-field-search-results__chip-secondary-text">
|
|
124
|
+
{dataProduct.datasetName}
|
|
125
|
+
</span>
|
|
126
|
+
</span>
|
|
127
|
+
)}
|
|
128
|
+
</span>
|
|
129
|
+
}
|
|
130
|
+
onClick={() => onOpenDataProduct(dataProduct)}
|
|
131
|
+
className="marketplace-lakehouse-field-search-results__data-product-link"
|
|
132
|
+
size="small"
|
|
133
|
+
/>
|
|
134
|
+
))}
|
|
135
|
+
{fieldSearchResultState.dataProducts.length >
|
|
136
|
+
FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS && (
|
|
137
|
+
<Chip
|
|
138
|
+
key={`${fieldSearchResultState.id}-toggle`}
|
|
139
|
+
label={toggleLabel}
|
|
140
|
+
onClick={() => onToggleExpanded(fieldSearchResultState.id)}
|
|
141
|
+
size="small"
|
|
142
|
+
variant="outlined"
|
|
143
|
+
className="marketplace-lakehouse-field-search-results__data-product-toggle"
|
|
144
|
+
/>
|
|
145
|
+
)}
|
|
146
|
+
</>
|
|
147
|
+
) : (
|
|
148
|
+
<Typography className="marketplace-lakehouse-field-search-results__list-item-text marketplace-lakehouse-field-search-results__list-item-text--empty">
|
|
149
|
+
{FieldSearchResultListItemLabel.EMPTY_VALUE}
|
|
150
|
+
</Typography>
|
|
151
|
+
)}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
return (
|
|
157
|
+
<LegendMarketplaceListItem
|
|
158
|
+
className="marketplace-lakehouse-field-search-results__list-item"
|
|
159
|
+
content={content}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
);
|
|
@@ -181,7 +181,7 @@ const TaxonomyTreeNode: React.FC<{
|
|
|
181
181
|
);
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
const FilterSection: React.FC<{
|
|
184
|
+
export const FilterSection: React.FC<{
|
|
185
185
|
title: string;
|
|
186
186
|
children: React.ReactNode;
|
|
187
187
|
}> = ({ title, children }) => (
|
|
@@ -195,7 +195,7 @@ const FilterSection: React.FC<{
|
|
|
195
195
|
</div>
|
|
196
196
|
);
|
|
197
197
|
|
|
198
|
-
const FilterCheckboxOption: React.FC<{
|
|
198
|
+
export const FilterCheckboxOption: React.FC<{
|
|
199
199
|
label: string;
|
|
200
200
|
checked: boolean;
|
|
201
201
|
onChange: () => void;
|
|
@@ -48,6 +48,9 @@ export const LegendMarketplaceTerminalCard = observer(
|
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
const [modalMessage, setModalMessage] = useState<string>('');
|
|
51
|
+
const [modalTotalCount, setModalTotalCount] = useState<
|
|
52
|
+
number | null | undefined
|
|
53
|
+
>(undefined);
|
|
51
54
|
|
|
52
55
|
const legendMarketplaceBaseStore = useLegendMarketplaceBaseStore();
|
|
53
56
|
const applicationStore = legendMarketplaceBaseStore.applicationStore;
|
|
@@ -72,6 +75,7 @@ export const LegendMarketplaceTerminalCard = observer(
|
|
|
72
75
|
if (result.recommendations && result.recommendations.length > 0) {
|
|
73
76
|
setRecommendedItems(result.recommendations);
|
|
74
77
|
setModalMessage(result.message);
|
|
78
|
+
setModalTotalCount(result.totalCount);
|
|
75
79
|
setShowRecommendationsModal(true);
|
|
76
80
|
}
|
|
77
81
|
} catch (error) {
|
|
@@ -97,9 +101,11 @@ export const LegendMarketplaceTerminalCard = observer(
|
|
|
97
101
|
_selectedTerminal: TerminalResult,
|
|
98
102
|
recommendations: TerminalResult[],
|
|
99
103
|
responseMessage: string,
|
|
104
|
+
totalCount?: number | null,
|
|
100
105
|
) => {
|
|
101
106
|
setRecommendedItems(recommendations);
|
|
102
107
|
setModalMessage(responseMessage);
|
|
108
|
+
setModalTotalCount(totalCount);
|
|
103
109
|
setShowRecommendationsModal(true);
|
|
104
110
|
},
|
|
105
111
|
[],
|
|
@@ -203,6 +209,7 @@ export const LegendMarketplaceTerminalCard = observer(
|
|
|
203
209
|
setShowModal={setShowRecommendationsModal}
|
|
204
210
|
onViewCart={handleViewCart}
|
|
205
211
|
onTerminalSelected={handleTerminalSelected}
|
|
212
|
+
totalCount={modalTotalCount}
|
|
206
213
|
/>
|
|
207
214
|
</Card>
|
|
208
215
|
);
|