mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-02 22:37:32 +00:00
Backport: chief-pig -> rh-test (commits: f2952e9ef2 5d7321e23a 75857b35b5 bf03253709 df68b56483 )
This commit is contained in:
@@ -4,9 +4,11 @@ import { compare, valid } from 'semver'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import type { SettingParams } from '@/platform/settings/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import type { Settings } from '@/schemas/apiSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import type { TreeNode } from '@/types/treeExplorerTypes'
|
||||
|
||||
export const getSettingInfo = (setting: SettingParams) => {
|
||||
@@ -73,6 +75,39 @@ export const useSettingStore = defineStore('setting', () => {
|
||||
onChange(settingsById.value[key], newValue, oldValue)
|
||||
settingValues.value[key] = newValue
|
||||
await api.storeSetting(key, newValue)
|
||||
|
||||
try {
|
||||
const dialogStore = useDialogStore()
|
||||
if (dialogStore.isDialogOpen('global-settings')) {
|
||||
const telemetry = useTelemetry()
|
||||
const settingParameter = settingsById.value[key]
|
||||
const { category, subCategory } = getSettingInfo(
|
||||
settingParameter ??
|
||||
({
|
||||
id: String(key)
|
||||
} as unknown as SettingParams)
|
||||
)
|
||||
|
||||
const inputType = (() => {
|
||||
const settingType = settingParameter?.type
|
||||
if (!settingType) return undefined
|
||||
return typeof settingType === 'function'
|
||||
? 'custom'
|
||||
: String(settingType)
|
||||
})()
|
||||
|
||||
telemetry?.trackSettingChanged({
|
||||
setting_id: String(key),
|
||||
input_type: inputType,
|
||||
category,
|
||||
sub_category: subCategory,
|
||||
previous_value: oldValue,
|
||||
new_value: newValue
|
||||
})
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to track setting change', err)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
NodeSearchResultMetadata,
|
||||
PageVisibilityMetadata,
|
||||
RunButtonProperties,
|
||||
SettingChangedMetadata,
|
||||
SurveyResponses,
|
||||
TabCountMetadata,
|
||||
TelemetryEventName,
|
||||
@@ -413,6 +414,10 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
|
||||
this.trackEvent(TelemetryEvents.EXECUTION_SUCCESS, metadata)
|
||||
}
|
||||
|
||||
trackSettingChanged(metadata: SettingChangedMetadata): void {
|
||||
this.trackEvent(TelemetryEvents.SETTING_CHANGED, metadata)
|
||||
}
|
||||
|
||||
getExecutionContext(): ExecutionContext {
|
||||
// Try to initialize composables if not ready and not in onboarding mode
|
||||
if (!this._composablesReady && !this.isOnboardingMode) {
|
||||
|
||||
@@ -126,6 +126,18 @@ export interface TabCountMetadata {
|
||||
tab_count: number
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings change metadata
|
||||
*/
|
||||
export interface SettingChangedMetadata {
|
||||
setting_id: string
|
||||
input_type?: string
|
||||
category?: string
|
||||
sub_category?: string
|
||||
previous_value?: unknown
|
||||
new_value?: unknown
|
||||
}
|
||||
|
||||
/**
|
||||
* Node search metadata
|
||||
*/
|
||||
@@ -200,6 +212,9 @@ export interface TelemetryProvider {
|
||||
trackExecutionError(metadata: ExecutionErrorMetadata): void
|
||||
trackExecutionSuccess(metadata: ExecutionSuccessMetadata): void
|
||||
|
||||
// Settings events
|
||||
trackSettingChanged(metadata: SettingChangedMetadata): void
|
||||
|
||||
// App lifecycle management
|
||||
markAppReady?(): void
|
||||
identifyUser?(userId: string): void
|
||||
@@ -247,6 +262,9 @@ export const TelemetryEvents = {
|
||||
// Template Filter Analytics
|
||||
TEMPLATE_FILTER_CHANGED: 'app:template_filter_changed',
|
||||
|
||||
// Settings
|
||||
SETTING_CHANGED: 'app:setting_changed',
|
||||
|
||||
// Execution Lifecycle
|
||||
EXECUTION_START: 'execution_start',
|
||||
EXECUTION_ERROR: 'execution_error',
|
||||
@@ -275,3 +293,4 @@ export type TelemetryEventProperties =
|
||||
| NodeSearchMetadata
|
||||
| NodeSearchResultMetadata
|
||||
| TemplateFilterMetadata
|
||||
| SettingChangedMetadata
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
import type { SettingParams } from '@/platform/settings/types'
|
||||
import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
|
||||
// Mock the api
|
||||
vi.mock('@/scripts/api', () => ({
|
||||
@@ -17,6 +18,14 @@ vi.mock('@/scripts/api', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock telemetry provider
|
||||
const trackSettingChanged = vi.fn()
|
||||
vi.mock('@/platform/telemetry', () => ({
|
||||
useTelemetry: vi.fn(() => ({
|
||||
trackSettingChanged
|
||||
}))
|
||||
}))
|
||||
|
||||
// Mock the app
|
||||
vi.mock('@/scripts/app', () => ({
|
||||
app: {
|
||||
@@ -399,6 +408,53 @@ describe('useSettingStore', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should send telemetry when global settings dialog is visible', async () => {
|
||||
const setting: SettingParams = {
|
||||
id: 'main.sub.setting.name',
|
||||
name: 'Telemetry Visible',
|
||||
type: 'text',
|
||||
defaultValue: 'default'
|
||||
}
|
||||
|
||||
store.addSetting(setting)
|
||||
|
||||
const dialogStore = useDialogStore()
|
||||
dialogStore.showDialog({
|
||||
key: 'global-settings',
|
||||
title: 'Settings',
|
||||
component: {}
|
||||
})
|
||||
|
||||
await store.set('main.sub.setting.name', 'newvalue')
|
||||
|
||||
expect(trackSettingChanged).toHaveBeenCalledTimes(1)
|
||||
expect(trackSettingChanged).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
setting_id: 'main.sub.setting.name',
|
||||
input_type: 'text',
|
||||
category: 'main',
|
||||
sub_category: 'sub',
|
||||
previous_value: 'default',
|
||||
new_value: 'newvalue'
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('should not send telemetry when global settings dialog is not visible', async () => {
|
||||
const setting: SettingParams = {
|
||||
id: 'main.sub.setting.name',
|
||||
name: 'Telemetry Invisible',
|
||||
type: 'text',
|
||||
defaultValue: 'default'
|
||||
}
|
||||
|
||||
store.addSetting(setting)
|
||||
|
||||
await store.set('main.sub.setting.name', 'newvalue')
|
||||
|
||||
expect(trackSettingChanged).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
describe('object mutation prevention', () => {
|
||||
beforeEach(() => {
|
||||
const setting: SettingParams = {
|
||||
|
||||
Reference in New Issue
Block a user