@finos/legend-application-marketplace
Version:
Legend Marketplace application core
215 lines • 18.8 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { observer } from 'mobx-react-lite';
import { Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, FormControl, IconButton, InputLabel, ListSubheader, MenuItem, Select, TextField, } from '@mui/material';
import { V1_AWSSnowflakeIngestEnvironment, V1_DataContract, V1_DataSubscriptionTargetType, V1_SnowflakeNetwork, V1_SnowflakeRegion, V1_SnowflakeTarget, } from '@finos/legend-graph';
import React, { useEffect, useState } from 'react';
import { isNonNullable, isType, LegendUser } from '@finos/legend-shared';
import { getUserById } from '../../../stores/lakehouse/LakehouseUtils.js';
import { useLegendMarketplaceBaseStore } from '../../../application/LegendMarketplaceFrameworkProvider.js';
import { useAuth } from 'react-oidc-context';
import { CloseIcon, CubesLoadingIndicator, CubesLoadingIndicatorIcon, UserDisplay, } from '@finos/legend-art';
import { DataGrid, } from '@finos/legend-lego/data-grid';
import { flowResult } from 'mobx';
import { useParams } from '@finos/legend-application/browser';
import { LEGEND_MARKETPLACE_ROUTE_PATTERN_TOKEN, } from '../../../__lib__/LegendMarketplaceNavigation.js';
const UserCellRenderer = (props) => {
const { userId, userDataMap, navigationService, isLoading, userProfileImageUrl, applicationDirectoryUrl, } = props;
const userData = userId ? userDataMap.get(userId) : undefined;
if (isLoading) {
return _jsx(CircularProgress, { size: 20 });
}
else if (userData instanceof LegendUser) {
const imgSrc = userProfileImageUrl?.replace('{userId}', userData.id);
const openUserDirectoryLink = () => navigationService.navigator.visitAddress(`${applicationDirectoryUrl}/${userId}`);
return (_jsx(UserDisplay, { user: userData, imgSrc: imgSrc, onClick: () => openUserDirectoryLink(), className: "marketplace-lakehouse-subscriptions__subscriptions-viewer__grid__user-display" }));
}
else if (userData) {
return _jsx(_Fragment, { children: userData });
}
else {
return _jsx(_Fragment, { children: userId });
}
};
const LakehouseSubscriptionsCreateDialog = observer((props) => {
const { open, onClose, accessGroupState, contractId, onSubmit } = props;
const [targetType] = useState(V1_DataSubscriptionTargetType.Snowflake);
const [snowflakeAccountId, setSnowflakeAccountId] = useState('');
const [snowflakeRegion] = useState(V1_SnowflakeRegion.AWS_US_EAST_1);
const [snowflakeNetwork] = useState(V1_SnowflakeNetwork.GOLDMAN);
const handleClose = () => {
setSnowflakeAccountId('');
onClose();
};
// TODO: Figure out better way to get the preferred list of snowflake accounts instead
// of relying upon ingest environment URN in the URL
const params = useParams();
const ingestEnvironmentUrn = params[LEGEND_MARKETPLACE_ROUTE_PATTERN_TOKEN.ingestEnvironmentUrn];
const environmentDetails = accessGroupState.accessState.viewerState.lakehouseStore
.lakehouseIngestEnvironmentDetails;
const suggestedSnowflakeAccounts = Array.from(new Set(environmentDetails
.filter((details) => isType(details, V1_AWSSnowflakeIngestEnvironment))
.filter((details) => details.urn === ingestEnvironmentUrn)
.map((ingestEnvironmentDetails) => ingestEnvironmentDetails.snowflakeAccount)));
const otherSnowflakeAccounts = Array.from(new Set(environmentDetails
.filter((details) => isType(details, V1_AWSSnowflakeIngestEnvironment))
.map((ingestEnvironmentDetails) => ingestEnvironmentDetails.snowflakeAccount)
.filter((account) => !suggestedSnowflakeAccounts.includes(account))));
return (_jsxs(Dialog, { open: open, onClose: onClose, className: "marketplace-lakehouse-subscriptions__subscription-creator", slotProps: {
paper: {
component: 'form',
onSubmit: (event) => {
event.preventDefault();
if (targetType === V1_DataSubscriptionTargetType.Snowflake) {
const snowflakeTarget = new V1_SnowflakeTarget();
snowflakeTarget.snowflakeAccountId = snowflakeAccountId;
snowflakeTarget.snowflakeRegion = snowflakeRegion;
snowflakeTarget.snowflakeNetwork = snowflakeNetwork;
// eslint-disable-next-line no-void
void onSubmit(snowflakeTarget);
handleClose();
}
else {
handleClose();
throw new Error(`Unsupported target type: ${targetType}`);
}
},
},
}, children: [_jsx(DialogTitle, { children: "Create New Subscription" }), _jsxs(DialogContent, { children: [_jsx(TextField, { required: true, margin: "dense", id: "contractId", name: "contractId", label: "Contract ID", fullWidth: true, variant: "outlined", value: contractId, disabled: true }), _jsxs(FormControl, { fullWidth: true, margin: "dense", children: [_jsx(InputLabel, { id: "target-type-select-label", children: "Target Type" }), _jsx(Select, { required: true, labelId: "target-type-select-label", id: "target-type-select", value: targetType, label: "Target Type", disabled: true, children: Object.values(V1_DataSubscriptionTargetType).map((_targetType) => (_jsx(MenuItem, { value: _targetType, children: _targetType }, _targetType))) })] }), _jsxs(FormControl, { fullWidth: true, margin: "dense", children: [_jsx(InputLabel, { id: "snowflake-account-id-select-label", children: "Snowflake Account ID" }), _jsxs(Select, { required: true, labelId: "snowflake-account-id-select-label", id: "snowflake-account-id-select", value: snowflakeAccountId, label: "Snowflake Account ID", onChange: (event) => {
setSnowflakeAccountId(event.target.value);
}, autoFocus: true, children: [suggestedSnowflakeAccounts.length > 0 && (_jsx(ListSubheader, { className: "marketplace-lakehouse-subscriptions__subscription-creator__select__subheader", children: "Suggested Accounts" })), suggestedSnowflakeAccounts.map((snowflakeAccount) => (_jsx(MenuItem, { value: snowflakeAccount, className: "marketplace-lakehouse-subscriptions__subscription-creator__select__item", children: snowflakeAccount }, snowflakeAccount))), suggestedSnowflakeAccounts.length > 0 &&
otherSnowflakeAccounts.length > 0 && (_jsx(ListSubheader, { className: "marketplace-lakehouse-subscriptions__subscription-creator__select__subheader", children: "Other Accounts" })), otherSnowflakeAccounts.map((snowflakeAccount) => (_jsx(MenuItem, { value: snowflakeAccount, className: "marketplace-lakehouse-subscriptions__subscription-creator__select__item", children: snowflakeAccount }, snowflakeAccount)))] })] }), _jsxs(FormControl, { fullWidth: true, margin: "dense", children: [_jsx(InputLabel, { id: "snowflake-region-select-label", children: "Snowflake Region" }), _jsx(Select, { required: true, labelId: "snowflake-region-select-label", id: "snowflake-region-select", value: snowflakeRegion, label: "Snowflake Region", disabled: true, children: Object.values(V1_SnowflakeRegion).map((region) => (_jsx(MenuItem, { value: region, children: region }, region))) })] }), _jsxs(FormControl, { fullWidth: true, margin: "dense", children: [_jsx(InputLabel, { id: "snowflake-network-select-label", children: "Snowflake Network" }), _jsx(Select, { required: true, labelId: "snowflake-network-select-label", id: "snowflake-network-select", value: snowflakeNetwork, label: "Snowflake Network", disabled: true, children: Object.values(V1_SnowflakeNetwork).map((_snowflakeNetwork) => (_jsx(MenuItem, { value: _snowflakeNetwork, children: _snowflakeNetwork }, _snowflakeNetwork))) })] })] }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: handleClose, variant: "outlined", children: "Cancel" }), _jsx(Button, { type: "submit", variant: "contained", children: "Create Subsciption" })] })] }));
});
export const DataProductSubscriptionViewer = observer((props) => {
const { open, accessGroupState, onClose } = props;
const auth = useAuth();
const legendMarketplaceStore = useLegendMarketplaceBaseStore();
const [userDataMap, setUserDataMap] = useState(new Map());
const [isLoadingUserData, setIsLoadingUserData] = useState(false);
const [showCreateDialog, setShowCreateDialog] = useState(false);
useEffect(() => {
const fetchUserData = async (userIds) => {
const userSearchService = legendMarketplaceStore.userSearchService;
if (userSearchService) {
setIsLoadingUserData(true);
try {
const users = (await Promise.all(userIds.map(async (userId) => getUserById(userId, userSearchService)))).filter(isNonNullable);
const userMap = new Map();
users.forEach((user) => {
userMap.set(user.id, user);
});
setUserDataMap(userMap);
}
finally {
setIsLoadingUserData(false);
}
}
};
const userIds = accessGroupState.subscriptions.map((subscription) => subscription.createdBy);
// eslint-disable-next-line no-void
void fetchUserData(userIds);
}, [
accessGroupState.subscriptions,
legendMarketplaceStore.userSearchService,
]);
const contract = accessGroupState.associatedContract;
const subscriptions = accessGroupState.subscriptions;
const isLoading = accessGroupState.fetchingSubscriptionsState.isInProgress;
if (!(contract instanceof V1_DataContract)) {
return (_jsxs(Dialog, { open: open, onClose: onClose, fullWidth: true, maxWidth: "md", children: [_jsx(DialogTitle, { children: "Data Product Subscriptions" }), _jsx(IconButton, { onClick: onClose, className: "marketplace-dialog-close-btn", children: _jsx(CloseIcon, {}) }), _jsxs(DialogContent, { children: [_jsxs("div", { children: ["Unable to show subscriptions for", ' ', _jsx("span", { className: "marketplace-lakehouse-text__emphasis", children: accessGroupState.group.id }), ' ', "Access Point Group in", ' ', _jsx("span", { className: "marketplace-lakehouse-text__emphasis", children: accessGroupState.accessState.viewerState.product.name }), ' ', "Data Product."] }), _jsx("div", { children: "No contract found for Access Point Group." })] })] }));
}
const createDialogHandleSubmit = async (target) => {
await flowResult(accessGroupState.createSubscription(contract.guid, target, auth.user?.access_token));
};
return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: open, onClose: onClose, fullWidth: true, maxWidth: "md", children: [_jsx(DialogTitle, { children: "Data Product Subscriptions" }), _jsx(IconButton, { onClick: onClose, className: "marketplace-dialog-close-btn", children: _jsx(CloseIcon, {}) }), _jsxs(DialogContent, { className: "marketplace-lakehouse-subscriptions__subscriptions-viewer__content", children: [_jsx(CubesLoadingIndicator, { isLoading: isLoading, children: _jsx(CubesLoadingIndicatorIcon, {}) }), !isLoading && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "marketplace-lakehouse-subscriptions__subscriptions-viewer__description", children: ["Subscriptions for", ' ', _jsx("span", { className: "marketplace-lakehouse-text__emphasis", children: accessGroupState.group.id }), ' ', "Access Point Group in", ' ', _jsx("span", { className: "marketplace-lakehouse-text__emphasis", children: accessGroupState.accessState.viewerState.product.name }), ' ', "Data Product"] }), _jsx(Button, { onClick: () => setShowCreateDialog(true), variant: "contained", className: "marketplace-lakehouse-subscriptions__subscriptions-viewer__create-btn", children: "Create New Subscription" }), _jsx(Box, { className: "marketplace-lakehouse-subscriptions__subscriptions-viewer__grid ag-theme-balham", children: _jsx(DataGrid, { rowData: subscriptions, onRowDataUpdated: (params) => {
params.api.refreshCells({ force: true });
}, suppressFieldDotNotation: true, suppressContextMenu: false, rowHeight: 45, columnDefs: [
{
minWidth: 50,
sortable: true,
resizable: true,
headerName: 'Target Type',
valueGetter: (p) => p.data?.target instanceof V1_SnowflakeTarget
? 'Snowflake'
: 'Unknown',
flex: 1,
},
{
minWidth: 50,
sortable: true,
resizable: true,
headerName: 'Snowflake Account ID',
valueGetter: (p) => p.data?.target instanceof V1_SnowflakeTarget
? p.data.target.snowflakeAccountId
: 'Unknown',
flex: 1,
},
{
minWidth: 50,
sortable: true,
resizable: true,
headerName: 'Snowflake Region',
valueGetter: (p) => p.data?.target instanceof V1_SnowflakeTarget
? p.data.target.snowflakeRegion
: 'Unknown',
flex: 1,
},
{
minWidth: 50,
sortable: true,
resizable: true,
headerName: 'Snowflake Network',
valueGetter: (p) => p.data?.target instanceof V1_SnowflakeTarget
? p.data.target.snowflakeNetwork
: 'Unknown',
flex: 1,
},
{
minWidth: 50,
sortable: true,
resizable: true,
headerName: 'Created By',
cellRenderer: (params) => {
return (_jsx(UserCellRenderer, { userId: params.data?.createdBy, userDataMap: userDataMap, navigationService: legendMarketplaceStore.applicationStore
.navigationService, isLoading: isLoadingUserData, userProfileImageUrl: legendMarketplaceStore.applicationStore.config
.marketplaceUserProfileImageUrl, applicationDirectoryUrl: legendMarketplaceStore.applicationStore.config
.lakehouseEntitlementsConfig
?.applicationDirectoryUrl }));
},
flex: 2,
},
{
minWidth: 50,
sortable: true,
resizable: true,
headerName: 'Subscription Id',
valueGetter: (p) => p.data?.guid,
flex: 1,
hide: true,
},
{
minWidth: 50,
sortable: true,
resizable: true,
headerName: 'Contract ID',
valueGetter: (p) => p.data?.dataContractId,
flex: 1,
hide: true,
},
] }) })] }))] })] }), _jsx(LakehouseSubscriptionsCreateDialog, { open: showCreateDialog, onClose: () => setShowCreateDialog(false), accessGroupState: accessGroupState, contractId: contract.guid, onSubmit: createDialogHandleSubmit })] }));
});
//# sourceMappingURL=DataProductSubscriptionsViewer.js.map