diff --git a/redisinsight/ui/src/components/config/Config.spec.tsx b/redisinsight/ui/src/components/config/Config.spec.tsx
index b7134bd176..c4f4aa65de 100644
--- a/redisinsight/ui/src/components/config/Config.spec.tsx
+++ b/redisinsight/ui/src/components/config/Config.spec.tsx
@@ -2,7 +2,7 @@ import React from 'react'
import { cloneDeep } from 'lodash'
import { BuildType } from 'uiSrc/constants/env'
import { localStorageService } from 'uiSrc/services'
-import { setFeaturesToHighlight, setOnboarding } from 'uiSrc/slices/app/features'
+import { getFeatureFlags, setFeaturesToHighlight, setOnboarding } from 'uiSrc/slices/app/features'
import { getNotifications } from 'uiSrc/slices/app/notifications'
import { render, mockedStore, cleanup, MOCKED_HIGHLIGHTING_FEATURES } from 'uiSrc/utils/test-utils'
@@ -63,6 +63,7 @@ describe('Config', () => {
getNotifications(),
getWBGuides(),
getWBTutorials(),
+ getFeatureFlags(),
getUserConfigSettings(),
]
expect(store.getActions()).toEqual([...afterRenderActions])
@@ -95,6 +96,7 @@ describe('Config', () => {
getNotifications(),
getWBGuides(),
getWBTutorials(),
+ getFeatureFlags(),
getUserConfigSettings(),
setSettingsPopupState(true),
]
diff --git a/redisinsight/ui/src/components/config/Config.tsx b/redisinsight/ui/src/components/config/Config.tsx
index da0c53696b..1fec3b36c9 100644
--- a/redisinsight/ui/src/components/config/Config.tsx
+++ b/redisinsight/ui/src/components/config/Config.tsx
@@ -6,7 +6,7 @@ import { BrowserStorageItem } from 'uiSrc/constants'
import { BuildType } from 'uiSrc/constants/env'
import { BUILD_FEATURES } from 'uiSrc/constants/featuresHighlighting'
import { localStorageService } from 'uiSrc/services'
-import { setFeaturesToHighlight, setOnboarding } from 'uiSrc/slices/app/features'
+import { fetchFeatureFlags, setFeaturesToHighlight, setOnboarding } from 'uiSrc/slices/app/features'
import { fetchNotificationsAction } from 'uiSrc/slices/app/notifications'
import {
@@ -53,6 +53,8 @@ const Config = () => {
dispatch(fetchGuides())
dispatch(fetchTutorials())
+ dispatch(fetchFeatureFlags())
+
// fetch config settings, after that take spec
if (pathname !== SETTINGS_PAGE_PATH) {
dispatch(fetchUserConfigSettings(() => dispatch(fetchUserSettingsSpec())))
diff --git a/redisinsight/ui/src/components/feature-flag-component/FeatureFlagComponent.spec.tsx b/redisinsight/ui/src/components/feature-flag-component/FeatureFlagComponent.spec.tsx
new file mode 100644
index 0000000000..8149c07827
--- /dev/null
+++ b/redisinsight/ui/src/components/feature-flag-component/FeatureFlagComponent.spec.tsx
@@ -0,0 +1,45 @@
+import React from 'react'
+import { render, screen } from 'uiSrc/utils/test-utils'
+
+import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
+import { FeatureFlags } from 'uiSrc/constants'
+
+import FeatureFlagComponent from './FeatureFlagComponent'
+
+jest.mock('uiSrc/slices/app/features', () => ({
+ ...jest.requireActual('uiSrc/slices/app/features'),
+ appFeatureFlagsFeaturesSelector: jest.fn().mockReturnValue({
+ name: {
+ flag: false
+ }
+ }),
+}))
+
+const InnerComponent = () => ()
+describe('FeatureFlagComponent', () => {
+ it('should not render component by default', () => {
+ render(
+
+
+
+ )
+
+ expect(screen.queryByTestId('inner-component')).not.toBeInTheDocument()
+ })
+
+ it('should render component', () => {
+ (appFeatureFlagsFeaturesSelector as jest.Mock).mockReturnValueOnce({
+ name: {
+ flag: true
+ }
+ })
+
+ render(
+
+
+
+ )
+
+ expect(screen.getByTestId('inner-component')).toBeInTheDocument()
+ })
+})
diff --git a/redisinsight/ui/src/components/feature-flag-component/FeatureFlagComponent.tsx b/redisinsight/ui/src/components/feature-flag-component/FeatureFlagComponent.tsx
new file mode 100644
index 0000000000..4a717b1b83
--- /dev/null
+++ b/redisinsight/ui/src/components/feature-flag-component/FeatureFlagComponent.tsx
@@ -0,0 +1,19 @@
+import React from 'react'
+import { useSelector } from 'react-redux'
+import { FeatureFlags } from 'uiSrc/constants'
+import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
+
+export interface Props {
+ name: FeatureFlags
+ children: React.ReactElement
+}
+
+const FeatureFlagComponent = (props: Props) => {
+ const { children, name } = props
+ const { [name]: feature } = useSelector(appFeatureFlagsFeaturesSelector)
+ const { flag, variant } = feature ?? { flag: false }
+
+ return flag ? React.cloneElement(children, { variant }) : null
+}
+
+export default FeatureFlagComponent
diff --git a/redisinsight/ui/src/components/feature-flag-component/index.ts b/redisinsight/ui/src/components/feature-flag-component/index.ts
new file mode 100644
index 0000000000..0061aed91d
--- /dev/null
+++ b/redisinsight/ui/src/components/feature-flag-component/index.ts
@@ -0,0 +1,3 @@
+import FeatureFlagComponent from './FeatureFlagComponent'
+
+export default FeatureFlagComponent
diff --git a/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx b/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx
index 757da3a2ac..e4726f72bf 100644
--- a/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx
+++ b/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx
@@ -3,7 +3,7 @@ import { useDispatch, useSelector } from 'react-redux'
import { io, Socket } from 'socket.io-client'
import { remove } from 'lodash'
-import { SocketEvent } from 'uiSrc/constants'
+import { SocketEvent, SocketFeaturesEvent } from 'uiSrc/constants'
import { NotificationEvent } from 'uiSrc/constants/notifications'
import { setNewNotificationAction } from 'uiSrc/slices/app/notifications'
import { setIsConnected } from 'uiSrc/slices/app/socket-connection'
@@ -11,6 +11,7 @@ import { getBaseApiUrl, Nullable } from 'uiSrc/utils'
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
import { setTotalUnread } from 'uiSrc/slices/recommendations/recommendations'
import { RecommendationsSocketEvents } from 'uiSrc/constants/recommendations'
+import { getFeatureFlagsSuccess } from 'uiSrc/slices/app/features'
const CommonAppSubscription = () => {
const { id: instanceId } = useSelector(connectedInstanceSelector)
@@ -38,6 +39,13 @@ const CommonAppSubscription = () => {
dispatch(setNewNotificationAction(data))
})
+ socketRef.current.on(SocketFeaturesEvent.Features, (data) => {
+ dispatch(getFeatureFlagsSuccess(data))
+
+ // or
+ // dispatch(fetchFeatureFlags())
+ })
+
// Catch disconnect
socketRef.current?.on(SocketEvent.Disconnect, () => {
unSubscribeFromAllRecommendations()
diff --git a/redisinsight/ui/src/components/index.ts b/redisinsight/ui/src/components/index.ts
index 9261f2c7ca..495a8350fb 100644
--- a/redisinsight/ui/src/components/index.ts
+++ b/redisinsight/ui/src/components/index.ts
@@ -25,6 +25,7 @@ import CodeBlock from './code-block'
import ShowChildByCondition from './show-child-by-condition'
import RecommendationVoting from './recommendation-voting'
import RecommendationCopyComponent from './recommendation-copy-component'
+import FeatureFlagComponent from './feature-flag-component'
export {
NavigationMenu,
@@ -57,4 +58,5 @@ export {
ShowChildByCondition,
RecommendationVoting,
RecommendationCopyComponent,
+ FeatureFlagComponent,
}
diff --git a/redisinsight/ui/src/constants/api.ts b/redisinsight/ui/src/constants/api.ts
index 3695f8ac1e..cb530c0165 100644
--- a/redisinsight/ui/src/constants/api.ts
+++ b/redisinsight/ui/src/constants/api.ts
@@ -109,6 +109,8 @@ enum ApiEndpoints {
REDISEARCH = 'redisearch',
REDISEARCH_SEARCH = 'redisearch/search',
HISTORY = 'history',
+
+ FEATURES = 'features',
}
export const DEFAULT_SEARCH_MATCH = '*'
diff --git a/redisinsight/ui/src/constants/featureFlags.ts b/redisinsight/ui/src/constants/featureFlags.ts
new file mode 100644
index 0000000000..7ad469600d
--- /dev/null
+++ b/redisinsight/ui/src/constants/featureFlags.ts
@@ -0,0 +1,3 @@
+export enum FeatureFlags {
+ liveRecommendations = 'liveRecommendations'
+}
diff --git a/redisinsight/ui/src/constants/index.ts b/redisinsight/ui/src/constants/index.ts
index 2dd89c36c9..a424dea36d 100644
--- a/redisinsight/ui/src/constants/index.ts
+++ b/redisinsight/ui/src/constants/index.ts
@@ -25,4 +25,5 @@ export * from './durationUnits'
export * from './streamViews'
export * from './bulkActions'
export * from './workbench'
+export * from './featureFlags'
export { ApiEndpoints, BrowserStorageItem, ApiStatusCode, apiErrors }
diff --git a/redisinsight/ui/src/constants/socketEvents.ts b/redisinsight/ui/src/constants/socketEvents.ts
index 903cdb29f9..303c58d6c3 100644
--- a/redisinsight/ui/src/constants/socketEvents.ts
+++ b/redisinsight/ui/src/constants/socketEvents.ts
@@ -3,3 +3,7 @@ export enum SocketEvent {
Disconnect = 'disconnect',
ConnectionError = 'connect_error',
}
+
+export enum SocketFeaturesEvent {
+ Features = 'features'
+}
diff --git a/redisinsight/ui/src/pages/instance/InstancePage.spec.tsx b/redisinsight/ui/src/pages/instance/InstancePage.spec.tsx
index 6b73edf8f2..5674b8bec9 100644
--- a/redisinsight/ui/src/pages/instance/InstancePage.spec.tsx
+++ b/redisinsight/ui/src/pages/instance/InstancePage.spec.tsx
@@ -6,6 +6,7 @@ import { instance, mock } from 'ts-mockito'
import { cleanup, mockedStore, render } from 'uiSrc/utils/test-utils'
import { BrowserStorageItem } from 'uiSrc/constants'
import { localStorageService } from 'uiSrc/services'
+import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
import InstancePage, { getDefaultSizes, Props } from './InstancePage'
const mockedProps = mock()
@@ -17,6 +18,15 @@ jest.mock('uiSrc/services', () => ({
},
}))
+jest.mock('uiSrc/slices/app/features', () => ({
+ ...jest.requireActual('uiSrc/slices/app/features'),
+ appFeatureFlagsFeaturesSelector: jest.fn().mockReturnValue({
+ liveRecommendations: {
+ flag: false
+ }
+ }),
+}))
+
let store: typeof mockedStore
beforeEach(() => {
cleanup()
@@ -50,7 +60,22 @@ describe('InstancePage', () => {
expect(queryByTestId('expand-cli')).toBeInTheDocument()
})
- it('should render with LiveTimeRecommendations Component', () => {
+ it('should not render LiveTimeRecommendations Component by default', () => {
+ const { queryByTestId } = render(
+
+
+
+ )
+
+ expect(queryByTestId('recommendations-trigger')).not.toBeInTheDocument()
+ })
+
+ it('should render LiveTimeRecommendations Component with feature flag', () => {
+ (appFeatureFlagsFeaturesSelector as jest.Mock).mockReturnValueOnce({
+ liveRecommendations: {
+ flag: true
+ }
+ })
const { queryByTestId } = render(
diff --git a/redisinsight/ui/src/pages/instance/InstancePage.tsx b/redisinsight/ui/src/pages/instance/InstancePage.tsx
index 07dc55baff..df3e1428b1 100644
--- a/redisinsight/ui/src/pages/instance/InstancePage.tsx
+++ b/redisinsight/ui/src/pages/instance/InstancePage.tsx
@@ -6,12 +6,16 @@ import cx from 'classnames'
import { setInitialAnalyticsSettings } from 'uiSrc/slices/analytics/settings'
import {
- fetchConnectedInstanceAction, fetchConnectedInstanceInfoAction,
+ fetchConnectedInstanceAction,
+ fetchConnectedInstanceInfoAction,
fetchInstancesAction,
getDatabaseConfigInfoAction,
instancesSelector,
} from 'uiSrc/slices/instances/instances'
-import { fetchRecommendationsAction, resetRecommendationsHighlighting } from 'uiSrc/slices/recommendations/recommendations'
+import {
+ fetchRecommendationsAction,
+ resetRecommendationsHighlighting
+} from 'uiSrc/slices/recommendations/recommendations'
import {
appContextSelector,
setAppContextConnectedInstanceId,
@@ -19,8 +23,9 @@ import {
setDbConfig,
} from 'uiSrc/slices/app/context'
import { resetPatternKeysData } from 'uiSrc/slices/browser/keys'
-import { BrowserStorageItem } from 'uiSrc/constants'
+import { BrowserStorageItem, FeatureFlags } from 'uiSrc/constants'
import { localStorageService } from 'uiSrc/services'
+import { FeatureFlagComponent } from 'uiSrc/components'
import { resetOutput } from 'uiSrc/slices/cli/cli-output'
import { cliSettingsSelector } from 'uiSrc/slices/cli/cli-settings'
import BottomGroupComponents from 'uiSrc/components/bottom-group-components/BottomGroupComponents'
@@ -123,7 +128,9 @@ const InstancePage = ({ routes = [] }: Props) => {
return (
<>
-
+
+
+
{
+ state.featureFlags.loading = true
+ },
+ getFeatureFlagsSuccess: (state, { payload }) => {
+ state.featureFlags.loading = false
+ state.featureFlags.features = payload.features
+ },
+ getFeatureFlagsFailure: (state) => {
+ state.featureFlags.loading = false
+ },
}
})
@@ -92,7 +110,10 @@ export const {
skipOnboarding,
setOnboardPrevStep,
setOnboardNextStep,
- setOnboarding
+ setOnboarding,
+ getFeatureFlags,
+ getFeatureFlagsSuccess,
+ getFeatureFlagsFailure
} = appFeaturesSlice.actions
export const appFeatureSelector = (state: RootState) => state.app.features
@@ -100,6 +121,8 @@ export const appFeatureHighlightingSelector = (state: RootState) => state.app.fe
export const appFeaturePagesHighlightingSelector = (state: RootState) => state.app.features.highlighting.pages
export const appFeatureOnboardingSelector = (state: RootState) => state.app.features.onboarding
+export const appFeatureFlagsSelector = (state: RootState) => state.app.features.featureFlags
+export const appFeatureFlagsFeaturesSelector = (state: RootState) => state.app.features.featureFlags.features
export default appFeaturesSlice.reducer
@@ -113,3 +136,26 @@ export function incrementOnboardStepAction(step: OnboardingSteps, skipCount = 0,
}
}
}
+
+export function fetchFeatureFlags(
+ onSuccessAction?: (data: any) => void,
+ onFailAction?: () => void
+) {
+ return async (dispatch: AppDispatch) => {
+ dispatch(getFeatureFlags())
+
+ try {
+ const { data, status } = await apiService.get(
+ ApiEndpoints.FEATURES
+ )
+
+ if (isStatusSuccessful(status)) {
+ dispatch(getFeatureFlagsSuccess(data))
+ onSuccessAction?.(data)
+ }
+ } catch (error) {
+ dispatch(getFeatureFlagsFailure())
+ onFailAction?.()
+ }
+ }
+}
diff --git a/redisinsight/ui/src/slices/interfaces/app.ts b/redisinsight/ui/src/slices/interfaces/app.ts
index 260801ade1..7623de7439 100644
--- a/redisinsight/ui/src/slices/interfaces/app.ts
+++ b/redisinsight/ui/src/slices/interfaces/app.ts
@@ -1,7 +1,7 @@
import { AxiosError } from 'axios'
import { RelativeWidthSizes } from 'uiSrc/components/virtual-table/interfaces'
import { Nullable } from 'uiSrc/utils'
-import { DurationUnits, ICommands } from 'uiSrc/constants'
+import { DurationUnits, FeatureFlags, ICommands } from 'uiSrc/constants'
import { IKeyPropTypes } from 'uiSrc/constants/prop-types/keys'
import { GetServerInfoResponse } from 'apiSrc/modules/server/dto/server.dto'
import { RedisString as RedisStringAPI } from 'apiSrc/common/constants/redis-string'
@@ -146,6 +146,11 @@ export interface StateAppSocketConnection {
isConnected: boolean
}
+export interface FeatureFlagComponent {
+ flag: boolean
+ variant?: string
+}
+
export interface StateAppFeatures {
highlighting: {
version: string
@@ -158,6 +163,12 @@ export interface StateAppFeatures {
currentStep: number
totalSteps: number
isActive: boolean
+ },
+ featureFlags: {
+ loading: boolean
+ features: {
+ [key in FeatureFlags]?: FeatureFlagComponent
+ }
}
}
export enum NotificationType {
diff --git a/redisinsight/ui/src/slices/tests/app/features.spec.ts b/redisinsight/ui/src/slices/tests/app/features.spec.ts
index ce598b937a..429adbf49b 100644
--- a/redisinsight/ui/src/slices/tests/app/features.spec.ts
+++ b/redisinsight/ui/src/slices/tests/app/features.spec.ts
@@ -9,7 +9,11 @@ import reducer, {
skipOnboarding,
setOnboardPrevStep,
setOnboardNextStep,
- incrementOnboardStepAction
+ incrementOnboardStepAction,
+ getFeatureFlags,
+ getFeatureFlagsSuccess,
+ getFeatureFlagsFailure,
+ fetchFeatureFlags
} from 'uiSrc/slices/app/features'
import {
cleanup,
@@ -18,6 +22,7 @@ import {
mockedStore,
mockStore
} from 'uiSrc/utils/test-utils'
+import { apiService } from 'uiSrc/services'
let store: typeof mockedStore
beforeEach(() => {
@@ -366,6 +371,87 @@ describe('slices', () => {
})
})
+ describe('getFeatureFlags', () => {
+ it('should properly set state', () => {
+ const state = {
+ ...initialState,
+ featureFlags: {
+ ...initialState.featureFlags,
+ loading: true
+ }
+ }
+
+ // Act
+ const nextState = reducer(initialState, getFeatureFlags())
+
+ // Assert
+ const rootState = Object.assign(initialStateDefault, {
+ app: { features: nextState },
+ })
+
+ expect(appFeatureSelector(rootState)).toEqual(state)
+ })
+ })
+
+ describe('getFeatureFlagsSuccess', () => {
+ it('should properly set state', () => {
+ const payload = {
+ features: {
+ liveRecommendations: {
+ flag: true
+ }
+ }
+ }
+ const state = {
+ ...initialState,
+ featureFlags: {
+ ...initialState.featureFlags,
+ features: payload.features,
+ }
+ }
+
+ // Act
+ const nextState = reducer(initialState, getFeatureFlagsSuccess(payload))
+
+ // Assert
+ const rootState = Object.assign(initialStateDefault, {
+ app: { features: nextState },
+ })
+
+ expect(appFeatureSelector(rootState)).toEqual(state)
+ })
+ })
+
+ describe('getFeatureFlagsFailure', () => {
+ it('should properly set state', () => {
+ const currentState = {
+ ...initialState,
+ featureFlags: {
+ ...initialState.featureFlags,
+ loading: true
+ }
+ }
+
+ const state = {
+ ...initialState,
+ featureFlags: {
+ ...initialState.featureFlags,
+ loading: false
+ }
+ }
+
+ // Act
+ const nextState = reducer(currentState, getFeatureFlagsFailure())
+
+ // Assert
+ const rootState = Object.assign(initialStateDefault, {
+ app: { features: nextState },
+ })
+
+ expect(appFeatureSelector(rootState)).toEqual(state)
+ })
+ })
+
// thunks
describe('incrementOnboardStepAction', () => {
it('should call setOnboardNextStep', async () => {
@@ -431,4 +517,48 @@ describe('slices', () => {
expect(mockedStore.getActions()).toEqual([])
})
})
+
+ describe('fetchFeatureFlags', () => {
+ it('succeed to fetch data', async () => {
+ // Arrange
+ const data = { features: { liveRecommendations: true } }
+ const responsePayload = { data, status: 200 }
+
+ apiService.get = jest.fn().mockResolvedValue(responsePayload)
+
+ // Act
+ await store.dispatch(fetchFeatureFlags())
+
+ // Assert
+ const expectedActions = [
+ getFeatureFlags(),
+ getFeatureFlagsSuccess(data),
+ ]
+
+ expect(store.getActions()).toEqual(expectedActions)
+ })
+
+ it('failed to fetch data', async () => {
+ const errorMessage = 'Something was wrong!'
+ const responsePayload = {
+ response: {
+ status: 500,
+ data: { message: errorMessage },
+ },
+ }
+
+ apiService.get = jest.fn().mockRejectedValue(responsePayload)
+
+ // Act
+ await store.dispatch(fetchFeatureFlags())
+
+ // Assert
+ const expectedActions = [
+ getFeatureFlags(),
+ getFeatureFlagsFailure(),
+ ]
+
+ expect(store.getActions()).toEqual(expectedActions)
+ })
+ })
})
diff --git a/redisinsight/ui/src/telemetry/checkAnalytics.ts b/redisinsight/ui/src/telemetry/checkAnalytics.ts
index 5ee4be792a..c38c2ac51e 100644
--- a/redisinsight/ui/src/telemetry/checkAnalytics.ts
+++ b/redisinsight/ui/src/telemetry/checkAnalytics.ts
@@ -5,4 +5,5 @@ import store from 'uiSrc/slices/store'
export const checkIsAnalyticsGranted = () =>
!!get(store.getState(), 'user.settings.config.agreements.analytics', false)
+export const getInfoServer = () => get(store.getState(), 'app.info.server', {})
export const getAppType = () => get(store.getState(), 'app.info.server.appType')
diff --git a/redisinsight/ui/src/telemetry/interfaces.ts b/redisinsight/ui/src/telemetry/interfaces.ts
index 87c4fe84c2..ee9243509b 100644
--- a/redisinsight/ui/src/telemetry/interfaces.ts
+++ b/redisinsight/ui/src/telemetry/interfaces.ts
@@ -8,7 +8,15 @@ export interface ITelemetryIdentify {
export interface ITelemetryService {
initialize(): Promise
- pageView(name: string, appType: string, databaseId?: string): Promise
+ pageView(
+ name: string,
+ params: {
+ buildType?: string
+ controlNumber?: number
+ controlGroup?: string
+ databaseId?: string
+ }
+ ): Promise
identify(opts: ITelemetryIdentify): Promise
event(opts: ITelemetryEvent): Promise
anonymousId: string
diff --git a/redisinsight/ui/src/telemetry/segment.ts b/redisinsight/ui/src/telemetry/segment.ts
index 035d02a7ff..db3b9b26c9 100644
--- a/redisinsight/ui/src/telemetry/segment.ts
+++ b/redisinsight/ui/src/telemetry/segment.ts
@@ -51,12 +51,15 @@ export class SegmentTelemetryService implements ITelemetryService {
return this._anonymousId
}
- async pageView(name: string, appType: string, databaseId?: string): Promise {
+ async pageView(
+ name: string,
+ properties: object
+ ): Promise {
return new Promise((resolve, reject) => {
try {
const pageInfo = this._getPageInfo()
const { page = {} } = { ...pageInfo }
- window.analytics.page(name, { databaseId, buildType: appType, ...page }, {
+ window.analytics.page(name, { ...properties, ...page }, {
context: {
ip: '0.0.0.0',
...pageInfo
diff --git a/redisinsight/ui/src/telemetry/telemetryUtils.ts b/redisinsight/ui/src/telemetry/telemetryUtils.ts
index 6217739b37..ed4659cc55 100644
--- a/redisinsight/ui/src/telemetry/telemetryUtils.ts
+++ b/redisinsight/ui/src/telemetry/telemetryUtils.ts
@@ -10,7 +10,7 @@ import { localStorageService } from 'uiSrc/services'
import { ApiEndpoints, BrowserStorageItem, KeyTypes, StreamViews } from 'uiSrc/constants'
import { KeyViewType } from 'uiSrc/slices/interfaces/keys'
import { StreamViewType } from 'uiSrc/slices/interfaces/stream'
-import { checkIsAnalyticsGranted, getAppType } from 'uiSrc/telemetry/checkAnalytics'
+import { checkIsAnalyticsGranted, getInfoServer } from 'uiSrc/telemetry/checkAnalytics'
import { AdditionalRedisModule } from 'apiSrc/modules/database/models/additional.redis.module'
import {
ITelemetrySendEvent,
@@ -60,13 +60,15 @@ const sendEventTelemetry = (payload: ITelemetrySendEvent) => {
const isAnalyticsGranted = checkIsAnalyticsGranted()
setAnonymousId(isAnalyticsGranted)
- const appType = getAppType()
+ const { appType: buildType, controlNumber, controlGroup } = getInfoServer() as Record
if (isAnalyticsGranted || nonTracking) {
return telemetryService?.event({
event,
properties: {
- buildType: appType,
+ buildType,
+ controlNumber,
+ controlGroup,
...eventData,
},
})
@@ -86,10 +88,19 @@ const sendPageViewTelemetry = (payload: ITelemetrySendPageView) => {
const isAnalyticsGranted = checkIsAnalyticsGranted()
setAnonymousId(isAnalyticsGranted)
- const appType = getAppType()
+
+ const { appType: buildType, controlNumber, controlGroup } = getInfoServer() as Record
if (isAnalyticsGranted || nonTracking) {
- telemetryService?.pageView(name, appType, databaseId)
+ telemetryService?.pageView(
+ name,
+ {
+ buildType,
+ controlNumber,
+ controlGroup,
+ databaseId
+ }
+ )
}
}
diff --git a/redisinsight/ui/src/utils/test-utils.tsx b/redisinsight/ui/src/utils/test-utils.tsx
index 8ec1e0507d..719f1b3e1a 100644
--- a/redisinsight/ui/src/utils/test-utils.tsx
+++ b/redisinsight/ui/src/utils/test-utils.tsx
@@ -216,7 +216,8 @@ jest.mock(
'uiSrc/telemetry/checkAnalytics',
() => ({
checkIsAnalyticsGranted: jest.fn(),
- getAppType: jest.fn()
+ getAppType: jest.fn(),
+ getInfoServer: jest.fn().mockReturnValue({}),
})
)