diff --git a/src/types/window.d.ts b/src/types/window.d.ts index 0b9398ec28..8bc682785c 100644 --- a/src/types/window.d.ts +++ b/src/types/window.d.ts @@ -44,4 +44,6 @@ interface Window { systemSettings?: import('../services/settings').SettingsObject; api: import('../services/api/index').YdbEmbeddedAPI; + + [key: `yaCounter${number}`]: any; } diff --git a/src/uiFactory/types.ts b/src/uiFactory/types.ts index d4502a7583..6818a39e84 100644 --- a/src/uiFactory/types.ts +++ b/src/uiFactory/types.ts @@ -43,6 +43,7 @@ export interface UIFactory { countHealthcheckIssuesByType: (issueTrees: IssuesTree[]) => Record; }; hasAccess?: boolean; + yaMetricaMap?: Record; } export type HandleCreateDB = (params: {clusterName: string}) => Promise; diff --git a/src/utils/yaMetrica.ts b/src/utils/yaMetrica.ts new file mode 100644 index 0000000000..b6465eee4b --- /dev/null +++ b/src/utils/yaMetrica.ts @@ -0,0 +1,75 @@ +import {uiFactory} from '../uiFactory/uiFactory'; + +/** + * Interface for a counter that provides methods for tracking metrics. + * + * @method hit - Tracks a hit event with optional arguments. https://yandex.ru/support/metrica/ru/objects/hit + * @method params - Sets parameters for the counter with optional arguments. https://yandex.ru/support/metrica/ru/objects/params-method + * @method userParams - Sets user-specific parameters for the counter with optional arguments. https://yandex.ru/support/metrica/ru/objects/user-params + * @method reachGoal - Tracks a goal achievement event with optional arguments. https://yandex.ru/support/metrica/ru/objects/reachgoal + */ +export interface Counter { + hit: (...args: unknown[]) => void; + params: (...args: unknown[]) => void; + userParams: (...args: unknown[]) => void; + reachGoal: (...args: unknown[]) => void; +} + +const yaMetricaMap = uiFactory.yaMetricaMap; + +/** + * A fake implementation of a counter metric for Yandex.Metrica. + * This class is used when the actual Yandex.Metrica counter is not defined, + * and it provides a warning message the first time any of its methods are called. + * + * @property name - The name of the counter. + * @property warnShown - Flag to indicate if the warning has been shown. + */ +class FakeMetrica implements Counter { + name: string; + + private warnShown = false; + + constructor(name: string) { + this.name = name; + } + + hit() { + this.warnOnce(); + } + + params() { + this.warnOnce(); + } + + userParams() { + this.warnOnce(); + } + + reachGoal() { + this.warnOnce(); + } + + private warnOnce() { + if (!this.warnShown) { + console.warn(`Yandex.Metrica counter "${this.name}" is not defined\n`); + this.warnShown = true; + } + } +} + +/** + * Retrieves a Yandex Metrica instance by name from the global window object. + * If no instance is found for the given name, returns a FakeMetrica instance instead. + * + * @param name The name of the metrica to retrieve + * @returns The Yandex Metrica instance if found, otherwise a FakeMetrica instance + */ +export function getMetrica(name: string) { + const yaMetricaId = yaMetricaMap?.[name]; + const metricaInstance = yaMetricaId + ? (window[`yaCounter${yaMetricaId}`] as Counter) + : undefined; + + return metricaInstance ?? new FakeMetrica(name); +}