/** * 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 { TerminalResult, TraderProfile, type Filter, type MarketplaceServerClient, type TerminalServicesResponse, ProductType, type FetchProductsParams, } from '@finos/legend-server-marketplace'; import { action, flow, flowResult, makeObservable, observable } from 'mobx'; import type { LegendMarketplaceApplicationStore, LegendMarketplaceBaseStore, } from './LegendMarketplaceBaseStore.js'; import { ActionState, type GeneratorFn, LegendUser, assertErrorThrown, } from '@finos/legend-shared'; export enum VendorDataProviderType { ALL = 'All', TERMINAL_LICENSE = 'Terminal License', ADD_ONS = 'Add-Ons', ORDER_PROFILE = 'Order Profile', } export class LegendMarketPlaceVendorDataStore { readonly applicationStore: LegendMarketplaceApplicationStore; readonly store: LegendMarketplaceBaseStore; marketplaceServerClient: MarketplaceServerClient; selectedUser: LegendUser = new LegendUser(); readonly fetchingProvidersState = ActionState.create(); terminalProviders: TerminalResult[] = []; addOnProviders: TerminalResult[] = []; traderProfileProviders: TraderProfile[] = []; providers: TerminalResult[] = []; traderProfileAllProviders: TraderProfile[] = []; ownedPermissions: TerminalResult[] = []; page = 1; itemsPerPage = 24; totalTerminalItems = 0; totalAddOnItems = 0; totalTraderProfileItems = 0; totalItems = 0; totalOwnedPermissions = 0; searchTerm = ''; providersFilters: Filter[] = []; providerDisplayState: VendorDataProviderType = VendorDataProviderType.ALL; constructor( applicationStore: LegendMarketplaceApplicationStore, store: LegendMarketplaceBaseStore, ) { makeObservable(this, { selectedUser: observable, terminalProviders: observable, addOnProviders: observable, traderProfileProviders: observable, providers: observable, traderProfileAllProviders: observable, ownedPermissions: observable, page: observable, itemsPerPage: observable, totalTerminalItems: observable, totalAddOnItems: observable, totalTraderProfileItems: observable, totalItems: observable, totalOwnedPermissions: observable, searchTerm: observable, providerDisplayState: observable, providersFilters: observable, setProviderDisplayState: action, setProvidersFilters: action, setPage: action, setItemsPerPage: action, setSearchTerm: action, setSelectedUser: action, resetSelectedUser: action, init: flow, refresh: flow, populateProviders: flow, }); this.applicationStore = applicationStore; this.store = store; this.marketplaceServerClient = store.marketplaceServerClient; } *init(): GeneratorFn { try { this.selectedUser = new LegendUser(); this.selectedUser.id = this.applicationStore.identityService.currentUser; } catch (error) { this.applicationStore.notificationService.notifyError( `Failed to get current user: ${error}`, ); } this.refresh(); } *refresh(): GeneratorFn { try { yield flowResult(this.populateProviders()); } catch (error) { assertErrorThrown(error); this.applicationStore.notificationService.notifyError( `Failed to initialize vendors: ${error.message}`, ); } } setProviderDisplayState(value: VendorDataProviderType): void { this.providerDisplayState = value; this.page = 1; } setProvidersFilters(value: Filter[]): void { this.providersFilters = value; this.page = 1; } setPage(value: number): void { this.page = value; } setItemsPerPage(value: number): void { this.itemsPerPage = value; this.page = 1; } setSearchTerm(value: string): void { this.searchTerm = value; this.page = 1; } setSelectedUser(user: LegendUser): void { this.selectedUser = user; this.refresh(); } resetSelectedUser(): void { this.selectedUser = new LegendUser(); this.selectedUser.id = this.applicationStore.identityService.currentUser; this.refresh(); } *populateProviders(): GeneratorFn { try { this.fetchingProvidersState.inProgress(); if (this.providerDisplayState === VendorDataProviderType.ALL) { const params: FetchProductsParams = { kerberos: this.selectedUser.id, product_type: ProductType.ALL, preferred_products: true, page_size: this.itemsPerPage, search: this.searchTerm, }; const response = (yield this.marketplaceServerClient.fetchProducts( params, )) as TerminalServicesResponse; this.terminalProviders = (response.vendor_profiles ?? []).map((json) => TerminalResult.serialization.fromJson(json), ); this.addOnProviders = (response.service_pricing ?? []).map((json) => TerminalResult.serialization.fromJson(json), ); this.traderProfileProviders = (response.order_profile ?? []).map( (json) => TraderProfile.serialization.fromJson(json), ); this.totalTerminalItems = response.vendor_profiles_total_count ?? 0; this.totalAddOnItems = response.service_pricing_total_count ?? 0; this.totalTraderProfileItems = response.order_profile_total_count ?? 0; } else if ( this.providerDisplayState === VendorDataProviderType.TERMINAL_LICENSE ) { const params: FetchProductsParams = { kerberos: this.selectedUser.id, product_type: ProductType.VENDOR_PROFILE, preferred_products: false, page_size: this.itemsPerPage, search: this.searchTerm, page_number: this.page, }; const response = (yield this.marketplaceServerClient.fetchProducts( params, )) as TerminalServicesResponse; const terminalLicenseResponse = response as TerminalServicesResponse & { ownedPermissions?: unknown[]; ownedPermissionsCount?: number; }; this.providers = (response.vendor_profiles ?? []).map((json) => TerminalResult.serialization.fromJson(json), ); this.ownedPermissions = ( terminalLicenseResponse.ownedPermissions ?? [] ).map((json: unknown) => TerminalResult.serialization.fromJson( json as Record, ), ); this.totalItems = response.total_count ?? 0; this.totalOwnedPermissions = terminalLicenseResponse.ownedPermissionsCount ?? this.ownedPermissions.length; } else if (this.providerDisplayState === VendorDataProviderType.ADD_ONS) { const params: FetchProductsParams = { kerberos: this.selectedUser.id, product_type: ProductType.SERVICE_PRICING, preferred_products: false, page_size: this.itemsPerPage, search: this.searchTerm, page_number: this.page, }; const response = (yield this.marketplaceServerClient.fetchProducts( params, )) as TerminalServicesResponse; this.providers = (response.service_pricing ?? []).map((json) => TerminalResult.serialization.fromJson(json), ); this.totalItems = response.total_count ?? 0; } else { // ORDER_PROFILE const params: FetchProductsParams = { kerberos: this.selectedUser.id, product_type: ProductType.ORDER_PROFILE, preferred_products: false, page_size: this.itemsPerPage, search: this.searchTerm, page_number: this.page, }; const response = (yield this.marketplaceServerClient.fetchProducts( params, )) as TerminalServicesResponse; this.traderProfileAllProviders = (response.order_profile ?? []).map( (json) => TraderProfile.serialization.fromJson(json), ); this.totalItems = response.total_count ?? 0; } this.fetchingProvidersState.complete(); } catch (error) { assertErrorThrown(error); this.applicationStore.notificationService.notifyError( `Failed to fetch vendors: ${error.message}`, ); this.fetchingProvidersState.fail(); } } }