UNPKG

@finos/legend-application-marketplace

Version:
215 lines 18.8 kB
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