@procore/ai-translations 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.internal.md +257 -0
- package/README.md +159 -1
- package/dist/legacy/index.d.mts +105 -1
- package/dist/legacy/index.d.ts +105 -1
- package/dist/legacy/index.js +171 -14
- package/dist/legacy/index.mjs +159 -9
- package/dist/modern/index.d.mts +105 -1
- package/dist/modern/index.d.ts +105 -1
- package/dist/modern/index.js +171 -14
- package/dist/modern/index.mjs +159 -9
- package/package.json +1 -1
package/dist/legacy/index.d.ts
CHANGED
|
@@ -2,6 +2,35 @@ import * as _tanstack_react_query from '@tanstack/react-query';
|
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
3
|
import React, { ReactNode } from 'react';
|
|
4
4
|
|
|
5
|
+
/** Shape of an analytic event passed to the MFE's `onTrackAnalyticsEvent` callback. */
|
|
6
|
+
interface AnalyticEvent {
|
|
7
|
+
key: string;
|
|
8
|
+
properties: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
/** Function provided by the MFE that sends the event to the analytics destination. */
|
|
11
|
+
type AIAnalyticsTracker = (event: AnalyticEvent) => void;
|
|
12
|
+
/** Feature scope: `'project'` for project-level tools, `'company'` for company-level tools. */
|
|
13
|
+
type Scope = 'project' | 'company';
|
|
14
|
+
/**
|
|
15
|
+
* Parts needed to build an event key following the pattern:
|
|
16
|
+
* `ux.web.feature.{scope}.{tool}.{object}.{action}`
|
|
17
|
+
*/
|
|
18
|
+
interface EventKeyParts {
|
|
19
|
+
scope: Scope;
|
|
20
|
+
tool: string;
|
|
21
|
+
object: string;
|
|
22
|
+
action: string;
|
|
23
|
+
}
|
|
24
|
+
/** Standard properties included in every AI analytics event. */
|
|
25
|
+
interface AIAnalyticsEventProperties {
|
|
26
|
+
user_locale: string;
|
|
27
|
+
project_locale?: string;
|
|
28
|
+
company_locale?: string;
|
|
29
|
+
tool: string;
|
|
30
|
+
page: string;
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
}
|
|
33
|
+
|
|
5
34
|
interface TranslationProgress {
|
|
6
35
|
/**
|
|
7
36
|
* Progress percentage (0-100)
|
|
@@ -39,12 +68,22 @@ interface ModelDownloadProgress {
|
|
|
39
68
|
interface AITranslationContextValue {
|
|
40
69
|
ait: (text: string) => Promise<string>;
|
|
41
70
|
locale: string;
|
|
71
|
+
/** Company-level locale from environment metadata (e.g. `"de-DE"`). */
|
|
72
|
+
companyLocale?: string;
|
|
73
|
+
/** Project-level locale from environment metadata (e.g. `"fr-CA"`). */
|
|
74
|
+
projectLocale?: string;
|
|
42
75
|
renderVersion?: number;
|
|
43
76
|
/** Batch-translation progress; `null` while the queue is idle. */
|
|
44
77
|
translationProgress: TranslationProgress | null;
|
|
45
78
|
/** Chrome AI model download progress; `null` until a download begins. */
|
|
46
79
|
modelDownloadProgress: ModelDownloadProgress | null;
|
|
47
80
|
tool: string;
|
|
81
|
+
/** Called by `useAIAnalytics` with a fully assembled event. The MFE is responsible for sending it. */
|
|
82
|
+
onTrackAnalyticsEvent?: AIAnalyticsTracker;
|
|
83
|
+
/** Page context used to build the event key object segment (e.g. `'view'`, `'list_column_description'`). */
|
|
84
|
+
page?: string;
|
|
85
|
+
/** Feature scope: `'project'` or `'company'`. */
|
|
86
|
+
scope?: Scope;
|
|
48
87
|
}
|
|
49
88
|
|
|
50
89
|
interface ConfigurationResponse {
|
|
@@ -117,6 +156,61 @@ declare function useConfig(toolName: string, options?: UseConfigOptions): _tanst
|
|
|
117
156
|
*/
|
|
118
157
|
declare function useAITranslation(): AITranslationContextValue;
|
|
119
158
|
|
|
159
|
+
/** Button type identifiers for the event key `object` segment. */
|
|
160
|
+
declare const BUTTON_TYPE: {
|
|
161
|
+
readonly TRANSLATE: "translate";
|
|
162
|
+
readonly HIGHLIGHT: "highlight";
|
|
163
|
+
};
|
|
164
|
+
type ButtonType = (typeof BUTTON_TYPE)[keyof typeof BUTTON_TYPE];
|
|
165
|
+
/** Action identifiers for the event key `action` segment. */
|
|
166
|
+
declare const ACTION: {
|
|
167
|
+
readonly CLICKED: "clicked";
|
|
168
|
+
};
|
|
169
|
+
type Action = (typeof ACTION)[keyof typeof ACTION];
|
|
170
|
+
/**
|
|
171
|
+
* Builds the `object` segment: `{pageContext}_{buttonType}_button`
|
|
172
|
+
* e.g. `buildObject('view', 'translate')` → `'view_translate_button'`
|
|
173
|
+
*/
|
|
174
|
+
declare function buildObject(pageContext: string, buttonType: ButtonType): string;
|
|
175
|
+
/**
|
|
176
|
+
* Builds a fully-qualified event key:
|
|
177
|
+
* `ux.web.feature.{scope}.{tool}.{object}.{action}`
|
|
178
|
+
*/
|
|
179
|
+
declare function buildEventKey(parts: EventKeyParts): string;
|
|
180
|
+
interface BuildAnalyticEventParams {
|
|
181
|
+
scope: Scope;
|
|
182
|
+
tool: string;
|
|
183
|
+
/** Prefix for the object segment, matches the Provider `page` prop (e.g. `'view'`). */
|
|
184
|
+
pageContext: string;
|
|
185
|
+
buttonType: ButtonType;
|
|
186
|
+
baseProperties: AIAnalyticsEventProperties;
|
|
187
|
+
/** Defaults to `'clicked'` if omitted. */
|
|
188
|
+
action?: Action;
|
|
189
|
+
additionalProperties?: Record<string, unknown>;
|
|
190
|
+
}
|
|
191
|
+
/** Assembles a complete `AnalyticEvent` (key + merged properties) ready for `onTrackAnalyticsEvent`. */
|
|
192
|
+
declare function buildAnalyticEvent(params: BuildAnalyticEventParams): AnalyticEvent;
|
|
193
|
+
|
|
194
|
+
interface UseAIAnalyticsReturn {
|
|
195
|
+
/** Fires `ux.web.feature.{scope}.{tool}.{page}_translate_button.clicked`. */
|
|
196
|
+
trackTranslateButtonClicked: (additionalProperties?: Record<string, unknown>) => void;
|
|
197
|
+
/** Fires `ux.web.feature.{scope}.{tool}.{page}_highlight_button.clicked`. */
|
|
198
|
+
trackHighlightButtonClicked: (additionalProperties?: Record<string, unknown>) => void;
|
|
199
|
+
/** Generic tracking for custom button types or actions. */
|
|
200
|
+
trackCustomEvent: (buttonType: ButtonType | string, action?: Action | string, additionalProperties?: Record<string, unknown>) => void;
|
|
201
|
+
/** `true` when `onTrackAnalyticsEvent` was provided to `AITranslationProvider`. */
|
|
202
|
+
isTrackingEnabled: boolean;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Returns analytics tracking helpers pre-wired to the Provider context.
|
|
206
|
+
* All functions no-op if `onTrackAnalyticsEvent` was not supplied.
|
|
207
|
+
*
|
|
208
|
+
* @throws if called outside of an `AITranslationProvider`.
|
|
209
|
+
*/
|
|
210
|
+
declare function useAIAnalytics(): UseAIAnalyticsReturn;
|
|
211
|
+
|
|
212
|
+
declare function isSupportedBrowser(): boolean;
|
|
213
|
+
|
|
120
214
|
interface AITranslationProviderProps {
|
|
121
215
|
children: ReactNode;
|
|
122
216
|
locale: string;
|
|
@@ -125,6 +219,16 @@ interface AITranslationProviderProps {
|
|
|
125
219
|
userId: number;
|
|
126
220
|
projectId: number;
|
|
127
221
|
enableAIT?: boolean;
|
|
222
|
+
/** Company-level locale from environment metadata (e.g. `"de-DE"`). Passed through to context for downstream consumers such as Amplitude. */
|
|
223
|
+
companyLocale?: string;
|
|
224
|
+
/** Project-level locale from environment metadata (e.g. `"fr-CA"`). Passed through to context for downstream consumers such as Amplitude. */
|
|
225
|
+
projectLocale?: string;
|
|
226
|
+
/** Called by `useAIAnalytics` with a pre-assembled event. The MFE sends it to the analytics API. */
|
|
227
|
+
onTrackAnalyticsEvent?: AIAnalyticsTracker;
|
|
228
|
+
/** Page context for the event key object segment (e.g. `'view'`, `'list_column_description'`). */
|
|
229
|
+
page?: string;
|
|
230
|
+
/** Feature scope: `'project'` or `'company'`. */
|
|
231
|
+
scope?: Scope;
|
|
128
232
|
}
|
|
129
233
|
declare function AITranslationProvider(props: AITranslationProviderProps): react_jsx_runtime.JSX.Element;
|
|
130
234
|
|
|
@@ -177,4 +281,4 @@ declare global {
|
|
|
177
281
|
var _BACKEND_AI_TRANSLATION_IN_PROGRESS_: boolean;
|
|
178
282
|
}
|
|
179
283
|
|
|
180
|
-
export { AITranslateText, type AITranslateTextProps, AITranslationProvider, AI_TRANSLATION_FEATURE_FLAG_KEY, type TranslatedIconProps, type UseConfigOptions, getAITranslationLDId, useAITranslation, useConfig };
|
|
284
|
+
export { ACTION, type AIAnalyticsEventProperties, type AIAnalyticsTracker, AITranslateText, type AITranslateTextProps, AITranslationProvider, AI_TRANSLATION_FEATURE_FLAG_KEY, type Action, type AnalyticEvent, BUTTON_TYPE, type BuildAnalyticEventParams, type ButtonType, type EventKeyParts, type Scope, type TranslatedIconProps, type UseAIAnalyticsReturn, type UseConfigOptions, buildAnalyticEvent, buildEventKey, buildObject, getAITranslationLDId, isSupportedBrowser, useAIAnalytics, useAITranslation, useConfig };
|
package/dist/legacy/index.js
CHANGED
|
@@ -22,10 +22,17 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
22
22
|
// src/index.ts
|
|
23
23
|
var index_exports = {};
|
|
24
24
|
__export(index_exports, {
|
|
25
|
+
ACTION: () => ACTION,
|
|
25
26
|
AITranslateText: () => AITranslateText,
|
|
26
27
|
AITranslationProvider: () => AITranslationProvider,
|
|
27
28
|
AI_TRANSLATION_FEATURE_FLAG_KEY: () => AI_TRANSLATION_FEATURE_FLAG_KEY,
|
|
29
|
+
BUTTON_TYPE: () => BUTTON_TYPE,
|
|
30
|
+
buildAnalyticEvent: () => buildAnalyticEvent,
|
|
31
|
+
buildEventKey: () => buildEventKey,
|
|
32
|
+
buildObject: () => buildObject,
|
|
28
33
|
getAITranslationLDId: () => getAITranslationLDId,
|
|
34
|
+
isSupportedBrowser: () => isSupportedBrowser,
|
|
35
|
+
useAIAnalytics: () => useAIAnalytics,
|
|
29
36
|
useAITranslation: () => useAITranslation,
|
|
30
37
|
useConfig: () => useConfig
|
|
31
38
|
});
|
|
@@ -1449,6 +1456,7 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
|
|
|
1449
1456
|
};
|
|
1450
1457
|
|
|
1451
1458
|
// src/utils/browser.ts
|
|
1459
|
+
var supportedBrowsers = ["chrome", "arc", "opera"];
|
|
1452
1460
|
function detectBrowser() {
|
|
1453
1461
|
const ua = navigator.userAgent;
|
|
1454
1462
|
if (ua.includes("Arc/")) return "arc";
|
|
@@ -1459,6 +1467,10 @@ function detectBrowser() {
|
|
|
1459
1467
|
if (ua.includes("Chrome/")) return "chrome";
|
|
1460
1468
|
return "unknown";
|
|
1461
1469
|
}
|
|
1470
|
+
function isSupportedBrowser() {
|
|
1471
|
+
const browser = detectBrowser();
|
|
1472
|
+
return supportedBrowsers.includes(browser);
|
|
1473
|
+
}
|
|
1462
1474
|
|
|
1463
1475
|
// src/Provider.tsx
|
|
1464
1476
|
var import_react_query2 = require("@tanstack/react-query");
|
|
@@ -1472,7 +1484,12 @@ function AITranslationInnerProvider(props) {
|
|
|
1472
1484
|
companyId,
|
|
1473
1485
|
userId,
|
|
1474
1486
|
projectId,
|
|
1475
|
-
enableAIT = true
|
|
1487
|
+
enableAIT = true,
|
|
1488
|
+
companyLocale,
|
|
1489
|
+
projectLocale,
|
|
1490
|
+
onTrackAnalyticsEvent,
|
|
1491
|
+
page,
|
|
1492
|
+
scope
|
|
1476
1493
|
} = props;
|
|
1477
1494
|
const [translationProgress, setTranslationProgress] = (0, import_react.useState)(null);
|
|
1478
1495
|
const [modelDownloadProgress, setModelDownloadProgress] = (0, import_react.useState)(null);
|
|
@@ -1549,10 +1566,15 @@ function AITranslationInnerProvider(props) {
|
|
|
1549
1566
|
const contextValue = {
|
|
1550
1567
|
ait,
|
|
1551
1568
|
locale,
|
|
1569
|
+
companyLocale,
|
|
1570
|
+
projectLocale,
|
|
1552
1571
|
renderVersion: renderVersionManager.getVersion(),
|
|
1553
1572
|
translationProgress,
|
|
1554
1573
|
modelDownloadProgress,
|
|
1555
|
-
tool
|
|
1574
|
+
tool,
|
|
1575
|
+
onTrackAnalyticsEvent,
|
|
1576
|
+
page,
|
|
1577
|
+
scope
|
|
1556
1578
|
};
|
|
1557
1579
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AITranslationContext.Provider, { value: contextValue, children });
|
|
1558
1580
|
}
|
|
@@ -1572,15 +1594,143 @@ function useAITranslation() {
|
|
|
1572
1594
|
return ctx;
|
|
1573
1595
|
}
|
|
1574
1596
|
|
|
1597
|
+
// src/hooks/useAIAnalytics.ts
|
|
1598
|
+
var import_react3 = require("react");
|
|
1599
|
+
|
|
1600
|
+
// src/analytics/events.ts
|
|
1601
|
+
var BUTTON_TYPE = {
|
|
1602
|
+
TRANSLATE: "translate",
|
|
1603
|
+
HIGHLIGHT: "highlight"
|
|
1604
|
+
};
|
|
1605
|
+
var ACTION = {
|
|
1606
|
+
CLICKED: "clicked"
|
|
1607
|
+
};
|
|
1608
|
+
function buildObject(pageContext, buttonType) {
|
|
1609
|
+
return `${pageContext}_${buttonType}_button`;
|
|
1610
|
+
}
|
|
1611
|
+
function buildEventKey(parts) {
|
|
1612
|
+
const { scope, tool, object, action } = parts;
|
|
1613
|
+
return `ux.web.feature.${scope}.${tool}.${object}.${action}`;
|
|
1614
|
+
}
|
|
1615
|
+
function buildAnalyticEvent(params) {
|
|
1616
|
+
const {
|
|
1617
|
+
scope,
|
|
1618
|
+
tool,
|
|
1619
|
+
pageContext,
|
|
1620
|
+
buttonType,
|
|
1621
|
+
baseProperties,
|
|
1622
|
+
action,
|
|
1623
|
+
additionalProperties
|
|
1624
|
+
} = params;
|
|
1625
|
+
const resolvedAction = action ?? ACTION.CLICKED;
|
|
1626
|
+
const object = buildObject(pageContext, buttonType);
|
|
1627
|
+
const key = buildEventKey({
|
|
1628
|
+
scope,
|
|
1629
|
+
tool,
|
|
1630
|
+
object,
|
|
1631
|
+
action: resolvedAction
|
|
1632
|
+
});
|
|
1633
|
+
const properties = {
|
|
1634
|
+
...baseProperties,
|
|
1635
|
+
...additionalProperties
|
|
1636
|
+
};
|
|
1637
|
+
return { key, properties };
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1640
|
+
// src/hooks/useAIAnalytics.ts
|
|
1641
|
+
function useAIAnalytics() {
|
|
1642
|
+
const ctx = (0, import_react3.useContext)(AITranslationContext);
|
|
1643
|
+
if (!ctx) {
|
|
1644
|
+
throw new Error(
|
|
1645
|
+
"useAIAnalytics must be used inside an AITranslationProvider"
|
|
1646
|
+
);
|
|
1647
|
+
}
|
|
1648
|
+
const {
|
|
1649
|
+
locale,
|
|
1650
|
+
companyLocale,
|
|
1651
|
+
projectLocale,
|
|
1652
|
+
tool,
|
|
1653
|
+
page,
|
|
1654
|
+
scope,
|
|
1655
|
+
onTrackAnalyticsEvent
|
|
1656
|
+
} = ctx;
|
|
1657
|
+
const isTrackingEnabled = Boolean(onTrackAnalyticsEvent);
|
|
1658
|
+
const buildBaseProperties = (0, import_react3.useCallback)(() => {
|
|
1659
|
+
const props = {
|
|
1660
|
+
user_locale: locale,
|
|
1661
|
+
tool,
|
|
1662
|
+
page: page ?? ""
|
|
1663
|
+
};
|
|
1664
|
+
if (companyLocale) props.company_locale = companyLocale;
|
|
1665
|
+
if (projectLocale) props.project_locale = projectLocale;
|
|
1666
|
+
return props;
|
|
1667
|
+
}, [locale, tool, page, companyLocale, projectLocale]);
|
|
1668
|
+
const trackTranslateButtonClicked = (0, import_react3.useCallback)(
|
|
1669
|
+
(additionalProperties) => {
|
|
1670
|
+
if (!onTrackAnalyticsEvent || !page || !scope) return;
|
|
1671
|
+
onTrackAnalyticsEvent(
|
|
1672
|
+
buildAnalyticEvent({
|
|
1673
|
+
scope,
|
|
1674
|
+
tool,
|
|
1675
|
+
pageContext: page,
|
|
1676
|
+
buttonType: BUTTON_TYPE.TRANSLATE,
|
|
1677
|
+
baseProperties: buildBaseProperties(),
|
|
1678
|
+
additionalProperties
|
|
1679
|
+
})
|
|
1680
|
+
);
|
|
1681
|
+
},
|
|
1682
|
+
[onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
|
|
1683
|
+
);
|
|
1684
|
+
const trackHighlightButtonClicked = (0, import_react3.useCallback)(
|
|
1685
|
+
(additionalProperties) => {
|
|
1686
|
+
if (!onTrackAnalyticsEvent || !page || !scope) return;
|
|
1687
|
+
onTrackAnalyticsEvent(
|
|
1688
|
+
buildAnalyticEvent({
|
|
1689
|
+
scope,
|
|
1690
|
+
tool,
|
|
1691
|
+
pageContext: page,
|
|
1692
|
+
buttonType: BUTTON_TYPE.HIGHLIGHT,
|
|
1693
|
+
baseProperties: buildBaseProperties(),
|
|
1694
|
+
additionalProperties
|
|
1695
|
+
})
|
|
1696
|
+
);
|
|
1697
|
+
},
|
|
1698
|
+
[onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
|
|
1699
|
+
);
|
|
1700
|
+
const trackCustomEvent = (0, import_react3.useCallback)(
|
|
1701
|
+
(buttonType, action, additionalProperties) => {
|
|
1702
|
+
if (!onTrackAnalyticsEvent || !page || !scope) return;
|
|
1703
|
+
onTrackAnalyticsEvent(
|
|
1704
|
+
buildAnalyticEvent({
|
|
1705
|
+
scope,
|
|
1706
|
+
tool,
|
|
1707
|
+
pageContext: page,
|
|
1708
|
+
buttonType,
|
|
1709
|
+
baseProperties: buildBaseProperties(),
|
|
1710
|
+
action,
|
|
1711
|
+
additionalProperties
|
|
1712
|
+
})
|
|
1713
|
+
);
|
|
1714
|
+
},
|
|
1715
|
+
[onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
|
|
1716
|
+
);
|
|
1717
|
+
return {
|
|
1718
|
+
trackTranslateButtonClicked,
|
|
1719
|
+
trackHighlightButtonClicked,
|
|
1720
|
+
trackCustomEvent,
|
|
1721
|
+
isTrackingEnabled
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1575
1725
|
// src/components/AITranslateText.tsx
|
|
1576
|
-
var
|
|
1726
|
+
var import_react5 = require("react");
|
|
1577
1727
|
|
|
1578
1728
|
// src/components/TranslatedIcon.tsx
|
|
1579
|
-
var
|
|
1729
|
+
var import_react4 = require("react");
|
|
1580
1730
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1581
1731
|
var TranslatedIcon = ({
|
|
1582
|
-
width =
|
|
1583
|
-
height =
|
|
1732
|
+
width = 24,
|
|
1733
|
+
height = 24,
|
|
1584
1734
|
className,
|
|
1585
1735
|
color = "#000000"
|
|
1586
1736
|
}) => {
|
|
@@ -1598,7 +1748,7 @@ var TranslatedIcon = ({
|
|
|
1598
1748
|
"path",
|
|
1599
1749
|
{
|
|
1600
1750
|
fill: color,
|
|
1601
|
-
d: "M12.
|
|
1751
|
+
d: "M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM11 19.93C7.05 19.44 4 16.08 4 12C4 11.38 4.08 10.79 4.21 10.21L9 15V16C9 17.1 9.9 18 11 18V19.93ZM17.9 17.39C17.64 16.58 16.9 16 16 16H15V13C15 12.45 14.55 12 14 12H8V10H10C10.55 10 11 9.55 11 9V7H13C14.1 7 15 6.1 15 5V4.59C17.93 5.78 20 8.65 20 12C20 14.08 19.2 15.97 17.9 17.39Z"
|
|
1602
1752
|
}
|
|
1603
1753
|
)
|
|
1604
1754
|
}
|
|
@@ -1613,11 +1763,11 @@ var AITranslateText = ({
|
|
|
1613
1763
|
showHighlight = false,
|
|
1614
1764
|
translatedIconProps
|
|
1615
1765
|
}) => {
|
|
1616
|
-
const context = (0,
|
|
1617
|
-
const [displayText, setDisplayText] = (0,
|
|
1618
|
-
const [showHighlightState, setShowHighlightState] = (0,
|
|
1619
|
-
const eventHandlerRef = (0,
|
|
1620
|
-
(0,
|
|
1766
|
+
const context = (0, import_react5.useContext)(AITranslationContext);
|
|
1767
|
+
const [displayText, setDisplayText] = (0, import_react5.useState)(text ?? "");
|
|
1768
|
+
const [showHighlightState, setShowHighlightState] = (0, import_react5.useState)(showHighlight);
|
|
1769
|
+
const eventHandlerRef = (0, import_react5.useRef)(null);
|
|
1770
|
+
(0, import_react5.useEffect)(() => {
|
|
1621
1771
|
if (!context) return;
|
|
1622
1772
|
if (!eventHandlerRef.current) {
|
|
1623
1773
|
eventHandlerRef.current = new EventHandler(context.tool);
|
|
@@ -1636,14 +1786,14 @@ var AITranslateText = ({
|
|
|
1636
1786
|
);
|
|
1637
1787
|
return () => unsubscribe();
|
|
1638
1788
|
}, [context, text, showHighlight]);
|
|
1639
|
-
const reset = (0,
|
|
1789
|
+
const reset = (0, import_react5.useCallback)(
|
|
1640
1790
|
(displayValue = text) => {
|
|
1641
1791
|
setDisplayText(displayValue);
|
|
1642
1792
|
setShowHighlightState(false);
|
|
1643
1793
|
},
|
|
1644
1794
|
[text]
|
|
1645
1795
|
);
|
|
1646
|
-
(0,
|
|
1796
|
+
(0, import_react5.useEffect)(() => {
|
|
1647
1797
|
if (text == null || text === "") {
|
|
1648
1798
|
reset(text ?? "");
|
|
1649
1799
|
return;
|
|
@@ -1695,10 +1845,17 @@ var getAITranslationLDId = (domain) => {
|
|
|
1695
1845
|
};
|
|
1696
1846
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1697
1847
|
0 && (module.exports = {
|
|
1848
|
+
ACTION,
|
|
1698
1849
|
AITranslateText,
|
|
1699
1850
|
AITranslationProvider,
|
|
1700
1851
|
AI_TRANSLATION_FEATURE_FLAG_KEY,
|
|
1852
|
+
BUTTON_TYPE,
|
|
1853
|
+
buildAnalyticEvent,
|
|
1854
|
+
buildEventKey,
|
|
1855
|
+
buildObject,
|
|
1701
1856
|
getAITranslationLDId,
|
|
1857
|
+
isSupportedBrowser,
|
|
1858
|
+
useAIAnalytics,
|
|
1702
1859
|
useAITranslation,
|
|
1703
1860
|
useConfig
|
|
1704
1861
|
});
|
package/dist/legacy/index.mjs
CHANGED
|
@@ -1426,6 +1426,7 @@ var aitFunction = async (text, translationRegistry, config2, tool) => {
|
|
|
1426
1426
|
};
|
|
1427
1427
|
|
|
1428
1428
|
// src/utils/browser.ts
|
|
1429
|
+
var supportedBrowsers = ["chrome", "arc", "opera"];
|
|
1429
1430
|
function detectBrowser() {
|
|
1430
1431
|
const ua = navigator.userAgent;
|
|
1431
1432
|
if (ua.includes("Arc/")) return "arc";
|
|
@@ -1436,6 +1437,10 @@ function detectBrowser() {
|
|
|
1436
1437
|
if (ua.includes("Chrome/")) return "chrome";
|
|
1437
1438
|
return "unknown";
|
|
1438
1439
|
}
|
|
1440
|
+
function isSupportedBrowser() {
|
|
1441
|
+
const browser = detectBrowser();
|
|
1442
|
+
return supportedBrowsers.includes(browser);
|
|
1443
|
+
}
|
|
1439
1444
|
|
|
1440
1445
|
// src/Provider.tsx
|
|
1441
1446
|
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
|
|
@@ -1449,7 +1454,12 @@ function AITranslationInnerProvider(props) {
|
|
|
1449
1454
|
companyId,
|
|
1450
1455
|
userId,
|
|
1451
1456
|
projectId,
|
|
1452
|
-
enableAIT = true
|
|
1457
|
+
enableAIT = true,
|
|
1458
|
+
companyLocale,
|
|
1459
|
+
projectLocale,
|
|
1460
|
+
onTrackAnalyticsEvent,
|
|
1461
|
+
page,
|
|
1462
|
+
scope
|
|
1453
1463
|
} = props;
|
|
1454
1464
|
const [translationProgress, setTranslationProgress] = useState(null);
|
|
1455
1465
|
const [modelDownloadProgress, setModelDownloadProgress] = useState(null);
|
|
@@ -1526,10 +1536,15 @@ function AITranslationInnerProvider(props) {
|
|
|
1526
1536
|
const contextValue = {
|
|
1527
1537
|
ait,
|
|
1528
1538
|
locale,
|
|
1539
|
+
companyLocale,
|
|
1540
|
+
projectLocale,
|
|
1529
1541
|
renderVersion: renderVersionManager.getVersion(),
|
|
1530
1542
|
translationProgress,
|
|
1531
1543
|
modelDownloadProgress,
|
|
1532
|
-
tool
|
|
1544
|
+
tool,
|
|
1545
|
+
onTrackAnalyticsEvent,
|
|
1546
|
+
page,
|
|
1547
|
+
scope
|
|
1533
1548
|
};
|
|
1534
1549
|
return /* @__PURE__ */ jsx(AITranslationContext.Provider, { value: contextValue, children });
|
|
1535
1550
|
}
|
|
@@ -1549,12 +1564,140 @@ function useAITranslation() {
|
|
|
1549
1564
|
return ctx;
|
|
1550
1565
|
}
|
|
1551
1566
|
|
|
1567
|
+
// src/hooks/useAIAnalytics.ts
|
|
1568
|
+
import { useContext as useContext2, useCallback as useCallback2 } from "react";
|
|
1569
|
+
|
|
1570
|
+
// src/analytics/events.ts
|
|
1571
|
+
var BUTTON_TYPE = {
|
|
1572
|
+
TRANSLATE: "translate",
|
|
1573
|
+
HIGHLIGHT: "highlight"
|
|
1574
|
+
};
|
|
1575
|
+
var ACTION = {
|
|
1576
|
+
CLICKED: "clicked"
|
|
1577
|
+
};
|
|
1578
|
+
function buildObject(pageContext, buttonType) {
|
|
1579
|
+
return `${pageContext}_${buttonType}_button`;
|
|
1580
|
+
}
|
|
1581
|
+
function buildEventKey(parts) {
|
|
1582
|
+
const { scope, tool, object, action } = parts;
|
|
1583
|
+
return `ux.web.feature.${scope}.${tool}.${object}.${action}`;
|
|
1584
|
+
}
|
|
1585
|
+
function buildAnalyticEvent(params) {
|
|
1586
|
+
const {
|
|
1587
|
+
scope,
|
|
1588
|
+
tool,
|
|
1589
|
+
pageContext,
|
|
1590
|
+
buttonType,
|
|
1591
|
+
baseProperties,
|
|
1592
|
+
action,
|
|
1593
|
+
additionalProperties
|
|
1594
|
+
} = params;
|
|
1595
|
+
const resolvedAction = action ?? ACTION.CLICKED;
|
|
1596
|
+
const object = buildObject(pageContext, buttonType);
|
|
1597
|
+
const key = buildEventKey({
|
|
1598
|
+
scope,
|
|
1599
|
+
tool,
|
|
1600
|
+
object,
|
|
1601
|
+
action: resolvedAction
|
|
1602
|
+
});
|
|
1603
|
+
const properties = {
|
|
1604
|
+
...baseProperties,
|
|
1605
|
+
...additionalProperties
|
|
1606
|
+
};
|
|
1607
|
+
return { key, properties };
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// src/hooks/useAIAnalytics.ts
|
|
1611
|
+
function useAIAnalytics() {
|
|
1612
|
+
const ctx = useContext2(AITranslationContext);
|
|
1613
|
+
if (!ctx) {
|
|
1614
|
+
throw new Error(
|
|
1615
|
+
"useAIAnalytics must be used inside an AITranslationProvider"
|
|
1616
|
+
);
|
|
1617
|
+
}
|
|
1618
|
+
const {
|
|
1619
|
+
locale,
|
|
1620
|
+
companyLocale,
|
|
1621
|
+
projectLocale,
|
|
1622
|
+
tool,
|
|
1623
|
+
page,
|
|
1624
|
+
scope,
|
|
1625
|
+
onTrackAnalyticsEvent
|
|
1626
|
+
} = ctx;
|
|
1627
|
+
const isTrackingEnabled = Boolean(onTrackAnalyticsEvent);
|
|
1628
|
+
const buildBaseProperties = useCallback2(() => {
|
|
1629
|
+
const props = {
|
|
1630
|
+
user_locale: locale,
|
|
1631
|
+
tool,
|
|
1632
|
+
page: page ?? ""
|
|
1633
|
+
};
|
|
1634
|
+
if (companyLocale) props.company_locale = companyLocale;
|
|
1635
|
+
if (projectLocale) props.project_locale = projectLocale;
|
|
1636
|
+
return props;
|
|
1637
|
+
}, [locale, tool, page, companyLocale, projectLocale]);
|
|
1638
|
+
const trackTranslateButtonClicked = useCallback2(
|
|
1639
|
+
(additionalProperties) => {
|
|
1640
|
+
if (!onTrackAnalyticsEvent || !page || !scope) return;
|
|
1641
|
+
onTrackAnalyticsEvent(
|
|
1642
|
+
buildAnalyticEvent({
|
|
1643
|
+
scope,
|
|
1644
|
+
tool,
|
|
1645
|
+
pageContext: page,
|
|
1646
|
+
buttonType: BUTTON_TYPE.TRANSLATE,
|
|
1647
|
+
baseProperties: buildBaseProperties(),
|
|
1648
|
+
additionalProperties
|
|
1649
|
+
})
|
|
1650
|
+
);
|
|
1651
|
+
},
|
|
1652
|
+
[onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
|
|
1653
|
+
);
|
|
1654
|
+
const trackHighlightButtonClicked = useCallback2(
|
|
1655
|
+
(additionalProperties) => {
|
|
1656
|
+
if (!onTrackAnalyticsEvent || !page || !scope) return;
|
|
1657
|
+
onTrackAnalyticsEvent(
|
|
1658
|
+
buildAnalyticEvent({
|
|
1659
|
+
scope,
|
|
1660
|
+
tool,
|
|
1661
|
+
pageContext: page,
|
|
1662
|
+
buttonType: BUTTON_TYPE.HIGHLIGHT,
|
|
1663
|
+
baseProperties: buildBaseProperties(),
|
|
1664
|
+
additionalProperties
|
|
1665
|
+
})
|
|
1666
|
+
);
|
|
1667
|
+
},
|
|
1668
|
+
[onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
|
|
1669
|
+
);
|
|
1670
|
+
const trackCustomEvent = useCallback2(
|
|
1671
|
+
(buttonType, action, additionalProperties) => {
|
|
1672
|
+
if (!onTrackAnalyticsEvent || !page || !scope) return;
|
|
1673
|
+
onTrackAnalyticsEvent(
|
|
1674
|
+
buildAnalyticEvent({
|
|
1675
|
+
scope,
|
|
1676
|
+
tool,
|
|
1677
|
+
pageContext: page,
|
|
1678
|
+
buttonType,
|
|
1679
|
+
baseProperties: buildBaseProperties(),
|
|
1680
|
+
action,
|
|
1681
|
+
additionalProperties
|
|
1682
|
+
})
|
|
1683
|
+
);
|
|
1684
|
+
},
|
|
1685
|
+
[onTrackAnalyticsEvent, tool, page, scope, buildBaseProperties]
|
|
1686
|
+
);
|
|
1687
|
+
return {
|
|
1688
|
+
trackTranslateButtonClicked,
|
|
1689
|
+
trackHighlightButtonClicked,
|
|
1690
|
+
trackCustomEvent,
|
|
1691
|
+
isTrackingEnabled
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1552
1695
|
// src/components/AITranslateText.tsx
|
|
1553
1696
|
import {
|
|
1554
1697
|
useState as useState2,
|
|
1555
1698
|
useEffect as useEffect2,
|
|
1556
|
-
useContext as
|
|
1557
|
-
useCallback as
|
|
1699
|
+
useContext as useContext3,
|
|
1700
|
+
useCallback as useCallback3,
|
|
1558
1701
|
useRef as useRef2
|
|
1559
1702
|
} from "react";
|
|
1560
1703
|
|
|
@@ -1562,8 +1705,8 @@ import {
|
|
|
1562
1705
|
import "react";
|
|
1563
1706
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1564
1707
|
var TranslatedIcon = ({
|
|
1565
|
-
width =
|
|
1566
|
-
height =
|
|
1708
|
+
width = 24,
|
|
1709
|
+
height = 24,
|
|
1567
1710
|
className,
|
|
1568
1711
|
color = "#000000"
|
|
1569
1712
|
}) => {
|
|
@@ -1581,7 +1724,7 @@ var TranslatedIcon = ({
|
|
|
1581
1724
|
"path",
|
|
1582
1725
|
{
|
|
1583
1726
|
fill: color,
|
|
1584
|
-
d: "M12.
|
|
1727
|
+
d: "M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2ZM11 19.93C7.05 19.44 4 16.08 4 12C4 11.38 4.08 10.79 4.21 10.21L9 15V16C9 17.1 9.9 18 11 18V19.93ZM17.9 17.39C17.64 16.58 16.9 16 16 16H15V13C15 12.45 14.55 12 14 12H8V10H10C10.55 10 11 9.55 11 9V7H13C14.1 7 15 6.1 15 5V4.59C17.93 5.78 20 8.65 20 12C20 14.08 19.2 15.97 17.9 17.39Z"
|
|
1585
1728
|
}
|
|
1586
1729
|
)
|
|
1587
1730
|
}
|
|
@@ -1596,7 +1739,7 @@ var AITranslateText = ({
|
|
|
1596
1739
|
showHighlight = false,
|
|
1597
1740
|
translatedIconProps
|
|
1598
1741
|
}) => {
|
|
1599
|
-
const context =
|
|
1742
|
+
const context = useContext3(AITranslationContext);
|
|
1600
1743
|
const [displayText, setDisplayText] = useState2(text ?? "");
|
|
1601
1744
|
const [showHighlightState, setShowHighlightState] = useState2(showHighlight);
|
|
1602
1745
|
const eventHandlerRef = useRef2(null);
|
|
@@ -1619,7 +1762,7 @@ var AITranslateText = ({
|
|
|
1619
1762
|
);
|
|
1620
1763
|
return () => unsubscribe();
|
|
1621
1764
|
}, [context, text, showHighlight]);
|
|
1622
|
-
const reset =
|
|
1765
|
+
const reset = useCallback3(
|
|
1623
1766
|
(displayValue = text) => {
|
|
1624
1767
|
setDisplayText(displayValue);
|
|
1625
1768
|
setShowHighlightState(false);
|
|
@@ -1677,10 +1820,17 @@ var getAITranslationLDId = (domain) => {
|
|
|
1677
1820
|
}
|
|
1678
1821
|
};
|
|
1679
1822
|
export {
|
|
1823
|
+
ACTION,
|
|
1680
1824
|
AITranslateText,
|
|
1681
1825
|
AITranslationProvider,
|
|
1682
1826
|
AI_TRANSLATION_FEATURE_FLAG_KEY,
|
|
1827
|
+
BUTTON_TYPE,
|
|
1828
|
+
buildAnalyticEvent,
|
|
1829
|
+
buildEventKey,
|
|
1830
|
+
buildObject,
|
|
1683
1831
|
getAITranslationLDId,
|
|
1832
|
+
isSupportedBrowser,
|
|
1833
|
+
useAIAnalytics,
|
|
1684
1834
|
useAITranslation,
|
|
1685
1835
|
useConfig
|
|
1686
1836
|
};
|