@knime/hub-features 1.26.2 → 1.28.0
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/CHANGELOG.md +18 -0
- package/package.json +5 -3
- package/src/analytics/README.md +19 -73
- package/src/analytics/analytics.ts +97 -57
- package/src/analytics/index.ts +1 -1
- package/src/analytics/schema/cloudhome-event-functions.ts +247 -0
- package/src/analytics/schema/code-generator.js +158 -0
- package/src/analytics/schema/editor-event-functions.ts +1121 -0
- package/src/analytics/schema/schema.d.ts +765 -122
- package/src/analytics/schema/schema.json +3916 -269
- package/src/analytics/types.ts +22 -46
- package/src/analytics/utils/logger.ts +1 -0
- package/src/analytics/utils/eventIds.ts +0 -35
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @knime/hub-features
|
|
2
2
|
|
|
3
|
+
## 1.28.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2908385: - split returned events based on event source (editor/cloudhome)
|
|
8
|
+
- add secret created event (cloudhome)
|
|
9
|
+
- introduce page property to interaction property (only for cloudhome events)
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- a2f988b: add cloudhome events for creating and sharing deployments
|
|
14
|
+
|
|
15
|
+
## 1.27.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- 3a49573: Rework API for analytic events and the underlying schema
|
|
20
|
+
|
|
3
21
|
## 1.26.2
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knime/hub-features",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.28.0",
|
|
4
4
|
"description": "Vue components & composables for shared hub features",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"lodash-es": "4.18.1",
|
|
40
40
|
"ofetch": "^1.4.1",
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
|
-
"@knime/components": "1.46.6",
|
|
43
42
|
"@knime/styles": "1.15.1",
|
|
43
|
+
"@knime/components": "1.46.6",
|
|
44
44
|
"@knime/utils": "1.11.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
@@ -62,6 +62,8 @@
|
|
|
62
62
|
"scripts": {
|
|
63
63
|
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
|
64
64
|
"test:unit": "TZ='Europe/Berlin' vitest",
|
|
65
|
-
"generate-analytics-events": "
|
|
65
|
+
"generate-analytics-events": "pnpm generate-event-types && pnpm generate-event-functions",
|
|
66
|
+
"generate-event-types": "json2ts ./src/analytics/schema/schema.json > ./src/analytics/schema/schema.d.ts",
|
|
67
|
+
"generate-event-functions": "node ./src/analytics/schema/code-generator.js"
|
|
66
68
|
}
|
|
67
69
|
}
|
package/src/analytics/README.md
CHANGED
|
@@ -2,86 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
## Preface
|
|
4
4
|
|
|
5
|
-
This package provides
|
|
6
|
-
|
|
7
|
-
- Provides a builder function that creates and normalizes event payloads
|
|
8
|
-
- Provides a sender function that forwards a given event payload to a third party API.
|
|
9
|
-
The implementation of the third-party API is up to the consumer as long as it satisfies the adapter contract
|
|
10
|
-
|
|
11
|
-
The main reason why these behaviors are split are for increased flexibility and to also enable this feature being used on a setup where the creation of the event is separated to the sending of the event. Like for example, on host/guest application combination where there's an iframe communication layer between both apps.
|
|
5
|
+
This package provides functions that can produce analytics events.
|
|
12
6
|
|
|
13
7
|
## Usage examples
|
|
14
8
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
As stated above, some applications might only care (or have the correct setup) to construct events based on different code paths and user interactions.
|
|
9
|
+
This package makes no assumption of how the events are sent. Therefore, one must supply a "sender" as
|
|
10
|
+
part of the initialization.
|
|
18
11
|
|
|
19
12
|
```ts
|
|
20
13
|
import { analyticsEvents } from "@knime/hub-features/analytics";
|
|
21
14
|
|
|
22
|
-
// Create a
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
const event = newEvent({ id: "kai_prompted::kaiqa_button_prompt" });
|
|
28
|
-
|
|
29
|
-
// once you have this event object, the application can decide what to do with it.
|
|
30
|
-
// Whether that is sending it through an iframe as a message or some other event bus. OR sending it directly if it's so desired (see Sending events section)
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Keeping types in-sync
|
|
34
|
-
|
|
35
|
-
Due to the strict-type setup and the shape of the API of this package, reusing the type signature
|
|
36
|
-
of the function that creates the events can be tricky. However, this is helpful, for example, if you want to
|
|
37
|
-
wrap the create function with some other behavior of your own but keep the strong-type guarantees.
|
|
38
|
-
Below you can see an example for this use-case:
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
import {
|
|
42
|
-
analyticsEvents,
|
|
43
|
-
type CreateEventFn,
|
|
44
|
-
} from "@knime/hub-features/analytics";
|
|
45
|
-
|
|
46
|
-
const myCustomFunction: CreateEventFn = (...args) => {
|
|
47
|
-
const { newEvent } = analyticsEvents.eventBuilder(TheNeededContext);
|
|
48
|
-
|
|
49
|
-
// do something before
|
|
50
|
-
|
|
51
|
-
const event = newEvent(...args);
|
|
52
|
-
|
|
53
|
-
// do something with event
|
|
15
|
+
// Create a sender, which can be pretty much any object that provides a `send` function
|
|
16
|
+
const mySender = {
|
|
17
|
+
send: ({ event }) => {
|
|
18
|
+
// do something with event (e.g send over WS, dispatch to an iframe's parent, etc)
|
|
19
|
+
},
|
|
54
20
|
};
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
In this case, the type signature of `myCustomFunction` will match the one of `newEvent`, just like
|
|
58
|
-
in the previous example.
|
|
59
|
-
|
|
60
|
-
### Sending events
|
|
61
|
-
|
|
62
|
-
As stated in the preface, to send events, you need to provide an adapter
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
import {
|
|
66
|
-
analyticsEvents,
|
|
67
|
-
type AnalyticsAdapter,
|
|
68
|
-
} from "@knime/hub-features/analytics";
|
|
69
|
-
|
|
70
|
-
const myAdapter: AnalyticsAdapter = {
|
|
71
|
-
sendEvent({ event, metadata, idParser }) {
|
|
72
|
-
console.log("Parsed id", idParser(event.id));
|
|
73
|
-
console.log("Metadata", metadata);
|
|
74
|
-
console.log("Event", event)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// create the sender
|
|
79
|
-
const sender = analyticsEvents.eventSender(myAdapter);
|
|
80
|
-
|
|
81
|
-
// some event
|
|
82
|
-
const { newEvent } = analyticsEvents.eventBuilder(TheNeededContext);
|
|
83
|
-
const event = newEvent(...);
|
|
84
21
|
|
|
85
|
-
//
|
|
86
|
-
|
|
22
|
+
// Initialize the tracker
|
|
23
|
+
type SomeContext = { myContextField: string };
|
|
24
|
+
const eventTracker = analyticsEvents.init<SomeContext>({
|
|
25
|
+
context: { myContextField: "foo-123" },
|
|
26
|
+
sender: mySender,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Track an event. `someEvent` here is a placeholder name. In reality, the API will provide named functions that
|
|
30
|
+
// strongly-typed and may or may not require payload depending on the event's definition. Under the hood this will
|
|
31
|
+
// use the configured sender to forward your event
|
|
32
|
+
eventTracker.someEvent();
|
|
87
33
|
```
|
|
@@ -1,76 +1,116 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import * as cloudHomeFunctions from "./schema/cloudhome-event-functions";
|
|
3
|
+
import * as editorFunctions from "./schema/editor-event-functions";
|
|
1
4
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
CreateEventFn,
|
|
5
|
+
AnalyticsEvent,
|
|
6
|
+
AnalyticsEventSender,
|
|
7
|
+
DefaultContext,
|
|
6
8
|
Metadata,
|
|
7
9
|
} from "./types";
|
|
8
|
-
import { eventID } from "./utils/eventIds";
|
|
9
|
-
import { toSnakeCaseDeep } from "./utils/toSnakeCaseDeep";
|
|
10
10
|
|
|
11
11
|
const METADATA: Metadata = Object.freeze({
|
|
12
|
-
version: "
|
|
12
|
+
version: "v2.0",
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Unwraps the inner function imported from the generated functions.
|
|
17
|
+
* With this supply the context here and just expose the inner function
|
|
18
|
+
* but also ensure we keep the same names and type constraints
|
|
19
|
+
*/
|
|
20
|
+
type UnwrapFunction<T> = T extends (ctx: DefaultContext) => infer R
|
|
21
|
+
? R extends (...args: infer P) => infer Q
|
|
22
|
+
? (...args: P) => Q
|
|
23
|
+
: never
|
|
24
|
+
: never;
|
|
25
|
+
|
|
26
|
+
type EditorFunctionMap = typeof editorFunctions;
|
|
27
|
+
type CloudHomeFunctionMap = typeof cloudHomeFunctions;
|
|
28
|
+
|
|
29
|
+
type EditorBuilderFunctions = {
|
|
30
|
+
[K in keyof EditorFunctionMap]: UnwrapFunction<EditorFunctionMap[K]>;
|
|
31
|
+
};
|
|
32
|
+
type CloudHomeBuilderFunctions = {
|
|
33
|
+
[K in keyof CloudHomeFunctionMap]: UnwrapFunction<CloudHomeFunctionMap[K]>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type EditorSenderFunctions = {
|
|
37
|
+
[K in keyof EditorBuilderFunctions]: (
|
|
38
|
+
...args: Parameters<EditorBuilderFunctions[K]>
|
|
39
|
+
) => void;
|
|
40
|
+
};
|
|
41
|
+
type CloudHomeSenderFunctions = {
|
|
42
|
+
[K in keyof CloudHomeBuilderFunctions]: (
|
|
43
|
+
...args: Parameters<CloudHomeBuilderFunctions[K]>
|
|
44
|
+
) => void;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type BuilderFunctions<T extends DefaultContext> =
|
|
48
|
+
T["eventSource"] extends "editor"
|
|
49
|
+
? EditorBuilderFunctions
|
|
50
|
+
: CloudHomeBuilderFunctions;
|
|
51
|
+
|
|
52
|
+
type SenderFunctions<T extends DefaultContext> =
|
|
53
|
+
T["eventSource"] extends "editor"
|
|
54
|
+
? EditorSenderFunctions
|
|
55
|
+
: CloudHomeSenderFunctions;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* This function creates an event builder, which lets you construct correct and strongly-typed
|
|
59
|
+
* event payloads according to the current schema used by this package
|
|
60
|
+
* @param context
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
function eventBuilder<T extends DefaultContext>(
|
|
64
|
+
context: T,
|
|
65
|
+
): BuilderFunctions<T> {
|
|
66
|
+
const unwrapped = Object.fromEntries(
|
|
67
|
+
Object.entries(
|
|
68
|
+
context.eventSource === "editor" ? editorFunctions : cloudHomeFunctions,
|
|
69
|
+
).map(([name, fn]) => [name, fn(context)]),
|
|
70
|
+
) as BuilderFunctions<T>;
|
|
71
|
+
|
|
72
|
+
return { ...unwrapped };
|
|
73
|
+
}
|
|
74
|
+
|
|
15
75
|
export const analyticsEvents = Object.freeze({
|
|
16
76
|
METADATA,
|
|
17
77
|
/**
|
|
18
|
-
*
|
|
19
|
-
* event payloads according to the current schema used by this package
|
|
20
|
-
* @param context
|
|
21
|
-
* @returns
|
|
78
|
+
* Initialize the analytic event tracker
|
|
22
79
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
80
|
+
init: <T extends DefaultContext>(params: {
|
|
81
|
+
/**
|
|
82
|
+
* Context for the initialized tracker. This will remain unchanged throughout the lifecycle
|
|
83
|
+
* of this tracker
|
|
84
|
+
*/
|
|
85
|
+
context: T;
|
|
86
|
+
/**
|
|
87
|
+
* Sender interface; will be used to determine how to handle each event when its
|
|
88
|
+
* corresponding track function is invoked
|
|
89
|
+
*/
|
|
90
|
+
sender: AnalyticsEventSender;
|
|
91
|
+
}) => {
|
|
92
|
+
const builder = eventBuilder(params.context);
|
|
32
93
|
|
|
33
|
-
|
|
94
|
+
type AnyFn = (...args: any[]) => any;
|
|
34
95
|
|
|
35
|
-
|
|
36
|
-
if (!eventData) {
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
96
|
+
const wrapper = {} as SenderFunctions<T>;
|
|
39
97
|
|
|
40
|
-
|
|
41
|
-
|
|
98
|
+
// keep all the same functions of the builder but wrap around them for extra behavior
|
|
99
|
+
Object.keys(builder).forEach((fnName) => {
|
|
100
|
+
const key = fnName as keyof SenderFunctions<T>;
|
|
101
|
+
(wrapper as any)[key] = (...args: any[]) => {
|
|
102
|
+
// TS issue:
|
|
103
|
+
// ```A spread argument must either have a tuple type or be passed to a rest parameter.```
|
|
104
|
+
// This happens because when calling the methods generically, TS tries to join all function signatures
|
|
105
|
+
// into a union of tuples that contains all possible argument combinations for all of the functions.
|
|
106
|
+
// This leads to an unresolvable type error
|
|
107
|
+
// More details on the issue, see: https://github.com/microsoft/TypeScript/issues/49700
|
|
108
|
+
const event: AnalyticsEvent = (builder[key] as AnyFn)(...args);
|
|
42
109
|
|
|
43
|
-
|
|
44
|
-
id: `editor_${eventId}`,
|
|
45
|
-
data: {
|
|
46
|
-
...data,
|
|
47
|
-
// eslint-disable-next-line camelcase
|
|
48
|
-
job_id: context.jobId,
|
|
49
|
-
// eslint-disable-next-line camelcase
|
|
50
|
-
event_id: uniqueEventId,
|
|
51
|
-
timestamp: new Date().toISOString(),
|
|
52
|
-
},
|
|
110
|
+
params.sender.send({ event, metadata: METADATA });
|
|
53
111
|
};
|
|
112
|
+
});
|
|
54
113
|
|
|
55
|
-
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
return { newEvent };
|
|
59
|
-
},
|
|
60
|
-
/**
|
|
61
|
-
* This function creates an event sender which will use an internal implementation of an adapter
|
|
62
|
-
* to forward the event's data to an external third-party provider
|
|
63
|
-
* @returns
|
|
64
|
-
*/
|
|
65
|
-
eventSender: (adapter: AnalyticsAdapter) => {
|
|
66
|
-
const send = (event: AnalyticsPayload) => {
|
|
67
|
-
adapter.sendEvent({
|
|
68
|
-
event,
|
|
69
|
-
idParser: eventID(event.id).parse,
|
|
70
|
-
metadata: METADATA,
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return { send };
|
|
114
|
+
return wrapper;
|
|
75
115
|
},
|
|
76
116
|
});
|
package/src/analytics/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from "./analytics";
|
|
2
|
-
export type {
|
|
2
|
+
export type { AnalyticsEvent, AnalyticsEventSender } from "./types";
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
|
|
2
|
+
/* eslint-disable camelcase */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
// AUTO-GENERATED FILE. DO NOT EDIT.
|
|
5
|
+
import type { AnalyticsEvent, DefaultContext, EventFunctionArgs, GeneratedStaticFields, SchemaStaticFields } from "../types";
|
|
6
|
+
import { toSnakeCaseDeep } from "../utils/toSnakeCaseDeep";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Fired when the user clicks Run from the deployments page
|
|
10
|
+
*/
|
|
11
|
+
export const adHocExecutionStartedDeploymentsPage = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
|
|
12
|
+
const staticData = {
|
|
13
|
+
...toSnakeCaseDeep(ctx),
|
|
14
|
+
unique_event_id: crypto.randomUUID(),
|
|
15
|
+
timestamp: new Date().toISOString(),
|
|
16
|
+
event_name: "adhoc_execution_started",
|
|
17
|
+
event_source: "cloudhome",
|
|
18
|
+
event_display_name: "Ad Hoc Execution Started",
|
|
19
|
+
interaction: {
|
|
20
|
+
location: "main_area",
|
|
21
|
+
page: "deployments",
|
|
22
|
+
trigger: "user",
|
|
23
|
+
type: "click",
|
|
24
|
+
},
|
|
25
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
26
|
+
|
|
27
|
+
const event = { id: staticData.event_name, data: { ...staticData } };
|
|
28
|
+
|
|
29
|
+
return event;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Fired when the user clicks Run in the ad hoc execution panel
|
|
34
|
+
*/
|
|
35
|
+
export const adHocExecutionStartedExecutionPanel = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
|
|
36
|
+
const staticData = {
|
|
37
|
+
...toSnakeCaseDeep(ctx),
|
|
38
|
+
unique_event_id: crypto.randomUUID(),
|
|
39
|
+
timestamp: new Date().toISOString(),
|
|
40
|
+
event_name: "adhoc_execution_started",
|
|
41
|
+
event_source: "cloudhome",
|
|
42
|
+
event_display_name: "Ad Hoc Execution Started",
|
|
43
|
+
interaction: {
|
|
44
|
+
location: "contextual_side_panel",
|
|
45
|
+
page: "workflow_details",
|
|
46
|
+
trigger: "user",
|
|
47
|
+
type: "click",
|
|
48
|
+
},
|
|
49
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
50
|
+
|
|
51
|
+
const event = { id: staticData.event_name, data: { ...staticData } };
|
|
52
|
+
|
|
53
|
+
return event;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Fired when the user clicks Run from the workflow page
|
|
58
|
+
*/
|
|
59
|
+
export const adHocExecutionStartedWorkflowPage = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
|
|
60
|
+
const staticData = {
|
|
61
|
+
...toSnakeCaseDeep(ctx),
|
|
62
|
+
unique_event_id: crypto.randomUUID(),
|
|
63
|
+
timestamp: new Date().toISOString(),
|
|
64
|
+
event_name: "adhoc_execution_started",
|
|
65
|
+
event_source: "cloudhome",
|
|
66
|
+
event_display_name: "Ad Hoc Execution Started",
|
|
67
|
+
interaction: {
|
|
68
|
+
location: "main_area",
|
|
69
|
+
page: "workflow_details",
|
|
70
|
+
trigger: "user",
|
|
71
|
+
type: "click",
|
|
72
|
+
},
|
|
73
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
74
|
+
|
|
75
|
+
const event = { id: staticData.event_name, data: { ...staticData } };
|
|
76
|
+
|
|
77
|
+
return event;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Fired when the user creates a new secret by clicking Create in the side panel on the team secrets page
|
|
82
|
+
*/
|
|
83
|
+
export const secretCreatedTeamSecrets = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
|
|
84
|
+
const staticData = {
|
|
85
|
+
...toSnakeCaseDeep(ctx),
|
|
86
|
+
unique_event_id: crypto.randomUUID(),
|
|
87
|
+
timestamp: new Date().toISOString(),
|
|
88
|
+
event_name: "secret_created",
|
|
89
|
+
event_source: "cloudhome",
|
|
90
|
+
event_display_name: "Secret Created",
|
|
91
|
+
interaction: {
|
|
92
|
+
location: "contextual_side_panel",
|
|
93
|
+
page: "secrets",
|
|
94
|
+
trigger: "user",
|
|
95
|
+
type: "click",
|
|
96
|
+
},
|
|
97
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
98
|
+
|
|
99
|
+
const event = { id: staticData.event_name, data: { ...staticData } };
|
|
100
|
+
|
|
101
|
+
return event;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Fired when the user creates a new secret by clicking Create in the side panel on the personal secrets page
|
|
106
|
+
*/
|
|
107
|
+
export const secretCreatedMySecrets = <T extends DefaultContext>(ctx: T) => (): AnalyticsEvent => {
|
|
108
|
+
const staticData = {
|
|
109
|
+
...toSnakeCaseDeep(ctx),
|
|
110
|
+
unique_event_id: crypto.randomUUID(),
|
|
111
|
+
timestamp: new Date().toISOString(),
|
|
112
|
+
event_name: "secret_created",
|
|
113
|
+
event_source: "cloudhome",
|
|
114
|
+
event_display_name: "Secret Created",
|
|
115
|
+
interaction: {
|
|
116
|
+
location: "contextual_side_panel",
|
|
117
|
+
page: "my_secrets",
|
|
118
|
+
trigger: "user",
|
|
119
|
+
type: "click",
|
|
120
|
+
},
|
|
121
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
122
|
+
|
|
123
|
+
const event = { id: staticData.event_name, data: { ...staticData } };
|
|
124
|
+
|
|
125
|
+
return event;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Fired when the user clicks the Create button in the deployment creation side panel
|
|
130
|
+
*/
|
|
131
|
+
export const deploymentCreated = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentCreated">): AnalyticsEvent => {
|
|
132
|
+
const staticData = {
|
|
133
|
+
...toSnakeCaseDeep(ctx),
|
|
134
|
+
unique_event_id: crypto.randomUUID(),
|
|
135
|
+
timestamp: new Date().toISOString(),
|
|
136
|
+
event_name: "deployment_created",
|
|
137
|
+
event_source: "cloudhome",
|
|
138
|
+
event_display_name: "Deployment Created",
|
|
139
|
+
interaction: {
|
|
140
|
+
location: "contextual_side_panel",
|
|
141
|
+
page: "deployments",
|
|
142
|
+
trigger: "user",
|
|
143
|
+
type: "click",
|
|
144
|
+
},
|
|
145
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
146
|
+
|
|
147
|
+
const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
|
|
148
|
+
|
|
149
|
+
return event;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Fired when the user shares a deployment via the access management side panel on the deployments page
|
|
154
|
+
*/
|
|
155
|
+
export const deploymentSharedDeploymentsAccessPanel = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedDeploymentsAccessPanel">): AnalyticsEvent => {
|
|
156
|
+
const staticData = {
|
|
157
|
+
...toSnakeCaseDeep(ctx),
|
|
158
|
+
unique_event_id: crypto.randomUUID(),
|
|
159
|
+
timestamp: new Date().toISOString(),
|
|
160
|
+
event_name: "deployment_shared",
|
|
161
|
+
event_source: "cloudhome",
|
|
162
|
+
event_display_name: "Deployment Shared",
|
|
163
|
+
interaction: {
|
|
164
|
+
location: "contextual_side_panel",
|
|
165
|
+
page: "deployments",
|
|
166
|
+
trigger: "user",
|
|
167
|
+
type: "click",
|
|
168
|
+
},
|
|
169
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
170
|
+
|
|
171
|
+
const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
|
|
172
|
+
|
|
173
|
+
return event;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Fired when the user shares a deployment via the sharing popup on the deployments page
|
|
178
|
+
*/
|
|
179
|
+
export const deploymentSharedDeploymentsSharingPopup = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedDeploymentsSharingPopup">): AnalyticsEvent => {
|
|
180
|
+
const staticData = {
|
|
181
|
+
...toSnakeCaseDeep(ctx),
|
|
182
|
+
unique_event_id: crypto.randomUUID(),
|
|
183
|
+
timestamp: new Date().toISOString(),
|
|
184
|
+
event_name: "deployment_shared",
|
|
185
|
+
event_source: "cloudhome",
|
|
186
|
+
event_display_name: "Deployment Shared",
|
|
187
|
+
interaction: {
|
|
188
|
+
location: "module",
|
|
189
|
+
page: "deployments",
|
|
190
|
+
trigger: "user",
|
|
191
|
+
type: "click",
|
|
192
|
+
},
|
|
193
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
194
|
+
|
|
195
|
+
const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
|
|
196
|
+
|
|
197
|
+
return event;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Fired when the user shares a deployment via the access management side panel on the workflow page
|
|
202
|
+
*/
|
|
203
|
+
export const deploymentSharedWorkflowAccessPanel = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedWorkflowAccessPanel">): AnalyticsEvent => {
|
|
204
|
+
const staticData = {
|
|
205
|
+
...toSnakeCaseDeep(ctx),
|
|
206
|
+
unique_event_id: crypto.randomUUID(),
|
|
207
|
+
timestamp: new Date().toISOString(),
|
|
208
|
+
event_name: "deployment_shared",
|
|
209
|
+
event_source: "cloudhome",
|
|
210
|
+
event_display_name: "Deployment Shared",
|
|
211
|
+
interaction: {
|
|
212
|
+
location: "contextual_side_panel",
|
|
213
|
+
page: "workflow_details",
|
|
214
|
+
trigger: "user",
|
|
215
|
+
type: "click",
|
|
216
|
+
},
|
|
217
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
218
|
+
|
|
219
|
+
const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
|
|
220
|
+
|
|
221
|
+
return event;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Fired when the user shares a deployment via the sharing popup on the workflow page
|
|
226
|
+
*/
|
|
227
|
+
export const deploymentSharedWorkflowSharingPopup = <T extends DefaultContext>(ctx: T) => (eventData: EventFunctionArgs<"deploymentSharedWorkflowSharingPopup">): AnalyticsEvent => {
|
|
228
|
+
const staticData = {
|
|
229
|
+
...toSnakeCaseDeep(ctx),
|
|
230
|
+
unique_event_id: crypto.randomUUID(),
|
|
231
|
+
timestamp: new Date().toISOString(),
|
|
232
|
+
event_name: "deployment_shared",
|
|
233
|
+
event_source: "cloudhome",
|
|
234
|
+
event_display_name: "Deployment Shared",
|
|
235
|
+
interaction: {
|
|
236
|
+
location: "module",
|
|
237
|
+
page: "workflow_details",
|
|
238
|
+
trigger: "user",
|
|
239
|
+
type: "click",
|
|
240
|
+
},
|
|
241
|
+
} satisfies SchemaStaticFields & GeneratedStaticFields;
|
|
242
|
+
|
|
243
|
+
const event = { id: staticData.event_name, data: { ...staticData, payload: { ...toSnakeCaseDeep(eventData as Record<string, any>) } } };
|
|
244
|
+
|
|
245
|
+
return event;
|
|
246
|
+
};
|
|
247
|
+
|