@finos/legend-application-marketplace 0.2.13 → 0.2.15
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__/LegendMarketplaceNavigation.d.ts +2 -0
- package/lib/__lib__/LegendMarketplaceNavigation.d.ts.map +1 -1
- package/lib/__lib__/LegendMarketplaceNavigation.js +4 -0
- package/lib/__lib__/LegendMarketplaceNavigation.js.map +1 -1
- package/lib/application/LegendMarketplaceApplicationConfig.d.ts +9 -0
- package/lib/application/LegendMarketplaceApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendMarketplaceApplicationConfig.js +40 -22
- package/lib/application/LegendMarketplaceApplicationConfig.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/__test-utils__/LegendMarketplaceApplicationTestUtils.d.ts.map +1 -1
- package/lib/application/__test-utils__/LegendMarketplaceApplicationTestUtils.js +7 -0
- package/lib/application/__test-utils__/LegendMarketplaceApplicationTestUtils.js.map +1 -1
- package/lib/application/providers/LegendMarketplaceAIChatStoreProvider.d.ts +21 -0
- package/lib/application/providers/LegendMarketplaceAIChatStoreProvider.d.ts.map +1 -0
- package/lib/application/providers/LegendMarketplaceAIChatStoreProvider.js +29 -0
- package/lib/application/providers/LegendMarketplaceAIChatStoreProvider.js.map +1 -0
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/pages/Agents/LegendMarketplaceAgents.d.ts.map +1 -1
- package/lib/pages/Agents/LegendMarketplaceAgents.js +49 -17
- package/lib/pages/Agents/LegendMarketplaceAgents.js.map +1 -1
- package/lib/pages/Agents/MarketplaceAIChatView.d.ts +21 -0
- package/lib/pages/Agents/MarketplaceAIChatView.d.ts.map +1 -0
- package/lib/pages/Agents/MarketplaceAIChatView.js +141 -0
- package/lib/pages/Agents/MarketplaceAIChatView.js.map +1 -0
- package/lib/pages/Agents/MarketplaceAIInputBar.d.ts +22 -0
- package/lib/pages/Agents/MarketplaceAIInputBar.d.ts.map +1 -0
- package/lib/pages/Agents/MarketplaceAIInputBar.js +40 -0
- package/lib/pages/Agents/MarketplaceAIInputBar.js.map +1 -0
- package/lib/pages/Agents/MarketplaceAIProductAutosuggest.d.ts +25 -0
- package/lib/pages/Agents/MarketplaceAIProductAutosuggest.d.ts.map +1 -0
- package/lib/pages/Agents/MarketplaceAIProductAutosuggest.js +86 -0
- package/lib/pages/Agents/MarketplaceAIProductAutosuggest.js.map +1 -0
- package/lib/pages/Agents/MarketplaceAIProductCards.d.ts +23 -0
- package/lib/pages/Agents/MarketplaceAIProductCards.d.ts.map +1 -0
- package/lib/pages/Agents/MarketplaceAIProductCards.js +20 -0
- package/lib/pages/Agents/MarketplaceAIProductCards.js.map +1 -0
- package/lib/pages/Agents/MarketplaceAIScopeSelector.d.ts +19 -0
- package/lib/pages/Agents/MarketplaceAIScopeSelector.d.ts.map +1 -0
- package/lib/pages/Agents/MarketplaceAIScopeSelector.js +46 -0
- package/lib/pages/Agents/MarketplaceAIScopeSelector.js.map +1 -0
- package/lib/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.d.ts.map +1 -1
- package/lib/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.js +74 -63
- package/lib/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.js.map +1 -1
- package/lib/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.d.ts.map +1 -1
- package/lib/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.js +85 -69
- package/lib/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.js.map +1 -1
- package/lib/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.d.ts.map +1 -1
- package/lib/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.js +7 -11
- package/lib/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.js.map +1 -1
- package/lib/pages/Lakehouse/entitlements/PermitDataAccessRequest.d.ts +17 -0
- package/lib/pages/Lakehouse/entitlements/PermitDataAccessRequest.d.ts.map +1 -0
- package/lib/pages/Lakehouse/entitlements/PermitDataAccessRequest.js +126 -0
- package/lib/pages/Lakehouse/entitlements/PermitDataAccessRequest.js.map +1 -0
- package/lib/pages/Lakehouse/entitlements/WorkflowDataAccessRequest.d.ts.map +1 -1
- package/lib/pages/Lakehouse/entitlements/WorkflowDataAccessRequest.js +23 -65
- package/lib/pages/Lakehouse/entitlements/WorkflowDataAccessRequest.js.map +1 -1
- package/lib/pages/Lakehouse/entitlements/showTaskActionAlert.d.ts +29 -0
- package/lib/pages/Lakehouse/entitlements/showTaskActionAlert.d.ts.map +1 -0
- package/lib/pages/Lakehouse/entitlements/showTaskActionAlert.js +60 -0
- package/lib/pages/Lakehouse/entitlements/showTaskActionAlert.js.map +1 -0
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.d.ts.map +1 -1
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js +3 -8
- package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js.map +1 -1
- package/lib/stores/LegendMarketplaceBaseStore.d.ts +2 -1
- package/lib/stores/LegendMarketplaceBaseStore.d.ts.map +1 -1
- package/lib/stores/LegendMarketplaceBaseStore.js +8 -1
- package/lib/stores/LegendMarketplaceBaseStore.js.map +1 -1
- package/lib/stores/ai/LegendMarketplaceAIChatStore.d.ts +109 -0
- package/lib/stores/ai/LegendMarketplaceAIChatStore.d.ts.map +1 -0
- package/lib/stores/ai/LegendMarketplaceAIChatStore.js +1106 -0
- package/lib/stores/ai/LegendMarketplaceAIChatStore.js.map +1 -0
- package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.d.ts.map +1 -1
- package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.js +3 -2
- package/lib/stores/lakehouse/LegendMarketplaceProductViewerStore.js.map +1 -1
- package/lib/stores/lakehouse/dataProducts/ProductCardState.d.ts +1 -1
- package/lib/stores/lakehouse/dataProducts/ProductCardState.d.ts.map +1 -1
- package/lib/stores/lakehouse/dataProducts/ProductCardState.js +1 -2
- package/lib/stores/lakehouse/dataProducts/ProductCardState.js.map +1 -1
- package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.d.ts +30 -3
- package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.d.ts.map +1 -1
- package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.js +94 -16
- package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.js.map +1 -1
- package/lib/utils/EntitlementsUtils.d.ts +36 -2
- package/lib/utils/EntitlementsUtils.d.ts.map +1 -1
- package/lib/utils/EntitlementsUtils.js +225 -46
- package/lib/utils/EntitlementsUtils.js.map +1 -1
- package/lib/utils/SearchUtils.d.ts.map +1 -1
- package/lib/utils/SearchUtils.js +7 -4
- package/lib/utils/SearchUtils.js.map +1 -1
- package/package.json +10 -10
- package/src/__lib__/LegendMarketplaceNavigation.ts +11 -0
- package/src/application/LegendMarketplaceApplicationConfig.ts +62 -24
- package/src/application/LegendMarketplaceWebApplication.tsx +15 -0
- package/src/application/__test-utils__/LegendMarketplaceApplicationTestUtils.ts +7 -0
- package/src/application/providers/LegendMarketplaceAIChatStoreProvider.tsx +47 -0
- package/src/pages/Agents/LegendMarketplaceAgents.tsx +145 -23
- package/src/pages/Agents/MarketplaceAIChatView.tsx +555 -0
- package/src/pages/Agents/MarketplaceAIInputBar.tsx +91 -0
- package/src/pages/Agents/MarketplaceAIProductAutosuggest.tsx +181 -0
- package/src/pages/Agents/MarketplaceAIProductCards.tsx +111 -0
- package/src/pages/Agents/MarketplaceAIScopeSelector.tsx +84 -0
- package/src/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.tsx +131 -136
- package/src/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.tsx +158 -165
- package/src/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.tsx +12 -17
- package/src/pages/Lakehouse/entitlements/PermitDataAccessRequest.tsx +245 -0
- package/src/pages/Lakehouse/entitlements/WorkflowDataAccessRequest.tsx +25 -94
- package/src/pages/Lakehouse/entitlements/showTaskActionAlert.tsx +101 -0
- package/src/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.tsx +27 -31
- package/src/stores/LegendMarketplaceBaseStore.ts +12 -0
- package/src/stores/ai/LegendMarketplaceAIChatStore.ts +1720 -0
- package/src/stores/lakehouse/LegendMarketplaceProductViewerStore.ts +6 -0
- package/src/stores/lakehouse/dataProducts/ProductCardState.ts +3 -4
- package/src/stores/lakehouse/entitlements/EntitlementsDashboardState.ts +181 -48
- package/src/utils/EntitlementsUtils.tsx +341 -86
- package/src/utils/SearchUtils.tsx +7 -4
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,245 @@
|
|
|
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 { ActionAlertType } from '@finos/legend-application';
|
|
19
|
+
import { withLegendMarketplaceProductViewerStore } from '../../../application/providers/LegendMarketplaceProductViewerStoreProvider.js';
|
|
20
|
+
import { useParams } from '@finos/legend-application/browser';
|
|
21
|
+
import {
|
|
22
|
+
generateLakehouseDataProductPath,
|
|
23
|
+
generatePermitDataAccessRequestPagePath,
|
|
24
|
+
type WorkflowDataAccessRequestPathParams,
|
|
25
|
+
LEGEND_MARKETPLACE_ROUTE_PATTERN_TOKEN,
|
|
26
|
+
} from '../../../__lib__/LegendMarketplaceNavigation.js';
|
|
27
|
+
import { assertErrorThrown, guaranteeNonNullable } from '@finos/legend-shared';
|
|
28
|
+
import { useAuth } from 'react-oidc-context';
|
|
29
|
+
import { LegendMarketplacePage } from '../../LegendMarketplacePage.js';
|
|
30
|
+
import { useEffect, useState } from 'react';
|
|
31
|
+
import { useLegendMarketplaceBaseStore } from '../../../application/providers/LegendMarketplaceFrameworkProvider.js';
|
|
32
|
+
import { Box, Button } from '@mui/material';
|
|
33
|
+
import {
|
|
34
|
+
CubesLoadingIndicator,
|
|
35
|
+
CubesLoadingIndicatorIcon,
|
|
36
|
+
} from '@finos/legend-art';
|
|
37
|
+
import {
|
|
38
|
+
DataAccessRequestContent,
|
|
39
|
+
PermitDataAccessRequestState,
|
|
40
|
+
} from '@finos/legend-extension-dsl-data-product';
|
|
41
|
+
import { flowResult } from 'mobx';
|
|
42
|
+
import {
|
|
43
|
+
V1_deserializeDataRequestsWithWorkflowResponse,
|
|
44
|
+
V1_PermitTaskAction,
|
|
45
|
+
} from '@finos/legend-graph';
|
|
46
|
+
import { showTaskActionAlert } from './showTaskActionAlert.js';
|
|
47
|
+
|
|
48
|
+
export const PermitDataAccessRequestTask =
|
|
49
|
+
withLegendMarketplaceProductViewerStore(
|
|
50
|
+
observer(() => {
|
|
51
|
+
const marketplaceBaseStore = useLegendMarketplaceBaseStore();
|
|
52
|
+
const params = useParams<WorkflowDataAccessRequestPathParams>();
|
|
53
|
+
const auth = useAuth();
|
|
54
|
+
const currentUser =
|
|
55
|
+
marketplaceBaseStore.applicationStore.identityService.currentUser;
|
|
56
|
+
|
|
57
|
+
const [permitState, setPermitState] =
|
|
58
|
+
useState<PermitDataAccessRequestState>();
|
|
59
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
60
|
+
|
|
61
|
+
const dataAccessRequestId = guaranteeNonNullable(
|
|
62
|
+
params[LEGEND_MARKETPLACE_ROUTE_PATTERN_TOKEN.DATA_ACCESS_REQUEST_ID],
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const actionableTask = permitState?.getFirstOpenTask();
|
|
66
|
+
const userCanAction = actionableTask?.assignees.includes(currentUser);
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
const fetchAndInitialize = async () => {
|
|
70
|
+
try {
|
|
71
|
+
setIsLoading(true);
|
|
72
|
+
|
|
73
|
+
const pluginManager =
|
|
74
|
+
marketplaceBaseStore.applicationStore.pluginManager;
|
|
75
|
+
const permitClient =
|
|
76
|
+
marketplaceBaseStore.permitWorkflowServerClient;
|
|
77
|
+
|
|
78
|
+
const state = new PermitDataAccessRequestState(
|
|
79
|
+
dataAccessRequestId,
|
|
80
|
+
marketplaceBaseStore.applicationStore,
|
|
81
|
+
permitClient,
|
|
82
|
+
marketplaceBaseStore.userSearchService,
|
|
83
|
+
{
|
|
84
|
+
authServerClient:
|
|
85
|
+
marketplaceBaseStore.lakehouseContractServerClient,
|
|
86
|
+
fetchFresh: async (token) => {
|
|
87
|
+
const raw = await permitClient.getDataRequestWithWorkflow(
|
|
88
|
+
dataAccessRequestId,
|
|
89
|
+
token,
|
|
90
|
+
);
|
|
91
|
+
return V1_deserializeDataRequestsWithWorkflowResponse(
|
|
92
|
+
raw,
|
|
93
|
+
pluginManager.getPureProtocolProcessorPlugins(),
|
|
94
|
+
)[0];
|
|
95
|
+
},
|
|
96
|
+
getTaskPageUrl: (id) =>
|
|
97
|
+
marketplaceBaseStore.applicationStore.navigationService.navigator.generateAddress(
|
|
98
|
+
generatePermitDataAccessRequestPagePath(id),
|
|
99
|
+
),
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
setPermitState(state);
|
|
104
|
+
await flowResult(state.init(auth.user?.access_token));
|
|
105
|
+
} catch (error) {
|
|
106
|
+
assertErrorThrown(error);
|
|
107
|
+
marketplaceBaseStore.applicationStore.notificationService.notifyError(
|
|
108
|
+
`Error fetching data access request: ${error.message}`,
|
|
109
|
+
);
|
|
110
|
+
} finally {
|
|
111
|
+
setIsLoading(false);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
// eslint-disable-next-line no-void
|
|
115
|
+
void fetchAndInitialize();
|
|
116
|
+
}, [dataAccessRequestId, auth.user?.access_token, marketplaceBaseStore]);
|
|
117
|
+
|
|
118
|
+
const handleRefresh = async (): Promise<void> => {
|
|
119
|
+
if (permitState) {
|
|
120
|
+
try {
|
|
121
|
+
setIsLoading(true);
|
|
122
|
+
permitState.initializationState.reset();
|
|
123
|
+
await flowResult(permitState.init(auth.user?.access_token));
|
|
124
|
+
} finally {
|
|
125
|
+
setIsLoading(false);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const handleTaskAction = async (
|
|
131
|
+
action: V1_PermitTaskAction,
|
|
132
|
+
justification: string,
|
|
133
|
+
): Promise<void> => {
|
|
134
|
+
if (!actionableTask || !permitState) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
await flowResult(
|
|
138
|
+
permitState.performTaskAction(
|
|
139
|
+
actionableTask.taskId,
|
|
140
|
+
action,
|
|
141
|
+
justification,
|
|
142
|
+
auth.user?.access_token,
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
const label =
|
|
146
|
+
action === V1_PermitTaskAction.APPROVE ? 'approved' : 'denied';
|
|
147
|
+
marketplaceBaseStore.applicationStore.notificationService.notifySuccess(
|
|
148
|
+
`Request has been ${label}`,
|
|
149
|
+
);
|
|
150
|
+
await handleRefresh();
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const handleApproveClick = (): void => {
|
|
154
|
+
showTaskActionAlert({
|
|
155
|
+
applicationStore: marketplaceBaseStore.applicationStore,
|
|
156
|
+
title: 'Approve Request',
|
|
157
|
+
message:
|
|
158
|
+
'Please provide a business justification for approving this request.',
|
|
159
|
+
confirmLabel: 'Approve',
|
|
160
|
+
alertType: ActionAlertType.STANDARD,
|
|
161
|
+
requireJustification: true,
|
|
162
|
+
isLoading,
|
|
163
|
+
setIsLoading,
|
|
164
|
+
onConfirm: (justification) =>
|
|
165
|
+
handleTaskAction(V1_PermitTaskAction.APPROVE, justification),
|
|
166
|
+
errorPrefix: 'Error approving request',
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const handleDenyClick = (): void => {
|
|
171
|
+
showTaskActionAlert({
|
|
172
|
+
applicationStore: marketplaceBaseStore.applicationStore,
|
|
173
|
+
title: 'Deny Request',
|
|
174
|
+
message:
|
|
175
|
+
'Please provide a business justification for denying this request.',
|
|
176
|
+
confirmLabel: 'Deny',
|
|
177
|
+
alertType: ActionAlertType.CAUTION,
|
|
178
|
+
requireJustification: true,
|
|
179
|
+
isLoading,
|
|
180
|
+
setIsLoading,
|
|
181
|
+
onConfirm: (justification) =>
|
|
182
|
+
handleTaskAction(V1_PermitTaskAction.REJECT, justification),
|
|
183
|
+
errorPrefix: 'Error denying request',
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
<LegendMarketplacePage className="marketplace-lakehouse-single-contract-viewer">
|
|
189
|
+
<CubesLoadingIndicator isLoading={isLoading}>
|
|
190
|
+
<CubesLoadingIndicatorIcon />
|
|
191
|
+
</CubesLoadingIndicator>
|
|
192
|
+
{permitState?.dataRequestWithWorkflow && (
|
|
193
|
+
<div className="marketplace-lakehouse-single-contract-viewer__container">
|
|
194
|
+
{actionableTask !== undefined && (
|
|
195
|
+
<Box className="marketplace-lakehouse-single-contract-viewer__action-btns">
|
|
196
|
+
<Button
|
|
197
|
+
variant="contained"
|
|
198
|
+
color="success"
|
|
199
|
+
onClick={handleApproveClick}
|
|
200
|
+
title={
|
|
201
|
+
userCanAction
|
|
202
|
+
? ''
|
|
203
|
+
: 'You are not assigned to review this task'
|
|
204
|
+
}
|
|
205
|
+
disabled={!userCanAction || isLoading}
|
|
206
|
+
>
|
|
207
|
+
Approve Request
|
|
208
|
+
</Button>
|
|
209
|
+
<Button
|
|
210
|
+
variant="contained"
|
|
211
|
+
color="error"
|
|
212
|
+
onClick={handleDenyClick}
|
|
213
|
+
title={
|
|
214
|
+
userCanAction
|
|
215
|
+
? ''
|
|
216
|
+
: 'You are not assigned to review this task'
|
|
217
|
+
}
|
|
218
|
+
disabled={!userCanAction || isLoading}
|
|
219
|
+
>
|
|
220
|
+
Deny Request
|
|
221
|
+
</Button>
|
|
222
|
+
</Box>
|
|
223
|
+
)}
|
|
224
|
+
<DataAccessRequestContent
|
|
225
|
+
viewerState={permitState}
|
|
226
|
+
getDataProductUrl={(
|
|
227
|
+
dataProductId: string,
|
|
228
|
+
deploymentId: number,
|
|
229
|
+
) =>
|
|
230
|
+
marketplaceBaseStore.applicationStore.navigationService.navigator.generateAddress(
|
|
231
|
+
generateLakehouseDataProductPath(
|
|
232
|
+
dataProductId,
|
|
233
|
+
deploymentId,
|
|
234
|
+
),
|
|
235
|
+
)
|
|
236
|
+
}
|
|
237
|
+
onRefresh={handleRefresh}
|
|
238
|
+
isReadOnly={true}
|
|
239
|
+
/>
|
|
240
|
+
</div>
|
|
241
|
+
)}
|
|
242
|
+
</LegendMarketplacePage>
|
|
243
|
+
);
|
|
244
|
+
}),
|
|
245
|
+
);
|
|
@@ -15,10 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { observer } from 'mobx-react-lite';
|
|
18
|
-
import {
|
|
19
|
-
ActionAlertActionType,
|
|
20
|
-
ActionAlertType,
|
|
21
|
-
} from '@finos/legend-application';
|
|
18
|
+
import { ActionAlertType } from '@finos/legend-application';
|
|
22
19
|
import { withLegendMarketplaceProductViewerStore } from '../../../application/providers/LegendMarketplaceProductViewerStoreProvider.js';
|
|
23
20
|
import { useParams } from '@finos/legend-application/browser';
|
|
24
21
|
import {
|
|
@@ -36,7 +33,7 @@ import {
|
|
|
36
33
|
V1_RawWorkflowTask,
|
|
37
34
|
V1_WorkflowTaskStatus,
|
|
38
35
|
} from '@finos/legend-graph';
|
|
39
|
-
import { Box, Button
|
|
36
|
+
import { Box, Button } from '@mui/material';
|
|
40
37
|
import {
|
|
41
38
|
CubesLoadingIndicator,
|
|
42
39
|
CubesLoadingIndicatorIcon,
|
|
@@ -46,6 +43,7 @@ import {
|
|
|
46
43
|
WorkflowDataAccessRequestState,
|
|
47
44
|
} from '@finos/legend-extension-dsl-data-product';
|
|
48
45
|
import { flowResult } from 'mobx';
|
|
46
|
+
import { showTaskActionAlert } from './showTaskActionAlert.js';
|
|
49
47
|
|
|
50
48
|
export const WorkflowDataAccessRequestTask =
|
|
51
49
|
withLegendMarketplaceProductViewerStore(
|
|
@@ -71,10 +69,11 @@ export const WorkflowDataAccessRequestTask =
|
|
|
71
69
|
return undefined;
|
|
72
70
|
}
|
|
73
71
|
// Prefer workflow server tasks
|
|
74
|
-
const {
|
|
72
|
+
const { privilegeManagerTasks, dataOwnerTasks } =
|
|
75
73
|
workflowState.workflowTasks;
|
|
76
|
-
const
|
|
77
|
-
|
|
74
|
+
const allTasks = [...privilegeManagerTasks, ...dataOwnerTasks];
|
|
75
|
+
const workflowServerTask = allTasks.find(
|
|
76
|
+
(task) => task.status === 'OPEN',
|
|
78
77
|
);
|
|
79
78
|
if (workflowServerTask) {
|
|
80
79
|
return workflowServerTask;
|
|
@@ -85,8 +84,8 @@ export const WorkflowDataAccessRequestTask =
|
|
|
85
84
|
.find((task) => task.status === V1_WorkflowTaskStatus.OPEN);
|
|
86
85
|
if (fallbackTask) {
|
|
87
86
|
// Find the matching raw workflow task by taskId, or build a minimal one from the fallback
|
|
88
|
-
const matchingRaw =
|
|
89
|
-
(t) => t
|
|
87
|
+
const matchingRaw = allTasks.find(
|
|
88
|
+
(t) => t.taskId === fallbackTask.taskId,
|
|
90
89
|
);
|
|
91
90
|
if (matchingRaw) {
|
|
92
91
|
return matchingRaw;
|
|
@@ -180,100 +179,32 @@ export const WorkflowDataAccessRequestTask =
|
|
|
180
179
|
};
|
|
181
180
|
|
|
182
181
|
const handleApproveClick = () => {
|
|
183
|
-
|
|
184
|
-
|
|
182
|
+
showTaskActionAlert({
|
|
183
|
+
applicationStore: marketplaceBaseStore.applicationStore,
|
|
185
184
|
title: 'Approve Request',
|
|
186
185
|
message:
|
|
187
186
|
'Please provide a business justification for approving this request.',
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
placeholder="Business Justification"
|
|
195
|
-
onChange={(e) => {
|
|
196
|
-
justification = e.target.value;
|
|
197
|
-
}}
|
|
198
|
-
sx={{ marginTop: 2 }}
|
|
199
|
-
/>
|
|
200
|
-
),
|
|
201
|
-
type: ActionAlertType.STANDARD,
|
|
202
|
-
actions: [
|
|
203
|
-
{
|
|
204
|
-
label: 'Approve',
|
|
205
|
-
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
|
206
|
-
handler: () => {
|
|
207
|
-
if (!isLoading) {
|
|
208
|
-
setIsLoading(true);
|
|
209
|
-
handleApprove(justification)
|
|
210
|
-
.catch((error) => {
|
|
211
|
-
assertErrorThrown(error);
|
|
212
|
-
marketplaceBaseStore.applicationStore.notificationService.notifyError(
|
|
213
|
-
`Error approving request: ${error.message}`,
|
|
214
|
-
);
|
|
215
|
-
})
|
|
216
|
-
.finally(() => {
|
|
217
|
-
setIsLoading(false);
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
label: 'Cancel',
|
|
224
|
-
type: ActionAlertActionType.PROCEED,
|
|
225
|
-
default: true,
|
|
226
|
-
},
|
|
227
|
-
],
|
|
187
|
+
confirmLabel: 'Approve',
|
|
188
|
+
alertType: ActionAlertType.STANDARD,
|
|
189
|
+
isLoading,
|
|
190
|
+
setIsLoading,
|
|
191
|
+
onConfirm: (justification) => handleApprove(justification),
|
|
192
|
+
errorPrefix: 'Error approving request',
|
|
228
193
|
});
|
|
229
194
|
};
|
|
230
195
|
|
|
231
196
|
const handleDenyClick = () => {
|
|
232
|
-
|
|
233
|
-
|
|
197
|
+
showTaskActionAlert({
|
|
198
|
+
applicationStore: marketplaceBaseStore.applicationStore,
|
|
234
199
|
title: 'Deny Request',
|
|
235
200
|
message:
|
|
236
201
|
'Please provide a business justification for denying this request.',
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
placeholder="Business Justification"
|
|
244
|
-
onChange={(e) => {
|
|
245
|
-
justification = e.target.value;
|
|
246
|
-
}}
|
|
247
|
-
sx={{ marginTop: 2 }}
|
|
248
|
-
/>
|
|
249
|
-
),
|
|
250
|
-
type: ActionAlertType.CAUTION,
|
|
251
|
-
actions: [
|
|
252
|
-
{
|
|
253
|
-
label: 'Deny',
|
|
254
|
-
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
|
255
|
-
handler: () => {
|
|
256
|
-
if (!isLoading) {
|
|
257
|
-
setIsLoading(true);
|
|
258
|
-
handleDeny(justification)
|
|
259
|
-
.catch((error) => {
|
|
260
|
-
assertErrorThrown(error);
|
|
261
|
-
marketplaceBaseStore.applicationStore.notificationService.notifyError(
|
|
262
|
-
`Error denying request: ${error.message}`,
|
|
263
|
-
);
|
|
264
|
-
})
|
|
265
|
-
.finally(() => {
|
|
266
|
-
setIsLoading(false);
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
},
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
label: 'Cancel',
|
|
273
|
-
type: ActionAlertActionType.PROCEED,
|
|
274
|
-
default: true,
|
|
275
|
-
},
|
|
276
|
-
],
|
|
202
|
+
confirmLabel: 'Deny',
|
|
203
|
+
alertType: ActionAlertType.CAUTION,
|
|
204
|
+
isLoading,
|
|
205
|
+
setIsLoading,
|
|
206
|
+
onConfirm: (justification) => handleDeny(justification),
|
|
207
|
+
errorPrefix: 'Error denying request',
|
|
277
208
|
});
|
|
278
209
|
};
|
|
279
210
|
|
|
@@ -0,0 +1,101 @@
|
|
|
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 { TextField } from '@mui/material';
|
|
18
|
+
import {
|
|
19
|
+
ActionAlertActionType,
|
|
20
|
+
type ActionAlertType,
|
|
21
|
+
type GenericLegendApplicationStore,
|
|
22
|
+
} from '@finos/legend-application';
|
|
23
|
+
import { assertErrorThrown } from '@finos/legend-shared';
|
|
24
|
+
|
|
25
|
+
export function showTaskActionAlert(options: {
|
|
26
|
+
applicationStore: GenericLegendApplicationStore;
|
|
27
|
+
title: string;
|
|
28
|
+
message: string;
|
|
29
|
+
confirmLabel: string;
|
|
30
|
+
alertType: ActionAlertType;
|
|
31
|
+
requireJustification?: boolean;
|
|
32
|
+
isLoading: boolean;
|
|
33
|
+
setIsLoading: (loading: boolean) => void;
|
|
34
|
+
onConfirm: (justification: string) => Promise<void>;
|
|
35
|
+
errorPrefix: string;
|
|
36
|
+
}): void {
|
|
37
|
+
const {
|
|
38
|
+
applicationStore,
|
|
39
|
+
title,
|
|
40
|
+
message,
|
|
41
|
+
confirmLabel,
|
|
42
|
+
alertType,
|
|
43
|
+
requireJustification = false,
|
|
44
|
+
isLoading,
|
|
45
|
+
setIsLoading,
|
|
46
|
+
onConfirm,
|
|
47
|
+
errorPrefix,
|
|
48
|
+
} = options;
|
|
49
|
+
|
|
50
|
+
let justification = '';
|
|
51
|
+
applicationStore.alertService.setActionAlertInfo({
|
|
52
|
+
title,
|
|
53
|
+
message,
|
|
54
|
+
prompt: (
|
|
55
|
+
<TextField
|
|
56
|
+
fullWidth={true}
|
|
57
|
+
autoFocus={true}
|
|
58
|
+
multiline={true}
|
|
59
|
+
minRows={3}
|
|
60
|
+
placeholder="Business Justification"
|
|
61
|
+
onChange={(e) => {
|
|
62
|
+
justification = e.target.value;
|
|
63
|
+
}}
|
|
64
|
+
className="marketplace-lakehouse-entitlements__data-access-request-viewer__justification-field"
|
|
65
|
+
/>
|
|
66
|
+
),
|
|
67
|
+
type: alertType,
|
|
68
|
+
actions: [
|
|
69
|
+
{
|
|
70
|
+
label: confirmLabel,
|
|
71
|
+
type: ActionAlertActionType.PROCEED_WITH_CAUTION,
|
|
72
|
+
handler: () => {
|
|
73
|
+
if (requireJustification && !justification.trim()) {
|
|
74
|
+
applicationStore.notificationService.notifyError(
|
|
75
|
+
'Business justification is required',
|
|
76
|
+
);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!isLoading) {
|
|
80
|
+
setIsLoading(true);
|
|
81
|
+
onConfirm(justification)
|
|
82
|
+
.catch((error) => {
|
|
83
|
+
assertErrorThrown(error);
|
|
84
|
+
applicationStore.notificationService.notifyError(
|
|
85
|
+
`${errorPrefix}: ${error.message}`,
|
|
86
|
+
);
|
|
87
|
+
})
|
|
88
|
+
.finally(() => {
|
|
89
|
+
setIsLoading(false);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
label: 'Cancel',
|
|
96
|
+
type: ActionAlertActionType.PROCEED,
|
|
97
|
+
default: true,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
@@ -382,43 +382,39 @@ export const LegendMarketplaceSearchResults =
|
|
|
382
382
|
? `${searchResultsStore.filterSortProducts?.length ?? 0} Products`
|
|
383
383
|
: `${searchResultsStore.totalItems} Products`}
|
|
384
384
|
</Typography>
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
<button
|
|
391
|
-
type="button"
|
|
392
|
-
role="tab"
|
|
393
|
-
aria-selected={true}
|
|
394
|
-
tabIndex={0}
|
|
395
|
-
className="legend-marketplace-search-results__search-type-tab legend-marketplace-search-results__search-type-tab--active"
|
|
385
|
+
{isNonEmptyString(searchResultsStore.searchQuery) && (
|
|
386
|
+
<div
|
|
387
|
+
className="legend-marketplace-search-results__search-type-tabs"
|
|
388
|
+
role="tablist"
|
|
389
|
+
aria-label="Search result type"
|
|
396
390
|
>
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
391
|
+
<button
|
|
392
|
+
type="button"
|
|
393
|
+
role="tab"
|
|
394
|
+
aria-selected={true}
|
|
395
|
+
tabIndex={0}
|
|
396
|
+
className="legend-marketplace-search-results__search-type-tab legend-marketplace-search-results__search-type-tab--active"
|
|
397
|
+
>
|
|
398
|
+
Data Products
|
|
399
|
+
</button>
|
|
400
|
+
<button
|
|
401
|
+
type="button"
|
|
402
|
+
role="tab"
|
|
403
|
+
aria-selected={false}
|
|
404
|
+
tabIndex={-1}
|
|
405
|
+
className="legend-marketplace-search-results__search-type-tab"
|
|
406
|
+
onClick={() => {
|
|
407
407
|
applicationStore.navigationService.navigator.goToLocation(
|
|
408
408
|
generateFieldSearchResultsRoute(
|
|
409
409
|
searchResultsStore.searchQuery,
|
|
410
410
|
),
|
|
411
411
|
);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
>
|
|
419
|
-
Data Fields
|
|
420
|
-
</button>
|
|
421
|
-
</div>
|
|
412
|
+
}}
|
|
413
|
+
>
|
|
414
|
+
Data Fields
|
|
415
|
+
</button>
|
|
416
|
+
</div>
|
|
417
|
+
)}
|
|
422
418
|
<div className="legend-marketplace-search-results__sort-bar__controls">
|
|
423
419
|
<div className="legend-marketplace-search-results__view-toggle">
|
|
424
420
|
<div
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
LakehouseIngestServerClient,
|
|
54
54
|
LakehousePlatformServerClient,
|
|
55
55
|
LakehouseWorkflowServerClient,
|
|
56
|
+
PermitWorkflowServerClient,
|
|
56
57
|
} from '@finos/legend-server-lakehouse';
|
|
57
58
|
import { CartStore } from './cart/CartStore.js';
|
|
58
59
|
import { parseGAVCoordinates, type Entity } from '@finos/legend-storage';
|
|
@@ -92,6 +93,7 @@ export class LegendMarketplaceBaseStore {
|
|
|
92
93
|
readonly remoteEngine: V1_RemoteEngine;
|
|
93
94
|
readonly userSearchService: UserSearchService | undefined;
|
|
94
95
|
readonly lakehouseWorkflowServerClient: LakehouseWorkflowServerClient;
|
|
96
|
+
readonly permitWorkflowServerClient: PermitWorkflowServerClient;
|
|
95
97
|
readonly lakehouseDataProductService: LakehouseDataProductService;
|
|
96
98
|
readonly cartStore: CartStore;
|
|
97
99
|
readonly terminalAccessServerClient: TerminalAccessServerClient;
|
|
@@ -177,6 +179,16 @@ export class LegendMarketplaceBaseStore {
|
|
|
177
179
|
this.applicationStore.tracerService,
|
|
178
180
|
);
|
|
179
181
|
|
|
182
|
+
// permit + eTask workflow
|
|
183
|
+
this.permitWorkflowServerClient = new PermitWorkflowServerClient({
|
|
184
|
+
authBaseUrl: this.applicationStore.config.lakehouseServerUrl,
|
|
185
|
+
workflowBaseUrl:
|
|
186
|
+
this.applicationStore.config.lakehousePermitWorkflowServerUrl,
|
|
187
|
+
});
|
|
188
|
+
this.permitWorkflowServerClient.setTracerService(
|
|
189
|
+
this.applicationStore.tracerService,
|
|
190
|
+
);
|
|
191
|
+
|
|
180
192
|
// lakehouse ingest
|
|
181
193
|
this.lakehouseIngestServerClient = new LakehouseIngestServerClient(
|
|
182
194
|
undefined,
|