/** * Copyright (c) 2025-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 { LegendMarketplacePage } from '../LegendMarketplacePage.js'; import { useLegendMarketplaceDataAPIsStore, withLegendMarketplaceDataAPIsStore, } from '../../application/providers/LegendMarketplaceDataAPIsStoreProvider.js'; import { useCallback, useEffect, useRef } from 'react'; import { flowResult } from 'mobx'; import { CheckIcon, CubesLoadingIndicator, CubesLoadingIndicatorIcon, StarIcon, TableIcon, ViewHeadlineIcon, WindowIcon, clsx, } from '@finos/legend-art'; import { Container, FormControl, FormControlLabel, Grid, IconButton, MenuItem, Select, Switch, Typography, } from '@mui/material'; import { type LegendServiceCardState, LegendServiceSort, ServicesViewMode, } from '../../stores/dataAPIs/LegendMarketplaceDataAPIsStore.js'; import { LegendServiceCard } from '../../components/LegendServiceCard/LegendServiceCard.js'; import { LegendServiceListRow } from '../../components/LegendServiceCard/LegendServiceListRow.js'; import { LegendServiceGridView } from '../../components/LegendServiceCard/LegendServiceGrid.js'; import { PaginationControls } from '../../components/Pagination/PaginationControls.js'; import { DataAPIsFiltersPanel } from '../../components/DataAPIsFiltersPanel/DataAPIsFiltersPanel.js'; import { useSearchParams } from '@finos/legend-application/browser'; import { LEGEND_MARKETPLACE_DATA_APIS_QUERY_PARAM_TOKEN } from '../../__lib__/LegendMarketplaceNavigation.js'; import { LegendMarketplaceSearchBar } from '../../components/SearchBar/LegendMarketplaceSearchBar.js'; import { LegendMarketplaceTelemetryHelper } from '../../__lib__/LegendMarketplaceTelemetryHelper.js'; export const LegendMarketplaceDataAPIs = withLegendMarketplaceDataAPIsStore( observer(() => { const dataAPIsStore = useLegendMarketplaceDataAPIsStore(); const applicationStore = dataAPIsStore.marketplaceBaseStore.applicationStore; const [searchParams, setSearchParams] = useSearchParams(); const { viewMode } = dataAPIsStore; const pageRef = useRef(null); const queryFromUrl = searchParams.get( LEGEND_MARKETPLACE_DATA_APIS_QUERY_PARAM_TOKEN.QUERY, ); useEffect(() => { if (queryFromUrl) { dataAPIsStore.setSearchQuery(queryFromUrl); } flowResult(dataAPIsStore.fetchAllServices()).catch( applicationStore.alertUnhandledError, ); }, [dataAPIsStore, applicationStore, queryFromUrl]); const handlePageChange = useCallback( (page: number) => { dataAPIsStore.setPage(page); pageRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [dataAPIsStore], ); const handleItemsPerPageChange = useCallback( (itemsPerPage: number) => { dataAPIsStore.setItemsPerPage(itemsPerPage); }, [dataAPIsStore], ); const handleSearch = useCallback( (query: string | undefined) => { dataAPIsStore.setSearchQuery(query ?? ''); if (query) { LegendMarketplaceTelemetryHelper.logEvent_SearchServices( applicationStore.telemetryService, query, ); } setSearchParams((prev) => { const next = new URLSearchParams(prev); if (query) { next.set( LEGEND_MARKETPLACE_DATA_APIS_QUERY_PARAM_TOKEN.QUERY, query, ); } else { next.delete(LEGEND_MARKETPLACE_DATA_APIS_QUERY_PARAM_TOKEN.QUERY); } return next; }); }, [dataAPIsStore, setSearchParams, applicationStore], ); const handleServiceClick = useCallback( (serviceCardState: LegendServiceCardState) => { LegendMarketplaceTelemetryHelper.logEvent_ClickServiceCard( applicationStore.telemetryService, serviceCardState.service.pattern, serviceCardState.title, ); const legendServicesUrl = dataAPIsStore.marketplaceBaseStore.applicationStore.config .legendServicesUrl; if (legendServicesUrl) { const encodedPattern = serviceCardState.service.pattern .replace(/^\//, '') .replaceAll('/', '%2F'); applicationStore.navigationService.navigator.visitAddress( `${legendServicesUrl}/${encodedPattern}`, ); } }, [dataAPIsStore, applicationStore], ); const renderServiceView = (): React.ReactNode => { switch (viewMode) { case ServicesViewMode.LIST: return ( <>
{dataAPIsStore.paginatedServices.map((serviceCardState) => ( handleServiceClick(serviceCardState)} isFavorite={dataAPIsStore.isFavorite( serviceCardState.service.pattern, )} onToggleFavorite={() => dataAPIsStore.toggleFavorite( serviceCardState.service.pattern, ) } /> ))}
{dataAPIsStore.isLoading && ( )} ); case ServicesViewMode.GRID: return ( ); case ServicesViewMode.TILE: return ( {dataAPIsStore.paginatedServices.map((serviceCardState) => ( handleServiceClick(serviceCardState)} isFavorite={dataAPIsStore.isFavorite( serviceCardState.service.pattern, )} onToggleFavorite={() => dataAPIsStore.toggleFavorite( serviceCardState.service.pattern, ) } /> ))} {dataAPIsStore.isLoading && ( )} ); default: return null; } }; return (
handleSearch(query)} placeholder="Search Legend Services..." className="marketplace-data-apis__search-bar" enableAutosuggest={false} />
{dataAPIsStore.totalFilteredCount} Services
{ dataAPIsStore.setShowOwnServicesOnly(e.target.checked); }} size="small" /> } label="My Services" /> dataAPIsStore.setShowFavoritesOnly( !dataAPIsStore.showFavoritesOnly, ) } title={ dataAPIsStore.showFavoritesOnly ? 'Show all services' : 'Show favorites only' } size="small" >
{ dataAPIsStore.setViewMode(ServicesViewMode.TILE); LegendMarketplaceTelemetryHelper.logEvent_ToggleServicesViewMode( applicationStore.telemetryService, ServicesViewMode.TILE, ); }} title="Tile View" size="small" > { dataAPIsStore.setViewMode(ServicesViewMode.LIST); LegendMarketplaceTelemetryHelper.logEvent_ToggleServicesViewMode( applicationStore.telemetryService, ServicesViewMode.LIST, ); }} title="List View" size="small" > { dataAPIsStore.setViewMode(ServicesViewMode.GRID); LegendMarketplaceTelemetryHelper.logEvent_ToggleServicesViewMode( applicationStore.telemetryService, ServicesViewMode.GRID, ); }} title="Grid View" size="small" >
{dataAPIsStore.serviceCardStates.length > 0 && dataAPIsStore.totalFilteredCount === 0 ? (
No results found We couldn't find any Services matching your search. Try adjusting your search terms or clearing filters.
) : ( <>
{renderServiceView()}
{viewMode !== ServicesViewMode.GRID && ( )} )}
); }), );