@finos/legend-application-marketplace
Version:
Legend Marketplace application core
612 lines (570 loc) • 16.9 kB
text/typescript
/**
* 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 type { TelemetryService } from '@finos/legend-application';
import {
type V1_LiteDataContract,
V1_ResourceType,
type V1_ContractUserEventRecord,
type V1_EntitlementsLakehouseEnvironmentType,
} from '@finos/legend-graph';
import { LEGEND_MARKETPLACE_APP_EVENT } from './LegendMarketplaceAppEvent.js';
import { uuid } from '@finos/legend-shared';
import {
SEARCH_SESSION_KEY,
TELEMETRY_EVENT_STATUS,
type DATAPRODUCT_TYPE,
type MarketplaceUserSession,
} from '@finos/legend-extension-dsl-data-product';
export enum LEGEND_MARKETPLACE_PAGE {
HOME_PAGE = 'Home Page',
SEARCH_RESULTS_PAGE = 'Search Results Page',
}
export enum CONTRACT_ACTION {
APPROVED = 'approved',
DENIED = 'denied',
}
export enum ICON_TOOLBAR_TYPE {
USER = 'User Icon',
HELP = 'Help Icon',
}
type MarketplaceDataProductOrigin_TelemetryData = {
type: DATAPRODUCT_TYPE;
groupId?: string | undefined;
artifactId?: string | undefined;
versionId?: string | undefined;
path?: string | undefined;
};
type MarketplaceDataProduct_TelemetryData = {
origin?: MarketplaceDataProductOrigin_TelemetryData | undefined;
dataProductId?: string | undefined;
deploymentId?: number | undefined;
name?: string | undefined;
environmentClassification?:
| V1_EntitlementsLakehouseEnvironmentType
| undefined;
};
export class LegendMarketplaceTelemetryHelper {
private static getOrCreateUserSession(): MarketplaceUserSession {
const stored = localStorage.getItem(SEARCH_SESSION_KEY);
if (stored) {
const session = JSON.parse(stored) as MarketplaceUserSession;
return session;
} else {
const initialSession: MarketplaceUserSession = {
eventId: 0,
searchSessionId: undefined,
};
localStorage.setItem(SEARCH_SESSION_KEY, JSON.stringify(initialSession));
return initialSession;
}
}
private static updateSearchSessionId(
searchSessionId: string,
): MarketplaceUserSession {
const currentSession = this.getOrCreateUserSession();
const newSearchSession: MarketplaceUserSession = {
...currentSession,
searchSessionId: searchSessionId,
};
localStorage.setItem(SEARCH_SESSION_KEY, JSON.stringify(newSearchSession));
return newSearchSession;
}
static clearSearchSessionId(): MarketplaceUserSession {
const currentSession = this.getOrCreateUserSession();
const newSearchSession: MarketplaceUserSession = {
...currentSession,
searchSessionId: undefined,
};
if (currentSession.eventId !== 0) {
localStorage.setItem(
SEARCH_SESSION_KEY,
JSON.stringify(newSearchSession),
);
}
return newSearchSession;
}
private static updateEventId() {
const currentSession = this.getOrCreateUserSession();
const updatedSession: MarketplaceUserSession = {
...currentSession,
eventId: currentSession.eventId + 1,
};
localStorage.setItem(SEARCH_SESSION_KEY, JSON.stringify(updatedSession));
return updatedSession;
}
static logEvent_ClickingDataProductCard(
telemetryService: TelemetryService,
dataProductData: MarketplaceDataProduct_TelemetryData,
clickedFrom: LEGEND_MARKETPLACE_PAGE,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.CLICK_DATA_PRODUCT_CARD,
{
...dataProductData,
clickedFrom: clickedFrom,
...session,
},
);
}
static logEvent_SearchQuery(
telemetryService: TelemetryService,
query: string | undefined,
useProducerSearch: boolean,
searchedFrom: LEGEND_MARKETPLACE_PAGE,
useFieldSearch: boolean = false,
): void {
this.updateSearchSessionId(uuid());
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.SEARCH_QUERY, {
query,
useProducerSearch,
useFieldSearch,
searchedFrom,
...session,
});
}
static logEvent_ActionDataContracts(
telemetryService: TelemetryService,
selectedContracts: V1_ContractUserEventRecord[],
pendingTaskContracts: V1_LiteDataContract[] | undefined,
action: CONTRACT_ACTION,
actionTakenBy: string,
errors: string[] | undefined,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
const actionedContractsDetails = selectedContracts.map((contract) => {
const dataContract = pendingTaskContracts?.find(
(c) => c.guid === contract.dataContractId,
);
const accessPointGroup =
dataContract?.resourceType === V1_ResourceType.ACCESS_POINT_GROUP
? dataContract.accessPointGroup
: `${dataContract?.accessPointGroup ?? 'Unknown'} (${dataContract?.resourceType ?? 'Unknown Type'})`;
return {
taskId: contract.taskId,
dataContractId: contract.dataContractId,
consumer: contract.consumer,
type: contract.type,
targetDataProduct: dataContract?.resourceId ?? 'Unknown',
targetAccessPointGroup: accessPointGroup ?? 'Unknown',
requester: dataContract?.createdBy,
...session,
};
});
const data =
errors === undefined
? {
actionedContractsDetails: actionedContractsDetails,
action: action,
actionTakenBy: actionTakenBy,
status: TELEMETRY_EVENT_STATUS.SUCCESS,
}
: {
actionedContractsDetails: actionedContractsDetails,
action: action,
actionTakenBy: actionTakenBy,
status: TELEMETRY_EVENT_STATUS.FAILURE,
errors: errors,
};
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.ACTION_DATA_CONTRACTS,
data,
);
}
static logEvent_LoadDataProduct(
telemetryService: TelemetryService,
dataProductData: MarketplaceDataProduct_TelemetryData,
error: string | undefined,
): void {
const telemetryData =
error === undefined
? { ...dataProductData, status: TELEMETRY_EVENT_STATUS.SUCCESS }
: {
...dataProductData,
status: TELEMETRY_EVENT_STATUS.FAILURE,
error: error,
};
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.LOAD_DATA_PRODUCT,
telemetryData,
);
}
static logEvent_LoadSDLCDataProduct(
telemetryService: TelemetryService,
dataProductData: MarketplaceDataProduct_TelemetryData,
error: string | undefined,
): void {
const telemetryData =
error === undefined
? { ...dataProductData, status: TELEMETRY_EVENT_STATUS.SUCCESS }
: {
...dataProductData,
status: TELEMETRY_EVENT_STATUS.FAILURE,
error: error,
};
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.LOAD_SDLC_DATA_PRODUCT,
telemetryData,
);
}
static logEvent_LoadTerminal(
telemetryService: TelemetryService,
terminalId: string,
error: string | undefined,
): void {
const telemetryData =
error === undefined
? { terminalId: terminalId, status: TELEMETRY_EVENT_STATUS.SUCCESS }
: {
terminalId: terminalId,
status: TELEMETRY_EVENT_STATUS.FAILURE,
error: error,
};
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.LOAD_TERMINAL,
telemetryData,
);
}
static logEvent_LoadLegacyDataProduct(
telemetryService: TelemetryService,
groupId: string,
artifactId: string,
versionId: string,
path: string,
error: string | undefined,
): void {
const telemetryData =
error === undefined
? {
groupId: groupId,
artifactId: artifactId,
versionId: versionId,
path: path,
status: TELEMETRY_EVENT_STATUS.SUCCESS,
}
: {
groupId: groupId,
artifactId: artifactId,
versionId: versionId,
path: path,
status: TELEMETRY_EVENT_STATUS.FAILURE,
error: error,
};
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.LOAD_LEGACY_DATA_PRODUCT,
telemetryData,
);
}
static logEvent_ClickHeadertab(
telemetryService: TelemetryService,
tabTitle: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.CLICK_HEADER_TAB, {
tabTitle: tabTitle,
...session,
});
}
static logEvent_ToggleProducerSearch(
telemetryService: TelemetryService,
isEnabled: boolean,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.PRODUCER_SEARCH_TOGGLE,
{
toggleAction: isEnabled ? 'enabled' : 'disabled',
...session,
},
);
}
static logEvent_ToggleFieldSearch(
telemetryService: TelemetryService,
isEnabled: boolean,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.FIELD_SEARCH_TOGGLE,
{
toggleAction: isEnabled ? 'enabled' : 'disabled',
...session,
},
);
}
static logEvent_ToggleThemeMode(
telemetryService: TelemetryService,
isDarkMode: boolean,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.TOGGLE_THEME_MODE, {
currentTheme: isDarkMode ? 'dark' : 'light',
...session,
});
}
static logEvent_ToggleViewMode(
telemetryService: TelemetryService,
viewMode: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.TOGGLE_VIEW_MODE, {
viewMode,
...session,
});
}
static logEvent_ToggleServicesViewMode(
telemetryService: TelemetryService,
viewMode: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.TOGGLE_SERVICES_VIEW_MODE,
{
viewMode,
...session,
},
);
}
static logEvent_ClickToolbarMenu(
telemetryService: TelemetryService,
iconSource: ICON_TOOLBAR_TYPE,
menuTitle: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.CLICK_TOOLBAR_MENU, {
iconSource: iconSource,
menuTitle: menuTitle,
...session,
});
}
static logEvent_SearchAutosuggestSelection(
telemetryService: TelemetryService,
query: string,
suggestionType: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.SEARCH_AUTOSUGGEST_SELECTION,
{
query: query,
suggestionType: suggestionType,
...session,
},
);
}
static logEvent_DismissHomePageBanner(
telemetryService: TelemetryService,
bannerId: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.DISMISS_HOME_PAGE_BANNER,
{
bannerId: bannerId,
...session,
},
);
}
static logEvent_SubmitFeedback(
telemetryService: TelemetryService,
originPage: string,
rating: number,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.SUBMIT_FEEDBACK, {
originPage: originPage,
rating: rating,
...session,
});
}
static logEvent_ClickQueryDataProduct(
telemetryService: TelemetryService,
groupId: string,
artifactId: string,
versionId: string,
path: string,
executionContextKey: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.CLICK_QUERY_DATA_PRODUCT,
{
groupId: groupId,
artifactId: artifactId,
versionId: versionId,
path: path,
executionContextKey: executionContextKey,
...session,
},
);
}
static logEvent_ClickOpenServiceQuery(
telemetryService: TelemetryService,
groupId: string,
artifactId: string,
versionId: string,
servicePath: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.CLICK_OPEN_SERVICE_QUERY,
{
groupId: groupId,
artifactId: artifactId,
versionId: versionId,
servicePath: servicePath,
...session,
},
);
}
static logEvent_ClickQuickStartExtensionTab(
telemetryService: TelemetryService,
groupId: string,
artifactId: string,
versionId: string,
path: string,
tabKey: string,
executableTitle: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.CLICK_QUICKSTART_EXTENSION_TAB,
{
groupId: groupId,
artifactId: artifactId,
versionId: versionId,
path: path,
tabKey: tabKey,
executableTitle: executableTitle,
...session,
},
);
}
static logEvent_ApplySearchFilter(
telemetryService: TelemetryService,
filterType: string,
filterValue: string,
action: 'select' | 'deselect',
searchQuery: string | undefined,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.APPLY_SEARCH_FILTER,
{
filterType,
filterValue,
action,
searchQuery,
...session,
},
);
}
static logEvent_ClearSearchFilters(
telemetryService: TelemetryService,
searchQuery: string | undefined,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.CLEAR_SEARCH_FILTERS,
{
searchQuery,
...session,
},
);
}
static logEvent_ShowAllDataProducts(
telemetryService: TelemetryService,
searchQuery: string | undefined,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(
LEGEND_MARKETPLACE_APP_EVENT.SHOW_ALL_DATA_PRODUCTS,
{
searchQuery,
...session,
},
);
}
static logEvent_SearchServices(
telemetryService: TelemetryService,
query: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.SEARCH_SERVICES, {
query,
...session,
});
}
static logEvent_SortServices(
telemetryService: TelemetryService,
sortValue: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.SORT_SERVICES, {
sortValue,
...session,
});
}
static logEvent_FilterServices(
telemetryService: TelemetryService,
filterType: string,
filterValue: string,
action: 'add' | 'remove' | 'clear',
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.FILTER_SERVICES, {
filterType,
filterValue,
action,
...session,
});
}
static logEvent_ClickServiceCard(
telemetryService: TelemetryService,
pattern: string,
title: string,
): void {
this.updateEventId();
const session = this.getOrCreateUserSession();
telemetryService.logEvent(LEGEND_MARKETPLACE_APP_EVENT.CLICK_SERVICE_CARD, {
pattern,
title,
...session,
});
}
}