@patternfly/chatbot 2.2.0-prerelease.30 → 2.2.0-prerelease.31
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/dist/cjs/Message/ErrorMessage/ErrorMessage.d.ts +4 -0
- package/dist/cjs/Message/ErrorMessage/ErrorMessage.js +26 -0
- package/dist/cjs/Message/Message.d.ts +3 -1
- package/dist/cjs/Message/Message.js +4 -3
- package/dist/cjs/Message/Message.test.js +25 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/tracking/console_tracking_provider.d.ts +10 -0
- package/dist/cjs/tracking/console_tracking_provider.js +27 -0
- package/dist/cjs/tracking/index.d.ts +2 -0
- package/dist/cjs/tracking/index.js +23 -0
- package/dist/cjs/tracking/posthog_tracking_provider.d.ts +9 -0
- package/dist/cjs/tracking/posthog_tracking_provider.js +37 -0
- package/dist/cjs/tracking/segment_tracking_provider.d.ts +10 -0
- package/dist/cjs/tracking/segment_tracking_provider.js +50 -0
- package/dist/cjs/tracking/trackingProviderProxy.d.ts +9 -0
- package/dist/cjs/tracking/trackingProviderProxy.js +24 -0
- package/dist/cjs/tracking/tracking_api.d.ts +8 -0
- package/dist/cjs/tracking/tracking_api.js +2 -0
- package/dist/cjs/tracking/tracking_registry.d.ts +4 -0
- package/dist/cjs/tracking/tracking_registry.js +33 -0
- package/dist/cjs/tracking/tracking_spi.d.ts +9 -0
- package/dist/cjs/tracking/tracking_spi.js +2 -0
- package/dist/cjs/tracking/umami_tracking_provider.d.ts +14 -0
- package/dist/cjs/tracking/umami_tracking_provider.js +44 -0
- package/dist/dynamic/tracking/package.json +1 -0
- package/dist/esm/Message/ErrorMessage/ErrorMessage.d.ts +4 -0
- package/dist/esm/Message/ErrorMessage/ErrorMessage.js +21 -0
- package/dist/esm/Message/Message.d.ts +3 -1
- package/dist/esm/Message/Message.js +4 -3
- package/dist/esm/Message/Message.test.js +25 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/tracking/console_tracking_provider.d.ts +10 -0
- package/dist/esm/tracking/console_tracking_provider.js +23 -0
- package/dist/esm/tracking/index.d.ts +2 -0
- package/dist/esm/tracking/index.js +2 -0
- package/dist/esm/tracking/posthog_tracking_provider.d.ts +9 -0
- package/dist/esm/tracking/posthog_tracking_provider.js +33 -0
- package/dist/esm/tracking/segment_tracking_provider.d.ts +10 -0
- package/dist/esm/tracking/segment_tracking_provider.js +46 -0
- package/dist/esm/tracking/trackingProviderProxy.d.ts +9 -0
- package/dist/esm/tracking/trackingProviderProxy.js +22 -0
- package/dist/esm/tracking/tracking_api.d.ts +8 -0
- package/dist/esm/tracking/tracking_api.js +1 -0
- package/dist/esm/tracking/tracking_registry.d.ts +4 -0
- package/dist/esm/tracking/tracking_registry.js +26 -0
- package/dist/esm/tracking/tracking_spi.d.ts +9 -0
- package/dist/esm/tracking/tracking_spi.js +1 -0
- package/dist/esm/tracking/umami_tracking_provider.d.ts +14 -0
- package/dist/esm/tracking/umami_tracking_provider.js +40 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/patternfly-docs/content/extensions/chatbot/about-chatbot.md +3 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Analytics/Analytics.md +214 -0
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +24 -1
- package/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +24 -1
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.md +2 -0
- package/patternfly-docs/content/extensions/chatbot/examples/demos/Chatbot.tsx +37 -24
- package/patternfly-docs/content/extensions/chatbot/img/analytics-example.svg +118 -0
- package/patternfly-docs/content/extensions/chatbot/img/chatbot-analytics.svg +51 -0
- package/patternfly-docs/content/extensions/chatbot/img/posthog.svg +30 -0
- package/patternfly-docs/content/extensions/chatbot/img/segment.svg +36 -0
- package/patternfly-docs/content/extensions/chatbot/img/umami.svg +30 -0
- package/src/Message/ErrorMessage/ErrorMessage.tsx +14 -0
- package/src/Message/Message.test.tsx +32 -0
- package/src/Message/Message.tsx +50 -41
- package/src/index.ts +3 -0
- package/src/tracking/console_tracking_provider.ts +30 -0
- package/src/tracking/index.ts +3 -0
- package/src/tracking/posthog_tracking_provider.ts +42 -0
- package/src/tracking/segment_tracking_provider.ts +62 -0
- package/src/tracking/trackingProviderProxy.ts +28 -0
- package/src/tracking/tracking_api.ts +11 -0
- package/src/tracking/tracking_registry.ts +33 -0
- package/src/tracking/tracking_spi.ts +14 -0
- package/src/tracking/umami_tracking_provider.ts +54 -0
package/src/Message/Message.tsx
CHANGED
@@ -7,6 +7,7 @@ import React, { ReactNode } from 'react';
|
|
7
7
|
import Markdown from 'react-markdown';
|
8
8
|
import remarkGfm from 'remark-gfm';
|
9
9
|
import {
|
10
|
+
AlertProps,
|
10
11
|
Avatar,
|
11
12
|
AvatarProps,
|
12
13
|
ContentVariants,
|
@@ -42,6 +43,7 @@ import rehypeExternalLinks from 'rehype-external-links';
|
|
42
43
|
import rehypeSanitize from 'rehype-sanitize';
|
43
44
|
import { PluggableList } from 'react-markdown/lib';
|
44
45
|
import LinkMessage from './LinkMessage/LinkMessage';
|
46
|
+
import ErrorMessage from './ErrorMessage/ErrorMessage';
|
45
47
|
|
46
48
|
export interface MessageAttachment {
|
47
49
|
/** Name of file attached to the message */
|
@@ -141,6 +143,8 @@ export interface MessageProps extends Omit<React.HTMLProps<HTMLDivElement>, 'rol
|
|
141
143
|
additionalRehypePlugins?: PluggableList;
|
142
144
|
/** Whether to open links in message in new tab. */
|
143
145
|
openLinkInNewTab?: boolean;
|
146
|
+
/** Optional inline error message that can be displayed in the message */
|
147
|
+
error?: AlertProps;
|
144
148
|
}
|
145
149
|
|
146
150
|
export const MessageBase: React.FunctionComponent<MessageProps> = ({
|
@@ -169,6 +173,7 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
|
|
169
173
|
tableProps,
|
170
174
|
openLinkInNewTab = true,
|
171
175
|
additionalRehypePlugins = [],
|
176
|
+
error,
|
172
177
|
...props
|
173
178
|
}: MessageProps) => {
|
174
179
|
const { beforeMainContent, afterMainContent, endContent } = extraContent || {};
|
@@ -225,47 +230,51 @@ export const MessageBase: React.FunctionComponent<MessageProps> = ({
|
|
225
230
|
) : (
|
226
231
|
<>
|
227
232
|
{beforeMainContent && <>{beforeMainContent}</>}
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
233
|
+
{error ? (
|
234
|
+
<ErrorMessage {...error} />
|
235
|
+
) : (
|
236
|
+
<Markdown
|
237
|
+
components={{
|
238
|
+
p: (props) => <TextMessage component={ContentVariants.p} {...props} />,
|
239
|
+
code: ({ children, ...props }) => (
|
240
|
+
<CodeBlockMessage {...props} {...codeBlockProps}>
|
241
|
+
{children}
|
242
|
+
</CodeBlockMessage>
|
243
|
+
),
|
244
|
+
h1: (props) => <TextMessage component={ContentVariants.h1} {...props} />,
|
245
|
+
h2: (props) => <TextMessage component={ContentVariants.h2} {...props} />,
|
246
|
+
h3: (props) => <TextMessage component={ContentVariants.h3} {...props} />,
|
247
|
+
h4: (props) => <TextMessage component={ContentVariants.h4} {...props} />,
|
248
|
+
h5: (props) => <TextMessage component={ContentVariants.h5} {...props} />,
|
249
|
+
h6: (props) => <TextMessage component={ContentVariants.h6} {...props} />,
|
250
|
+
blockquote: (props) => <TextMessage component={ContentVariants.blockquote} {...props} />,
|
251
|
+
ul: (props) => <UnorderedListMessage {...props} />,
|
252
|
+
ol: (props) => <OrderedListMessage {...props} />,
|
253
|
+
li: (props) => <ListItemMessage {...props} />,
|
254
|
+
table: (props) => <TableMessage {...props} {...tableProps} />,
|
255
|
+
tbody: (props) => <TbodyMessage {...props} />,
|
256
|
+
thead: (props) => <TheadMessage {...props} />,
|
257
|
+
tr: (props) => <TrMessage {...props} />,
|
258
|
+
td: (props) => {
|
259
|
+
// Conflicts with Td type
|
260
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
261
|
+
const { width, ...rest } = props;
|
262
|
+
return <TdMessage {...rest} />;
|
263
|
+
},
|
264
|
+
th: (props) => <ThMessage {...props} />,
|
265
|
+
img: (props) => <ImageMessage {...props} />,
|
266
|
+
a: (props) => (
|
267
|
+
<LinkMessage href={props.href} rel={props.rel} target={props.target}>
|
268
|
+
{props.children}
|
269
|
+
</LinkMessage>
|
270
|
+
)
|
271
|
+
}}
|
272
|
+
remarkPlugins={[remarkGfm]}
|
273
|
+
rehypePlugins={rehypePlugins}
|
274
|
+
>
|
275
|
+
{content}
|
276
|
+
</Markdown>
|
277
|
+
)}
|
269
278
|
{afterMainContent && <>{afterMainContent}</>}
|
270
279
|
</>
|
271
280
|
)}
|
package/src/index.ts
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
import { TrackingSpi } from './tracking_spi';
|
2
|
+
import { TrackingApi, TrackingEventProperties } from './tracking_api';
|
3
|
+
|
4
|
+
export class ConsoleTrackingProvider implements TrackingSpi, TrackingApi {
|
5
|
+
trackPageView(url: string | undefined) {
|
6
|
+
// eslint-disable-next-line no-console
|
7
|
+
console.log('ConsoleProvider pageView', url);
|
8
|
+
}
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
10
|
+
registerProvider(): void {}
|
11
|
+
|
12
|
+
initialize(): void {
|
13
|
+
// eslint-disable-next-line no-console
|
14
|
+
console.log('ConsoleProvider initialize');
|
15
|
+
}
|
16
|
+
|
17
|
+
identify(userID: string): void {
|
18
|
+
// eslint-disable-next-line no-console
|
19
|
+
console.log('ConsoleProvider identify', userID);
|
20
|
+
}
|
21
|
+
|
22
|
+
trackSingleItem(item: string, properties?: TrackingEventProperties): void {
|
23
|
+
// eslint-disable-next-line no-console
|
24
|
+
console.log('ConsoleProvider: ' + item, properties);
|
25
|
+
}
|
26
|
+
|
27
|
+
getKey(): string {
|
28
|
+
return 'console';
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { posthog } from 'posthog-js';
|
2
|
+
|
3
|
+
import { TrackingApi, TrackingEventProperties } from './tracking_api';
|
4
|
+
import { InitProps, TrackingSpi } from './tracking_spi';
|
5
|
+
|
6
|
+
export class PosthogTrackingProvider implements TrackingSpi, TrackingApi {
|
7
|
+
getKey(): string {
|
8
|
+
return 'posthogKey';
|
9
|
+
}
|
10
|
+
|
11
|
+
initialize(props: InitProps): void {
|
12
|
+
// eslint-disable-next-line no-console
|
13
|
+
console.log('PosthogProvider initialize');
|
14
|
+
const posthogKey = props.posthogKey as string;
|
15
|
+
|
16
|
+
posthog.init(posthogKey, {
|
17
|
+
// eslint-disable-next-line camelcase
|
18
|
+
api_host: 'https://us.i.posthog.com',
|
19
|
+
// eslint-disable-next-line camelcase
|
20
|
+
person_profiles: 'identified_only' // or 'always' to create profiles for anonymous users as well
|
21
|
+
});
|
22
|
+
}
|
23
|
+
|
24
|
+
identify(userID: string): void {
|
25
|
+
// eslint-disable-next-line no-console
|
26
|
+
console.log('PosthogProvider userID: ' + userID);
|
27
|
+
posthog.identify(userID);
|
28
|
+
}
|
29
|
+
|
30
|
+
trackPageView(url: string | undefined): void {
|
31
|
+
// eslint-disable-next-line no-console
|
32
|
+
console.log('PostHogProvider url', url);
|
33
|
+
// TODO posthog seems to record that automatically.
|
34
|
+
// How to not clash with this here? Just leave as no-op?
|
35
|
+
}
|
36
|
+
|
37
|
+
trackSingleItem(item: string, properties?: TrackingEventProperties): void {
|
38
|
+
// eslint-disable-next-line no-console
|
39
|
+
console.log('PosthogProvider: trackSingleItem' + item, properties);
|
40
|
+
posthog.capture(item, { properties });
|
41
|
+
}
|
42
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { AnalyticsBrowser } from '@segment/analytics-next';
|
2
|
+
|
3
|
+
import { TrackingApi, TrackingEventProperties } from './tracking_api';
|
4
|
+
import { InitProps, TrackingSpi } from './tracking_spi';
|
5
|
+
|
6
|
+
export class SegmentTrackingProvider implements TrackingSpi, TrackingApi {
|
7
|
+
private analytics: AnalyticsBrowser | undefined;
|
8
|
+
getKey(): string {
|
9
|
+
return 'segmentKey';
|
10
|
+
}
|
11
|
+
|
12
|
+
initialize(props: InitProps): void {
|
13
|
+
// eslint-disable-next-line no-console
|
14
|
+
console.log('SegmentProvider initialize');
|
15
|
+
const segmentKey = props.segmentKey as string;
|
16
|
+
|
17
|
+
// We need to create an object here, as ts lint is unhappy otherwise
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
19
|
+
const integrations = props.segmentIntegrations as any;
|
20
|
+
|
21
|
+
this.analytics = AnalyticsBrowser.load(
|
22
|
+
{
|
23
|
+
writeKey: segmentKey,
|
24
|
+
cdnURL: props.segmentCdn as string
|
25
|
+
},
|
26
|
+
|
27
|
+
{
|
28
|
+
integrations: {
|
29
|
+
...integrations
|
30
|
+
}
|
31
|
+
}
|
32
|
+
);
|
33
|
+
}
|
34
|
+
|
35
|
+
identify(userID: string): void {
|
36
|
+
// eslint-disable-next-line no-console
|
37
|
+
console.log('SegmentProvider userID: ' + userID);
|
38
|
+
if (this.analytics) {
|
39
|
+
this.analytics.identify(userID);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
trackPageView(url: string | undefined): void {
|
44
|
+
// eslint-disable-next-line no-console
|
45
|
+
console.log('SegmentProvider url', url);
|
46
|
+
if (this.analytics) {
|
47
|
+
if (url) {
|
48
|
+
this.analytics.page(url);
|
49
|
+
} else {
|
50
|
+
this.analytics.page(); // Uses window.url
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
trackSingleItem(item: string, properties?: TrackingEventProperties): void {
|
56
|
+
// eslint-disable-next-line no-console
|
57
|
+
console.log('SegmentProvider: trackSingleItem' + item, properties);
|
58
|
+
if (this.analytics) {
|
59
|
+
this.analytics.track(item, { properties });
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { TrackingApi, TrackingEventProperties } from './tracking_api';
|
2
|
+
class TrackingProviderProxy implements TrackingApi {
|
3
|
+
providers: TrackingApi[] = [];
|
4
|
+
|
5
|
+
constructor(providers: TrackingApi[]) {
|
6
|
+
this.providers = providers;
|
7
|
+
}
|
8
|
+
|
9
|
+
identify(userID: string): void {
|
10
|
+
for (const provider of this.providers) {
|
11
|
+
provider.identify(userID);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
trackSingleItem(eventName: string, properties?: TrackingEventProperties): void {
|
16
|
+
for (const provider of this.providers) {
|
17
|
+
provider.trackSingleItem(eventName, properties);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
trackPageView(url: string | undefined) {
|
22
|
+
for (const provider of this.providers) {
|
23
|
+
provider.trackPageView(url);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
export default TrackingProviderProxy;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
export interface TrackingEventProperties {
|
2
|
+
[key: string]: string | number | boolean | undefined;
|
3
|
+
}
|
4
|
+
|
5
|
+
export interface TrackingApi {
|
6
|
+
identify: (userID: string) => void;
|
7
|
+
|
8
|
+
trackPageView: (url: string | undefined) => void;
|
9
|
+
|
10
|
+
trackSingleItem: (eventName: string, properties: TrackingEventProperties | undefined) => void;
|
11
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { InitProps, TrackingSpi } from './tracking_spi';
|
2
|
+
import { TrackingApi } from './tracking_api';
|
3
|
+
import TrackingProviderProxy from './trackingProviderProxy';
|
4
|
+
import { ConsoleTrackingProvider } from './console_tracking_provider';
|
5
|
+
import { SegmentTrackingProvider } from './segment_tracking_provider';
|
6
|
+
import { PosthogTrackingProvider } from './posthog_tracking_provider';
|
7
|
+
import { UmamiTrackingProvider } from './umami_tracking_provider';
|
8
|
+
|
9
|
+
export const getTrackingProviders = (initProps: InitProps): TrackingApi => {
|
10
|
+
const providers: TrackingSpi[] = [];
|
11
|
+
providers.push(new SegmentTrackingProvider());
|
12
|
+
providers.push(new PosthogTrackingProvider());
|
13
|
+
providers.push(new UmamiTrackingProvider());
|
14
|
+
|
15
|
+
// TODO dynamically find and register providers
|
16
|
+
|
17
|
+
// Initialize them
|
18
|
+
const enabledProviders: TrackingSpi[] = [];
|
19
|
+
for (const provider of providers) {
|
20
|
+
const key = provider.getKey();
|
21
|
+
if (Object.keys(initProps).indexOf(key) > -1) {
|
22
|
+
provider.initialize(initProps);
|
23
|
+
enabledProviders.push(provider);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
// Add the console provider
|
27
|
+
const consoleTrackingProvider = new ConsoleTrackingProvider();
|
28
|
+
enabledProviders.push(consoleTrackingProvider); // TODO noop- provider?
|
29
|
+
|
30
|
+
return new TrackingProviderProxy(enabledProviders);
|
31
|
+
};
|
32
|
+
|
33
|
+
export default getTrackingProviders;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { TrackingApi, TrackingEventProperties } from './tracking_api';
|
2
|
+
|
3
|
+
export interface InitProps {
|
4
|
+
[key: string]: string | number | boolean;
|
5
|
+
}
|
6
|
+
|
7
|
+
export interface TrackingSpi extends TrackingApi {
|
8
|
+
// Return a key in InitProps to check if the provided should be enabled
|
9
|
+
getKey: () => string;
|
10
|
+
// Initialize the provider
|
11
|
+
initialize: (props: InitProps) => void;
|
12
|
+
// Track a single item
|
13
|
+
trackSingleItem: (item: string, properties?: TrackingEventProperties) => void;
|
14
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { InitProps, TrackingSpi } from './tracking_spi';
|
2
|
+
import { TrackingApi, TrackingEventProperties } from './tracking_api';
|
3
|
+
|
4
|
+
declare global {
|
5
|
+
interface Window {
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
7
|
+
umami: any;
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
export class UmamiTrackingProvider implements TrackingSpi, TrackingApi {
|
12
|
+
getKey(): string {
|
13
|
+
return 'umamiKey';
|
14
|
+
}
|
15
|
+
|
16
|
+
initialize(props: InitProps): void {
|
17
|
+
// eslint-disable-next-line no-console
|
18
|
+
console.log('UmamiProvider initialize');
|
19
|
+
const umamiKey = props.umamiKey as string;
|
20
|
+
const hostUrl = props.umamiHostUrl as string;
|
21
|
+
|
22
|
+
const script = document.createElement('script');
|
23
|
+
script.src = hostUrl + '/script.js';
|
24
|
+
script.async = true;
|
25
|
+
script.defer = true;
|
26
|
+
|
27
|
+
// Configure Umami properties
|
28
|
+
script.setAttribute('data-website-id', umamiKey);
|
29
|
+
script.setAttribute('data-domains', 'localhost'); // TODO ?
|
30
|
+
script.setAttribute('data-auto-track', 'false');
|
31
|
+
script.setAttribute('data-host-url', hostUrl); // TODO ?
|
32
|
+
script.setAttribute('data-exclude-search', 'false'); // TODO ?
|
33
|
+
|
34
|
+
document.body.appendChild(script);
|
35
|
+
}
|
36
|
+
|
37
|
+
identify(userID: string): void {
|
38
|
+
// eslint-disable-next-line no-console
|
39
|
+
console.log('UmamiProvider userID: ' + userID);
|
40
|
+
window.umami?.identify({ userID });
|
41
|
+
}
|
42
|
+
|
43
|
+
trackPageView(url: string | undefined): void {
|
44
|
+
// eslint-disable-next-line no-console
|
45
|
+
console.log('UmamiProvider url', url);
|
46
|
+
window.umami?.track({ url });
|
47
|
+
}
|
48
|
+
|
49
|
+
trackSingleItem(item: string, properties?: TrackingEventProperties): void {
|
50
|
+
// eslint-disable-next-line no-console
|
51
|
+
console.log('UmamiProvider: trackSingleItem' + item, properties);
|
52
|
+
window.umami?.track(item, properties);
|
53
|
+
}
|
54
|
+
}
|