@finos/legend-extension-dsl-data-product 0.0.19 → 0.0.21
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/components/DataProduct/DataContract/EntitlementsDataContractViewer.d.ts +1 -2
- package/lib/components/DataProduct/DataContract/EntitlementsDataContractViewer.d.ts.map +1 -1
- package/lib/components/DataProduct/DataContract/EntitlementsDataContractViewer.js +64 -18
- package/lib/components/DataProduct/DataContract/EntitlementsDataContractViewer.js.map +1 -1
- package/lib/components/DataProduct/DataProductDataAccess.d.ts.map +1 -1
- package/lib/components/DataProduct/DataProductDataAccess.js +37 -5
- package/lib/components/DataProduct/DataProductDataAccess.js.map +1 -1
- package/lib/components/__test-utils__/TEST_DATA__LakehouseContractData.d.ts +4 -2
- package/lib/components/__test-utils__/TEST_DATA__LakehouseContractData.d.ts.map +1 -1
- package/lib/components/__test-utils__/TEST_DATA__LakehouseContractData.js +130 -1
- package/lib/components/__test-utils__/TEST_DATA__LakehouseContractData.js.map +1 -1
- package/lib/components/__test-utils__/TEST_DATA__LakehouseDataProducts.js +3 -3
- package/lib/components/__test-utils__/TEST_DATA__LakehouseDataProducts.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/DataProduct/DataProductAccessPointState.d.ts +4 -1
- package/lib/stores/DataProduct/DataProductAccessPointState.d.ts.map +1 -1
- package/lib/stores/DataProduct/DataProductAccessPointState.js +19 -0
- package/lib/stores/DataProduct/DataProductAccessPointState.js.map +1 -1
- package/lib/stores/DataProduct/EntitlementsDataContractViewerState.d.ts +10 -3
- package/lib/stores/DataProduct/EntitlementsDataContractViewerState.d.ts.map +1 -1
- package/lib/stores/DataProduct/EntitlementsDataContractViewerState.js +38 -9
- package/lib/stores/DataProduct/EntitlementsDataContractViewerState.js.map +1 -1
- package/package.json +9 -9
- package/src/components/DataProduct/DataContract/EntitlementsDataContractViewer.tsx +289 -150
- package/src/components/DataProduct/DataProductDataAccess.tsx +43 -4
- package/src/components/__test-utils__/TEST_DATA__LakehouseContractData.ts +137 -2
- package/src/components/__test-utils__/TEST_DATA__LakehouseDataProducts.ts +3 -3
- package/src/stores/DataProduct/DataProductAccessPointState.ts +25 -0
- package/src/stores/DataProduct/EntitlementsDataContractViewerState.ts +64 -13
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
Box,
|
|
23
23
|
Button,
|
|
24
24
|
Dialog,
|
|
25
|
+
DialogActions,
|
|
25
26
|
DialogContent,
|
|
26
27
|
DialogTitle,
|
|
27
28
|
IconButton,
|
|
@@ -47,17 +48,20 @@ import {
|
|
|
47
48
|
V1_ContractUserEventPrivilegeManagerPayload,
|
|
48
49
|
V1_ResourceType,
|
|
49
50
|
V1_UserApprovalStatus,
|
|
51
|
+
V1_UserType,
|
|
50
52
|
} from '@finos/legend-graph';
|
|
51
53
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
52
54
|
import {
|
|
53
55
|
type UserSearchService,
|
|
54
56
|
ActionState,
|
|
57
|
+
assertErrorThrown,
|
|
55
58
|
formatDate,
|
|
56
59
|
lodashCapitalize,
|
|
57
60
|
} from '@finos/legend-shared';
|
|
58
61
|
import { flowResult } from 'mobx';
|
|
59
62
|
import { useAuth } from 'react-oidc-context';
|
|
60
63
|
import {
|
|
64
|
+
ArrowUpFromBracketIcon,
|
|
61
65
|
CloseIcon,
|
|
62
66
|
CopyIcon,
|
|
63
67
|
CubesLoadingIndicator,
|
|
@@ -75,7 +79,6 @@ import {
|
|
|
75
79
|
import { UserRenderer } from '../../UserRenderer/UserRenderer.js';
|
|
76
80
|
import { isContractInTerminalState } from '../../../utils/DataContractUtils.js';
|
|
77
81
|
import type { GenericLegendApplicationStore } from '@finos/legend-application';
|
|
78
|
-
import type { DataProductAPGState } from '../../../stores/DataProduct/DataProductAPGState.js';
|
|
79
82
|
|
|
80
83
|
const AssigneesList = (props: {
|
|
81
84
|
userIds: string[];
|
|
@@ -167,6 +170,91 @@ const TaskApprovalView = (props: {
|
|
|
167
170
|
}
|
|
168
171
|
};
|
|
169
172
|
|
|
173
|
+
const ContractEscalationModal = (props: {
|
|
174
|
+
open: boolean;
|
|
175
|
+
onClose: () => void;
|
|
176
|
+
currentViewer: EntitlementsDataContractViewerState;
|
|
177
|
+
selectedUser: string | undefined;
|
|
178
|
+
refresh: () => Promise<void>;
|
|
179
|
+
}) => {
|
|
180
|
+
const { open, onClose, currentViewer, selectedUser, refresh } = props;
|
|
181
|
+
|
|
182
|
+
const auth = useAuth();
|
|
183
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
184
|
+
|
|
185
|
+
if (!selectedUser) {
|
|
186
|
+
return (
|
|
187
|
+
<Dialog open={open} onClose={onClose} fullWidth={true} maxWidth="sm">
|
|
188
|
+
<DialogContent className="marketplace-lakehouse-entitlements__data-contract-viewer__escalation__content">
|
|
189
|
+
<div>
|
|
190
|
+
Can't escalate privilege manager approval request. No user
|
|
191
|
+
selected.
|
|
192
|
+
</div>
|
|
193
|
+
</DialogContent>
|
|
194
|
+
<DialogActions>
|
|
195
|
+
<Button onClick={onClose} variant="outlined" disabled={isLoading}>
|
|
196
|
+
Close
|
|
197
|
+
</Button>
|
|
198
|
+
</DialogActions>
|
|
199
|
+
</Dialog>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const handleEscalate = async () => {
|
|
204
|
+
setIsLoading(true);
|
|
205
|
+
try {
|
|
206
|
+
await currentViewer.lakehouseContractServerClient.escalateUserOnContract(
|
|
207
|
+
currentViewer.liteContract.guid,
|
|
208
|
+
selectedUser,
|
|
209
|
+
false,
|
|
210
|
+
auth.user?.access_token,
|
|
211
|
+
);
|
|
212
|
+
currentViewer.applicationStore.notificationService.notifySuccess(
|
|
213
|
+
'Successfully escalated contract request',
|
|
214
|
+
);
|
|
215
|
+
// eslint-disable-next-line no-void
|
|
216
|
+
void refresh();
|
|
217
|
+
onClose();
|
|
218
|
+
} catch (error) {
|
|
219
|
+
assertErrorThrown(error);
|
|
220
|
+
currentViewer.applicationStore.alertUnhandledError(error);
|
|
221
|
+
} finally {
|
|
222
|
+
setIsLoading(false);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
return (
|
|
227
|
+
<Dialog open={open} onClose={onClose} fullWidth={true} maxWidth="sm">
|
|
228
|
+
<DialogContent className="marketplace-lakehouse-entitlements__data-contract-viewer__escalation__content">
|
|
229
|
+
<CubesLoadingIndicator isLoading={isLoading}>
|
|
230
|
+
<CubesLoadingIndicatorIcon />
|
|
231
|
+
</CubesLoadingIndicator>
|
|
232
|
+
{!isLoading && (
|
|
233
|
+
<div>
|
|
234
|
+
Are you sure you want to escalate the privilege manager approval
|
|
235
|
+
request?
|
|
236
|
+
</div>
|
|
237
|
+
)}
|
|
238
|
+
</DialogContent>
|
|
239
|
+
<DialogActions>
|
|
240
|
+
<Button
|
|
241
|
+
onClick={() => {
|
|
242
|
+
// eslint-disable-next-line no-void
|
|
243
|
+
void handleEscalate();
|
|
244
|
+
}}
|
|
245
|
+
variant="contained"
|
|
246
|
+
disabled={isLoading}
|
|
247
|
+
>
|
|
248
|
+
Escalate
|
|
249
|
+
</Button>
|
|
250
|
+
<Button onClick={onClose} variant="outlined" disabled={isLoading}>
|
|
251
|
+
Cancel
|
|
252
|
+
</Button>
|
|
253
|
+
</DialogActions>
|
|
254
|
+
</Dialog>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
|
|
170
258
|
export const EntitlementsDataContractViewer = observer(
|
|
171
259
|
(props: {
|
|
172
260
|
open: boolean;
|
|
@@ -174,20 +262,20 @@ export const EntitlementsDataContractViewer = observer(
|
|
|
174
262
|
currentViewer: EntitlementsDataContractViewerState;
|
|
175
263
|
getContractTaskUrl: (taskId: string) => string;
|
|
176
264
|
getDataProductUrl: (dataProductId: string, deploymentId: number) => string;
|
|
177
|
-
apgState?: DataProductAPGState | undefined;
|
|
178
265
|
initialSelectedUser?: string | undefined;
|
|
266
|
+
onRefresh?: (() => void) | (() => Promise<void>);
|
|
179
267
|
}) => {
|
|
180
268
|
const {
|
|
181
269
|
open,
|
|
182
270
|
currentViewer,
|
|
183
271
|
getContractTaskUrl,
|
|
184
272
|
getDataProductUrl,
|
|
185
|
-
apgState,
|
|
186
273
|
onClose,
|
|
187
274
|
initialSelectedUser,
|
|
275
|
+
onRefresh,
|
|
188
276
|
} = props;
|
|
189
277
|
const auth = useAuth();
|
|
190
|
-
const consumer = currentViewer.
|
|
278
|
+
const consumer = currentViewer.liteContract.consumer;
|
|
191
279
|
|
|
192
280
|
// We try to get the target users from the associated tasks first, since the
|
|
193
281
|
// tasks are what drive the timeline view. If there are no associated tasks,
|
|
@@ -244,6 +332,7 @@ export const EntitlementsDataContractViewer = observer(
|
|
|
244
332
|
string | undefined
|
|
245
333
|
>(initialSelectedUser ?? targetUsers?.[0]);
|
|
246
334
|
const [isLoading, setIsLoading] = useState(false);
|
|
335
|
+
const [showEscalationModal, setShowEscalationModal] = useState(false);
|
|
247
336
|
|
|
248
337
|
useEffect(() => {
|
|
249
338
|
if (!currentViewer.initializationState.hasCompleted) {
|
|
@@ -267,18 +356,13 @@ export const EntitlementsDataContractViewer = observer(
|
|
|
267
356
|
|
|
268
357
|
const refresh = async (): Promise<void> => {
|
|
269
358
|
setIsLoading(true);
|
|
270
|
-
if (apgState?.associatedUserContract) {
|
|
271
|
-
apgState.fetchUserAccessStatus(
|
|
272
|
-
apgState.associatedUserContract.guid,
|
|
273
|
-
currentViewer.lakehouseContractServerClient,
|
|
274
|
-
auth.user?.access_token,
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
359
|
currentViewer.initializationState = ActionState.create();
|
|
360
|
+
await onRefresh?.();
|
|
278
361
|
};
|
|
279
362
|
|
|
280
363
|
if (
|
|
281
|
-
currentViewer.
|
|
364
|
+
currentViewer.liteContract.resourceType !==
|
|
365
|
+
V1_ResourceType.ACCESS_POINT_GROUP
|
|
282
366
|
) {
|
|
283
367
|
return (
|
|
284
368
|
<Dialog open={true} onClose={onClose} fullWidth={true} maxWidth="md">
|
|
@@ -291,15 +375,15 @@ export const EntitlementsDataContractViewer = observer(
|
|
|
291
375
|
</IconButton>
|
|
292
376
|
<DialogContent className="marketplace-lakehouse-entitlements__data-contract-viewer__content">
|
|
293
377
|
Unable to display data contract request details for resource of type{' '}
|
|
294
|
-
{currentViewer.
|
|
295
|
-
{currentViewer.
|
|
378
|
+
{currentViewer.liteContract.resourceType} on data product{' '}
|
|
379
|
+
{currentViewer.liteContract.resourceId}.
|
|
296
380
|
</DialogContent>
|
|
297
381
|
</Dialog>
|
|
298
382
|
);
|
|
299
383
|
}
|
|
300
384
|
|
|
301
|
-
const dataProduct = currentViewer.
|
|
302
|
-
const accessPointGroup = currentViewer.
|
|
385
|
+
const dataProduct = currentViewer.liteContract.resourceId;
|
|
386
|
+
const accessPointGroup = currentViewer.liteContract.accessPointGroup;
|
|
303
387
|
const privilegeManagerApprovalTask = currentViewer.associatedTasks?.find(
|
|
304
388
|
(task) =>
|
|
305
389
|
task.rec.consumer === selectedTargetUser &&
|
|
@@ -314,6 +398,28 @@ export const EntitlementsDataContractViewer = observer(
|
|
|
314
398
|
privilegeManagerApprovalTask?.rec.status ===
|
|
315
399
|
V1_UserApprovalStatus.PENDING ||
|
|
316
400
|
dataOwnerApprovalTask?.rec.status === V1_UserApprovalStatus.PENDING;
|
|
401
|
+
const showEscalationButton =
|
|
402
|
+
selectedTargetUser ===
|
|
403
|
+
currentViewer.applicationStore.identityService.currentUser ||
|
|
404
|
+
(selectedTargetUser !== undefined &&
|
|
405
|
+
currentViewer.getContractUserType(selectedTargetUser) ===
|
|
406
|
+
V1_UserType.SYSTEM_ACCOUNT);
|
|
407
|
+
const isContractEscalated =
|
|
408
|
+
privilegeManagerApprovalTask?.rec.isEscalated === true;
|
|
409
|
+
const canEscalateContract = showEscalationButton && !isContractEscalated;
|
|
410
|
+
|
|
411
|
+
const copyContractId = (): void => {
|
|
412
|
+
currentViewer.applicationStore.clipboardService
|
|
413
|
+
.copyTextToClipboard(currentViewer.liteContract.guid)
|
|
414
|
+
.then(() =>
|
|
415
|
+
currentViewer.applicationStore.notificationService.notifySuccess(
|
|
416
|
+
'Contract ID Copied to Clipboard',
|
|
417
|
+
undefined,
|
|
418
|
+
2500,
|
|
419
|
+
),
|
|
420
|
+
)
|
|
421
|
+
.catch(currentViewer.applicationStore.alertUnhandledError);
|
|
422
|
+
};
|
|
317
423
|
|
|
318
424
|
const copyTaskLink = (text: string): void => {
|
|
319
425
|
currentViewer.applicationStore.clipboardService
|
|
@@ -360,6 +466,24 @@ export const EntitlementsDataContractViewer = observer(
|
|
|
360
466
|
>
|
|
361
467
|
<CopyIcon />
|
|
362
468
|
</IconButton>
|
|
469
|
+
{showEscalationButton && (
|
|
470
|
+
<span
|
|
471
|
+
title={
|
|
472
|
+
canEscalateContract
|
|
473
|
+
? 'Escalate request'
|
|
474
|
+
: isContractEscalated
|
|
475
|
+
? 'Request has already been escalated'
|
|
476
|
+
: 'Cannot escalate request'
|
|
477
|
+
}
|
|
478
|
+
>
|
|
479
|
+
<IconButton
|
|
480
|
+
onClick={() => setShowEscalationModal(true)}
|
|
481
|
+
disabled={!canEscalateContract}
|
|
482
|
+
>
|
|
483
|
+
<ArrowUpFromBracketIcon />
|
|
484
|
+
</IconButton>
|
|
485
|
+
</span>
|
|
486
|
+
)}
|
|
363
487
|
</>
|
|
364
488
|
) : (
|
|
365
489
|
<>Privilege Manager Approval</>
|
|
@@ -443,144 +567,159 @@ export const EntitlementsDataContractViewer = observer(
|
|
|
443
567
|
];
|
|
444
568
|
|
|
445
569
|
return (
|
|
446
|
-
|
|
447
|
-
<
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
<
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
<
|
|
456
|
-
</
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
<
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
<UserRenderer
|
|
482
|
-
userId={currentViewer.value.createdBy}
|
|
483
|
-
applicationStore={currentViewer.applicationStore}
|
|
484
|
-
userSearchService={currentViewer.userSearchService}
|
|
485
|
-
/>
|
|
570
|
+
<>
|
|
571
|
+
<Dialog open={open} onClose={onClose} fullWidth={true} maxWidth="md">
|
|
572
|
+
<DialogTitle>
|
|
573
|
+
{isContractInProgressForUser ? 'Pending ' : ''}Data Contract Request
|
|
574
|
+
</DialogTitle>
|
|
575
|
+
<IconButton
|
|
576
|
+
onClick={onClose}
|
|
577
|
+
className="marketplace-dialog-close-btn"
|
|
578
|
+
>
|
|
579
|
+
<CloseIcon />
|
|
580
|
+
</IconButton>
|
|
581
|
+
<DialogContent className="marketplace-lakehouse-entitlements__data-contract-viewer__content">
|
|
582
|
+
<CubesLoadingIndicator isLoading={isLoading}>
|
|
583
|
+
<CubesLoadingIndicatorIcon />
|
|
584
|
+
</CubesLoadingIndicator>
|
|
585
|
+
{!isLoading && (
|
|
586
|
+
<>
|
|
587
|
+
<div>
|
|
588
|
+
Access request for{' '}
|
|
589
|
+
<span className="marketplace-lakehouse-text__emphasis">
|
|
590
|
+
{accessPointGroup}
|
|
591
|
+
</span>{' '}
|
|
592
|
+
Access Point Group in{' '}
|
|
593
|
+
<Link
|
|
594
|
+
className="marketplace-lakehouse-text__emphasis"
|
|
595
|
+
href={getDataProductUrl(
|
|
596
|
+
dataProduct,
|
|
597
|
+
currentViewer.liteContract.deploymentId,
|
|
598
|
+
)}
|
|
599
|
+
target="_blank"
|
|
600
|
+
rel="noopener noreferrer"
|
|
601
|
+
>
|
|
602
|
+
{dataProduct}
|
|
603
|
+
</Link>{' '}
|
|
604
|
+
Data Product
|
|
486
605
|
</div>
|
|
487
|
-
<
|
|
488
|
-
<
|
|
489
|
-
Ordered
|
|
490
|
-
<
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
key={targetUsers[0]}
|
|
514
|
-
userId={targetUsers[0]}
|
|
515
|
-
applicationStore={currentViewer.applicationStore}
|
|
516
|
-
userSearchService={currentViewer.userSearchService}
|
|
517
|
-
/>
|
|
518
|
-
) : (
|
|
519
|
-
<Select
|
|
520
|
-
value={selectedTargetUser}
|
|
521
|
-
onChange={(event) =>
|
|
522
|
-
setSelectedTargetUser(event.target.value)
|
|
606
|
+
<Box className="marketplace-lakehouse-entitlements__data-contract-viewer__metadata">
|
|
607
|
+
<div className="marketplace-lakehouse-entitlements__data-contract-viewer__metadata__ordered-by">
|
|
608
|
+
<b>Ordered By: </b>
|
|
609
|
+
<UserRenderer
|
|
610
|
+
userId={currentViewer.liteContract.createdBy}
|
|
611
|
+
applicationStore={currentViewer.applicationStore}
|
|
612
|
+
userSearchService={currentViewer.userSearchService}
|
|
613
|
+
/>
|
|
614
|
+
</div>
|
|
615
|
+
<div className="marketplace-lakehouse-entitlements__data-contract-viewer__metadata__ordered-for">
|
|
616
|
+
<b>
|
|
617
|
+
Ordered For
|
|
618
|
+
<Tooltip
|
|
619
|
+
className="marketplace-lakehouse-entitlements__data-contract-viewer__metadata__ordered-for__tooltip__icon"
|
|
620
|
+
title={
|
|
621
|
+
<>
|
|
622
|
+
Contract consumer type:{' '}
|
|
623
|
+
{getOrganizationalScopeTypeName(
|
|
624
|
+
consumer,
|
|
625
|
+
currentViewer.applicationStore.pluginManager.getApplicationPlugins(),
|
|
626
|
+
)}
|
|
627
|
+
{getOrganizationalScopeTypeDetails(
|
|
628
|
+
consumer,
|
|
629
|
+
currentViewer.applicationStore.pluginManager.getApplicationPlugins(),
|
|
630
|
+
)}
|
|
631
|
+
</>
|
|
523
632
|
}
|
|
524
|
-
size="small"
|
|
525
|
-
className="marketplace-lakehouse-entitlements__data-contract-viewer__metadata__ordered-for__select"
|
|
526
633
|
>
|
|
527
|
-
|
|
528
|
-
</
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
</Box>
|
|
539
|
-
{!isContractInTerminalState(currentViewer.value) && (
|
|
540
|
-
<Box className="marketplace-lakehouse-entitlements__data-contract-viewer__refresh-btn">
|
|
541
|
-
<Button
|
|
542
|
-
size="small"
|
|
543
|
-
variant="outlined"
|
|
544
|
-
startIcon={<RefreshIcon />}
|
|
545
|
-
onClick={() => {
|
|
546
|
-
// eslint-disable-next-line no-void
|
|
547
|
-
void refresh();
|
|
548
|
-
}}
|
|
549
|
-
>
|
|
550
|
-
Refresh
|
|
551
|
-
</Button>
|
|
552
|
-
</Box>
|
|
553
|
-
)}
|
|
554
|
-
<Box className="marketplace-lakehouse-entitlements__data-contract-viewer__timeline">
|
|
555
|
-
<Timeline>
|
|
556
|
-
{steps.map((step, index) => (
|
|
557
|
-
<TimelineItem key={step.key}>
|
|
558
|
-
<TimelineOppositeContent className="marketplace-lakehouse-entitlements__data-contract-viewer__timeline__content">
|
|
559
|
-
{step.label}
|
|
560
|
-
</TimelineOppositeContent>
|
|
561
|
-
<TimelineSeparator>
|
|
562
|
-
<TimelineDot
|
|
563
|
-
color={step.isDeniedStep ? 'error' : 'primary'}
|
|
564
|
-
variant={
|
|
565
|
-
step.isCompleteOrActive ? 'filled' : 'outlined'
|
|
566
|
-
}
|
|
634
|
+
<InfoCircleIcon />
|
|
635
|
+
</Tooltip>
|
|
636
|
+
:{' '}
|
|
637
|
+
</b>
|
|
638
|
+
{targetUsers !== undefined ? (
|
|
639
|
+
targetUsers.length === 1 ? (
|
|
640
|
+
<UserRenderer
|
|
641
|
+
key={targetUsers[0]}
|
|
642
|
+
userId={targetUsers[0]}
|
|
643
|
+
applicationStore={currentViewer.applicationStore}
|
|
644
|
+
userSearchService={currentViewer.userSearchService}
|
|
567
645
|
/>
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
646
|
+
) : (
|
|
647
|
+
<Select
|
|
648
|
+
value={selectedTargetUser}
|
|
649
|
+
onChange={(event) =>
|
|
650
|
+
setSelectedTargetUser(event.target.value)
|
|
651
|
+
}
|
|
652
|
+
size="small"
|
|
653
|
+
className="marketplace-lakehouse-entitlements__data-contract-viewer__metadata__ordered-for__select"
|
|
654
|
+
>
|
|
655
|
+
{targetUserSelectItems}
|
|
656
|
+
</Select>
|
|
657
|
+
)
|
|
658
|
+
) : (
|
|
659
|
+
stringifyOrganizationalScope(consumer)
|
|
660
|
+
)}
|
|
661
|
+
</div>
|
|
662
|
+
<div>
|
|
663
|
+
<b>Business Justification: </b>
|
|
664
|
+
{currentViewer.liteContract.description}
|
|
665
|
+
</div>
|
|
666
|
+
</Box>
|
|
667
|
+
{!isContractInTerminalState(currentViewer.liteContract) && (
|
|
668
|
+
<Box className="marketplace-lakehouse-entitlements__data-contract-viewer__refresh-btn">
|
|
669
|
+
<Button
|
|
670
|
+
size="small"
|
|
671
|
+
variant="outlined"
|
|
672
|
+
startIcon={<RefreshIcon />}
|
|
673
|
+
onClick={() => {
|
|
674
|
+
// eslint-disable-next-line no-void
|
|
675
|
+
void refresh();
|
|
676
|
+
}}
|
|
677
|
+
>
|
|
678
|
+
Refresh
|
|
679
|
+
</Button>
|
|
680
|
+
</Box>
|
|
681
|
+
)}
|
|
682
|
+
<Box className="marketplace-lakehouse-entitlements__data-contract-viewer__timeline">
|
|
683
|
+
<Timeline>
|
|
684
|
+
{steps.map((step, index) => (
|
|
685
|
+
<TimelineItem key={step.key}>
|
|
686
|
+
<TimelineOppositeContent className="marketplace-lakehouse-entitlements__data-contract-viewer__timeline__content">
|
|
687
|
+
{step.label}
|
|
688
|
+
</TimelineOppositeContent>
|
|
689
|
+
<TimelineSeparator>
|
|
690
|
+
<TimelineDot
|
|
691
|
+
color={step.isDeniedStep ? 'error' : 'primary'}
|
|
692
|
+
variant={
|
|
693
|
+
step.isCompleteOrActive ? 'filled' : 'outlined'
|
|
694
|
+
}
|
|
695
|
+
/>
|
|
696
|
+
{index < steps.length - 1 && <TimelineConnector />}
|
|
697
|
+
</TimelineSeparator>
|
|
698
|
+
<TimelineContent className="marketplace-lakehouse-entitlements__data-contract-viewer__timeline__content">
|
|
699
|
+
{step.description}
|
|
700
|
+
</TimelineContent>
|
|
701
|
+
</TimelineItem>
|
|
702
|
+
))}
|
|
703
|
+
</Timeline>
|
|
704
|
+
</Box>
|
|
705
|
+
</>
|
|
706
|
+
)}
|
|
707
|
+
<Box className="marketplace-lakehouse-entitlements__data-contract-viewer__footer">
|
|
708
|
+
Contract ID: {currentViewer.liteContract.guid}
|
|
709
|
+
<IconButton onClick={() => copyContractId()}>
|
|
710
|
+
<CopyIcon />
|
|
711
|
+
</IconButton>
|
|
712
|
+
</Box>
|
|
713
|
+
</DialogContent>
|
|
714
|
+
</Dialog>
|
|
715
|
+
<ContractEscalationModal
|
|
716
|
+
open={showEscalationModal && canEscalateContract}
|
|
717
|
+
onClose={() => setShowEscalationModal(false)}
|
|
718
|
+
currentViewer={currentViewer}
|
|
719
|
+
selectedUser={selectedTargetUser}
|
|
720
|
+
refresh={refresh}
|
|
721
|
+
/>
|
|
722
|
+
</>
|
|
584
723
|
);
|
|
585
724
|
},
|
|
586
725
|
);
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
import {
|
|
39
39
|
type V1_RelationTypeColumn,
|
|
40
40
|
extractElementNameFromPath,
|
|
41
|
+
V1_AccessPointGroupReference,
|
|
41
42
|
V1_AdHocDeploymentDataProductOrigin,
|
|
42
43
|
V1_AppliedFunction,
|
|
43
44
|
V1_AppliedProperty,
|
|
@@ -352,6 +353,27 @@ const AccessPointTable = observer(
|
|
|
352
353
|
}`
|
|
353
354
|
: '',
|
|
354
355
|
},
|
|
356
|
+
{
|
|
357
|
+
headerName: 'Column Sample Values',
|
|
358
|
+
flex: 1,
|
|
359
|
+
wrapText: true,
|
|
360
|
+
autoHeight: true,
|
|
361
|
+
valueGetter: (_params) => {
|
|
362
|
+
if (!_params.data || !accessPointState.relationElement) {
|
|
363
|
+
return 'No sample values provided';
|
|
364
|
+
}
|
|
365
|
+
const columnName = _params.data.name;
|
|
366
|
+
const columnIndex =
|
|
367
|
+
accessPointState.relationElement.columns.indexOf(columnName);
|
|
368
|
+
if (columnIndex === -1) {
|
|
369
|
+
return 'No sample values provided';
|
|
370
|
+
}
|
|
371
|
+
const sampleValues = accessPointState.relationElement.rows
|
|
372
|
+
.map((row) => row.values[columnIndex])
|
|
373
|
+
.filter((value) => value !== undefined);
|
|
374
|
+
return sampleValues.join(', ');
|
|
375
|
+
},
|
|
376
|
+
},
|
|
355
377
|
];
|
|
356
378
|
|
|
357
379
|
return (
|
|
@@ -456,13 +478,15 @@ const AccessPointTable = observer(
|
|
|
456
478
|
<Box className="data-product__viewer__more-info__container">
|
|
457
479
|
{selectedTab === DataProductTabs.COLUMNS && (
|
|
458
480
|
<>
|
|
459
|
-
{accessPointState.fetchingRelationTypeState.isInProgress
|
|
481
|
+
{accessPointState.fetchingRelationTypeState.isInProgress ||
|
|
482
|
+
accessPointState.fetchingRelationElement.isInProgress ? (
|
|
460
483
|
<Box className="data-product__viewer__more-info__loading-indicator">
|
|
461
484
|
<CubesLoadingIndicator isLoading={true}>
|
|
462
485
|
<CubesLoadingIndicatorIcon />
|
|
463
486
|
</CubesLoadingIndicator>
|
|
464
487
|
</Box>
|
|
465
|
-
) : accessPointState.fetchingRelationTypeState.hasCompleted
|
|
488
|
+
) : accessPointState.fetchingRelationTypeState.hasCompleted &&
|
|
489
|
+
accessPointState.fetchingRelationElement.hasCompleted ? (
|
|
466
490
|
<Box
|
|
467
491
|
className={clsx(
|
|
468
492
|
'data-product__viewer__more-info__columns-grid ag-theme-balham',
|
|
@@ -567,18 +591,25 @@ export const DataProductAccessPointGroupViewer = observer(
|
|
|
567
591
|
const requestAccessButtonGroupRef = useRef<HTMLDivElement | null>(null);
|
|
568
592
|
|
|
569
593
|
const entitlementsDataContractViewerState = useMemo(() => {
|
|
570
|
-
return dataAccessState?.dataContract
|
|
594
|
+
return dataAccessState?.dataContract &&
|
|
595
|
+
dataAccessState.dataContract.resource instanceof
|
|
596
|
+
V1_AccessPointGroupReference &&
|
|
597
|
+
dataAccessState.dataContract.resource.accessPointGroup ===
|
|
598
|
+
apgState.apg.id
|
|
571
599
|
? new EntitlementsDataContractViewerState(
|
|
572
600
|
V1_transformDataContractToLiteDatacontract(
|
|
573
601
|
dataAccessState.dataContract,
|
|
574
602
|
),
|
|
575
603
|
apgState.applicationStore,
|
|
576
604
|
dataAccessState.lakehouseContractServerClient,
|
|
605
|
+
apgState.dataProductViewerState.graphManagerState,
|
|
577
606
|
apgState.dataProductViewerState.userSearchService,
|
|
578
607
|
)
|
|
579
608
|
: undefined;
|
|
580
609
|
}, [
|
|
610
|
+
apgState.apg.id,
|
|
581
611
|
apgState.applicationStore,
|
|
612
|
+
apgState.dataProductViewerState.graphManagerState,
|
|
582
613
|
apgState.dataProductViewerState.userSearchService,
|
|
583
614
|
dataAccessState?.dataContract,
|
|
584
615
|
dataAccessState?.lakehouseContractServerClient,
|
|
@@ -821,7 +852,15 @@ export const DataProductAccessPointGroupViewer = observer(
|
|
|
821
852
|
open={true}
|
|
822
853
|
onClose={() => dataAccessState.setDataContract(undefined)}
|
|
823
854
|
currentViewer={entitlementsDataContractViewerState}
|
|
824
|
-
|
|
855
|
+
onRefresh={() => {
|
|
856
|
+
if (apgState.associatedUserContract) {
|
|
857
|
+
apgState.fetchUserAccessStatus(
|
|
858
|
+
apgState.associatedUserContract.guid,
|
|
859
|
+
dataAccessState.lakehouseContractServerClient,
|
|
860
|
+
auth.user?.access_token,
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
}}
|
|
825
864
|
getContractTaskUrl={dataAccessState.getContractTaskUrl}
|
|
826
865
|
getDataProductUrl={dataAccessState.getDataProductUrl}
|
|
827
866
|
/>
|